Skip to content

Instantly share code, notes, and snippets.

@hollyhockberry
Created October 24, 2023 09:32
Show Gist options
  • Save hollyhockberry/855b37ad9d6670d911c04a6566a09b08 to your computer and use it in GitHub Desktop.
Save hollyhockberry/855b37ad9d6670d911c04a6566a09b08 to your computer and use it in GitHub Desktop.
M5Dial + Unit IR Sample
// Copyright (c) 2023 Inaba (@hollyhockberry)
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
#include <M5Unified.h>
#include <driver/pcnt.h>
#include <IRsend.h>
#include <IRrecv.h>
#include <limits>
struct {
bool enable;
uint64_t up, down;
} remote_codes = { .enable = false };
static IRsend* irsend = nullptr;
static IRrecv* irrecv = nullptr;
void init_pcnt() {
pcnt_config_t cfg = {
.pulse_gpio_num = 40,
.ctrl_gpio_num = 41,
.lctrl_mode = PCNT_MODE_KEEP,
.hctrl_mode = PCNT_MODE_REVERSE,
.pos_mode = PCNT_COUNT_INC,
.neg_mode = PCNT_COUNT_DEC,
.counter_h_lim = 32767,
.counter_l_lim = -32768,
.unit = PCNT_UNIT_0,
.channel = PCNT_CHANNEL_0
};
::pcnt_unit_config(&cfg);
::pcnt_counter_pause(PCNT_UNIT_0);
::pcnt_counter_clear(PCNT_UNIT_0);
::pcnt_counter_resume(PCNT_UNIT_0);
}
int16_t get_pcnt() {
int16_t count = 0;
::pcnt_get_counter_value(PCNT_UNIT_0, &count);
return count;
}
void drawBar(bool ok) {
const auto w = M5.Display.width();
const auto y = M5.Display.height() * 0.7;
const auto font = M5.Display.fontHeight();
M5.Display.fillRect(0, y, w, font * 2, ok ? TFT_RED : TFT_BLUE);
M5.Display.setTextDatum(middle_center);
M5.Display.setTextColor(TFT_WHITE, ok ? TFT_RED : TFT_BLUE);
M5.Display.drawString(ok ? "OK" : "Cancel", w / 2, y + font);
}
bool okcancel() {
bool res = true;
drawBar(res);
auto last = get_pcnt();
while (true) {
M5.update();
auto pcnt = get_pcnt();
if (last != pcnt) {
M5.Speaker.tone(2000, 20);
res = last < pcnt;
last =pcnt;
drawBar(res);
}
if (M5.BtnA.wasPressed()) {
M5.Speaker.tone(8000, 20);
return res;
}
m5gfx::delay(10);
}
}
bool recv(const char* message, uint64_t& code) {
const auto w = M5.Display.width();
const auto h = M5.Display.height();
M5.Display.clear();
M5.Display.setTextDatum(middle_center);
M5.Display.setTextColor(TFT_WHITE, TFT_TRANSPARENT);
M5.Display.drawString(message, w / 2, h * 0.3);
while (true) {
decode_results dr;
if (irrecv->decode(&dr)) {
irrecv->resume();
if (dr.value == UINT64_MAX) {
continue;
}
M5.Speaker.tone(4000, 20);
M5.Display.drawString(String(dr.value, HEX), w / 2, h / 2);
code = dr.value;
return okcancel();
}
m5gfx::delay(10);
}
}
void send(bool up) {
const uint64_t code = up ? remote_codes.up : remote_codes.down;
irsend->sendNEC(code, 32);
m5gfx::delay(100);
}
void setup() {
M5.begin();
M5.Display.setTextSize(2);
irsend = new IRsend(M5.getPin(m5::port_b_out));
irsend->begin();
irrecv = new IRrecv(M5.getPin(m5::port_b_in));
irrecv->enableIRIn();
init_pcnt();
}
void loop() {
static uint16_t last;
if (!remote_codes.enable) {
// receive remote code
while(!recv("Wait code for UP", remote_codes.up));
while(!recv("Wait code for DOWN", remote_codes.down));
remote_codes.enable = true;
M5.Display.clear();
last = get_pcnt();
return;
}
M5.update();
if (M5.BtnA.wasPressed()) {
remote_codes.enable = false;
M5.Speaker.tone(8000, 20);
return;
}
const auto curr = get_pcnt();
if (last != curr) {
send(curr > last);
last = curr;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment