Created
October 24, 2023 09:32
-
-
Save hollyhockberry/855b37ad9d6670d911c04a6566a09b08 to your computer and use it in GitHub Desktop.
M5Dial + Unit IR Sample
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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