Button functionality using MCP23017 interrupts and bugfixes
This commit is contained in:
parent
cae31628c0
commit
fb1cd73acf
@ -7,6 +7,8 @@ std::map<int, std::string> screenNameMap;
|
|||||||
|
|
||||||
#ifndef NO_MCP
|
#ifndef NO_MCP
|
||||||
Adafruit_MCP23X17 mcp;
|
Adafruit_MCP23X17 mcp;
|
||||||
|
const int MCP_INT_PIN = 8;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
bool timerRunning = true;
|
bool timerRunning = true;
|
||||||
int fgColor;
|
int fgColor;
|
||||||
@ -49,6 +51,8 @@ void setupComponents()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Serial.println("MCP23017 ok");
|
Serial.println("MCP23017 ok");
|
||||||
|
pinMode(MCP_INT_PIN, INPUT);
|
||||||
|
mcp.setupInterrupts(true, false, LOW);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -65,6 +69,7 @@ void setupComponents()
|
|||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
mcp.pinMode(i, INPUT_PULLUP);
|
mcp.pinMode(i, INPUT_PULLUP);
|
||||||
|
mcp.setupInterruptPin(i, LOW);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -117,7 +122,8 @@ void setupPreferences()
|
|||||||
{SCREEN_TIME, "Time"},
|
{SCREEN_TIME, "Time"},
|
||||||
{SCREEN_HALVING_COUNTDOWN, "Halving countdown"}};
|
{SCREEN_HALVING_COUNTDOWN, "Halving countdown"}};
|
||||||
|
|
||||||
for (int i = 0; i < screenNameMap.size() ; i++) {
|
for (int i = 0; i < screenNameMap.size(); i++)
|
||||||
|
{
|
||||||
String key = "screen" + String(i) + "Visible";
|
String key = "screen" + String(i) + "Visible";
|
||||||
screenVisible[i] = preferences.getBool(key.c_str(), true); // Default to true if not set
|
screenVisible[i] = preferences.getBool(key.c_str(), true); // Default to true if not set
|
||||||
}
|
}
|
||||||
@ -149,8 +155,9 @@ void handleScreenTasks(uint screen)
|
|||||||
switch (currentScreen)
|
switch (currentScreen)
|
||||||
{
|
{
|
||||||
case SCREEN_BLOCK_HEIGHT:
|
case SCREEN_BLOCK_HEIGHT:
|
||||||
if (blockNotifyTaskHandle)
|
if (blockNotifyTaskHandle) {
|
||||||
vTaskResume(blockNotifyTaskHandle);
|
vTaskResume(blockNotifyTaskHandle);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SCREEN_HALVING_COUNTDOWN:
|
case SCREEN_HALVING_COUNTDOWN:
|
||||||
if (blockNotifyTaskHandle)
|
if (blockNotifyTaskHandle)
|
||||||
@ -165,8 +172,10 @@ void handleScreenTasks(uint screen)
|
|||||||
vTaskResume(getPriceTaskHandle);
|
vTaskResume(getPriceTaskHandle);
|
||||||
break;
|
break;
|
||||||
case SCREEN_TIME:
|
case SCREEN_TIME:
|
||||||
if (minuteTaskHandle)
|
if (minuteTaskHandle) {
|
||||||
|
TimeScreen::onActivate();
|
||||||
vTaskResume(minuteTaskHandle);
|
vTaskResume(minuteTaskHandle);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,7 +201,8 @@ void timebasedChangeTask(void *parameter)
|
|||||||
int newCurrentScreen = (getCurrentScreen() + 1) % screenCount;
|
int newCurrentScreen = (getCurrentScreen() + 1) % screenCount;
|
||||||
String key = "screen" + String(newCurrentScreen) + "Visible";
|
String key = "screen" + String(newCurrentScreen) + "Visible";
|
||||||
|
|
||||||
while (!preferences.getBool(key.c_str(), true)) {
|
while (!preferences.getBool(key.c_str(), true))
|
||||||
|
{
|
||||||
newCurrentScreen = (newCurrentScreen + 1) % screenCount;
|
newCurrentScreen = (newCurrentScreen + 1) % screenCount;
|
||||||
key = "screen" + String(newCurrentScreen) + "Visible";
|
key = "screen" + String(newCurrentScreen) + "Visible";
|
||||||
}
|
}
|
||||||
@ -203,6 +213,36 @@ void timebasedChangeTask(void *parameter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int modulo(int x,int N) {
|
||||||
|
return (x % N + N) %N;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nextScreen()
|
||||||
|
{
|
||||||
|
int newCurrentScreen = (getCurrentScreen() + 1) % screenCount;
|
||||||
|
String key = "screen" + String(newCurrentScreen) + "Visible";
|
||||||
|
|
||||||
|
while (!preferences.getBool(key.c_str(), true))
|
||||||
|
{
|
||||||
|
newCurrentScreen = (newCurrentScreen + 1) % screenCount;
|
||||||
|
key = "screen" + String(newCurrentScreen) + "Visible";
|
||||||
|
}
|
||||||
|
setCurrentScreen(newCurrentScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void previousScreen()
|
||||||
|
{
|
||||||
|
int newCurrentScreen = modulo(getCurrentScreen() - 1, screenCount);
|
||||||
|
String key = "screen" + String(newCurrentScreen) + "Visible";
|
||||||
|
|
||||||
|
while (!preferences.getBool(key.c_str(), true))
|
||||||
|
{
|
||||||
|
newCurrentScreen = modulo(newCurrentScreen - 1, screenCount);
|
||||||
|
key = "screen" + String(newCurrentScreen) + "Visible";
|
||||||
|
}
|
||||||
|
setCurrentScreen(newCurrentScreen);
|
||||||
|
}
|
||||||
|
|
||||||
void setLights(int r, int g, int b)
|
void setLights(int r, int g, int b)
|
||||||
{
|
{
|
||||||
#ifdef WITH_RGB_LED
|
#ifdef WITH_RGB_LED
|
||||||
|
@ -28,3 +28,6 @@ int getBgColor();
|
|||||||
int getFgColor();
|
int getFgColor();
|
||||||
|
|
||||||
void setupSoftAP();
|
void setupSoftAP();
|
||||||
|
void nextScreen();
|
||||||
|
void previousScreen();
|
||||||
|
int modulo(int x,int N);
|
@ -33,9 +33,6 @@ ESP32Time rtc(3600);
|
|||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
#ifdef ARDUINO_LOLIN_S3
|
|
||||||
delay(2500);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ARDUINO_ESP32S3_DEV
|
#ifdef ARDUINO_ESP32S3_DEV
|
||||||
pinMode(LED_BUILTIN, OUTPUT);
|
pinMode(LED_BUILTIN, OUTPUT);
|
||||||
|
@ -26,6 +26,10 @@ void TimeScreen::onNewMinute() {
|
|||||||
TimeScreen::showScreen();
|
TimeScreen::showScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TimeScreen::onActivate() {
|
||||||
|
TimeScreen::showScreen();
|
||||||
|
}
|
||||||
|
|
||||||
std::array<String, 7> TimeScreen::getEpdContent() {
|
std::array<String, 7> TimeScreen::getEpdContent() {
|
||||||
return TimeScreen::epdContent;
|
return TimeScreen::epdContent;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ class TimeScreen {
|
|||||||
static void init();
|
static void init();
|
||||||
static void showScreen();
|
static void showScreen();
|
||||||
static void onNewMinute();
|
static void onNewMinute();
|
||||||
|
static void onActivate();
|
||||||
static std::array<String, 7> getEpdContent();
|
static std::array<String, 7> getEpdContent();
|
||||||
static TimeScreen* getInstance();
|
static TimeScreen* getInstance();
|
||||||
};
|
};
|
@ -34,6 +34,7 @@ extern uint32_t moment;
|
|||||||
|
|
||||||
#ifndef NO_MCP
|
#ifndef NO_MCP
|
||||||
extern Adafruit_MCP23X17 mcp;
|
extern Adafruit_MCP23X17 mcp;
|
||||||
|
extern const int MCP_INT_PIN;
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_RGB_LED
|
#ifdef WITH_RGB_LED
|
||||||
extern Adafruit_NeoPixel pixels;
|
extern Adafruit_NeoPixel pixels;
|
||||||
|
@ -1,30 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* Button 1: No functionality
|
||||||
|
* Button 2: Next Screen
|
||||||
|
* Button 3: Previous Screen
|
||||||
|
* Button 4: Queue full EPD update
|
||||||
|
*/
|
||||||
|
|
||||||
#include "button.hpp"
|
#include "button.hpp"
|
||||||
#ifndef NO_MCP
|
#ifndef NO_MCP
|
||||||
TaskHandle_t buttonTaskHandle = NULL;
|
TaskHandle_t buttonTaskHandle = NULL;
|
||||||
// Define a type for the event callback
|
// Define a type for the event callback
|
||||||
std::vector<EventCallback> buttonEventCallbacks; // Define a vector to hold multiple event callbacks
|
std::vector<EventCallback> buttonEventCallbacks; // Define a vector to hold multiple event callbacks
|
||||||
|
volatile boolean buttonPressed = false;
|
||||||
|
|
||||||
void buttonTask(void *parameter)
|
void buttonTask(void *parameter)
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 4; i++)
|
if (!digitalRead(MCP_INT_PIN))
|
||||||
{
|
{
|
||||||
if (!mcp.digitalRead(i))
|
uint pin = mcp.getLastInterruptPin();
|
||||||
{
|
if (pin == 3) {
|
||||||
Serial.println("Button " + String(i) + " Pressed!");
|
xTaskCreate(fullRefresh, "FullRefresh", 2048, NULL, 1, NULL);
|
||||||
delay(250);
|
|
||||||
}
|
}
|
||||||
|
else if (pin == 1)
|
||||||
|
{
|
||||||
|
nextScreen();
|
||||||
|
}
|
||||||
|
else if (pin == 2)
|
||||||
|
{
|
||||||
|
previousScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(250); // debounce
|
||||||
|
mcp.clearInterrupts(); // clear
|
||||||
}
|
}
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(250));
|
vTaskDelay(pdMS_TO_TICKS(250));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR handleButtonInterrupt()
|
||||||
|
{
|
||||||
|
buttonPressed = true;
|
||||||
|
// Serial.println("ISR");
|
||||||
|
// uint pin = mcp.getLastInterruptPin();
|
||||||
|
|
||||||
|
// if (pin == 1)
|
||||||
|
// {
|
||||||
|
// nextScreen();
|
||||||
|
// }
|
||||||
|
// else if (pin == 2)
|
||||||
|
// {
|
||||||
|
// previousScreen();
|
||||||
|
// }
|
||||||
|
// vTaskDelay(pdMS_TO_TICKS(250));
|
||||||
|
|
||||||
|
// mcp.clearInterrupts();
|
||||||
|
}
|
||||||
|
|
||||||
void setupButtonTask()
|
void setupButtonTask()
|
||||||
{
|
{
|
||||||
xTaskCreate(buttonTask, "MinuteTask", 2048, NULL, 1, &buttonTaskHandle); // Create the FreeRTOS task
|
xTaskCreate(buttonTask, "ButtonTask", 4096, NULL, 1, &buttonTaskHandle); // Create the FreeRTOS task
|
||||||
|
// Use interrupt instead of task
|
||||||
|
// attachInterrupt(MCP_INT_PIN, handleButtonInterrupt, FALLING);
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerNewButtonCallback(EventCallback cb)
|
void registerNewButtonCallback(EventCallback cb)
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <freertos/task.h>
|
#include <freertos/task.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "shared.hpp"
|
#include "shared.hpp"
|
||||||
|
#include "lib/functions.hpp"
|
||||||
|
|
||||||
extern TaskHandle_t buttonTaskHandle;
|
extern TaskHandle_t buttonTaskHandle;
|
||||||
|
|
||||||
@ -14,4 +15,6 @@ extern TaskHandle_t buttonTaskHandle;
|
|||||||
void buttonTask(void *pvParameters);
|
void buttonTask(void *pvParameters);
|
||||||
void setupButtonTask();
|
void setupButtonTask();
|
||||||
void registerNewButtonCallback(EventCallback cb);
|
void registerNewButtonCallback(EventCallback cb);
|
||||||
|
void IRAM_ATTR handleButtonInterrupt();
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -2,15 +2,14 @@
|
|||||||
|
|
||||||
#ifdef IS_S3
|
#ifdef IS_S3
|
||||||
// reversed
|
// reversed
|
||||||
const int EPD_CS[7] = {17, 21, 33, 10, 6, 4, 2};
|
// const int EPD_CS[7] = {17, 21, 33, 10, 6, 4, 2};
|
||||||
const int EPD_BUSY[7] = {16, 18, 37, 9, 7, 5, 3};
|
// const int EPD_BUSY[7] = {16, 18, 37, 9, 7, 5, 3};
|
||||||
const int EPD_RESET_MPD[7] = {14, 13, 12, 11, 10, 9, 8};
|
// const int EPD_RESET_MPD[7] = {14, 13, 12, 11, 10, 9, 8};
|
||||||
|
|
||||||
|
const int EPD_CS[7] = {2, 4, 6, 10, 33, 21, 17};
|
||||||
|
const int EPD_BUSY[7] = {3, 5, 7, 9, 37, 18, 16};
|
||||||
|
const int EPD_RESET_MPD[7] = {8, 9, 10, 11, 12, 13, 14};
|
||||||
|
|
||||||
//const int EPD_CS[7] = {2, 4, 6, 10, 33, 21, 17};
|
|
||||||
//const int EPD_BUSY[7] = {3, 5, 7, 9, 37, 18, 16};
|
|
||||||
//const int EPD_RESET_MPD[7] = {8, 9, 10, 11, 12, 13, 14};
|
|
||||||
// const int EPD_CS[7] = {2, 4, 10, 38, 34, 21, 17};
|
|
||||||
// const int EPD_BUSY[7] = {3, 5, 9, 36, 35, 18, 16};
|
|
||||||
const int EPD_DC = 14;
|
const int EPD_DC = 14;
|
||||||
const int RST_PIN = 15;
|
const int RST_PIN = 15;
|
||||||
#elif defined(IS_S2)
|
#elif defined(IS_S2)
|
||||||
@ -90,6 +89,7 @@ void setupDisplays()
|
|||||||
|
|
||||||
void resetAllDisplays()
|
void resetAllDisplays()
|
||||||
{
|
{
|
||||||
|
#ifdef NO_MCP
|
||||||
digitalWrite(RST_PIN, HIGH);
|
digitalWrite(RST_PIN, HIGH);
|
||||||
pinMode(RST_PIN, OUTPUT);
|
pinMode(RST_PIN, OUTPUT);
|
||||||
delay(20);
|
delay(20);
|
||||||
@ -97,16 +97,11 @@ void resetAllDisplays()
|
|||||||
delay(20);
|
delay(20);
|
||||||
digitalWrite(RST_PIN, HIGH);
|
digitalWrite(RST_PIN, HIGH);
|
||||||
delay(200);
|
delay(200);
|
||||||
|
#else
|
||||||
// for (int i = 8; i < 16; i++) {
|
for (int i = 0; i < displaySize; i++) {
|
||||||
// mcp.digitalWrite(i, HIGH);
|
resetSingleDisplay(i);
|
||||||
// mcp.pinMode(i, OUTPUT);
|
}
|
||||||
// delay(20);
|
#endif NO_MCP
|
||||||
// mcp.digitalWrite(i, LOW);
|
|
||||||
// delay(20);
|
|
||||||
// mcp.digitalWrite(i, HIGH);
|
|
||||||
// delay(200);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetSingleDisplay(int i)
|
void resetSingleDisplay(int i)
|
||||||
@ -318,10 +313,8 @@ void updateDisplay(void *pvParameters)
|
|||||||
if (epdContent[epdIndex].compareTo(currentEpdContent[epdIndex]) != 0)
|
if (epdContent[epdIndex].compareTo(currentEpdContent[epdIndex]) != 0)
|
||||||
{
|
{
|
||||||
currentEpdContent[epdIndex] = epdContent[epdIndex];
|
currentEpdContent[epdIndex] = epdContent[epdIndex];
|
||||||
// resetSingleDisplay(epdIndex);
|
|
||||||
#ifndef NO_MCP
|
#ifndef NO_MCP
|
||||||
displays[epdIndex].init(0, false);
|
displays[epdIndex].init(0, false);
|
||||||
delay(displays[epdIndex].epd2.power_on_time);
|
|
||||||
resetSingleDisplay(epdIndex);
|
resetSingleDisplay(epdIndex);
|
||||||
#endif
|
#endif
|
||||||
// displays[epdIndex].init(0, false);
|
// displays[epdIndex].init(0, false);
|
||||||
@ -344,7 +337,6 @@ void updateDisplay(void *pvParameters)
|
|||||||
}
|
}
|
||||||
|
|
||||||
displays[epdIndex].display(updatePartial);
|
displays[epdIndex].display(updatePartial);
|
||||||
// displays[epdIndex].powerOff();
|
|
||||||
displays[epdIndex].hibernate();
|
displays[epdIndex].hibernate();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -356,9 +348,8 @@ void showSetupQr(String ssid, String password)
|
|||||||
{
|
{
|
||||||
int displayIndex = 6;
|
int displayIndex = 6;
|
||||||
|
|
||||||
const String text = "WIFI:S:" + ssid + ";T:WPA;P:" + password + ";;"; // User-supplied text
|
const String text = "WIFI:S:" + ssid + ";T:WPA;P:" + password + ";;";
|
||||||
|
|
||||||
// genQrCode(text, &qrcode);
|
|
||||||
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
|
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
|
||||||
bool ok = qrcodegen_encodeText(text.c_str(), tempBuffer, qrcode, qrcodegen_Ecc_LOW,
|
bool ok = qrcodegen_encodeText(text.c_str(), tempBuffer, qrcode, qrcodegen_Ecc_LOW,
|
||||||
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
|
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
|
||||||
@ -367,8 +358,7 @@ void showSetupQr(String ssid, String password)
|
|||||||
|
|
||||||
const int padding = floor(float(displays[displayIndex].width() - (size * 4)) / 2);
|
const int padding = floor(float(displays[displayIndex].width() - (size * 4)) / 2);
|
||||||
const int paddingY = floor(float(displays[displayIndex].height() - (size * 4)) / 2);
|
const int paddingY = floor(float(displays[displayIndex].height() - (size * 4)) / 2);
|
||||||
// displays[displayIndex].setRotation(0);
|
|
||||||
// displays[displayIndex].setFullWindow();
|
|
||||||
displays[displayIndex].setPartialWindow(0, 0, displays[displayIndex].width(), displays[displayIndex].height());
|
displays[displayIndex].setPartialWindow(0, 0, displays[displayIndex].width(), displays[displayIndex].height());
|
||||||
displays[displayIndex].firstPage();
|
displays[displayIndex].firstPage();
|
||||||
|
|
||||||
@ -439,8 +429,6 @@ void showSetupQr(String ssid, String password)
|
|||||||
|
|
||||||
for (int i = 1; i < displaySize; (i = i+2)) {
|
for (int i = 1; i < displaySize; (i = i+2)) {
|
||||||
displays[i].setPartialWindow(0, 0, displays[i].width(), displays[i].height());
|
displays[i].setPartialWindow(0, 0, displays[i].width(), displays[i].height());
|
||||||
// displays[i].firstPage();
|
|
||||||
|
|
||||||
displays[i].fillScreen(GxEPD_WHITE);
|
displays[i].fillScreen(GxEPD_WHITE);
|
||||||
displays[i].display(true);
|
displays[i].display(true);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user