diff --git a/code/espurna/config/general.h b/code/espurna/config/general.h index 6e2f236c..c6ea5f58 100644 --- a/code/espurna/config/general.h +++ b/code/espurna/config/general.h @@ -715,6 +715,7 @@ #define MQTT_TOPIC_BOARD "board" #define MQTT_TOPIC_PULSE "pulse" #define MQTT_TOPIC_SPEED "speed" +#define MQTT_TOPIC_IR "ir" // Light module #define MQTT_TOPIC_CHANNEL "channel" @@ -1057,8 +1058,8 @@ #define IR_SUPPORT 0 // Do not build with IR support by default (10.25Kb) #endif -#ifndef IR_PIN -#define IR_PIN 4 // IR LED +#ifndef IR_RECEIVER_PIN +#define IR_RECEIVER_PIN 4 // IR LED #endif // 24 Buttons Set of the IR Remote @@ -1066,6 +1067,10 @@ #define IR_BUTTON_SET 1 // IR button set to use (see below) #endif +#ifndef IR_DEBOUNCE +#define IR_DEBOUNCE 500 // IR debounce time in milliseconds +#endif + //Remote Buttons SET 1 (for the original Remote shipped with the controller) #if IR_SUPPORT #if IR_BUTTON_SET == 1 diff --git a/code/espurna/config/hardware.h b/code/espurna/config/hardware.h index e1d9c8f6..17727ee7 100644 --- a/code/espurna/config/hardware.h +++ b/code/espurna/config/hardware.h @@ -1068,7 +1068,7 @@ // IR #define IR_SUPPORT 1 - #define IR_PIN 4 + #define IR_RECEIVER_PIN 4 #define IR_BUTTON_SET 1 #elif defined(MAGICHOME_LED_CONTROLLER_20) @@ -1097,7 +1097,7 @@ // IR #define IR_SUPPORT 1 - #define IR_PIN 4 + #define IR_RECEIVER_PIN 4 #define IR_BUTTON_SET 1 // ----------------------------------------------------------------------------- @@ -2649,7 +2649,7 @@ // IR - pin 4 #define IR_SUPPORT 1 - #define IR_PIN 4 + #define IR_RECEIVER_PIN 4 #define IR_BUTTON_SET 1 // A bit of DHT - pin 5 diff --git a/code/espurna/config/progmem.h b/code/espurna/config/progmem.h index 66c59017..ba607720 100644 --- a/code/espurna/config/progmem.h +++ b/code/espurna/config/progmem.h @@ -58,6 +58,9 @@ PROGMEM const char espurna_modules[] = #if INFLUXDB_SUPPORT "INFLUXDB " #endif + #if IR_SUPPORT + "IR " + #endif #if LLMNR_SUPPORT "LLMNR " #endif diff --git a/code/espurna/ir.ino b/code/espurna/ir.ino index 29e00afb..e57b45d0 100644 --- a/code/espurna/ir.ino +++ b/code/espurna/ir.ino @@ -20,83 +20,86 @@ unsigned long _ir_last_toggle = 0; // PRIVATE // ----------------------------------------------------------------------------- -void _irProcessCode(unsigned long code) { +void _irProcessCode(unsigned long code, unsigned char type) { - static unsigned long last_code; - boolean found = false; + // Check valid code + unsigned long last_code = 0; + unsigned long last_time = 0; + if (code == 0xFFFFFFFF) return; + if (type == 0xFF) return; + if ((last_code == code) && (millis() - last_time < IR_DEBOUNCE)) return; + last_code = code; + DEBUG_MSG_P(PSTR("[IR] Received 0x%08X (%d)\n"), code, type); - // Repeat last valid code - DEBUG_MSG_P(PSTR("[IR] Received 0x%06X\n"), code); - if (code == 0xFFFFFFFF) { - DEBUG_MSG_P(PSTR("[IR] Processing 0x%06X\n"), code); - code = last_code; - } + #if IR_BUTTON_SET > 0 - for (unsigned char i = 0; i < IR_BUTTON_COUNT ; i++) { + boolean found = false; - uint32_t button_code = pgm_read_dword(&IR_BUTTON[i][0]); - if (code == button_code) { + for (unsigned char i = 0; i < IR_BUTTON_COUNT ; i++) { - unsigned long button_mode = pgm_read_dword(&IR_BUTTON[i][1]); - unsigned long button_value = pgm_read_dword(&IR_BUTTON[i][2]); + uint32_t button_code = pgm_read_dword(&IR_BUTTON[i][0]); + if (code == button_code) { - if (button_mode == IR_BUTTON_MODE_STATE) { - relayStatus(0, button_value); - } + unsigned long button_mode = pgm_read_dword(&IR_BUTTON[i][1]); + unsigned long button_value = pgm_read_dword(&IR_BUTTON[i][2]); - if (button_mode == IR_BUTTON_MODE_TOGGLE) { + if (button_mode == IR_BUTTON_MODE_STATE) { + relayStatus(0, button_value); + } - if (millis() - _ir_last_toggle > 250){ + if (button_mode == IR_BUTTON_MODE_TOGGLE) { relayToggle(button_value); - _ir_last_toggle = millis(); - } else { - DEBUG_MSG_P(PSTR("[IR] Ignoring repeated code\n")); } - } - #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE + #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE - if (button_mode == IR_BUTTON_MODE_BRIGHTER) { - lightBrightnessStep(button_value ? 1 : -1); - nice_delay(150); //debounce - } + if (button_mode == IR_BUTTON_MODE_BRIGHTER) { + lightBrightnessStep(button_value ? 1 : -1); + nice_delay(150); //debounce + } - if (button_mode == IR_BUTTON_MODE_RGB) { - lightColor(button_value); - } + if (button_mode == IR_BUTTON_MODE_RGB) { + lightColor(button_value); + } - /* - #if LIGHT_PROVIDER == LIGHT_PROVIDER_FASTLED - if (button_mode == IR_BUTTON_MODE_EFFECT) { - _buttonAnimMode(button_value); + /* + #if LIGHT_PROVIDER == LIGHT_PROVIDER_FASTLED + if (button_mode == IR_BUTTON_MODE_EFFECT) { + _buttonAnimMode(button_value); + } + #endif + */ + + /* + if (button_mode == IR_BUTTON_MODE_HSV) { + lightColor(button_value); } - #endif - */ + */ - /* - if (button_mode == IR_BUTTON_MODE_HSV) { - lightColor(button_value); - } - */ + lightUpdate(true, true); - lightUpdate(true, true); + #endif - #endif + found = true; + break; - found = true; - last_code = code; - break; + } - } + } - } + if (!found) { + DEBUG_MSG_P(PSTR("[IR] Ignoring code\n")); + } - if (!found) { - DEBUG_MSG_P(PSTR("[IR] Ignoring code\n")); - } + #endif -} + #if MQTT_SUPPORT + char buffer[16]; + snprintf_P(buffer, sizeof(buffer), "0x%08X", code); + mqttSend(MQTT_TOPIC_IR, buffer); + #endif +} // ----------------------------------------------------------------------------- // PUBLIC API @@ -104,7 +107,7 @@ void _irProcessCode(unsigned long code) { void irSetup() { - _ir_recv = new IRrecv(IR_PIN); + _ir_recv = new IRrecv(IR_RECEIVER_PIN); _ir_recv->enableIRIn(); // Register loop @@ -114,8 +117,7 @@ void irSetup() { void irLoop() { if (_ir_recv->decode(&_ir_results)) { - unsigned long code = _ir_results.value; - _irProcessCode(code); + _irProcessCode(_ir_results.value, _ir_results.decode_type); _ir_recv->resume(); // Receive the next value } }