diff --git a/code/espurna/config/hardware.h b/code/espurna/config/hardware.h index 690a7610..b3ac61c7 100644 --- a/code/espurna/config/hardware.h +++ b/code/espurna/config/hardware.h @@ -617,6 +617,14 @@ #define LED1_PIN 13 #define LED1_PIN_INVERSE 1 + // RFB-Direct + #ifdef RFB_DIRECT + #undef DEVICE + #define DEVICE "SONOFF_RFBRIDGE_DIRECT" + #define RFB_RX_PIN 4 + #define RFB_TX_PIN 5 + #endif + #elif defined(ITEAD_SONOFF_B1) // Info @@ -1641,7 +1649,7 @@ #define MANUFACTURER "MAXCIO" #define DEVICE "WUS002S" - // Buttons + // Buttons #define BUTTON1_PIN 2 #define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH #define BUTTON1_RELAY 1 diff --git a/code/espurna/rfbridge.ino b/code/espurna/rfbridge.ino index e9d3f1f7..96b0dbfd 100644 --- a/code/espurna/rfbridge.ino +++ b/code/espurna/rfbridge.ino @@ -11,6 +11,10 @@ Copyright (C) 2017-2018 by Xose PĂ©rez #include #include +#ifdef RFB_DIRECT +#include +#endif + // ----------------------------------------------------------------------------- // DEFINITIONS // ----------------------------------------------------------------------------- @@ -51,6 +55,11 @@ static std::queue _rfb_message_queue; Ticker _rfb_ticker; bool _rfb_ticker_active = false; +#ifdef RFB_DIRECT +RCSwitch * _rfModem; +bool _learning = false; +#endif + // ----------------------------------------------------------------------------- // PRIVATES // ----------------------------------------------------------------------------- @@ -105,6 +114,7 @@ void _rfbWebSocketOnAction(uint32_t client_id, const char * action, JsonObject& } void _rfbAck() { + #ifndef RFB_DIRECT DEBUG_MSG_P(PSTR("[RFBRIDGE] Sending ACK\n")); Serial.println(); Serial.write(RF_CODE_START); @@ -112,17 +122,22 @@ void _rfbAck() { Serial.write(RF_CODE_STOP); Serial.flush(); Serial.println(); + #endif } void _rfbLearn() { - - DEBUG_MSG_P(PSTR("[RFBRIDGE] Sending LEARN\n")); - Serial.println(); - Serial.write(RF_CODE_START); - Serial.write(RF_CODE_LEARN); - Serial.write(RF_CODE_STOP); - Serial.flush(); - Serial.println(); + #ifdef RFB_DIRECT + DEBUG_MSG_P(PSTR("[RFBRIDGE] Entering LEARN mode\n")); + _learning = true; + #else + DEBUG_MSG_P(PSTR("[RFBRIDGE] Sending LEARN\n")); + Serial.println(); + Serial.write(RF_CODE_START); + Serial.write(RF_CODE_LEARN); + Serial.write(RF_CODE_STOP); + Serial.flush(); + Serial.println(); + #endif #if WEB_SUPPORT char buffer[100]; @@ -139,13 +154,25 @@ void _rfbSendRaw(const byte *message, const unsigned char n = RF_MESSAGE_SIZE) { } void _rfbSend(byte * message) { - Serial.println(); - Serial.write(RF_CODE_START); - Serial.write(RF_CODE_RFOUT); - _rfbSendRaw(message); - Serial.write(RF_CODE_STOP); - Serial.flush(); - Serial.println(); + #ifdef RFB_DIRECT + unsigned int protocol = message[1]; + unsigned int bitlength = message[4]; + unsigned long rf_code = + (message[5] << 24) | + (message[6] << 16) | + (message[7] << 8) | + (message[8] << 0) ; + _rfModem->setProtocol(protocol); + _rfModem->send(rf_code, bitlength); + #else + Serial.println(); + Serial.write(RF_CODE_START); + Serial.write(RF_CODE_RFOUT); + _rfbSendRaw(message); + Serial.write(RF_CODE_STOP); + Serial.flush(); + Serial.println(); + #endif } void _rfbSend() { @@ -301,33 +328,74 @@ void _rfbDecode() { } void _rfbReceive() { - - static bool receiving = false; - - while (Serial.available()) { - - yield(); - byte c = Serial.read(); - //DEBUG_MSG_P(PSTR("[RFBRIDGE] Received 0x%02X\n"), c); - - if (receiving) { - if (c == RF_CODE_STOP && (_uartpos == 1 || _uartpos == RF_MESSAGE_SIZE + 1)) { + #ifdef RFB_DIRECT + static long learn_start = 0; + if (!_learning && learn_start) { + learn_start = 0; + } + if (_learning) { + if (!learn_start) { + DEBUG_MSG_P(PSTR("[RFBRIDGE] arming learn timeout\n")); + learn_start = millis(); + } + if (learn_start > 0 && millis() - learn_start > RF_LEARN_TIMEOUT) { + DEBUG_MSG_P(PSTR("[RFBRIDGE] learn timeout triggered\n")); + memset(_uartbuf, 0, sizeof(_uartbuf)); + _uartbuf[0] = RF_CODE_LEARN_KO; _rfbDecode(); - receiving = false; - } else if (_uartpos <= RF_MESSAGE_SIZE) { - _uartbuf[_uartpos++] = c; - } else { - // wrong message, should have received a RF_CODE_STOP - receiving = false; + _learning = false; } - } else if (c == RF_CODE_START) { - _uartpos = 0; - receiving = true; } - } + if (_rfModem->available()) { + static unsigned long last = 0; + if (millis() - last > RF_DEBOUNCE) { + last = millis(); + unsigned long rf_code = _rfModem->getReceivedValue(); + if ( rf_code > 0) { + DEBUG_MSG_P(PSTR("[RFBRIDGE] Received code: %08X\n"), rf_code); + memset(_uartbuf, 0, sizeof(_uartbuf)); + unsigned char *msgbuf = _uartbuf + 1; + _uartbuf[0] = _learning ? RF_CODE_LEARN_OK: RF_CODE_RFIN; + msgbuf[0] = 0xC0; + msgbuf[1] = _rfModem->getReceivedProtocol(); + msgbuf[4] = _rfModem->getReceivedBitlength(); + msgbuf[5] = rf_code >> 24; + msgbuf[6] = rf_code >> 16; + msgbuf[7] = rf_code >> 8; + msgbuf[8] = rf_code >> 0; + _rfbDecode(); + _learning = false; + } + } + _rfModem->resetAvailable(); + } + #else + static bool receiving = false; + + while (Serial.available()) { + yield(); + byte c = Serial.read(); + //DEBUG_MSG_P(PSTR("[RFBRIDGE] Received 0x%02X\n"), c); + if (receiving) { + if (c == RF_CODE_STOP && (_uartpos == 1 || _uartpos == RF_MESSAGE_SIZE + 1)) { + _rfbDecode(); + receiving = false; + } else if (_uartpos <= RF_MESSAGE_SIZE) { + _uartbuf[_uartpos++] = c; + } else { + // wrong message, should have received a RF_CODE_STOP + receiving = false; + } + } else if (c == RF_CODE_START) { + _uartpos = 0; + receiving = true; + } + + } + #endif } bool _rfbCompare(const char * code1, const char * code2) { @@ -346,9 +414,9 @@ void _rfbMqttCallback(unsigned int type, const char * topic, const char * payloa snprintf_P(buffer, sizeof(buffer), PSTR("%s/+"), MQTT_TOPIC_RFLEARN); mqttSubscribe(buffer); mqttSubscribe(MQTT_TOPIC_RFOUT); - #if RF_RAW_SUPPORT - mqttSubscribe(MQTT_TOPIC_RFRAW); - #endif + #if RF_RAW_SUPPORT + mqttSubscribe(MQTT_TOPIC_RFRAW); + #endif } if (type == MQTT_MESSAGE_EVENT) { @@ -522,6 +590,14 @@ void rfbSetup() { wsOnActionRegister(_rfbWebSocketOnAction); #endif + #ifdef RFB_DIRECT + _rfModem = new RCSwitch(); + _rfModem->enableReceive(RFB_RX_PIN); + _rfModem->enableTransmit(RFB_TX_PIN); + DEBUG_MSG_P(PSTR("[RFBRIDGE] RF receiver on GPIO %u\n"), RFB_RX_PIN); + DEBUG_MSG_P(PSTR("[RFBRIDGE] RF transmitter on GPIO %u\n"), RFB_TX_PIN); + #endif + // Register loop espurnaRegisterLoop(rfbLoop); diff --git a/code/platformio.ini b/code/platformio.ini index 1bfbd65b..db86f9e3 100644 --- a/code/platformio.ini +++ b/code/platformio.ini @@ -718,6 +718,31 @@ upload_flags = ${common.upload_flags} monitor_baud = 19200 extra_scripts = ${common.extra_scripts} +[env:itead-sonoff-rfbridge-direct] +platform = ${common.platform} +framework = arduino +board = esp01_1m +board_flash_mode = dout +lib_deps = ${common.lib_deps} +lib_ignore = ${common.lib_ignore} +build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_RFBRIDGE -DRFB_DIRECT +monitor_baud = 19200 +extra_scripts = ${common.extra_scripts} + +[env:itead-sonoff-rfbridge-direct-ota] +platform = ${common.platform} +framework = arduino +board = esp01_1m +board_flash_mode = dout +lib_deps = ${common.lib_deps} +lib_ignore = ${common.lib_ignore} +build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_RFBRIDGE -DRFB_DIRECT +upload_speed = 115200 +upload_port = "192.168.4.1" +upload_flags = --auth=fibonacci --port 8266 +monitor_baud = 19200 +extra_scripts = ${common.extra_scripts} + # ------------------------------------------------------------------------------ [env:itead-slampher]