diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b6a4145c..718620ec4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,20 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.8.0dev] 2019-06-08 +## [1.8.0] 2019-06-15 ### Added - Support for HeatPump (e.g. the Nefit Enviline) - new device: Buderus MM50 Mixer - new devices: Junkers FW100 and ISM1 (thanks @Vuego123) -- tx_mode takes a value from 0 to 3 for the different Tx logic - ``` - 0 = original classic ems logic - 1 = @kwertie01 ems+ logic (https://github.com/proddy/EMS-ESP/issues/23#issuecomment-476872291) - 2 = @susisstrolch logic [(pull request 113)](https://github.com/proddy/EMS-ESP/pull/113) - 3 = @philrich logic for Junkers (https://github.com/proddy/EMS-ESP/files/3190563/ems-delay-rev-poll.patch.txt) - ``` +- Improved Tx logic to support EMS, EMS+ and Heatronics (thanks kwertie01, susisstrolch, philrich) +- MQTT heartbeat ### Fixed diff --git a/lib/MyESP/MyESP.cpp b/lib/MyESP/MyESP.cpp index 9a50c21a1..48d7d4422 100644 --- a/lib/MyESP/MyESP.cpp +++ b/lib/MyESP/MyESP.cpp @@ -673,7 +673,7 @@ bool MyESP::_changeSetting(uint8_t wc, const char * setting, const char * value) } ok = true; jw.enableSTA(false); - myDebug_P(PSTR("Note: please reboot to apply new WiFi settings")); + myDebug_P(PSTR("Note: please 'reboot' ESP to apply new WiFi settings")); } else if (strcmp(setting, "wifi_password") == 0) { if (_wifi_password) free(_wifi_password); @@ -683,7 +683,7 @@ bool MyESP::_changeSetting(uint8_t wc, const char * setting, const char * value) } ok = true; jw.enableSTA(false); - myDebug_P(PSTR("Note: please reboot to apply new WiFi settings")); + myDebug_P(PSTR("Note: please 'reboot' ESP to apply new WiFi settings")); } else if (strcmp(setting, "mqtt_host") == 0) { if (_mqtt_host) diff --git a/platformio.ini-example b/platformio.ini-example index 9cc77c048..027670d7b 100644 --- a/platformio.ini-example +++ b/platformio.ini-example @@ -8,19 +8,24 @@ default_envs = debug [common] -; hard code if you prefer. Recommendation is to set from within the app when in Serial or AP mode -; wifi_settings = '-DWIFI_SSID="XXXX"' '-DWIFI_PASSWORD="XXXX"' -wifi_settings = - debug_flags = -Wall -Wextra -Werror -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unused-variable -DTESTS -general_flags = -g -w -DNO_GLOBAL_EEPROM ${common.wifi_settings} +general_flags = -g -w -DNO_GLOBAL_EEPROM + +arduino_core_2_3_0 = espressif8266@1.5.0 +arduino_core_2_4_0 = espressif8266@1.6.0 +arduino_core_2_4_1 = espressif8266@1.7.3 +arduino_core_2_4_2 = espressif8266@1.8.0 +arduino_core_2_5_0 = espressif8266@2.0.4 +arduino_core_2_5_1 = espressif8266@2.1.1 +arduino_core_2_5_2 = espressif8266@2.2.1 +arduino_core_latest = espressif8266 [env] board = d1_mini ; board = nodemcuv2 ; board = d1_mini_pro framework = arduino -platform = espressif8266 +platform = ${common.arduino_core_latest} lib_deps = CRC32 CircularBuffer @@ -31,8 +36,9 @@ lib_deps = EEPROM_rotate upload_speed = 921600 monitor_speed = 115200 -upload_protocol = espota -upload_port = ems-esp.local +; uncomment next 2 lines for OTA +;upload_protocol = espota +;upload_port = ems-esp.local [env:debug] build_flags = ${common.general_flags} ${common.debug_flags} diff --git a/src/ems-esp.cpp b/src/ems-esp.cpp index 20456c04b..097f9de63 100644 --- a/src/ems-esp.cpp +++ b/src/ems-esp.cpp @@ -106,7 +106,6 @@ command_t project_cmds[] = { {true, "shower_alert ", "send a warning of cold water after shower time is exceeded"}, {true, "publish_wait ", "set frequency for publishing to MQTT"}, {true, "heating_circuit <1 | 2>", "set the thermostat HC to work with if using multiple heating circuits"}, - {true, "tx_mode ", "0=classic ems logic, 1=@kwertie01 ems+ logic, 2=@susisstrolch logic, 3=@philrich logic for Junkers"}, {false, "info", "show data captured on the EMS bus"}, {false, "log ", "set logging mode to none, basic, thermostat only, raw or verbose"}, @@ -347,9 +346,8 @@ void showInfo() { if (ems_getTxCapable()) { char valuestr[8] = {0}; // for formatting floats - myDebug_P(PSTR(" Tx: Last poll=%s seconds ago, Tx mode=%d, # successful write requests=%d"), + myDebug_P(PSTR(" Tx: Last poll=%s seconds ago, # successful write requests=%d"), _float_to_char(valuestr, (ems_getPollFrequency() / (float)1000000), 3), - ems_getTxMode(), EMS_Sys_Status.emsTxPkgs); } else { myDebug_P(PSTR(" Tx: no signal")); @@ -1058,9 +1056,6 @@ bool FSCallback(MYESP_FSACTION action, const JsonObject json) { // shower_alert EMSESP_Status.shower_alert = json["shower_alert"]; - // tx mode - ems_setTxMode(json["tx_mode"]); - // publish_wait if (!(EMSESP_Status.publish_wait = json["publish_wait"])) { EMSESP_Status.publish_wait = DEFAULT_PUBLISHWAIT; // default value @@ -1087,7 +1082,6 @@ bool FSCallback(MYESP_FSACTION action, const JsonObject json) { json["shower_alert"] = EMSESP_Status.shower_alert; json["publish_wait"] = EMSESP_Status.publish_wait; json["heating_circuit"] = EMSESP_Status.heating_circuit; - json["tx_mode"] = ems_getTxMode(); return true; } @@ -1218,11 +1212,6 @@ bool SettingsCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, c } } - // tx delay/ tx mode - if (((strcmp(setting, "tx_mode") == 0) || (strcmp(setting, "tx_delay") == 0)) && (wc == 2)) { - ems_setTxMode(atoi(value)); - ok = true; - } } if (action == MYESP_FSACTION_LIST) { @@ -1249,7 +1238,6 @@ bool SettingsCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, c myDebug_P(PSTR(" shower_timer=%s"), EMSESP_Status.shower_timer ? "on" : "off"); myDebug_P(PSTR(" shower_alert=%s"), EMSESP_Status.shower_alert ? "on" : "off"); myDebug_P(PSTR(" publish_wait=%d"), EMSESP_Status.publish_wait); - myDebug_P(PSTR(" tx_mode=%d"), ems_getTxMode()); } return ok; @@ -1689,11 +1677,7 @@ void setup() { // set up myESP for Wifi, MQTT, MDNS and Telnet myESP.setTelnet(project_cmds, ArraySize(project_cmds), TelnetCommandCallback, TelnetCallback); // set up Telnet commands -#ifdef WIFI_SSID - myESP.setWIFI(WIFI_SSID, WIFI_PASSWORD, WIFICallback); -#else - myESP.setWIFI(NULL, NULL, WIFICallback); // pull the wifi settings from the SPIFFS stored settings -#endif + myESP.setWIFI(NULL, NULL, WIFICallback); // MQTT host, username and password taken from the SPIFFS settings myESP.setMQTT( diff --git a/src/ems.cpp b/src/ems.cpp index 0e097301c..33bbb2adb 100644 --- a/src/ems.cpp +++ b/src/ems.cpp @@ -228,7 +228,6 @@ void ems_init() { EMS_Sys_Status.emsTxDisabled = false; EMS_Sys_Status.emsPollFrequency = 0; EMS_Sys_Status.txRetryCount = 0; - EMS_Sys_Status.emsTxMode = 0; EMS_Sys_Status.emsReverse = false; // thermostat @@ -341,23 +340,6 @@ bool ems_getPoll() { return EMS_Sys_Status.emsPollEnabled; } -void ems_setTxMode(uint8_t mode) { - EMS_Sys_Status.emsTxMode = mode; - - // special case for Junkers. If tx_mode is 3 then set the reverse poll flag - // https://github.com/proddy/EMS-ESP/issues/103#issuecomment-495945850 - if (mode == 3) { - EMS_Sys_Status.emsReverse = true; - myDebug_P(PSTR("Forcing emsReverse for Junkers")); // TODO: remove at some point when 2 is the standard - } else { - EMS_Sys_Status.emsReverse = false; - } -} - -uint8_t ems_getTxMode() { - return EMS_Sys_Status.emsTxMode; -} - bool ems_getEmsRefreshed() { return EMS_Sys_Status.emsRefreshed; } @@ -2455,7 +2437,7 @@ void ems_testTelegram(uint8_t test_num) { EMS_Sys_Status.emsTxStatus = EMS_TX_STATUS_IDLE; } - static uint8_t * telegram = (uint8_t *)malloc(EMS_MAX_TELEGRAM_LENGTH); // warning, memory is not free'd so use only for debugging + static uint8_t * telegram = (uint8_t *)malloc(EMS_MAX_TELEGRAM_LENGTH); // warning, memory is never set free so use only for debugging char telegram_string[200]; strlcpy(telegram_string, TEST_DATA[test_num - 1], sizeof(telegram_string)); diff --git a/src/ems.h b/src/ems.h index f256ae4fa..e20ca7660 100644 --- a/src/ems.h +++ b/src/ems.h @@ -97,7 +97,6 @@ typedef struct { bool emsTxCapable; // able to send via Tx bool emsTxDisabled; // true to prevent all Tx uint8_t txRetryCount; // # times the last Tx was re-sent - uint8_t emsTxMode; // handles Tx logic bool emsReverse; // if true, poll logic is reversed } _EMS_Sys_Status; @@ -315,7 +314,6 @@ void ems_setFlowTemp(uint8_t temperature); void ems_setWarmWaterActivated(bool activated); void ems_setWarmTapWaterActivated(bool activated); void ems_setPoll(bool b); -void ems_setTxMode(uint8_t mode); void ems_setLogging(_EMS_SYS_LOGGING loglevel); void ems_setEmsRefreshed(bool b); void ems_setWarmWaterModeComfort(uint8_t comfort); @@ -331,7 +329,6 @@ bool ems_getPoll(); bool ems_getTxEnabled(); bool ems_getThermostatEnabled(); bool ems_getBoilerEnabled(); -uint8_t ems_getTxMode(); bool ems_getBusConnected(); _EMS_SYS_LOGGING ems_getLogging(); bool ems_getEmsRefreshed(); diff --git a/src/emsuart.cpp b/src/emsuart.cpp index 3e906b042..0afcccd56 100644 --- a/src/emsuart.cpp +++ b/src/emsuart.cpp @@ -137,10 +137,8 @@ void ICACHE_FLASH_ATTR emsuart_init() { // disable esp debug which will go to Tx and mess up the line - see https://github.com/espruino/Espruino/issues/655 system_set_os_print(0); -// swap Rx and Tx pins to use GPIO13 (D7) and GPIO15 (D8) respectively -#ifndef NO_UART_SWAP + // swap Rx and Tx pins to use GPIO13 (D7) and GPIO15 (D8) respectively system_uart_swap(); -#endif ETS_UART_INTR_ATTACH(emsuart_rx_intr_handler, NULL); ETS_UART_INTR_ENABLE(); @@ -161,35 +159,6 @@ void ICACHE_FLASH_ATTR emsuart_start() { ETS_UART_INTR_ENABLE(); } -/* - * Send a BRK signal - * Which is a 11-bit set of zero's (11 cycles) - */ -void ICACHE_FLASH_ATTR emsuart_tx_brk() { - uint32_t tmp; - - // must make sure Tx FIFO is empty - while (((USS(EMSUART_UART) >> USTXC) & 0xFF) != 0) - ; - - tmp = ((1 << UCRXRST) | (1 << UCTXRST)); // bit mask - USC0(EMSUART_UART) |= (tmp); // set bits - USC0(EMSUART_UART) &= ~(tmp); // clear bits - - // To create a 11-bit we set TXD_BRK bit so the break signal will - // automatically be sent when the tx fifo is empty - tmp = (1 << UCBRK); - USC0(EMSUART_UART) |= (tmp); // set bit - - if (EMS_Sys_Status.emsTxMode <= 1) { // classic mode and ems+ (0, 1) - delayMicroseconds(EMSUART_TX_BRK_WAIT); - } else if (EMS_Sys_Status.emsTxMode == 3) { // junkers mode - delayMicroseconds(EMSUART_TX_WAIT_BRK - EMSUART_TX_LAG); // 1144 (11 Bits) - } - - USC0(EMSUART_UART) &= ~(tmp); // clear bit -} - /* * set loopback mode and clear Tx/Rx FIFO */ @@ -207,75 +176,50 @@ void ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) { if (len == 0) return; - if (EMS_Sys_Status.emsTxMode == 0) { // classic mode logic - for (uint8_t i = 0; i < len; i++) { - USF(EMSUART_UART) = buf[i]; + /* + * based on code from https://github.com/proddy/EMS-ESP/issues/103 by @susisstrolch + * we emit the whole telegram, with Rx interrupt disabled, collecting busmaster response in FIFO. + * after sending the last char we poll the Rx status until either + * - size(Rx FIFO) == size(Tx-Telegram) + * - is detected + * At end of receive we re-enable Rx-INT and send a Tx-BRK in loopback mode. + */ + ETS_UART_INTR_DISABLE(); // disable rx interrupt + + // clear Rx status register + USC0(EMSUART_UART) |= (1 << UCRXRST); // reset uart rx fifo + emsuart_flush_fifos(); + + // throw out the telegram... + for (uint8_t i = 0; i < len;) { + USF(EMSUART_UART) = buf[i++]; // send each Tx byte + // wait for echo from busmaster + while ((((USS(EMSUART_UART) >> USRXC) & 0xFF) < i || (USIS(EMSUART_UART) & (1 << UIBD)))) { + delayMicroseconds(EMSUART_BIT_TIME); // burn CPU cycles... } - emsuart_tx_brk(); // send - } else if (EMS_Sys_Status.emsTxMode == 1) { // With extra tx delay for EMS+ - for (uint8_t i = 0; i < len; i++) { - USF(EMSUART_UART) = buf[i]; - delayMicroseconds(EMSUART_TX_BRK_WAIT); // https://github.com/proddy/EMS-ESP/issues/23# - } - emsuart_tx_brk(); // send - } else if (EMS_Sys_Status.emsTxMode == 3) { // Junkers logic by @philrich - for (uint8_t i = 0; i < len; i++) { - USF(EMSUART_UART) = buf[i]; - - // just to be safe wait for tx fifo empty (needed?) - while (((USS(EMSUART_UART) >> USTXC) & 0xff) != 0) - ; - - // wait until bits are sent on wire - delayMicroseconds(EMSUART_TX_WAIT_BYTE - EMSUART_TX_LAG + EMSUART_TX_WAIT_GAP); - } - emsuart_tx_brk(); // send - } else if (EMS_Sys_Status.emsTxMode == 2) { // smart Tx - take two - https://github.com/proddy/EMS-ESP/issues/103 by @susisstrolch - - /* - * we emit the whole telegram, with Rx interrupt disabled, collecting busmaster response in FIFO. - * after sending the last char we poll the Rx status until either - * - size(Rx FIFO) == size(Tx-Telegram) - * - is detected - * At end of receive we re-enable Rx-INT and send a Tx-BRK in loopback mode. - */ - ETS_UART_INTR_DISABLE(); // disable rx interrupt - - // clear Rx status register - USC0(EMSUART_UART) |= (1 << UCRXRST); // reset uart rx fifo - emsuart_flush_fifos(); - - // throw out the telegram... - for (uint8_t i = 0; i < len;) { - USF(EMSUART_UART) = buf[i++]; // send each Tx byte - // wait for echo from busmaster - while ((((USS(EMSUART_UART) >> USRXC) & 0xFF) < i || (USIS(EMSUART_UART) & (1 << UIBD)))) { - delayMicroseconds(EMSUART_BIT_TIME); // burn CPU cycles... - } - } - - // we got the whole telegram in the Rx buffer - // on Rx-BRK (bus collision), we simply enable Rx and leave it - // otherwise we send the final Tx-BRK in the loopback and re=enable Rx-INT. - // worst case, we'll see an additional Rx-BRK... - if (!(USIS(EMSUART_UART) & (1 << UIBD))) { - // no bus collision - send terminating BRK signal - emsuart_loopback(true); - USC0(EMSUART_UART) |= (1 << UCBRK); // set - - // wait until BRK detected... - while (!(USIS(EMSUART_UART) & (1 << UIBD))) { - delayMicroseconds(EMSUART_BIT_TIME); - } - - USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear - - USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ - emsuart_loopback(false); // disable loopback mode - } - - ETS_UART_INTR_ENABLE(); // receive anything from FIFO... } + + // we got the whole telegram in the Rx buffer + // on Rx-BRK (bus collision), we simply enable Rx and leave it + // otherwise we send the final Tx-BRK in the loopback and re=enable Rx-INT. + // worst case, we'll see an additional Rx-BRK... + if (!(USIS(EMSUART_UART) & (1 << UIBD))) { + // no bus collision - send terminating BRK signal + emsuart_loopback(true); + USC0(EMSUART_UART) |= (1 << UCBRK); // set + + // wait until BRK detected... + while (!(USIS(EMSUART_UART) & (1 << UIBD))) { + delayMicroseconds(EMSUART_BIT_TIME); + } + + USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear + + USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ + emsuart_loopback(false); // disable loopback mode + } + + ETS_UART_INTR_ENABLE(); // receive anything from FIFO... } /* diff --git a/src/emsuart.h b/src/emsuart.h index 839082a08..cd57cd4da 100644 --- a/src/emsuart.h +++ b/src/emsuart.h @@ -13,15 +13,10 @@ #define EMSUART_CONFIG 0x1C // 8N1 (8 bits, no stop bits, 1 parity) #define EMSUART_BAUD 9600 // uart baud rate for the EMS circuit -#define EMS_MAXBUFFERS 10 // 4 buffers for circular filling to avoid collisions -#define EMS_MAXBUFFERSIZE 32 // max size of the buffer. packets are max 32 bytes +#define EMS_MAXBUFFERS 10 // buffers for circular filling to avoid collisions +#define EMS_MAXBUFFERSIZE 32 // max size of the buffer. packets are max 32 bytes to support EMS 1.0 -#define EMSUART_TX_BRK_WAIT 2070 // the BRK from Boiler master is roughly 1.039ms, so accounting for hardware lag using around 2078 (for half-duplex) - 8 (lag) -#define EMSUART_BIT_TIME 104 // bit time @9600 baud -#define EMSUART_TX_WAIT_BYTE EMSUART_BIT_TIME * 10 // Time to send one Byte (8 Bits, 1 Start Bit, 1 Stop Bit) -#define EMSUART_TX_WAIT_BRK EMSUART_BIT_TIME * 11 // Time to send a BRK Signal (11 Bit) -#define EMSUART_TX_WAIT_GAP EMSUART_BIT_TIME * 7 // Gap between to Bytes -#define EMSUART_TX_LAG 8 // Assumed Lag +#define EMSUART_BIT_TIME 104 // bit time @9600 baud #define EMSUART_recvTaskPrio 1 #define EMSUART_recvTaskQueueLen 64 @@ -36,4 +31,3 @@ void ICACHE_FLASH_ATTR emsuart_stop(); void ICACHE_FLASH_ATTR emsuart_start(); void ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len); void ICACHE_FLASH_ATTR emsuart_tx_poll(); -void ICACHE_FLASH_ATTR emsuart_tx_brk(); diff --git a/src/version.h b/src/version.h index e3f3dbd13..fa69ef04e 100644 --- a/src/version.h +++ b/src/version.h @@ -6,5 +6,5 @@ #pragma once #define APP_NAME "EMS-ESP" -#define APP_VERSION "1.8.0b15" +#define APP_VERSION "1.8.0" #define APP_HOSTNAME "ems-esp"