diff --git a/README.md b/README.md index ebb2781..4229ebd 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,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 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(s), single-button(s) (short), single-button(s) (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. -Thanks @QDaniel for the idea + basic implementation (first three features named above)! +* 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. ## 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 for webgui is currently pretty outdated. This will be fixed soon when i18n-support will be integrated. diff --git a/changelog.md b/changelog.md index 12a4303..a2f4f41 100644 --- a/changelog.md +++ b/changelog.md @@ -31,3 +31,4 @@ * 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. diff --git a/platformio.ini b/platformio.ini index c0883d7..4eead2d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -22,6 +22,7 @@ lib_deps_external = https://github.com/me-no-dev/AsyncTCP https://github.com/bblanchon/ArduinoJson.git https://github.com/pschatzmann/ESP32-A2DP.git + https://github.com/Arduino-IRremote/Arduino-IRremote.git [env:common] platform = espressif32 diff --git a/src/main.cpp b/src/main.cpp index fee8ee7..8703d88 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,6 +30,9 @@ #include "esp_bt.h" #include "BluetoothA2DPSink.h" #endif +#ifdef IR_CONTROL_ENABLE + #include +#endif #include "Audio.h" #include "SPI.h" #include "FS.h" @@ -289,7 +292,11 @@ IPAddress myIP; #endif // HW-Timer -hw_timer_t *timer = NULL; +#ifndef IR_CONTROL_ENABLE + hw_timer_t *timer = NULL; +#else + uint32_t lastRcCmdTimestamp = 0; +#endif volatile SemaphoreHandle_t timerSemaphore; // Button-helper @@ -4341,6 +4348,112 @@ void printWakeUpReason() { } #endif +#ifdef IR_CONTROL_ENABLE + void handleIrReceiver() { + static uint8_t lastVolume = 0; + + if (IrReceiver.decode()) { + + // Print a short summary of received data + IrReceiver.printIRResultShort(&Serial); + Serial.println(); + IrReceiver.resume(); // Enable receiving of the next value + bool rcActionOk = false; + if (millis() - lastRcCmdTimestamp >= IR_DEBOUNCE) { + rcActionOk = true; // not used for volume up/down + lastRcCmdTimestamp = millis(); + } + + switch (IrReceiver.decodedIRData.command) { + case RC_PLAY: { + if (rcActionOk) { + doCmdAction(CMD_PLAYPAUSE); + Serial.println(F("RC: Play")); + } + break; + } + case RC_PAUSE: { + if (rcActionOk) { + doCmdAction(CMD_PLAYPAUSE); + Serial.println(F("RC: Pause")); + } + break; + } + case RC_NEXT: { + if (rcActionOk) { + doCmdAction(CMD_NEXTTRACK); + Serial.println(F("RC: Next")); + } + break; + } + case RC_PREVIOUS: { + if (rcActionOk) { + doCmdAction(CMD_PREVTRACK); + Serial.println(F("RC: Previous")); + } + break; + } + case RC_FIRST: { + if (rcActionOk) { + doCmdAction(CMD_FIRSTTRACK); + Serial.println(F("RC: First")); + } + break; + } + case RC_LAST: { + if (rcActionOk) { + doCmdAction(CMD_LASTTRACK); + Serial.println(F("RC: Last")); + } + break; + } + case RC_MUTE: { + if (rcActionOk) { + if (currentVolume > 0) { + lastVolume = currentVolume; + currentVolume = 0; + } else { + currentVolume = lastVolume; // Remember last volume if mute is pressed again + } + xQueueSend(volumeQueue, ¤tVolume, 0); + Serial.println(F("RC: Mute")); + } + break; + } + case RC_BLUETOOTH: { + if (rcActionOk) { + doCmdAction(TOGGLE_BLUETOOTH_MODE); + Serial.println(F("RC: Bluetooth")); + } + break; + } + case RC_FTP: { + if (rcActionOk) { + doCmdAction(ENABLE_FTP_SERVER); + Serial.println(F("RC: FTP")); + } + break; + } + case RC_VOL_DOWN: { + doCmdAction(CMD_VOLUMEDOWN); + Serial.println(F("RC: Volume down")); + break; + } + case RC_VOL_UP: { + doCmdAction(CMD_VOLUMEUP); + Serial.println(F("RC: Volume up")); + break; + } + default: { + if (rcActionOk) { + Serial.println(F("RC: unknown")); + } + } + } + } + } +#endif + void setup() { Serial.begin(115200); #if (WAKEUP_BUTTON <= 39) @@ -4861,6 +4974,10 @@ void setup() { } #endif + #ifdef IR_CONTROL_ENABLE + IrReceiver.begin(IRLED_PIN); + #endif + lastTimeActiveTimestamp = millis(); // initial set after boot bootComplete = true; @@ -4936,7 +5053,9 @@ void loop() { #ifdef PLAY_LAST_RFID_AFTER_REBOOT recoverLastRfidPlayed(); #endif - + #ifdef IR_CONTROL_ENABLE + handleIrReceiver(); + #endif } diff --git a/src/settings-custom.h b/src/settings-custom.h index 1da926f..7eb6e86 100644 --- a/src/settings-custom.h +++ b/src/settings-custom.h @@ -83,4 +83,24 @@ #ifdef MEASURE_BATTERY_VOLTAGE uint8_t rdiv1 = 129; // Rdiv1 of voltage-divider (kOhms) (measure exact value with multimeter!) uint16_t rdiv2 = 129; // Rdiv2 of voltage-divider (kOhms) (measure exact value with multimeter!) => used to measure voltage via ADC! +#endif + +// (Optional) remote control via infrared +#ifdef IR_CONTROL_ENABLE + #define IRLED_PIN 22 // GPIO where IR-receiver is connected (only tested with VS1838B) + #define IR_DEBOUNCE 200 // Interval in ms to wait at least for next signal (not used for actions volume up/down) + + // Actions available. Use your own remote control and have a look at the console for "Command=0x??". E.g. "Protocol=NEC Address=0x17F Command=0x68 Repeat gap=39750us" + #define RC_PLAY 0x68 // command for play + #define RC_PAUSE 0x67 // command for pause + #define RC_NEXT 0x6b // command for next track of playlist + #define RC_PREVIOUS 0x6a // command for previous track of playlist + #define RC_FIRST 0x6c // command for first track of playlist + #define RC_LAST 0x6d // command for last track of playlist + #define RC_VOL_UP 0x1a // Command for volume up (one step) + #define RC_VOL_DOWN 0x1b // Command for volume down (one step) + #define RC_MUTE 0x1c // Command to mute ESPuino + #define RC_SHUTDOWN 0x2a // Command for deepsleep + #define RC_BLUETOOTH 0x72 // Command to enable/disable bluetooth + #define RC_FTP 0x65 // Command to enable FTP-server #endif \ No newline at end of file diff --git a/src/settings-espa1s.h b/src/settings-espa1s.h index 9c78a5b..dd6fcde 100644 --- a/src/settings-espa1s.h +++ b/src/settings-espa1s.h @@ -77,4 +77,24 @@ #ifdef MEASURE_BATTERY_VOLTAGE uint8_t rdiv1 = 129; // Rdiv1 of voltage-divider (kOhms) (measure exact value with multimeter!) uint16_t rdiv2 = 389; // Rdiv2 of voltage-divider (kOhms) (measure exact value with multimeter!) => used to measure voltage via ADC! +#endif + +// (Optional) remote control via infrared +#ifdef IR_CONTROL_ENABLE + #define IRLED_PIN 22 // GPIO where IR-receiver is connected (only tested with VS1838B) + #define IR_DEBOUNCE 200 // Interval in ms to wait at least for next signal (not used for actions volume up/down) + + // Actions available. Use your own remote control and have a look at the console for "Command=0x??". E.g. "Protocol=NEC Address=0x17F Command=0x68 Repeat gap=39750us" + #define RC_PLAY 0x68 // command for play + #define RC_PAUSE 0x67 // command for pause + #define RC_NEXT 0x6b // command for next track of playlist + #define RC_PREVIOUS 0x6a // command for previous track of playlist + #define RC_FIRST 0x6c // command for first track of playlist + #define RC_LAST 0x6d // command for last track of playlist + #define RC_VOL_UP 0x1a // Command for volume up (one step) + #define RC_VOL_DOWN 0x1b // Command for volume down (one step) + #define RC_MUTE 0x1c // Command to mute ESPuino + #define RC_SHUTDOWN 0x2a // Command for deepsleep + #define RC_BLUETOOTH 0x72 // Command to enable/disable bluetooth + #define RC_FTP 0x65 // Command to enable FTP-server #endif \ No newline at end of file diff --git a/src/settings-lolin32.h b/src/settings-lolin32.h index 3c06422..5e558b0 100644 --- a/src/settings-lolin32.h +++ b/src/settings-lolin32.h @@ -89,4 +89,24 @@ #ifdef MEASURE_BATTERY_VOLTAGE uint8_t rdiv1 = 129; // Rdiv1 of voltage-divider (kOhms) (measure exact value with multimeter!) uint16_t rdiv2 = 129; // Rdiv2 of voltage-divider (kOhms) (measure exact value with multimeter!) => used to measure voltage via ADC! +#endif + +// (Optional) remote control via infrared +#ifdef IR_CONTROL_ENABLE + #define IRLED_PIN 22 // GPIO where IR-receiver is connected (only tested with VS1838B) + #define IR_DEBOUNCE 200 // Interval in ms to wait at least for next signal (not used for actions volume up/down) + + // Actions available. Use your own remote control and have a look at the console for "Command=0x??". E.g. "Protocol=NEC Address=0x17F Command=0x68 Repeat gap=39750us" + #define RC_PLAY 0x68 // command for play + #define RC_PAUSE 0x67 // command for pause + #define RC_NEXT 0x6b // command for next track of playlist + #define RC_PREVIOUS 0x6a // command for previous track of playlist + #define RC_FIRST 0x6c // command for first track of playlist + #define RC_LAST 0x6d // command for last track of playlist + #define RC_VOL_UP 0x1a // Command for volume up (one step) + #define RC_VOL_DOWN 0x1b // Command for volume down (one step) + #define RC_MUTE 0x1c // Command to mute ESPuino + #define RC_SHUTDOWN 0x2a // Command for deepsleep + #define RC_BLUETOOTH 0x72 // Command to enable/disable bluetooth + #define RC_FTP 0x65 // Command to enable FTP-server #endif \ No newline at end of file diff --git a/src/settings-lolin_d32.h b/src/settings-lolin_d32.h index 0724422..17003f0 100644 --- a/src/settings-lolin_d32.h +++ b/src/settings-lolin_d32.h @@ -89,4 +89,24 @@ #ifdef MEASURE_BATTERY_VOLTAGE uint8_t rdiv1 = 100; // Cannot be changed, it's built in uint16_t rdiv2 = 100; // Cannot be changed, it's built in +#endif + +// (Optional) remote control via infrared +#ifdef IR_CONTROL_ENABLE + #define IRLED_PIN 22 // GPIO where IR-receiver is connected (only tested with VS1838B) + #define IR_DEBOUNCE 200 // Interval in ms to wait at least for next signal (not used for actions volume up/down) + + // Actions available. Use your own remote control and have a look at the console for "Command=0x??". E.g. "Protocol=NEC Address=0x17F Command=0x68 Repeat gap=39750us" + #define RC_PLAY 0x68 // command for play + #define RC_PAUSE 0x67 // command for pause + #define RC_NEXT 0x6b // command for next track of playlist + #define RC_PREVIOUS 0x6a // command for previous track of playlist + #define RC_FIRST 0x6c // command for first track of playlist + #define RC_LAST 0x6d // command for last track of playlist + #define RC_VOL_UP 0x1a // Command for volume up (one step) + #define RC_VOL_DOWN 0x1b // Command for volume down (one step) + #define RC_MUTE 0x1c // Command to mute ESPuino + #define RC_SHUTDOWN 0x2a // Command for deepsleep + #define RC_BLUETOOTH 0x72 // Command to enable/disable bluetooth + #define RC_FTP 0x65 // Command to enable FTP-server #endif \ No newline at end of file diff --git a/src/settings-lolin_d32_pro.h b/src/settings-lolin_d32_pro.h index ddcf0d7..9268991 100644 --- a/src/settings-lolin_d32_pro.h +++ b/src/settings-lolin_d32_pro.h @@ -85,4 +85,24 @@ #ifdef MEASURE_BATTERY_VOLTAGE uint8_t rdiv1 = 100; // Cannot be changed, it's built in uint16_t rdiv2 = 100; // Cannot be changed, it's built in +#endif + +// (Optional) remote control via infrared +#ifdef IR_CONTROL_ENABLE + #define IRLED_PIN 22 // GPIO where IR-receiver is connected (only tested with VS1838B) + #define IR_DEBOUNCE 200 // Interval in ms to wait at least for next signal (not used for actions volume up/down) + + // Actions available. Use your own remote control and have a look at the console for "Command=0x??". E.g. "Protocol=NEC Address=0x17F Command=0x68 Repeat gap=39750us" + #define RC_PLAY 0x68 // command for play + #define RC_PAUSE 0x67 // command for pause + #define RC_NEXT 0x6b // command for next track of playlist + #define RC_PREVIOUS 0x6a // command for previous track of playlist + #define RC_FIRST 0x6c // command for first track of playlist + #define RC_LAST 0x6d // command for last track of playlist + #define RC_VOL_UP 0x1a // Command for volume up (one step) + #define RC_VOL_DOWN 0x1b // Command for volume down (one step) + #define RC_MUTE 0x1c // Command to mute ESPuino + #define RC_SHUTDOWN 0x2a // Command for deepsleep + #define RC_BLUETOOTH 0x72 // Command to enable/disable bluetooth + #define RC_FTP 0x65 // Command to enable FTP-server #endif \ No newline at end of file diff --git a/src/settings.h b/src/settings.h index ad91c4b..664b2a3 100644 --- a/src/settings.h +++ b/src/settings.h @@ -31,8 +31,8 @@ //#define PLAY_LAST_RFID_AFTER_REBOOT // When restarting ESPuino, the last RFID that was active before, is recalled and played //#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 //################## select SD card mode #############################