diff --git a/README.md b/README.md index ea9e8e8..67bce0d 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ I started this project back in october 2019 and never expected it to become that * Partition-layout for ESP32 is changed along with this branch. This step was necessary in order to resize (enlarge) the memory-region where especially the assignments for the RFID-tags are saved. As all permanent settings (e.g. WiFi-settings) are saved there too, it's necessary to re-enter WiFi-credentials after update. But the most important thing is to recover the assignments for the RFID-tags. Please consult my [migration-document](https://forum.espuino.de/t/wechsel-zum-refactoring-branch-was-ist-zu-beachten/510). ## Changelog Last three events: +* 30.09.2021: Added feature `PAUSE_WHEN_RFID_REMOVED` for RC522 after having it already for PN5180 (thanks @elmar-ops for contribution) * 23.07.2021: Adding new playmode: from local .m3u-file (files or webstreams) * 13.07.2021: Adding OTA-support via webGUI -* 09.07.2021: Making branch `refactoring` the new master ## 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). * For ESPuinos making use of SPI for SD (instead of SD_MMC), there's currently a problem that sometimes leads to incomplete file-transfers via webtransfer or FTP. I'm about to [investigate...](https://forum.espuino.de/t/probleme-beim-webtransfer/542) diff --git a/changelog.md b/changelog.md index 148125c..e24e8e0 100644 --- a/changelog.md +++ b/changelog.md @@ -10,7 +10,7 @@ * 09.07.2021: Making master the new branch `old` (not maintained any longer!) * 13.07.2021: Adding OTA-support via webGUI * 23.07.2021: Adding new playmode: from local .m3u-file (files or webstreams) - +* 30.09.2021: Added feature `PAUSE_WHEN_RFID_REMOVED` for RC522 after having it already for PN5180 (thanks @elmar-ops for contribution) ## Old (monolithic main.cpp) * 11.07.2020: Added support for reversed Neopixel addressing. * 09.10.2020: mqttUser / mqttPassword can now be configured via webgui. @@ -49,3 +49,4 @@ * 19.03.2021: Added support for port-expander PCA9555. Can be used for everything, that is "button-like": buttons, headphone-detect, PN5180.IRQ. * 28.03.2021: Added support for fileseek. With commands `CMD_SEEK_FORWARDS` and `CMD_SEEK_BACKWARDS` it's possible to jump a number of seconds defined in `jumpOffset`. * 30.03.2021: Added support for stereo/mono via `PLAY_MONO_SPEAKER`. If active, mono is used while headphones remain stereo (if `HEADPHONE_ADJUST_ENABLE` is active). +* no more updates will follow! diff --git a/src/LogMessages_DE.cpp b/src/LogMessages_DE.cpp index 5811e1a..5dba278 100644 --- a/src/LogMessages_DE.cpp +++ b/src/LogMessages_DE.cpp @@ -206,4 +206,6 @@ const char otaNotSupported[] PROGMEM = "Firmware-update wird von diesem ESPuino nicht unterstuetzt!"; const char otaNotSupportedWebsite[] PROGMEM = "

Firmware-update wird von diesem ESPuino nicht unterstuetzt!
Zur letzten Seite zurückkehren.

"; const char noPlaylist[] PROGMEM = "Keine Playlist aktiv."; + const char rfidTagRemoved[] PROGMEM = "RFID-Karte wurde entfernt"; + const char rfidTagReapplied[] PROGMEM = "RFID-Karte erneut aufgelegt"; #endif diff --git a/src/LogMessages_EN.cpp b/src/LogMessages_EN.cpp index 7fbd807..ef7182f 100644 --- a/src/LogMessages_EN.cpp +++ b/src/LogMessages_EN.cpp @@ -206,5 +206,7 @@ const char otaNotSupported[] PROGMEM = "Firmware-update isn't supported by this ESPuino!"; const char otaNotSupportedWebsite[] PROGMEM = "

FFirmware-update isn't supported by this ESPuino!
Back to last page.

