diff --git a/README.md b/README.md
index bfd445c..d2c68d9 100644
--- a/README.md
+++ b/README.md
@@ -5,9 +5,9 @@
* DE: Ich habe ein primär deutschsprachiges Forum aufgesetzt, welches ich mit reichlich Doku versehen habe. Würde mich freuen, euch dort zu sehen: https://forum.espuino.de. Ihr könnt euch dort mit eurem Github-Login einloggen, jedoch auch "normal" anmelden. Dokumenation findet ihr insbesondere hier: https://forum.espuino.de/c/dokumentation/anleitungen/10
## Changelog
Moved to [another location](changelog.md) as it became to prominent here. Only last three events are kept:
-* 25.02.2020: Added support for .m4a and .wav-files.
-* 26.02.2020: Shutdown via webgui is now available.
-* 05.03.2020: Added support for remote control via infrared. Make sure to enable `IR_CONTROL_ENABLE` to use this feature and don't forget to assign corresponding rc-commands of *your* remote control to actions.
+* 26.02.2021: Shutdown via webgui is now available.
+* 05.03.2021: Added support for remote control via infrared. Make sure to enable `IR_CONTROL_ENABLE` to use this feature and don't forget to assign corresponding rc-commands of *your* remote control to actions.
+* 19.03.2021: Added support for port-expander PCA9555. Can be used for everything, that is "button-like": buttons, headphone-detect, PN5180.IRQ.
## Known bugs
* Some webstreams don't run. Guess it's a combination of saturated connection-pool and lack of heap-memory. Works probably better if ESP32-WROVER (e.g. Lolin D32 pro) is used, as this chip has PSRAM. Advice: Don't enable modules (e.g. MQTT) if you don't need them as this could save memory (and trouble).
* English translation/version for webgui is currently pretty outdated. This will be fixed soon when i18n-support will be integrated.
@@ -219,6 +219,10 @@ This toggles the current WiFi-status: if it's currently enabled, it will be disa
## Bluetooth
ESPuino can be used as bluetooth-sink (a2dp). This mode can be enabled/disabled via a RFID-modification-card. Applying one will restart ESPuino immediately. Two modes are available which are toggled in between: "normal" and "bluetooth". Normal means: SD + WiFi are available whereas in mode "bluetooth" only bluetooth-support can be provided. If bluetooth is active, this is indicated by four slow rotating *blue* LEDs. Now you can stream to your ESPuino e.g. with your mobile device. Tested this with Android 8 and worked 100% flawless.
+
+## Port-expander
+There might be situations where you run out of GPIOs. To address this, port-expander [PCA9555](https://www.nxp.com/docs/en/data-sheet/PCA9555.pdf) can be used to extend number of input-channels (output-mode is not supported by ESPuino). This port-expander provides 2 ports with 8 channels each - so 16 channels in total. To activate PCA9555 you need to set `PORT_EXPANDER_ENABLE`. Like GPIOs in your develboard-specific settings-file, you can assign numbers. Range is 100->115 where 100: port 0 channel 0 -> 107: port 0 channel 7; 108: port 1 channel 0 -> 115: port 1 channel 7. If you only need 8 channels: connect stuff only to port 0 and change `portsToRead` to 1. Via `expanderI2cAddress` port-expander's I2C-address can be changed. 0x20 is true, if all A0, A1, A2 are wired to GND.
+Port-expander is read by hardware-timer. Interrupt-pin can be connected optionally and is only used to wake up ESP32. If so I suggest to use `WAKEUP_BUTTON`.
## After ESPuino is connected to your WiFi
After bringing ESPuino part of your LAN/WiFi, the 'regular' webgui is available at the IP assigned by your router (or the configured hostname). Using this GUI, you can configure:
* WiFi
diff --git a/changelog.md b/changelog.md
index a2f4f41..e70e41a 100644
--- a/changelog.md
+++ b/changelog.md
@@ -18,17 +18,18 @@
* 20.12.2020: Due to memory-issues with webstreams, FTP needs to be activated by pressing pause+next-button now
More to come...
* 23.12.2020: User-config is now split into general part (settings.h) and develboard-specific part (e.g. settings-lolin32.h)
-* 13.01.2020: Added fileexlorer to webgui (thanks @grch87 for contribution!). Now files and directories can be renamed, uploaded and deleted via webgui.
-* 17.01.2020: Added directive `STATIC_IP_ENABLE`: (optional) static IPv4-configuration
-* 18.01.2020: Added directive `PN5180_ENABLE_LPCD`: awake from deepsleep with PN5180 is now possible (but needs another GPIO)
-* 25.01.2020: Added directive `USE_LAST_VOLUME_AFTER_REBOOT`: Remembers volume used at last shutdown after reboot. This overwrites initial volume from GUI.
-* 28.01.2020: Removed cached RFID-filebrowser and replaced by realtime-browser
-* 01.02.2020: Introducing PCB: Lolin32 with SD_MMC + PN5180
-* 06.02.2020: German umlauts now supported. When uploading via FTP make sure to change charset to CP437.
-* 09.02.2020: Added support for bluetooth-sink (a2dp). Thanks @grch87 & @elmar-ops for providing this feature!
-* 25.02.2020: Added support for dynamic button-layout. Rotary-encoder is now optional and up to five buttons can be used.
-* 25.02.2020: Actions can be freely assigned to buttons (multi-button, single-button (short), single-button (long))
-* 25.02.2020: Added support for webcontrol: basic control (volume, play/pause, next, previous, first, last track) can now be controlled via webgui.
-* 25.02.2020: Added support for .m4a and .wav-files.
-* 26.02.2020: Shutdown via webgui is now available.
-* 05.03.2020: Added support for remote control via infrared. Make sure to enable `IR_CONTROL_ENABLE` to use this feature and don't forget to assign corresponding rc-commands of *your* remote control to actions.
+* 13.01.2021: Added fileexlorer to webgui (thanks @grch87 for contribution!). Now files and directories can be renamed, uploaded and deleted via webgui.
+* 17.01.2021: Added directive `STATIC_IP_ENABLE`: (optional) static IPv4-configuration
+* 18.01.2021: Added directive `PN5180_ENABLE_LPCD`: awake from deepsleep with PN5180 is now possible (but needs another GPIO)
+* 25.01.2021: Added directive `USE_LAST_VOLUME_AFTER_REBOOT`: Remembers volume used at last shutdown after reboot. This overwrites initial volume from GUI.
+* 28.01.2021: Removed cached RFID-filebrowser and replaced by realtime-browser
+* 01.02.2021: Introducing PCB: Lolin32 with SD_MMC + PN5180
+* 06.02.2021: German umlauts now supported. When uploading via FTP make sure to change charset to CP437.
+* 09.02.2021: Added support for bluetooth-sink (a2dp). Thanks @grch87 & @elmar-ops for providing this feature!
+* 25.02.2021: Added support for dynamic button-layout. Rotary-encoder is now optional and up to five buttons can be used.
+* 25.02.2021: Actions can be freely assigned to buttons (multi-button, single-button (short), single-button (long))
+* 25.02.2021: Added support for webcontrol: basic control (volume, play/pause, next, previous, first, last track) can now be controlled via webgui.
+* 25.02.2021: Added support for .m4a and .wav-files.
+* 26.02.2021: Shutdown via webgui is now available.
+* 05.03.2021: Added support for remote control via infrared. Make sure to enable `IR_CONTROL_ENABLE` to use this feature and don't forget to assign corresponding rc-commands of *your* remote control to actions.
+* 19.03.2021: Added support for port-expander PCA9555. Can be used for everything, that is "button-like": buttons, headphone-detect, PN5180.IRQ.
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index 3e22911..1a872cd 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -47,8 +47,10 @@
#ifdef RFID_READER_TYPE_MFRC522_SPI
#include
#endif
-#ifdef RFID_READER_TYPE_MFRC522_I2C
+#if defined(RFID_READER_TYPE_MFRC522_I2C) || defined(PORT_EXPANDER_ENABLE)
#include "Wire.h"
+#endif
+#ifdef RFID_READER_TYPE_MFRC522_I2C
#include
#endif
#ifdef RFID_READER_TYPE_PN5180
@@ -259,6 +261,18 @@ TaskHandle_t fileStorageTaskHandle;
TaskHandle_t LED;
#endif
+// I2C
+#if defined(RFID_READER_TYPE_MFRC522_I2C) || defined(PORT_EXPANDER_ENABLE)
+ static TwoWire i2cBusTwo = TwoWire(1);
+#endif
+#ifdef RFID_READER_TYPE_MFRC522_I2C
+ static MFRC522 mfrc522(MFRC522_ADDR, MFRC522_RST_PIN, i2cBusTwo);
+#endif
+
+#ifdef PORT_EXPANDER_ENABLE
+ uint8_t expanderPorts[portsToRead];
+#endif
+
#if (HAL == 2)
#include "AC101.h"
static TwoWire i2cBusOne = TwoWire(0);
@@ -267,10 +281,6 @@ TaskHandle_t fileStorageTaskHandle;
#ifdef RFID_READER_TYPE_MFRC522_SPI
static MFRC522 mfrc522(RFID_CS, RST_PIN);
#endif
-#ifdef RFID_READER_TYPE_MFRC522_I2C
- static TwoWire i2cBusTwo = TwoWire(1);
- static MFRC522 mfrc522(MFRC522_ADDR, MFRC522_RST_PIN, i2cBusTwo);
-#endif
// FTP
#ifdef FTP_ENABLE
@@ -327,24 +337,40 @@ QueueHandle_t rfidCardQueue;
RingbufHandle_t explorerFileUploadRingBuffer;
QueueHandle_t explorerFileUploadStatusQueue;
-// Only enable those buttons that use GPIOs <= 39
+// Only enable those buttons that are not disabled (99 or >115)
+// 0 -> 39: GPIOs
+// 100 -> 115: Port-expander
#if (NEXT_BUTTON >= 0 && NEXT_BUTTON <= 39)
#define BUTTON_0_ENABLE
+#elif (NEXT_BUTTON >= 100 && NEXT_BUTTON <= 115)
+ #define EXPANDER_0_ENABLE
#endif
#if (PREVIOUS_BUTTON >= 0 && PREVIOUS_BUTTON <= 39)
#define BUTTON_1_ENABLE
+#elif (PREVIOUS_BUTTON >= 100 && PREVIOUS_BUTTON <= 115)
+ #define EXPANDER_1_ENABLE
#endif
#if (PAUSEPLAY_BUTTON >= 0 && PAUSEPLAY_BUTTON <= 39)
#define BUTTON_2_ENABLE
+#elif (PAUSEPLAY_BUTTON >= 100 && PAUSEPLAY_BUTTON <= 115)
+ #define EXPANDER_2_ENABLE
#endif
#ifdef USEROTARY_ENABLE
- #define BUTTON_3_ENABLE
+ #if (DREHENCODER_BUTTON >= 0 && DREHENCODER_BUTTON <= 39)
+ #define BUTTON_3_ENABLE
+ #elif (DREHENCODER_BUTTON >= 100 && DREHENCODER_BUTTON <= 115)
+ #define EXPANDER_3_ENABLE
+ #endif
#endif
#if (BUTTON_4 >= 0 && BUTTON_4 <= 39)
#define BUTTON_4_ENABLE
+#elif (BUTTON_4 >= 100 && BUTTON_4 <= 115)
+ #define EXPANDER_4_ENABLE
#endif
#if (BUTTON_5 >= 0 && BUTTON_5 <= 39)
#define BUTTON_5_ENABLE
+#elif (BUTTON_5 >= 100 && BUTTON_5 <= 115)
+ #define EXPANDER_5_ENABLE
#endif
// Prototypes
@@ -353,6 +379,7 @@ static int arrSortHelper(const void* a, const void* b);
void batteryVoltageTester(void);
void buttonHandler();
void deepSleepManager(void);
+bool digitalReadFromAll(const uint8_t _channel);
void doButtonActions(void);
void doRfidCardModifications(const uint32_t mod);
void doCmdAction(const uint16_t mod);
@@ -385,6 +412,9 @@ float measureBatteryVoltage(void);
#endif
size_t nvsRfidWriteWrapper (const char *_rfidCardId, const char *_track, const uint32_t _playPosition, const uint8_t _playMode, const uint16_t _trackLastPlayed, const uint16_t _numberOfTracks);
void onWebsocketEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len);
+#ifdef PORT_EXPANDER_ENABLE
+ bool portExpanderHandler();
+#endif
bool processJsonRequest(char *_serialJson);
void randomizePlaylist (char *str[], const uint32_t count);
char ** returnPlaylistFromWebstream(const char *_webUrl);
@@ -431,19 +461,6 @@ void logger(const uint8_t _currentLogLevel, const char *_logBuffer, const uint8_
}
-int countChars(const char* string, char ch) {
- int count = 0;
- int length = strlen(string);
-
- for (uint8_t i = 0; i < length; i++) {
- if (string[i] == ch) {
- count++;
- }
- }
-
- return count;
-}
-
void IRAM_ATTR onTimer() {
xSemaphoreGiveFromISR(timerSemaphore, NULL);
}
@@ -510,6 +527,52 @@ void IRAM_ATTR onTimer() {
}
#endif
+#ifdef PORT_EXPANDER_ENABLE
+ // Reads input from port-expander and writes output into global array
+ // Datasheet: https://www.nxp.com/docs/en/data-sheet/PCA9555.pdf
+ bool portExpanderHandler() {
+ i2cBusTwo.beginTransmission(expanderI2cAddress);
+ for (uint8_t i=0; i 107
+ return (expanderPorts[1] & (1 << (_channel-108))); // Remove offset 100 + 8 (return false if pressed)
+ } else {
+ return true;
+ }
+
+ #endif
+
+ default: // Everything else (doesn't make sense at all) isn't supposed to be pressed
+ return true;
+ }
+}
+
// If timer-semaphore is set, read buttons (unless controls are locked)
void buttonHandler() {
@@ -517,24 +580,30 @@ void buttonHandler() {
if (lockControls) {
return;
}
+ #ifdef PORT_EXPANDER_ENABLE
+ portExpanderHandler();
+ #endif
unsigned long currentTimestamp = millis();
- #ifdef BUTTON_0_ENABLE
- buttons[0].currentState = digitalRead(NEXT_BUTTON);
+
+ // Buttons can be mixed between GPIO and port-expander.
+ // But at the same time only one of them can be for example NEXT_BUTTON
+ #if defined(BUTTON_0_ENABLE) || defined(EXPANDER_0_ENABLE)
+ buttons[0].currentState = digitalReadFromAll(NEXT_BUTTON);
#endif
- #ifdef BUTTON_1_ENABLE
- buttons[1].currentState = digitalRead(PREVIOUS_BUTTON);
+ #if defined(BUTTON_1_ENABLE) || defined(EXPANDER_1_ENABLE)
+ buttons[1].currentState = digitalReadFromAll(PREVIOUS_BUTTON);
#endif
- #ifdef BUTTON_2_ENABLE
- buttons[2].currentState = digitalRead(PAUSEPLAY_BUTTON);
+ #if defined(BUTTON_2_ENABLE) || defined(EXPANDER_2_ENABLE)
+ buttons[2].currentState = digitalReadFromAll(PAUSEPLAY_BUTTON);
#endif
- #ifdef BUTTON_3_ENABLE
- buttons[3].currentState = digitalRead(DREHENCODER_BUTTON);
+ #if defined(BUTTON_3_ENABLE) || defined(EXPANDER_3_ENABLE)
+ buttons[3].currentState = digitalReadFromAll(DREHENCODER_BUTTON);
#endif
- #ifdef BUTTON_4_ENABLE
- buttons[4].currentState = digitalRead(BUTTON_4);
+ #if defined(BUTTON_4_ENABLE) || defined(EXPANDER_4_ENABLE)
+ buttons[4].currentState = digitalReadFromAll(BUTTON_4);
#endif
- #ifdef BUTTON_5_ENABLE
- buttons[5].currentState = digitalRead(BUTTON_5);
+ #if defined(BUTTON_5_ENABLE) || defined(EXPANDER_5_ENABLE)
+ buttons[5].currentState = digitalReadFromAll(BUTTON_5);
#endif
// Iterate over all buttons in struct-array
@@ -551,15 +620,12 @@ void buttonHandler() {
buttons[i].lastState = buttons[i].currentState;
}
}
+ doButtonActions();
}
// Do corresponding actions for all buttons
void doButtonActions(void) {
- if (lockControls) {
- return; // Avoid button-handling if buttons are locked
- }
-
if (buttons[0].isPressed && buttons[1].isPressed) {
buttons[0].isPressed = false;
buttons[1].isPressed = false;
@@ -2355,7 +2421,7 @@ void gotoLPCD() {
Serial.println(F("prepare low power card detection..."));
nfc.prepareLPCD();
nfc.clearIRQStatus(0xffffffff);
- Serial.print(F("PN5180 IRQ PIN: ")); Serial.println(digitalRead(RFID_IRQ));
+ Serial.print(F("PN5180 IRQ PIN: ")); Serial.println(digitalReadFromAll(RFID_IRQ));
// turn on LPCD
uint16_t wakeupCounterInMs = 0x3FF; // must be in the range of 0x0 - 0xA82. max wake-up time is 2960 ms.
if (nfc.switchToLPCD(wakeupCounterInMs)) {
@@ -3739,7 +3805,7 @@ void setupVolume(void) {
maxVolume = maxVolumeSpeaker;
return;
#else
- if (digitalRead(HP_DETECT)) {
+ if (digitalReadFromAll(HP_DETECT)) {
maxVolume = maxVolumeSpeaker; // 1 if headphone is not connected
} else {
maxVolume = maxVolumeHeadphone; // 0 if headphone is connected (put to GND)
@@ -3753,7 +3819,7 @@ void setupVolume(void) {
#ifdef HEADPHONE_ADJUST_ENABLE
void headphoneVolumeManager(void) {
- bool currentHeadPhoneDetectionState = digitalRead(HP_DETECT);
+ bool currentHeadPhoneDetectionState = digitalReadFromAll(HP_DETECT);
if (headphoneLastDetectionState != currentHeadPhoneDetectionState && (millis() - headphoneLastDetectionTimestamp >= headphoneLastDetectionDebounce)) {
if (currentHeadPhoneDetectionState) {
@@ -4330,7 +4396,7 @@ void printWakeUpReason() {
nfc14443.setupRF();
if (!nfc14443.isCardPresent()) {
nfc14443.clearIRQStatus(0xffffffff);
- Serial.print(F("Logic level at PN5180' IRQ-PIN: ")); Serial.println(digitalRead(RFID_IRQ));
+ Serial.print(F("Logic level at PN5180' IRQ-PIN: ")); Serial.println(digitalReadFromAll(RFID_IRQ));
// turn on LPCD
uint16_t wakeupCounterInMs = 0x3FF; // needs to be in the range of 0x0 - 0xA82. max wake-up time is 2960 ms.
if (nfc14443.switchToLPCD(wakeupCounterInMs)) {
@@ -4470,32 +4536,32 @@ void setup() {
#endif
#ifdef NEOPIXEL_ENABLE // Try to find button that is used for shutdown via longpress-action (only necessary for Neopixel)
- #ifdef BUTTON_0_ENABLE
+ #if defined(BUTTON_0_ENABLE) || defined(EXPANDER_0_ENABLE)
#if (BUTTON_0_LONG == CMD_SLEEPMODE)
shutdownButton = 0;
#endif
#endif
- #ifdef BUTTON_1_ENABLE
+ #if defined(BUTTON_1_ENABLE) || defined(EXPANDER_1_ENABLE)
#if (BUTTON_1_LONG == CMD_SLEEPMODE)
shutdownButton = 1;
#endif
#endif
- #ifdef BUTTON_2_ENABLE
+ #if defined(BUTTON_2_ENABLE) || defined(EXPANDER_2_ENABLE)
#if (BUTTON_2_LONG == CMD_SLEEPMODE)
shutdownButton = 2;
#endif
#endif
- #ifdef BUTTON_3_ENABLE
+ #if defined(BUTTON_3_ENABLE) || defined(EXPANDER_3_ENABLE)
#if (BUTTON_3_LONG == CMD_SLEEPMODE)
shutdownButton = 3;
#endif
#endif
- #ifdef BUTTON_4_ENABLE
+ #if defined(BUTTON_4_ENABLE) || defined(EXPANDER_4_ENABLE)
#if (BUTTON_4_LONG == CMD_SLEEPMODE)
shutdownButton = 4;
#endif
#endif
- #ifdef BUTTON_5_ENABLE
+ #if defined(BUTTON_5_ENABLE) || defined(EXPANDER_5_ENABLE)
#if (BUTTON_5_LONG == CMD_SLEEPMODE)
shutdownButton = 5;
#endif
@@ -4547,34 +4613,34 @@ void setup() {
prefsRfid.putString("228064156042", "#0#0#110#0"); // modification-card (repeat playlist)
prefsRfid.putString("212130160042", "#/mp3/Hoerspiele/Yakari/Sammlung2#0#3#0");*/
-#ifdef NEOPIXEL_ENABLE
- xTaskCreatePinnedToCore(
- showLed, /* Function to implement the task */
- "LED", /* Name of the task */
- 2000, /* Stack size in words */
- NULL, /* Task input parameter */
- 1 | portPRIVILEGE_BIT, /* Priority of the task */
- &LED, /* Task handle. */
- 0 /* Core where the task should run */
- );
-#endif
+ #ifdef NEOPIXEL_ENABLE
+ xTaskCreatePinnedToCore(
+ showLed, /* Function to implement the task */
+ "LED", /* Name of the task */
+ 2000, /* Stack size in words */
+ NULL, /* Task input parameter */
+ 1 | portPRIVILEGE_BIT, /* Priority of the task */
+ &LED, /* Task handle. */
+ 0 /* Core where the task should run */
+ );
+ #endif
-#if (HAL == 2)
- i2cBusOne.begin(IIC_DATA, IIC_CLK, 40000);
+ #if (HAL == 2)
+ i2cBusOne.begin(IIC_DATA, IIC_CLK, 40000);
- while (not ac.begin()) {
- Serial.println(F("AC101 Failed!"));
- delay(1000);
- }
- Serial.println(F("AC101 via I2C - OK!"));
+ while (not ac.begin()) {
+ Serial.println(F("AC101 Failed!"));
+ delay(1000);
+ }
+ Serial.println(F("AC101 via I2C - OK!"));
- pinMode(22, OUTPUT);
- digitalWrite(22, HIGH);
+ pinMode(22, OUTPUT);
+ digitalWrite(22, HIGH);
- pinMode(GPIO_PA_EN, OUTPUT);
- digitalWrite(GPIO_PA_EN, HIGH);
- Serial.println(F("Built-in amplifier enabled\n"));
-#endif
+ pinMode(GPIO_PA_EN, OUTPUT);
+ digitalWrite(GPIO_PA_EN, HIGH);
+ Serial.println(F("Built-in amplifier enabled\n"));
+ #endif
#ifdef RFID_READER_TYPE_MFRC522_SPI
SPI.begin(RFID_SCK, RFID_MISO, RFID_MOSI, RFID_CS);
@@ -4610,7 +4676,8 @@ void setup() {
#endif
}
- #ifdef RFID_READER_TYPE_MFRC522_I2C
+ // Init 2nd i2c-bus if RC522 is used with i2c or if port-expander is enabled
+ #if defined(RFID_READER_TYPE_MFRC522_I2C) || defined(PORT_EXPANDER_ENABLE)
i2cBusTwo.begin(ext_IIC_DATA, ext_IIC_CLK, 40000);
delay(50);
loggerNl(serialDebug, (char *) FPSTR(rfidScannerReady), LOGLEVEL_DEBUG);
@@ -4634,18 +4701,18 @@ void setup() {
// print wake-up reason
printWakeUpReason();
#ifdef PN5180_ENABLE_LPCD
- // disable pin hold from deep sleep
- gpio_deep_sleep_hold_dis();
- gpio_hold_dis(gpio_num_t(RFID_CS)); // NSS
- gpio_hold_dis(gpio_num_t(RFID_RST)); // RST
+ // disable pin hold from deep sleep
+ gpio_deep_sleep_hold_dis();
+ gpio_hold_dis(gpio_num_t(RFID_CS)); // NSS
+ gpio_hold_dis(gpio_num_t(RFID_RST)); // RST
#endif
- // show SD card type
+ // show SD card type
#ifdef SD_MMC_1BIT_MODE
- loggerNl(serialDebug, (char *) FPSTR(sdMountedMmc1BitMode), LOGLEVEL_NOTICE);
- uint8_t cardType = SD_MMC.cardType();
+ loggerNl(serialDebug, (char *) FPSTR(sdMountedMmc1BitMode), LOGLEVEL_NOTICE);
+ uint8_t cardType = SD_MMC.cardType();
#else
- loggerNl(serialDebug, (char *) FPSTR(sdMountedSpiMode), LOGLEVEL_NOTICE);
- uint8_t cardType = SD.cardType();
+ loggerNl(serialDebug, (char *) FPSTR(sdMountedSpiMode), LOGLEVEL_NOTICE);
+ uint8_t cardType = SD.cardType();
#endif
Serial.print(F("SD card type: "));
if (cardType == CARD_MMC) {
@@ -4660,7 +4727,7 @@ void setup() {
#ifdef HEADPHONE_ADJUST_ENABLE
pinMode(HP_DETECT, INPUT);
- headphoneLastDetectionState = digitalRead(HP_DETECT);
+ headphoneLastDetectionState = digitalReadFromAll(HP_DETECT);
#endif
// Create queues
@@ -4898,7 +4965,7 @@ void setup() {
timerSemaphore = xSemaphoreCreateBinary();
timer = timerBegin(0, 240, true); // Prescaler: CPU-clock in MHz
timerAttachInterrupt(timer, &onTimer, true);
- timerAlarmWrite(timer, 1000, true); // 1000 Hz
+ timerAlarmWrite(timer, 10000, true); // 100 Hz
timerAlarmEnable(timer);
// Create tasks
@@ -5050,7 +5117,6 @@ void loop() {
batteryVoltageTester();
#endif
buttonHandler();
- doButtonActions();
sleepHandler();
deepSleepManager();
rfidPreferenceLookupHandler();
diff --git a/src/settings-custom.h b/src/settings-custom.h
index 5124e89..0b00c3e 100644
--- a/src/settings-custom.h
+++ b/src/settings-custom.h
@@ -49,18 +49,25 @@
#ifdef USEROTARY_ENABLE
#define DREHENCODER_CLK 34 // If you want to reverse encoder's direction, just switch GPIOs of CLK with DT (in software or hardware)
#define DREHENCODER_DT 35 // Info: Lolin D32 / Lolin D32 pro 35 are using 35 for battery-voltage-monitoring!
- #define DREHENCODER_BUTTON 32 // Button 3: is used to switch ESPuino on and off
+ #define DREHENCODER_BUTTON 32 // (set to 99 to disable; 0->39 for GPIO; 100->115 for port-expander)
#endif
- // Control-buttons (set to 99 to disable)
+ // Control-buttons (set to 99 to DISABLE; 0->39 for GPIO; 100->115 for port-expander)
#define NEXT_BUTTON 4 // Button 0: GPIO to detect next
#define PREVIOUS_BUTTON 2 // Button 1: GPIO to detect previous (Important: as of 19.11.2020 changed from 33 to 2; make sure to change in SD-MMC-mode)
#define PAUSEPLAY_BUTTON 0 // Button 2: GPIO to detect pause/play
#define BUTTON_4 99 // Button 4: unnamed optional button
#define BUTTON_5 99 // Button 5: unnamed optional button
- // Wake-up button
- // Please note: only RTC-GPIOs (0, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, 39, 99) can be used! Set to 99 to disable.
+ // I2C-configuration (necessary for RC522 [only via i2c - not spi!] or port-expander)
+ #if defined(RFID_READER_TYPE_MFRC522_I2C) || defined(PORT_EXPANDER_ENABLE)
+ #define ext_IIC_CLK 4 // i2c-SCL (clock)
+ #define ext_IIC_DATA 2 // i2c-SDA (data)
+ #endif
+
+ // Wake-up button => this also is the interrupt-pin if port-expander is enabled!
+ // Please note: only RTC-GPIOs (0, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, 39, 99) can be used! Set to 99 to DISABLE.
+ // Please note #2: this button can be used as interrupt-pin for port-expander. If so, all pins connected to port-expander can wake up ESPuino.
#define WAKEUP_BUTTON DREHENCODER_BUTTON // Defines the button that is used to wake up ESPuino from deepsleep.
// (optional) Power-control
diff --git a/src/settings-espa1s.h b/src/settings-espa1s.h
index a2998c2..b06b8ff 100644
--- a/src/settings-espa1s.h
+++ b/src/settings-espa1s.h
@@ -43,18 +43,25 @@
#ifdef USEROTARY_ENABLE
#define DREHENCODER_CLK 5 // If you want to reverse encoder's direction, just switch GPIOs of CLK with DT (in software or hardware)
#define DREHENCODER_DT 18 // Info: Lolin D32 / Lolin D32 pro 35 are using 35 for battery-voltage-monitoring!
- #define DREHENCODER_BUTTON 4 // Button 3: is used to switch ESPuino on and off
+ #define DREHENCODER_BUTTON 4 // (set to 99 to disable; 0->39 for GPIO; 100->115 for port-expander)
#endif
- // Control-buttons (set to 99 to disable)
+ // Control-buttons (set to 99 to DISABLE; 0->39 for GPIO; 100->115 for port-expander)
#define NEXT_BUTTON 199 // Button 0: GPIO to detect next
#define PREVIOUS_BUTTON 198 // Button 1: GPIO to detect previous (Important: as of 19.11.2020 changed from 33 to 2; make sure to change in SD-MMC-mode)
#define PAUSEPLAY_BUTTON 36 // Button 2: GPIO to detect pause/play
#define BUTTON_4 99 // Button 4: unnamed optional button
#define BUTTON_5 99 // Button 5: unnamed optional button
- // Wake-up button
- // Please note: only RTC-GPIOs (0, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, 39, 99) can be used! Set to 99 to disable.
+ // I2C-configuration (necessary for RC522 [only via i2c - not spi!] or port-expander)
+ #if defined(RFID_READER_TYPE_MFRC522_I2C) || defined(PORT_EXPANDER_ENABLE)
+ #define ext_IIC_CLK 5 // i2c-SCL (clock)
+ #define ext_IIC_DATA 2 // i2c-SDA (data)
+ #endif
+
+ // Wake-up button => this also is the interrupt-pin if port-expander is enabled!
+ // Please note: only RTC-GPIOs (0, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, 39, 99) can be used! Set to 99 to DISABLE.
+ // Please note #2: this button can be used as interrupt-pin for port-expander. If so, all pins connected to port-expander can wake up ESPuino.
#define WAKEUP_BUTTON DREHENCODER_BUTTON // Defines the button that is used to wake up ESPuino from deepsleep.
// Power-control
diff --git a/src/settings-lolin32.h b/src/settings-lolin32.h
index 5e558b0..57c3b59 100644
--- a/src/settings-lolin32.h
+++ b/src/settings-lolin32.h
@@ -53,18 +53,25 @@
#ifdef USEROTARY_ENABLE
#define DREHENCODER_CLK 34 // If you want to reverse encoder's direction, just switch GPIOs of CLK with DT (in software or hardware)
#define DREHENCODER_DT 35 // Info: Lolin D32 / Lolin D32 pro 35 are using 35 for battery-voltage-monitoring!
- #define DREHENCODER_BUTTON 32 // Button 3: is used to switch ESPuino on and off
+ #define DREHENCODER_BUTTON 32 // (set to 99 to disable; 0->39 for GPIO; 100->115 for port-expander)
#endif
-// Control-buttons (set to 99 to disable)
+// Control-buttons (set to 99 to DISABLE; 0->39 for GPIO; 100->115 for port-expander)
#define NEXT_BUTTON 4 // Button 0: GPIO to detect next
#define PREVIOUS_BUTTON 2 // Button 1: GPIO to detect previous (Important: as of 19.11.2020 changed from 33 to 2; make sure to change in SD-MMC-mode)
#define PAUSEPLAY_BUTTON 5 // Button 2: GPIO to detect pause/play
#define BUTTON_4 99 // Button 4: unnamed optional button
#define BUTTON_5 99 // Button 5: unnamed optional button
-// Wake-up button
-// Please note: only RTC-GPIOs (0, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, 39, 99) can be used! Set to 99 to disable.
+// I2C-configuration (necessary for RC522 [only via i2c - not spi!] or port-expander)
+#if defined(RFID_READER_TYPE_MFRC522_I2C) || defined(PORT_EXPANDER_ENABLE)
+ #define ext_IIC_CLK 5 // i2c-SCL (clock)
+ #define ext_IIC_DATA 2 // i2c-SDA (data)
+#endif
+
+// Wake-up button => this also is the interrupt-pin if port-expander is enabled!
+// Please note: only RTC-GPIOs (0, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, 39, 99) can be used! Set to 99 to DISABLE.
+// Please note #2: this button can be used as interrupt-pin for port-expander. If so, all pins connected to port-expander can wake up ESPuino.
#define WAKEUP_BUTTON DREHENCODER_BUTTON // Defines the button that is used to wake up ESPuino from deepsleep.
// (optional) Power-control
diff --git a/src/settings-lolin_d32.h b/src/settings-lolin_d32.h
index 508412b..934fa3f 100644
--- a/src/settings-lolin_d32.h
+++ b/src/settings-lolin_d32.h
@@ -56,18 +56,25 @@
#ifdef USEROTARY_ENABLE
#define DREHENCODER_CLK 34 // If you want to reverse encoder's direction, just switch GPIOs of CLK with DT (in software or hardware)
#define DREHENCODER_DT 33 // Info: Lolin D32 is using 35 for battery-voltage-monitoring!
- #define DREHENCODER_BUTTON 32 // Button is used to switch ESPuino on and off
+ #define DREHENCODER_BUTTON 32 // (set to 99 to disable; 0->39 for GPIO; 100->115 for port-expander)
#endif
- // Control-buttons (set to 99 to disable)
+// Control-buttons (set to 99 to DISABLE; 0->39 for GPIO; 100->115 for port-expander)
#define NEXT_BUTTON 4 // Button 0: GPIO to detect next
#define PREVIOUS_BUTTON 2 // Button 1: GPIO to detect previous (Important: as of 19.11.2020 changed from 33 to 2; make sure to change in SD-MMC-mode)
#define PAUSEPLAY_BUTTON 5 // Button 2: GPIO to detect pause/play
#define BUTTON_4 99 // Button 4: unnamed optional button
#define BUTTON_5 99 // Button 5: unnamed optional button
- // Wake-up button
- // Please note: only RTC-GPIOs (0, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, 39, 99) can be used! Set to 99 to disable.
+ // I2C-configuration (necessary for RC522 [only via i2c - not spi!] or port-expander)
+ #if defined(RFID_READER_TYPE_MFRC522_I2C) || defined(PORT_EXPANDER_ENABLE)
+ #define ext_IIC_CLK 5 // i2c-SCL (clock)
+ #define ext_IIC_DATA 2 // i2c-SDA (data)
+ #endif
+
+ // Wake-up button => this also is the interrupt-pin if port-expander is enabled!
+ // Please note: only RTC-GPIOs (0, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, 39, 99) can be used! Set to 99 to DISABLE.
+ // Please note #2: this button can be used as interrupt-pin for port-expander. If so, all pins connected to port-expander can wake up ESPuino.
#define WAKEUP_BUTTON DREHENCODER_BUTTON // Defines the button that is used to wake up ESPuino from deepsleep.
// (optional) Power-control
diff --git a/src/settings-lolin_d32_pro.h b/src/settings-lolin_d32_pro.h
index 6a42d5e..9dbc082 100644
--- a/src/settings-lolin_d32_pro.h
+++ b/src/settings-lolin_d32_pro.h
@@ -51,18 +51,25 @@
#ifdef USEROTARY_ENABLE
#define DREHENCODER_CLK 34 // If you want to reverse encoder's direction, just switch GPIOs of CLK with DT (in software or hardware)
#define DREHENCODER_DT 39 // 39 = 'VN'; Info: Lolin D32 pro is using 35 for battery-voltage-monitoring!
- #define DREHENCODER_BUTTON 36 // Button 3: is used to switch ESPuino on and off; 36 = 'VP'
+ #define DREHENCODER_BUTTON 36 // (set to 99 to disable; 0->39 for GPIO; 100->115 for port-expander)
#endif
- // Control-buttons (set to 99 to disable)
+ // Control-buttons (set to 99 to DISABLE; 0->39 for GPIO; 100->115 for port-expander)
#define NEXT_BUTTON 0 // Button 0: GPIO to detect next
#define PREVIOUS_BUTTON 2 // Button 1: GPIO to detect previous (Important: as of 19.11.2020 changed from 33 to 2; make sure to change in SD-MMC-mode)
#define PAUSEPLAY_BUTTON 32 // Button 2: GPIO to detect pause/play
#define BUTTON_4 99 // Button 4: unnamed optional button
#define BUTTON_5 99 // Button 5: unnamed optional button
- // Wake-up button
- // Please note: only RTC-GPIOs (0, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, 39, 99) can be used! Set to 99 to disable.
+ // I2C-configuration (necessary for RC522 [only via i2c - not spi!] or port-expander)
+ #if defined(RFID_READER_TYPE_MFRC522_I2C) || defined(PORT_EXPANDER_ENABLE)
+ #define ext_IIC_CLK 5 // i2c-SCL (clock)
+ #define ext_IIC_DATA 2 // i2c-SDA (data)
+ #endif
+
+ // Wake-up button => this also is the interrupt-pin if port-expander is enabled!
+ // Please note: only RTC-GPIOs (0, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, 39, 99) can be used! Set to 99 to DISABLE.
+ // Please note #2: this button can be used as interrupt-pin for port-expander. If so, all pins connected to port-expander can wake up ESPuino.
#define WAKEUP_BUTTON DREHENCODER_BUTTON // Defines the button that is used to wake up ESPuino from deepsleep.
// (optional) Power-control
diff --git a/src/settings-ttgo_t8.h b/src/settings-ttgo_t8.h
index 8fc8c8a..3c26adf 100644
--- a/src/settings-ttgo_t8.h
+++ b/src/settings-ttgo_t8.h
@@ -51,18 +51,25 @@
#ifdef USEROTARY_ENABLE
#define DREHENCODER_CLK 34 // If you want to reverse encoder's direction, just switch GPIOs of CLK with DT (in software or hardware)
#define DREHENCODER_DT 33 // Info: Lolin D32 / Lolin D32 pro 35 are using 35 for battery-voltage-monitoring!
- #define DREHENCODER_BUTTON 32 // Button 3: is used to switch ESPuino on and off
+ #define DREHENCODER_BUTTON 32 // (set to 99 to disable; 0->39 for GPIO; 100->115 for port-expander)
#endif
-// Control-buttons (set to 99 to disable)
+// Control-buttons (set to 99 to DISABLE; 0->39 for GPIO; 100->115 for port-expander)
#define NEXT_BUTTON 0 // Button 0: GPIO to detect next
#define PREVIOUS_BUTTON 36 // Button 1: GPIO to detect previous (Important: as of 19.11.2020 changed from 33 to 2; make sure to change in SD-MMC-mode)
#define PAUSEPLAY_BUTTON 39 // Button 2: GPIO to detect pause/play
#define BUTTON_4 99 // Button 4: unnamed optional button
#define BUTTON_5 99 // Button 5: unnamed optional button
-// Wake-up button
-// Please note: only RTC-GPIOs (0, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, 39, 99) can be used! Set to 99 to disable.
+// I2C-configuration (necessary for RC522 [only via i2c - not spi!] or port-expander)
+#if defined(RFID_READER_TYPE_MFRC522_I2C) || defined(PORT_EXPANDER_ENABLE)
+ #define ext_IIC_CLK 5 // i2c-SCL (clock)
+ #define ext_IIC_DATA 2 // i2c-SDA (data)
+#endif
+
+// Wake-up button => this also is the interrupt-pin if port-expander is enabled!
+// Please note: only RTC-GPIOs (0, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, 39, 99) can be used! Set to 99 to DISABLE.
+// Please note #2: this button can be used as interrupt-pin for port-expander. If so, all pins connected to port-expander can wake up ESPuino.
#define WAKEUP_BUTTON DREHENCODER_BUTTON // Defines the button that is used to wake up ESPuino from deepsleep.
// (optional) Power-control
diff --git a/src/settings.h b/src/settings.h
index 82bcc7e..e3b41fe 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -21,6 +21,7 @@
//########################## MODULES #################################
+ //#define PORT_EXPANDER_ENABLE // When enabled, buttons can be connected via port-expander PCA9555
#define MDNS_ENABLE // When enabled, you don't have to handle with ESPuino's IP-address. If hostname is set to "ESPuino", you can reach it via ESPuino.local
#define MQTT_ENABLE // Make sure to configure mqtt-server and (optionally) username+pwd
#define FTP_ENABLE // Enables FTP-server; DON'T FORGET TO ACTIVATE AFTER BOOT BY PRESSING PAUSE + NEXT-BUTTONS (IN PARALLEL)!
@@ -57,6 +58,12 @@
#endif
+ //############# Port-expander-configuration ######################
+ #ifdef PORT_EXPANDER_ENABLE
+ const uint8_t portsToRead = 2; // PCA9555 has two ports à 8 channels. If 8 channels are sufficient, set to 1 and only use the first port!
+ uint8_t expanderI2cAddress = 0x20; // I2C-address of PCA9555
+ #endif
+
//################## BUTTON-Layout ##################################
/* German documentation: https://forum.espuino.de/t/das-dynamische-button-layout/224
Please note the following numbers as you need to know them in order to define actions for buttons.