"; const char noPlaylist[] PROGMEM = "No active playlist."; + const char rfidTagRemoved[] PROGMEM = "RFID-tag removed"; + const char rfidTagReapplied[] PROGMEM = "RFID-tag reapplied"; #endif diff --git a/src/RfidMfrc522.cpp b/src/RfidMfrc522.cpp index f67af77..c07980c 100644 --- a/src/RfidMfrc522.cpp +++ b/src/RfidMfrc522.cpp @@ -5,6 +5,8 @@ #include "MemX.h" #include "Queues.h" #include "System.h" +#include +#include "AudioPlayer.h" #if defined RFID_READER_TYPE_MFRC522_SPI || defined RFID_READER_TYPE_MFRC522_I2C #ifdef RFID_READER_TYPE_MFRC522_SPI @@ -18,6 +20,7 @@ #endif extern unsigned long Rfid_LastRfidCheckTimestamp; + static void Rfid_Task(void *parameter); #ifdef RFID_READER_TYPE_MFRC522_I2C extern TwoWire i2cBusTwo; @@ -33,52 +36,143 @@ SPI.setFrequency(1000000); #endif - // Init RC522 Card-Reader + // Init RC522 Card-Reader #if defined(RFID_READER_TYPE_MFRC522_I2C) || defined(RFID_READER_TYPE_MFRC522_SPI) mfrc522.PCD_Init(); mfrc522.PCD_SetAntennaGain(rfidGain); delay(50); Log_Println((char *) FPSTR(rfidScannerReady), LOGLEVEL_DEBUG); + + xTaskCreatePinnedToCore( + Rfid_Task, /* Function to implement the task */ + "rfid", /* Name of the task */ + 1536, /* Stack size in words */ + NULL, /* Task input parameter */ + 2 | portPRIVILEGE_BIT, /* Priority of the task */ + NULL, /* Task handle. */ + 1 /* Core where the task should run */ + ); #endif } - void Rfid_Cyclic(void) { - byte cardId[cardIdSize]; - String cardIdString; - - if ((millis() - Rfid_LastRfidCheckTimestamp) >= RFID_SCAN_INTERVAL) { - Rfid_LastRfidCheckTimestamp = millis(); - // Reset the loop if no new card is present on the sensor/reader. This saves the entire process when idle. - - if (!mfrc522.PICC_IsNewCardPresent()) { - return; - } - - // Select one of the cards - if (!mfrc522.PICC_ReadCardSerial()) { - return; - } - - //mfrc522.PICC_DumpToSerial(&(mfrc522.uid)); - mfrc522.PICC_HaltA(); - mfrc522.PCD_StopCrypto1(); - - memcpy(cardId, mfrc522.uid.uidByte, cardIdSize); + void Rfid_Task(void *parameter) { + uint8_t control = 0x00; - Log_Print((char *) FPSTR(rfidTagDetected), LOGLEVEL_NOTICE); - for (uint8_t i = 0u; i < cardIdSize; i++) { - snprintf(Log_Buffer, Log_BufferLength, "%02x%s", cardId[i], (i < cardIdSize - 1u) ? "-" : "\n"); - Log_Print(Log_Buffer, LOGLEVEL_NOTICE); + for (;;) { + if (RFID_SCAN_INTERVAL/2 >= 20) { + vTaskDelay(RFID_SCAN_INTERVAL/2); + } else { + vTaskDelay(20); } + byte cardId[cardIdSize]; + String cardIdString; + #ifdef PAUSE_WHEN_RFID_REMOVED + byte lastValidcardId[cardIdSize]; + bool cardAppliedCurrentRun = false; + bool sameCardReapplied = false; + #endif + if ((millis() - Rfid_LastRfidCheckTimestamp) >= RFID_SCAN_INTERVAL) { + //snprintf(Log_Buffer, Log_BufferLength, "%u", uxTaskGetStackHighWaterMark(NULL)); + //Log_Println(Log_Buffer, LOGLEVEL_DEBUG); + + Rfid_LastRfidCheckTimestamp = millis(); + // Reset the loop if no new card is present on the sensor/reader. This saves the entire process when idle. + + if (!mfrc522.PICC_IsNewCardPresent()) { + continue; + } + + // Select one of the cards + if (!mfrc522.PICC_ReadCardSerial()) { + continue; + } + #ifdef PAUSE_WHEN_RFID_REMOVED + cardAppliedCurrentRun = true; + #endif + + #ifndef PAUSE_WHEN_RFID_REMOVED + mfrc522.PICC_HaltA(); + mfrc522.PCD_StopCrypto1(); + #endif + + memcpy(cardId, mfrc522.uid.uidByte, cardIdSize); + + #ifdef PAUSE_WHEN_RFID_REMOVED + if (memcmp((const void *)lastValidcardId, (const void *)cardId, sizeof(cardId)) == 0) { + sameCardReapplied = true; + } + #endif + + Log_Print((char *) FPSTR(rfidTagDetected), LOGLEVEL_NOTICE); + for (uint8_t i=0u; i < cardIdSize; i++) { + snprintf(Log_Buffer, Log_BufferLength, "%02x%s", cardId[i], (i < cardIdSize - 1u) ? "-" : "\n"); + Log_Print(Log_Buffer, LOGLEVEL_NOTICE); + } + + for (uint8_t i=0u; i < cardIdSize; i++) { + char num[4]; + snprintf(num, sizeof(num), "%03d", cardId[i]); + cardIdString += num; + } + + #ifdef PAUSE_WHEN_RFID_REMOVED + if (!sameCardReapplied) { // Don't allow to send card to queue if it's the same card again... + xQueueSend(gRfidCardQueue, cardIdString.c_str(), 0); + } else { + // If pause-button was pressed while card was not applied, playback could be active. If so: don't pause when card is reapplied again as the desired functionality would be reversed in this case. + if (gPlayProperties.pausePlay && System_GetOperationMode() != OPMODE_BLUETOOTH) { + AudioPlayer_TrackControlToQueueSender(PAUSEPLAY); // ... play/pause instead (but not for BT) + } + } + memcpy(lastValidcardId, mfrc522.uid.uidByte, cardIdSize); + #else + xQueueSend(gRfidCardQueue, cardIdString.c_str(), 0); // If PAUSE_WHEN_RFID_REMOVED isn't active, every card-apply leads to new playlist-generation + #endif + + #ifdef PAUSE_WHEN_RFID_REMOVED + // https://github.com/miguelbalboa/rfid/issues/188; voodoo! :-) + while (true) { + if (RFID_SCAN_INTERVAL/2 >= 20) { + vTaskDelay(RFID_SCAN_INTERVAL/2); + } else { + vTaskDelay(20); + } + control=0; + for (uint8_t i=0u; i<3; i++) { + if (!mfrc522.PICC_IsNewCardPresent()) { + if (mfrc522.PICC_ReadCardSerial()) { + control |= 0x16; + } + if (mfrc522.PICC_ReadCardSerial()) { + control |= 0x16; + } + control += 0x1; + } + control += 0x4; + } + + if (control == 13 || control == 14) { + //card is still there + } else { + break; + } + } + + Log_Println((char *) FPSTR(rfidTagRemoved), LOGLEVEL_NOTICE); + if (!gPlayProperties.pausePlay && System_GetOperationMode() != OPMODE_BLUETOOTH) { + AudioPlayer_TrackControlToQueueSender(PAUSEPLAY); + Log_Println((char *) FPSTR(rfidTagReapplied), LOGLEVEL_NOTICE); + } + mfrc522.PICC_HaltA(); + mfrc522.PCD_StopCrypto1(); + cardAppliedCurrentRun = false; + #endif + } + } + } - for (uint8_t i = 0u; i < cardIdSize; i++) { - char num[4]; - snprintf(num, sizeof(num), "%03d", cardId[i]); - cardIdString += num; - } - - xQueueSend(gRfidCardQueue, cardIdString.c_str(), 0); - } + void Rfid_Cyclic(void) { + // Not necessary as cyclic stuff performed by task Rfid_Task() } void Rfid_Exit(void) { diff --git a/src/logmessages.h b/src/logmessages.h index 57b4764..ffec709 100644 --- a/src/logmessages.h +++ b/src/logmessages.h @@ -202,3 +202,5 @@ extern const char fwEnd[]; extern const char otaNotSupported[]; extern const char otaNotSupportedWebsite[]; extern const char noPlaylist[]; +extern const char rfidTagRemoved[]; +extern const char rfidTagReapplied[]; diff --git a/src/revision.h b/src/revision.h index 6f25352..22b5b45 100644 --- a/src/revision.h +++ b/src/revision.h @@ -1,4 +1,4 @@ #ifndef __REVISION_H__ #define __REVISION_H__ - constexpr const char softwareRevision[] PROGMEM = "Software-revision: 20210924-1"; + constexpr const char softwareRevision[] PROGMEM = "Software-revision: 20210930-1"; #endif \ No newline at end of file diff --git a/src/settings.h b/src/settings.h index e2874a6..f2b52bd 100644 --- a/src/settings.h +++ b/src/settings.h @@ -24,7 +24,7 @@ //########################## MODULES ################################# - //#define PORT_EXPANDER_ENABLE // When enabled, buttons can be connected via port-expander PCA9555 + //#define PORT_EXPANDER_ENABLE // When enabled, buttons can be connected via port-expander PCA9555 (https://forum.espuino.de/t/einsatz-des-port-expanders-pca9555/306) //#define I2S_COMM_FMT_LSB_ENABLE // Enables FMT instead of MSB for I2S-communication-format. Used e.g. by PT2811. Don't enable for MAX98357a, AC101 or PCM5102A) #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 @@ -41,13 +41,13 @@ //#define USE_LAST_VOLUME_AFTER_REBOOT // Remembers the volume used at last shutdown after reboot #define USEROTARY_ENABLE // If rotary-encoder is used (don't forget to review WAKEUP_BUTTON if you disable this feature!) #define BLUETOOTH_ENABLE // If enabled and bluetooth-mode is active, you can stream to your ESPuino via bluetooth (a2dp-sink). - //#define IR_CONTROL_ENABLE // Enables remote control + //#define IR_CONTROL_ENABLE // Enables remote control (https://forum.espuino.de/t/neues-feature-fernsteuerung-per-infrarot-fernbedienung/265) #define CACHED_PLAYLIST_ENABLE // Enables playlist-caching (infos: https://forum.espuino.de/t/neues-feature-cached-playlist/515) - //#define PAUSE_WHEN_RFID_REMOVED // (Only PN5180) Playback starts when card is applied and pauses, when card is removed (https://forum.espuino.de/t/neues-feature-pausieren-wenn-rfid-karte-entfernt-wurde/541) + //#define PAUSE_WHEN_RFID_REMOVED // Playback starts when card is applied and pauses automatically, when card is removed (https://forum.espuino.de/t/neues-feature-pausieren-wenn-rfid-karte-entfernt-wurde/541) //################## select SD card mode ############################# - //#define SD_MMC_1BIT_MODE // run SD card in SD-MMC 1Bit mode + //#define SD_MMC_1BIT_MODE // run SD card in SD-MMC 1Bit mode (using GPIOs 15 + 14 + 2 is mandatory!) //#define SINGLE_SPI_ENABLE // If only one SPI-instance should be used instead of two (not yet working!) @@ -71,7 +71,7 @@ //############# Port-expander-configuration ###################### #ifdef PORT_EXPANDER_ENABLE - constexpr uint8_t expanderI2cAddress = 0x20; // I2C-address of PCA9555 + constexpr uint8_t expanderI2cAddress = 0x20; // I2C-address of PCA9555 (0x20 is true if PCA's pins A0+A1+A2 are pulled to GND) #endif //################## BUTTON-Layout ##################################