diff --git a/.gitignore b/.gitignore index 303d778b1..887d4c52b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ emsesp doc/github.txt doc/test_data.txt +/src/uart/uart_proddy.txt diff --git a/platformio.ini b/platformio.ini index 93b877eb6..f94869833 100644 --- a/platformio.ini +++ b/platformio.ini @@ -4,6 +4,7 @@ [platformio] default_envs = esp8266 ; default_envs = esp32 +; default_envs = esp32_d1 # override any settings with your own local ones in pio_local.ini extra_configs = pio_local.ini @@ -21,7 +22,7 @@ extra_configs = pio_local.ini ;debug_flags = -DDEBUG_ESP_PORT=Serial -DDEBUG_ESP_CORE -DDEBUG_ESP_SSL -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_TLS_MEM debug_flags = - -D EMSESP_DEBUG + ; -D EMSESP_DEBUG ; -D EMSESP_SAFE_MODE ; -D ENABLE_CORS -D CORS_ORIGIN=\"http://localhost:3000\" @@ -62,7 +63,7 @@ check_flags = clangtidy: --checks=-*,clang-analyzer-*,performance-* ; USB upload -; upload_protocol = esptool + ;upload_protocol = esptool ; example ports for OSX ;upload_port = /dev/cu.wchusbserial14403 ;upload_port = /dev/cu.usbserial-1440 @@ -73,7 +74,7 @@ upload_protocol = espota upload_flags = --port=8266 --auth=neo -upload_port = ems-esp.local +;upload_port = 192.168.0.20 [env:esp8266] build_type = release @@ -86,6 +87,7 @@ board_build.f_cpu = 160000000L ; 160MHz board_build.ldscript = eagle.flash.4m1m.ld ; 1019 KB sketch, 1000 KB SPIFFS. 4KB EEPROM, 4KB RFCAL, 12KB WIFI stack, 2052 KB OTA & buffer ; board_build.ldscript = eagle.flash.4m2m.ld ; 1019 KB sketch, 2024 KB SPIFFS. 4KB EEPROM, 4KB RFCAL, 12KB WIFI stack, 1028 KB OTA & buffer build_flags = ${common.build_flags} ${common.debug_flags} -D PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY +upload_port = 192.168.0.20 [env:esp32] build_type = release @@ -94,3 +96,10 @@ board = esp32dev lib_deps = ${common.libs_core} ${common.libs_esp32} build_flags = ${common.build_flags} ${common.debug_flags} -D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH +[env:esp32_d1] +build_type = release +platform = espressif32 +board = wemos_d1_mini32 +lib_deps = ${common.libs_core} ${common.libs_esp32} +build_flags = ${common.build_flags} ${common.debug_flags} -D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH -D WEMOS_D1_32 +upload_port = 192.168.0.23 diff --git a/src/boiler.cpp b/src/boiler.cpp index 283c3fc01..55e6a2fcb 100644 --- a/src/boiler.cpp +++ b/src/boiler.cpp @@ -49,7 +49,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const LOG_DEBUG(F("Registering new Boiler with device ID 0x%02X"), device_id); // the telegram handlers... - register_telegram_type(0x18, F("UBAMonitorFast"), true, std::bind(&Boiler::process_UBAMonitorFast, this, _1)); + register_telegram_type(0x18, F("UBAMonitorFast"), false, std::bind(&Boiler::process_UBAMonitorFast, this, _1)); register_telegram_type(0x19, F("UBAMonitorSlow"), true, std::bind(&Boiler::process_UBAMonitorSlow, this, _1)); register_telegram_type(0x34, F("UBAMonitorWW"), false, std::bind(&Boiler::process_UBAMonitorWW, this, _1)); register_telegram_type(0x1C, F("UBAMaintenanceStatus"), false, std::bind(&Boiler::process_UBAMaintenanceStatus, this, _1)); @@ -61,12 +61,12 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_telegram_type(0x16, F("UBAParameters"), true, std::bind(&Boiler::process_UBAParameters, this, _1)); register_telegram_type(0x1A, F("UBASetPoints"), false, std::bind(&Boiler::process_UBASetPoints, this, _1)); register_telegram_type(0xD1, F("UBAOutdoorTemp"), false, std::bind(&Boiler::process_UBAOutdoorTemp, this, _1)); - register_telegram_type(0xE4, F("UBAMonitorFastPlus"), true, std::bind(&Boiler::process_UBAMonitorFastPlus, this, _1)); - register_telegram_type(0xE5, F("UBAMonitorSlowPlus"), true, std::bind(&Boiler::process_UBAMonitorSlowPlus, this, _1)); + register_telegram_type(0xE4, F("UBAMonitorFastPlus"), false, std::bind(&Boiler::process_UBAMonitorFastPlus, this, _1)); + register_telegram_type(0xE5, F("UBAMonitorSlowPlus"), false, std::bind(&Boiler::process_UBAMonitorSlowPlus, this, _1)); register_telegram_type(0xE9, F("UBADHWStatus"), false, std::bind(&Boiler::process_UBADHWStatus, this, _1)); - register_telegram_type(0xE3, F("HeatPumpMonitor1"), true, std::bind(&Boiler::process_HPMonitor1, this, _1)); - register_telegram_type(0xE5, F("HeatPumpMonitor2"), true, std::bind(&Boiler::process_HPMonitor2, this, _1)); + register_telegram_type(0xE3, F("HeatPumpMonitor1"), false, std::bind(&Boiler::process_HPMonitor1, this, _1)); + register_telegram_type(0xE5, F("HeatPumpMonitor2"), false, std::bind(&Boiler::process_HPMonitor2, this, _1)); // MQTT callbacks register_mqtt_topic("boiler_cmd", std::bind(&Boiler::boiler_cmd, this, _1)); @@ -190,14 +190,17 @@ void Boiler::publish_values() { doc["pumpMod"] = pumpMod_; } if (wWCircPump_ != EMS_VALUE_BOOL_NOTSET) { - doc["wWCircPump"] = wWCircPump_; + doc["wWCircPump"] = Helpers::render_value(s, wWCircPump_, EMS_VALUE_BOOL); } if (wWCircPumpType_ != EMS_VALUE_BOOL_NOTSET) { - doc["wWCiPuType"] = wWCircPumpType_; + doc["wWCiPuType"] = wWCircPumpType_ ? "valve" : "pump"; } if (wWCircPumpMode_ != EMS_VALUE_UINT_NOTSET) { doc["wWCiPuMode"] = wWCircPumpMode_; } + if (wWCirc_ != EMS_VALUE_BOOL_NOTSET) { + doc["wWCirc"] = Helpers::render_value(s, wWCirc_, EMS_VALUE_BOOL); + } if (extTemp_ != EMS_VALUE_SHORT_NOTSET) { doc["outdoorTemp"] = (float)extTemp_ / 10; } diff --git a/src/console.cpp b/src/console.cpp index 5d6c68b59..c0c61053f 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -235,7 +235,7 @@ void Console::load_standard_commands(unsigned int context) { } // trace logic - if (level == uuid::log::Level::TRACE) { + if (level == uuid::log::Level::TRACE || level == uuid::log::Level::DEBUG) { watch_id = LOG_TRACE_WATCH_NONE; // no watch ID set if (arguments.size() > 1) { // next argument is raw or full @@ -243,6 +243,8 @@ void Console::load_standard_commands(unsigned int context) { emsesp::EMSESP::trace_raw(true); } else if (arguments[1] == read_flash_string(F_(full))) { emsesp::EMSESP::trace_raw(false); + } else { + emsesp::EMSESP::trace_watch_id(Helpers::hextoint(arguments[1].c_str())); } // get the watch_id if its set diff --git a/src/console.h b/src/console.h index 337133426..27d8afe1e 100644 --- a/src/console.h +++ b/src/console.h @@ -112,6 +112,7 @@ MAKE_PSTR(deviceid_optional, "[device ID]") MAKE_PSTR(invalid_log_level, "Invalid log level") MAKE_PSTR(ip_address_optional, "[IP address]") MAKE_PSTR(ip_address_mandatory, "") +MAKE_PSTR(port_mandatory, "") MAKE_PSTR(log_level_fmt, "Log level = %s") MAKE_PSTR(log_level_optional, "[level]") MAKE_PSTR(name_mandatory, "") diff --git a/src/device_library.h b/src/device_library.h index 6ef1e19a1..2f1e9a492 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -24,36 +24,38 @@ */ // Boilers - 0x08 -{115, DeviceType::BOILER, F("Topline/GB162"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, -{123, DeviceType::BOILER, F("GBx72/Trendline/Cerapur/Greenstar Si/27i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, -{133, DeviceType::BOILER, F("GB125/Logamatic MC110"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, -{203, DeviceType::BOILER, F("Logamax U122/Cerapur"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, -{208, DeviceType::BOILER, F("Logamax plus/GB192/Condens GC9000"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, { 64, DeviceType::BOILER, F("BK13,BK15/Smartline/GB1x2"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, -{234, DeviceType::BOILER, F("Logamax Plus GB122"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, +{ 72, DeviceType::BOILER, F("GB125/MC10"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, { 84, DeviceType::BOILER, F("Logamax Plus GB022"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, { 95, DeviceType::BOILER, F("Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, +{115, DeviceType::BOILER, F("Topline/GB162"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {122, DeviceType::BOILER, F("Proline"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, +{123, DeviceType::BOILER, F("GBx72/Trendline/Cerapur/Greenstar Si/27i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, +{133, DeviceType::BOILER, F("GB125/Logamatic MC110"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {170, DeviceType::BOILER, F("Logano GB212"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {172, DeviceType::BOILER, F("Enviline/Compress 6000AW"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, -{ 72, DeviceType::BOILER, F("MC10"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, +{195, DeviceType::BOILER, F("Condens 5000i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, +{203, DeviceType::BOILER, F("Logamax U122/Cerapur"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, +{208, DeviceType::BOILER, F("Logamax plus/GB192/Condens GC9000"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, +{234, DeviceType::BOILER, F("Logamax Plus GB122"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, + // Solar Modules - 0x30 { 73, DeviceType::SOLAR, F("SM10"), DeviceFlags::EMS_DEVICE_FLAG_SM10}, -{163, DeviceType::SOLAR, F("SM100"), DeviceFlags::EMS_DEVICE_FLAG_SM100}, -{164, DeviceType::SOLAR, F("SM200"), DeviceFlags::EMS_DEVICE_FLAG_SM100}, {101, DeviceType::SOLAR, F("ISM1"), DeviceFlags::EMS_DEVICE_FLAG_SM100}, {162, DeviceType::SOLAR, F("SM50"), DeviceFlags::EMS_DEVICE_FLAG_SM100}, +{163, DeviceType::SOLAR, F("SM100"), DeviceFlags::EMS_DEVICE_FLAG_SM100}, +{164, DeviceType::SOLAR, F("SM200"), DeviceFlags::EMS_DEVICE_FLAG_SM100}, // Mixing Modules - 0x20-0x27 for HC, 0x28-0x29 for WWC -{160, DeviceType::MIXING, F("MM100"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, -{161, DeviceType::MIXING, F("MM200"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, { 69, DeviceType::MIXING, F("MM10"), DeviceFlags::EMS_DEVICE_FLAG_MM10}, {159, DeviceType::MIXING, F("MM50"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, +{160, DeviceType::MIXING, F("MM100"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, +{161, DeviceType::MIXING, F("MM200"), DeviceFlags::EMS_DEVICE_FLAG_MMPLUS}, // Heat Pumps - 0x38 -{252, DeviceType::HEATPUMP, F("HP Module"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, {200, DeviceType::HEATPUMP, F("HP Module"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, +{252, DeviceType::HEATPUMP, F("HP Module"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // Switches - 0x11 { 71, DeviceType::SWITCH, F("WM10"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x11 @@ -61,36 +63,38 @@ // Controllers - 0x09 / 0x10 / 0x50 { 68, DeviceType::CONTROLLER, F("BC10/RFM20"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 { 89, DeviceType::CONTROLLER, F("BC10 GB142"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 -{218, DeviceType::CONTROLLER, F("M200/RFM200"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x50 -{190, DeviceType::CONTROLLER, F("BC10"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 +{ 95, DeviceType::CONTROLLER, F("HT3"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 {114, DeviceType::CONTROLLER, F("BC10"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 {125, DeviceType::CONTROLLER, F("BC25"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 -{169, DeviceType::CONTROLLER, F("BC40"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 {152, DeviceType::CONTROLLER, F("Controller"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 -{ 95, DeviceType::CONTROLLER, F("HT3"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 -{209, DeviceType::CONTROLLER, F("ErP"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 -{230, DeviceType::CONTROLLER, F("BC Base"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 +{169, DeviceType::CONTROLLER, F("BC40"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 +{190, DeviceType::CONTROLLER, F("BC10"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 {207, DeviceType::CONTROLLER, F("Sense II/CS200"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x10 +{209, DeviceType::CONTROLLER, F("ErP"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 +{218, DeviceType::CONTROLLER, F("M200/RFM200"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x50 +{230, DeviceType::CONTROLLER, F("BC Base"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 +{241, DeviceType::CONTROLLER, F("Condens 5000i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09 + // Connect devices - 0x02 +{171, DeviceType::CONNECT, F("OpenTherm Converter"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x02 {205, DeviceType::CONNECT, F("Moduline Easy Connect"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x02 {206, DeviceType::CONNECT, F("Easy Connect"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x02 -{171, DeviceType::CONNECT, F("OpenTherm Converter"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x02 // Gateways - 0x48 / 0x18 -{189, DeviceType::GATEWAY, F("KM200"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x48 { 94, DeviceType::GATEWAY, F("RFM20 Remote Base for RC20RF"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x18 +{189, DeviceType::GATEWAY, F("KM200"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x48 // Thermostat - not currently supporting write operations, like the Easy/100 types - 0x18 {202, DeviceType::THERMOSTAT, F("Logamatic TC100/Moduline Easy"), DeviceFlags::EMS_DEVICE_FLAG_EASY | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18, cannot write {203, DeviceType::THERMOSTAT, F("EasyControl CT200"), DeviceFlags::EMS_DEVICE_FLAG_EASY | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18, cannot write // Thermostat - Common for Buderus/Nefit/Bosch specific - 0x17 / 0x10 / 0x18 +{ 67, DeviceType::THERMOSTAT, F("RC30"), DeviceFlags::EMS_DEVICE_FLAG_RC30_1},// 0x10 - based on RC35 +{ 77, DeviceType::THERMOSTAT, F("RC20/Moduline 300"), DeviceFlags::EMS_DEVICE_FLAG_RC20},// 0x17 +{ 78, DeviceType::THERMOSTAT, F("Moduline 400"), DeviceFlags::EMS_DEVICE_FLAG_RC30}, // 0x10 { 79, DeviceType::THERMOSTAT, F("RC10/Moduline 100"), DeviceFlags::EMS_DEVICE_FLAG_RC10},// 0x17 { 80, DeviceType::THERMOSTAT, F("Moduline 200"), DeviceFlags::EMS_DEVICE_FLAG_RC10}, // 0x17 -{ 77, DeviceType::THERMOSTAT, F("RC20/Moduline 300"), DeviceFlags::EMS_DEVICE_FLAG_RC20},// 0x17 -{ 67, DeviceType::THERMOSTAT, F("RC30"), DeviceFlags::EMS_DEVICE_FLAG_RC30_1},// 0x10 - based on RC35 -{ 78, DeviceType::THERMOSTAT, F("Moduline 400"), DeviceFlags::EMS_DEVICE_FLAG_RC30}, // 0x10 { 86, DeviceType::THERMOSTAT, F("RC35"), DeviceFlags::EMS_DEVICE_FLAG_RC35}, // 0x10 { 93, DeviceType::THERMOSTAT, F("RC20RF"), DeviceFlags::EMS_DEVICE_FLAG_RC20}, // 0x19 {157, DeviceType::THERMOSTAT, F("RC200/CW100"), DeviceFlags::EMS_DEVICE_FLAG_RC100}, // 0x18 @@ -99,7 +103,7 @@ // Thermostat - Sieger - 0x10 / 0x17 { 76, DeviceType::THERMOSTAT, F("ES73"), DeviceFlags::EMS_DEVICE_FLAG_RC35}, // 0x10 -{113, DeviceType::THERMOSTAT, F("ES72"), DeviceFlags::EMS_DEVICE_FLAG_RC20_2}, // 0x17 +{113, DeviceType::THERMOSTAT, F("ES72/RC20"), DeviceFlags::EMS_DEVICE_FLAG_RC20_2}, // 0x17 // Thermostat - Junkers - 0x10 {105, DeviceType::THERMOSTAT, F("FW100"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS}, diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 567b12c4f..1db79d3d2 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -228,7 +228,7 @@ std::string EMSdevice::telegram_type_name(std::shared_ptr telegr } for (const auto & tf : telegram_functions_) { - if (tf.telegram_type_id_ == (telegram->type_id && ((telegram->type_id & 0xF0) != 0xF0))) { + if ((tf.telegram_type_id_ == telegram->type_id) && ((telegram->type_id & 0x0F0) != 0xF0)) { return uuid::read_flash_string(tf.telegram_type_name_); } } diff --git a/src/emsesp.cpp b/src/emsesp.cpp index fe6fdb95e..ce89b6c45 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -189,7 +189,7 @@ void EMSESP::show_values(uuid::console::Shell & shell) { if (!sensor_devices().empty()) { shell.printfln(F("External temperature sensors:")); for (const auto & device : sensor_devices()) { - shell.printfln(F(" Sensor ID %s: %s°C"), device.to_string().c_str(), Helpers::render_value(valuestr, device.temperature_c_, 2)); + shell.printfln(F(" Sensor ID %s: %s°C"), device.to_string().c_str(), Helpers::render_value(valuestr, device.temperature_c_, 2)); } shell.println(); } @@ -247,6 +247,7 @@ std::string EMSESP::pretty_telegram(std::shared_ptr telegram) { // get the type name, any match will do if (type_name.empty()) { type_name = emsdevice->telegram_type_name(telegram); + } } } @@ -362,13 +363,12 @@ void EMSESP::process_version(std::shared_ptr telegram) { uint8_t product_id = telegram->message_data[offset]; // product ID // get version as XX.XX - char buf[6] = {0}; std::string version(5, '\0'); snprintf_P(&version[0], version.capacity() + 1, - PSTR("%s.%s"), - Helpers::smallitoa(buf, telegram->message_data[offset + 1]), - Helpers::smallitoa(buf, telegram->message_data[offset + 2])); + PSTR("%02d.%02d"), + telegram->message_data[offset + 1], + telegram->message_data[offset + 2]); // some devices store the protocol type (HT3, Buderus) in the last byte uint8_t brand; @@ -565,8 +565,10 @@ void EMSESP::send_write_request(const uint16_t type_id, // we check if its a complete telegram or just a single byte (which could be a poll or a return status) void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) { // check first for echo + //LOG_TRACE(F("Rx: %s"), Helpers::data_to_hex(data, length).c_str()); uint8_t first_value = data[0]; if (((first_value & 0x7F) == txservice_.ems_bus_id()) && (length > 1)) { + rxservice_.add(data, length); // just for logging return; // it's an echo } @@ -750,7 +752,7 @@ void EMSESP::console_commands(Shell & shell, unsigned int context) { shell.printfln(F("Performing a deep scan by pinging our device library...")); std::vector Device_Ids; - Device_Ids.push_back(0x09); // Controllers - 0x09 + Device_Ids.push_back(0x08); // Boilers - 0x08 Device_Ids.push_back(0x38); // HeatPump - 0x38 Device_Ids.push_back(0x30); // Solar Module - 0x30 Device_Ids.push_back(0x09); // Controllers - 0x09 @@ -758,10 +760,16 @@ void EMSESP::console_commands(Shell & shell, unsigned int context) { Device_Ids.push_back(0x48); // Gateway - 0x48 Device_Ids.push_back(0x20); // Mixing Devices - 0x20 Device_Ids.push_back(0x21); // Mixing Devices - 0x21 + Device_Ids.push_back(0x22); // Mixing Devices - 0x22 + Device_Ids.push_back(0x23); // Mixing Devices - 0x23 + Device_Ids.push_back(0x28); // Mixing Devices WW- 0x28 + Device_Ids.push_back(0x29); // Mixing Devices WW- 0x29 Device_Ids.push_back(0x10); // Thermostats - 0x10 Device_Ids.push_back(0x17); // Thermostats - 0x17 - Device_Ids.push_back(0x18); // Thermostats - 0x18 - Device_Ids.push_back(0x19); // Thermostats - 0x19 + Device_Ids.push_back(0x18); // Thermostat remote - 0x18 + Device_Ids.push_back(0x19); // Thermostat remote - 0x19 + Device_Ids.push_back(0x1A); // Thermostat remote - 0x1A + Device_Ids.push_back(0x1B); // Thermostat remote - 0x1B Device_Ids.push_back(0x11); // Switches - 0x11 // send the read command with Version command diff --git a/src/helpers.cpp b/src/helpers.cpp index 0b4ef1d3a..2350f53e1 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -152,7 +152,7 @@ char * Helpers::render_value(char * result, const int16_t value, const uint8_t f result[0] = '\0'; // remove errors or invalid values, 0x7D00 and higher - if ((value == EMS_VALUE_SHORT_NOTSET) || (value == EMS_VALUE_SHORT_INVALID)) { + if ((value == EMS_VALUE_SHORT_NOTSET) || (value == EMS_VALUE_SHORT_INVALID) || (value == EMS_VALUE_USHORT_NOTSET)) { strlcpy(result, "?", 10); return result; } @@ -279,6 +279,8 @@ uint32_t Helpers::hextoint(const char * hex) { byte = byte - 'a' + 10; else if (byte >= 'A' && byte <= 'F') byte = byte - 'A' + 10; + else + return 0; // error // shift 4 to make space for new digit, and add the 4 bits of the new digit val = (val << 4) | (byte & 0xF); } diff --git a/src/mixing.cpp b/src/mixing.cpp index 85bdad9ef..2a94bc245 100644 --- a/src/mixing.cpp +++ b/src/mixing.cpp @@ -37,7 +37,6 @@ Mixing::Mixing(uint8_t device_type, uint8_t device_id, uint8_t product_id, const register_telegram_type(device_id - 0x28 + 0x0331, F("MMPLUSStatusMessage_WWC"), true, std::bind(&Mixing::process_MMPLUSStatusMessage_WWC, this, _1)); } } - // EMS 1.0 if (flags == EMSdevice::EMS_DEVICE_FLAG_MM10) { register_telegram_type(0x00AA, F("MMConfigMessage"), false, nullptr); @@ -77,11 +76,10 @@ void Mixing::show_values(uuid::console::Shell & shell) { } else { shell.printfln(F(" Heating Circuit #: %d"), hc_); } - - print_value(shell, 2, F("Current flow temperature"), F_(degrees), Helpers::render_value(buffer, flowTemp_, 10)); - print_value(shell, 2, F("Setpoint flow temperature"), F_(degrees), Helpers::render_value(buffer, flowSetTemp_, 1)); - print_value(shell, 2, F("Current pump modulation"), Helpers::render_value(buffer, pumpMod_, 1)); - print_value(shell, 2, F("Current valve status"), Helpers::render_value(buffer, status_, 1)); + print_value(shell, 4, F("Current flow temperature"), F_(degrees), Helpers::render_value(buffer, flowTemp_, 10)); + print_value(shell, 4, F("Setpoint flow temperature"), F_(degrees), Helpers::render_value(buffer, flowSetTemp_, 1)); + print_value(shell, 4, F("Current pump modulation"), Helpers::render_value(buffer, pumpMod_, 1)); + print_value(shell, 4, F("Current valve status"), Helpers::render_value(buffer, status_, 1)); } // publish values via MQTT @@ -120,11 +118,10 @@ void Mixing::publish_values() { #ifdef EMSESP_DEBUG LOG_DEBUG(F("[DEBUG] Performing a mixing module publish")); #endif - char topic[30]; char s[3]; // for formatting strings strlcpy(topic, "mixing_data", 30); - strlcat(topic, Helpers::itoa(s, hc_), 30); // append hc to topic + strlcat(topic, Helpers::itoa(s, device_id() - 0x20 + 1), 30); // append hc to topic Mqtt::publish(topic, doc); } diff --git a/src/mixing.h b/src/mixing.h index d81443b7f..6b430f62e 100644 --- a/src/mixing.h +++ b/src/mixing.h @@ -63,6 +63,7 @@ class Mixing : public EMSdevice { uint8_t status_ = EMS_VALUE_UINT_NOTSET; uint8_t flowSetTemp_ = EMS_VALUE_UINT_NOTSET; Type type_ = Type::NONE; + }; } // namespace emsesp diff --git a/src/mqtt.cpp b/src/mqtt.cpp index c616eadd3..e14acc1b8 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -24,9 +24,11 @@ MAKE_PSTR_WORD(qos) MAKE_PSTR_WORD(base) MAKE_PSTR_WORD(heartbeat) MAKE_PSTR_WORD(ip) +MAKE_PSTR_WORD(port) MAKE_PSTR_WORD(nested) MAKE_PSTR_WORD(single) MAKE_PSTR_WORD(ha) +MAKE_PSTR_WORD(custom) MAKE_PSTR_WORD(publish_time) MAKE_PSTR_WORD(publish) MAKE_PSTR_WORD(connected) @@ -646,6 +648,8 @@ void Mqtt::console_commands(Shell & shell, unsigned int context) { value = Settings::MQTT_format::NESTED; } else if (arguments[0] == read_flash_string(F_(ha))) { value = Settings::MQTT_format::HA; + } else if (arguments[0] == read_flash_string(F_(custom))) { + value = Settings::MQTT_format::CUSTOM; } else { shell.println(F("Must be single, nested or ha")); return; @@ -655,7 +659,7 @@ void Mqtt::console_commands(Shell & shell, unsigned int context) { shell.println(F("Please restart EMS-ESP")); }, [](Shell & shell __attribute__((unused)), const std::vector & arguments __attribute__((unused))) -> const std::vector { - return std::vector{read_flash_string(F_(single)), read_flash_string(F_(nested)), read_flash_string(F_(ha))}; + return std::vector{read_flash_string(F_(single)), read_flash_string(F_(nested)), read_flash_string(F_(ha)), read_flash_string(F_(custom))}; }); EMSESPShell::commands->add_command(ShellContext::MQTT, @@ -723,6 +727,19 @@ void Mqtt::console_commands(Shell & shell, unsigned int context) { reconnect(); }); + EMSESPShell::commands->add_command(ShellContext::MQTT, + CommandFlags::ADMIN, + flash_string_vector{F_(set), F_(port)}, + flash_string_vector{F_(port_mandatory)}, + [](Shell & shell __attribute__((unused)), const std::vector & arguments) { + Settings settings; + if (!arguments.empty()) { + settings.mqtt_port(atoi(arguments.front().c_str())); + settings.commit(); + } + reconnect(); + }); + EMSESPShell::commands->add_command(ShellContext::MQTT, CommandFlags::ADMIN, flash_string_vector{F_(set), F_(qos)}, @@ -820,6 +837,8 @@ void Mqtt::console_commands(Shell & shell, unsigned int context) { shell.printfln(F_(mqtt_format_fmt), F_(nested)); } else if (settings.mqtt_format() == Settings::MQTT_format::HA) { shell.printfln(F_(mqtt_format_fmt), F_(ha)); + } else if (settings.mqtt_format() == Settings::MQTT_format::CUSTOM) { + shell.printfln(F_(mqtt_format_fmt), F_(custom)); } shell.printfln(F_(mqtt_heartbeat_fmt), settings.mqtt_heartbeat() ? F_(enabled) : F_(disabled)); shell.printfln(F_(mqtt_publish_time_fmt), settings.mqtt_publish_time()); diff --git a/src/sensors.cpp b/src/sensors.cpp index c187a124e..554c005d5 100644 --- a/src/sensors.cpp +++ b/src/sensors.cpp @@ -222,7 +222,6 @@ uint64_t Sensors::Device::id() const { std::string Sensors::Device::to_string() const { std::string str(20, '\0'); - snprintf_P(&str[0], str.capacity() + 1, PSTR("%02X-%04X-%04X-%04X-%02X"), @@ -234,6 +233,7 @@ std::string Sensors::Device::to_string() const { return str; } + // send all dallas sensor values as a JSON package to MQTT // assumes there are devices void Sensors::publish_values() { @@ -274,13 +274,18 @@ void Sensors::publish_values() { uint8_t i = 1; for (const auto & device : devices_) { - char sensorID[10]; // sensor{1-n} - strlcpy(sensorID, "sensor", 10); - char s[5]; - strlcat(sensorID, Helpers::itoa(s, i++), 10); - JsonObject dataSensor = doc.createNestedObject(sensorID); - dataSensor["id"] = device.to_string(); - dataSensor["temp"] = Helpers::render_value(s, device.temperature_c_, 2); + if (mqtt_format_ == Settings::MQTT_format::CUSTOM) { + char s[5]; + doc[device.to_string()] = Helpers::render_value(s, device.temperature_c_, 2); + } else { + char sensorID[10]; // sensor{1-n} + strlcpy(sensorID, "sensor", 10); + char s[5]; + strlcat(sensorID, Helpers::itoa(s, i++), 10); + JsonObject dataSensor = doc.createNestedObject(sensorID); + dataSensor["id"] = device.to_string(); + dataSensor["temp"] = Helpers::render_value(s, device.temperature_c_, 2); + } } if (mqtt_format_ == Settings::MQTT_format::HA) { diff --git a/src/sensors.h b/src/sensors.h index 9c66eedd7..f4bf76d91 100644 --- a/src/sensors.h +++ b/src/sensors.h @@ -66,7 +66,11 @@ class Sensors { #if defined(ESP8266) static constexpr uint8_t SENSOR_GPIO = 14; // D5 #elif defined(ESP32) +#ifdef WEMOS_D1_32 static constexpr uint8_t SENSOR_GPIO = 18; // Wemos D1-32 for compatibility D5 +#else + static constexpr uint8_t SENSOR_GPIO = 14; +#endif #endif enum class State { IDLE, READING, SCANNING }; diff --git a/src/solar.cpp b/src/solar.cpp index 254e17539..22c4add94 100644 --- a/src/solar.cpp +++ b/src/solar.cpp @@ -172,9 +172,9 @@ void Solar::process_SM100Status2(std::shared_ptr telegram) { * e.g. 30 00 FF 00 02 8E 00 00 00 00 00 00 06 C5 00 00 76 35 */ void Solar::process_SM100Energy(std::shared_ptr telegram) { - telegram->read_value(energyLastHour_, 0); // last hour / 10 in Wh - telegram->read_value(energyToday_, 4); // todays in Wh - telegram->read_value(energyTotal_, 8); // total / 10 in kWh + telegram->read_value32(energyLastHour_, 0); // last hour / 10 in Wh + telegram->read_value32(energyToday_, 4); // todays in Wh + telegram->read_value32(energyTotal_, 8); // total / 10 in kWh } /* diff --git a/src/system.h b/src/system.h index 3d69ac658..06fd5c32f 100644 --- a/src/system.h +++ b/src/system.h @@ -83,8 +83,13 @@ class System { static constexpr uint8_t LED_GPIO = 2; static constexpr uint8_t LED_ON = LOW; #elif defined(ESP32) - static constexpr uint8_t LED_GPIO = 5; // 5 on Lolin D32, 2 on Wemos D1-32 mini. Use 0 for off. - static constexpr uint8_t LED_ON = LOW; // LOW on Lolin D32, HIGH on Wemos D1-32 mini +#ifdef WEMOS_D1_32 + static constexpr uint8_t LED_GPIO = 2; // on Wemos D1-32 + static constexpr uint8_t LED_ON = HIGH; +#else + static constexpr uint8_t LED_GPIO = 5; + static constexpr uint8_t LED_ON = LOW; +#endif #else static constexpr uint8_t LED_GPIO = 0; static constexpr uint8_t LED_ON = 0; diff --git a/src/telegram.cpp b/src/telegram.cpp index a5eff0f3b..07026b4b8 100644 --- a/src/telegram.cpp +++ b/src/telegram.cpp @@ -104,13 +104,13 @@ std::string Telegram::to_string(const uint8_t * telegram, uint8_t length) const // if offset is 0, it takes the whole telegram. if it's for example 1 it'll show the 2nd data item and // everything after it // returns -1 if out of bounds -int8_t Telegram::_getDataPosition(const uint8_t index) const { - return ((index - offset) >= message_length) ? -1 : (index - offset); +int8_t Telegram::_getDataPosition(const uint8_t index, const uint8_t size) const { + return ((index - offset + size - 1) >= message_length) ? -1 : (index - offset); } // unsigned byte void Telegram::read_value(uint8_t & param, const uint8_t index) const { - int8_t pos = _getDataPosition(index); + int8_t pos = _getDataPosition(index, sizeof(param)); if (pos < 0) { return; } @@ -119,7 +119,7 @@ void Telegram::read_value(uint8_t & param, const uint8_t index) const { // signed byte void Telegram::read_value(int8_t & param, const uint8_t index) const { - int8_t pos = _getDataPosition(index); + int8_t pos = _getDataPosition(index, sizeof(param)); if (pos < 0) { return; } @@ -128,7 +128,7 @@ void Telegram::read_value(int8_t & param, const uint8_t index) const { // unsigned short void Telegram::read_value(uint16_t & param, const uint8_t index) const { - int8_t pos = _getDataPosition(index); + int8_t pos = _getDataPosition(index, sizeof(param)); if (pos < 0) { return; } @@ -145,7 +145,7 @@ void Telegram::read_value(uint16_t & param, const uint8_t index) const { // signed short void Telegram::read_value(int16_t & param, const uint8_t index) const { - int8_t pos = _getDataPosition(index); + int8_t pos = _getDataPosition(index, sizeof(param)); if (pos < 0) { return; } @@ -160,9 +160,9 @@ void Telegram::read_value(int16_t & param, const uint8_t index) const { param = value; } -// Long +// Long 24 bit void Telegram::read_value(uint32_t & param, const uint8_t index) const { - int8_t pos = _getDataPosition(index); + int8_t pos = _getDataPosition(index, 3); if (pos < 0) { return; } @@ -170,9 +170,19 @@ void Telegram::read_value(uint32_t & param, const uint8_t index) const { param = (uint32_t)((message_data[pos] << 16) + (message_data[pos + 1] << 8) + (message_data[pos + 2])); } +// Long 32 bit +void Telegram::read_value32(uint32_t & param, const uint8_t index) const { + int8_t pos = _getDataPosition(index, sizeof(param)); + if (pos < 0) { + return; + } + + param = (uint32_t)((message_data[pos] << 24) + (message_data[pos] << 16) + (message_data[pos + 1] << 8) + (message_data[pos + 2])); +} + // bit from an unsigned byte void Telegram::read_value(uint8_t & param, const uint8_t index, const uint8_t bit) const { - int8_t pos = _getDataPosition(index); + int8_t pos = _getDataPosition(index, sizeof(param)); if (pos < 0) { return; } @@ -182,7 +192,7 @@ void Telegram::read_value(uint8_t & param, const uint8_t index, const uint8_t bi // convert signed short to single 8 byte, for setpoint thermostat temperatures that don't store their temps in 2 bytes void Telegram::read_value8(int16_t & param, const uint8_t index) const { - int8_t pos = _getDataPosition(index); + int8_t pos = _getDataPosition(index, 1); if (pos < 0) { return; } @@ -212,10 +222,10 @@ void RxService::start() { void RxService::loop() { #ifndef EMSESP_STANDALONE // give rx some breathing space - if ((uuid::get_uptime() - last_rx_check_) < RX_LOOP_WAIT) { - return; - } - last_rx_check_ = uuid::get_uptime(); + //if ((uuid::get_uptime() - last_rx_check_) < RX_LOOP_WAIT) { + // return; + //} + //last_rx_check_ = uuid::get_uptime(); #endif while (!rx_telegrams_.empty()) { @@ -270,7 +280,7 @@ void RxService::add(uint8_t * data, uint8_t length) { uint8_t message_length; // work out depending on the type where the data message block starts - if (data[2] < 0xF0) { + if (data[2] < 0xF0 || length < 6) { // EMS 1.0 type_id = data[2]; message_data = data + 4; // message block starts at 5th byte @@ -365,6 +375,7 @@ void TxService::loop() { // sends a 1 byte poll which is our own device ID void TxService::send_poll() { + //LOG_TRACE(F("Ack %02X"),ems_bus_id() ^ ems_mask()); EMSuart::send_poll(ems_bus_id() ^ ems_mask()); } @@ -473,7 +484,7 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) { // send the telegram to the UART Tx EMSUART_STATUS status = EMSuart::transmit(telegram_raw, length); - + //LOG_TRACE(F("Tx: %s"), Helpers::data_to_hex(telegram_raw, length).c_str()); if (status != EMS_TX_STATUS_OK) { LOG_ERROR(F("Failed to transmit Tx via UART. Error: %s"), status == EMS_TX_WTD_TIMEOUT ? F("Timeout") : F("BRK")); } @@ -496,6 +507,7 @@ void TxService::send_telegram(const uint8_t * data, const uint8_t length) { // send the telegram to the UART Tx EMSUART_STATUS status = EMSuart::transmit(telegram_raw, length); + //LOG_TRACE(F("Tx: %s"), Helpers::data_to_hex(telegram_raw, length).c_str()); if (status != EMS_TX_STATUS_OK) { LOG_ERROR(F("Failed to transmit Tx via UART. Error: %s"), status == EMS_TX_WTD_TIMEOUT ? F("Timeout") : F("BRK")); } diff --git a/src/telegram.h b/src/telegram.h index 8b6fa661f..ef6129b21 100644 --- a/src/telegram.h +++ b/src/telegram.h @@ -76,6 +76,7 @@ class Telegram { void read_value(uint16_t & param, const uint8_t index) const; void read_value(uint32_t & param, const uint8_t index) const; + void read_value32(uint32_t & param, const uint8_t index) const; void read_value(uint8_t & param, const uint8_t index, const uint8_t bit) const; void read_value(uint8_t & param, const uint8_t index) const; void read_value(int16_t & param, const uint8_t index) const; @@ -83,7 +84,7 @@ class Telegram { void read_value(int8_t & param, const uint8_t index) const; private: - int8_t _getDataPosition(const uint8_t index) const; + int8_t _getDataPosition(const uint8_t index, const uint8_t size) const; }; class EMSbus { diff --git a/src/thermostat.cpp b/src/thermostat.cpp index 3314741c0..faa76608c 100644 --- a/src/thermostat.cpp +++ b/src/thermostat.cpp @@ -400,7 +400,8 @@ bool Thermostat::updated_values() { static uint16_t current_value_ = 0; for (const auto & hc : heating_circuits_) { // don't publish if we haven't yet received some data - if ((hc->setpoint_roomTemp == EMS_VALUE_SHORT_NOTSET) || (hc->curr_roomTemp == EMS_VALUE_SHORT_NOTSET)) { +// if ((hc->setpoint_roomTemp == EMS_VALUE_SHORT_NOTSET) || (hc->curr_roomTemp == EMS_VALUE_SHORT_NOTSET)) { + if (hc->setpoint_roomTemp == EMS_VALUE_SHORT_NOTSET) { return false; } new_value += hc->setpoint_roomTemp + hc->curr_roomTemp + hc->mode; @@ -445,15 +446,12 @@ void Thermostat::publish_values() { if (tempsensor2 != EMS_VALUE_USHORT_NOTSET) { rootThermostat["inttemp2"] = (float)tempsensor2 / 10; } - if (ibaCalIntTemperature != EMS_VALUE_INT_NOTSET) { rootThermostat["intoffset"] = (float)ibaCalIntTemperature / 2; } - if (ibaMinExtTemperature != EMS_VALUE_INT_NOTSET) { rootThermostat["minexttemp"] = (float)ibaMinExtTemperature; // min ext temp for heating curve, in deg. } - if (ibaBuildingType != EMS_VALUE_UINT_NOTSET) { if (ibaBuildingType == 0) { rootThermostat["building"] = "light"; @@ -463,7 +461,6 @@ void Thermostat::publish_values() { rootThermostat["building"] = "heavy"; } } - if (mqtt_format_ == Settings::MQTT_format::SINGLE) { Mqtt::publish("thermostat_data", doc); rootThermostat = doc.to(); // clear object @@ -472,8 +469,9 @@ void Thermostat::publish_values() { // go through all the heating circuits for (const auto & hc : heating_circuits_) { - if ((hc->setpoint_roomTemp == EMS_VALUE_SHORT_NOTSET) || (hc->curr_roomTemp == EMS_VALUE_SHORT_NOTSET)) { - break; // skip this HC as we don't have the temperature values yet +// if ((hc->setpoint_roomTemp == EMS_VALUE_SHORT_NOTSET) || (hc->curr_roomTemp == EMS_VALUE_SHORT_NOTSET)) { + if (hc->setpoint_roomTemp == EMS_VALUE_SHORT_NOTSET) { + break; // skip this HC } has_data = true; @@ -506,7 +504,8 @@ void Thermostat::publish_values() { if (hc->setpoint_roomTemp != EMS_VALUE_SHORT_NOTSET) { dataThermostat["seltemp"] = Helpers::round2((float)hc->setpoint_roomTemp / setpoint_temp_divider); } - if (hc->curr_roomTemp != EMS_VALUE_SHORT_NOTSET) { + + if (hc->curr_roomTemp != EMS_VALUE_SHORT_NOTSET && hc->curr_roomTemp != EMS_VALUE_USHORT_NOTSET) { dataThermostat["currtemp"] = Helpers::round2((float)hc->curr_roomTemp / curr_temp_divider); } @@ -555,10 +554,10 @@ void Thermostat::publish_values() { // special handling of mode type, for the RC35 replace with summer/holiday // https://github.com/proddy/EMS-ESP/issues/373#issuecomment-619810209 if ((flags & 0x0F) == EMS_DEVICE_FLAG_RC35) { - if (hc->holiday_mode != EMS_VALUE_UINT_NOTSET) { - dataThermostat["modetype"] = F("holiday"); - } else if (hc->summer_mode != EMS_VALUE_UINT_NOTSET) { + if (hc->summer_mode) { dataThermostat["modetype"] = F("summer"); + } else if (hc->holiday_mode) { + dataThermostat["modetype"] = F("holiday"); } else if (hc->mode_type != EMS_VALUE_UINT_NOTSET) { dataThermostat["modetype"] = mode_tostring(hc->get_mode_type(flags)); } @@ -586,6 +585,8 @@ void Thermostat::publish_values() { Mqtt::publish("thermostat_data", doc); } else if (mqtt_format_ == Settings::MQTT_format::HA) { Mqtt::publish("homeassistant/climate/ems-esp/state", doc); + } else if (mqtt_format_ == Settings::MQTT_format::CUSTOM) { + Mqtt::publish("thermostat_data", doc); } } @@ -775,25 +776,80 @@ std::string Thermostat::mode_tostring(uint8_t mode) const { void Thermostat::show_values(uuid::console::Shell & shell) { EMSdevice::show_values(shell); // always call this to show header - char buffer[10]; // for formatting only + char buffer[10]; // for formatting only + uint8_t flags = (this->flags() & 0x0F); // specific thermostat characteristics, strip the option bits if (datetime_.size()) { - shell.printfln(F(" Clock: %s"), datetime_.c_str()); - if (ibaClockOffset != EMS_VALUE_UINT_NOTSET) { - print_value(shell, 1, F("Offset clock"), Helpers::render_value(buffer, ibaClockOffset, 1)); // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s + shell.printfln(F(" Clock: %s"), datetime_.c_str()); + if (ibaClockOffset != EMS_VALUE_UINT_NOTSET && flags == EMS_DEVICE_FLAG_RC30_1) { + print_value(shell, 2, F("Offset clock"), Helpers::render_value(buffer, ibaClockOffset, 1)); // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s } } - uint8_t flags = (this->flags() & 0x0F); // specific thermostat characteristics, strip the option bits - if (flags == EMS_DEVICE_FLAG_RC35) { - print_value(shell, 1, F("Damped Outdoor temperature"), F_(degrees), Helpers::render_value(buffer, dampedoutdoortemp, 1)); - print_value(shell, 1, F("Tempsensor 1"), F_(degrees), Helpers::render_value(buffer, tempsensor1, 10)); - print_value(shell, 1, F("Tempsensor 2"), F_(degrees), Helpers::render_value(buffer, tempsensor2, 10)); + print_value(shell, 2, F("Damped Outdoor temperature"), F_(degrees), Helpers::render_value(buffer, dampedoutdoortemp, 1)); + print_value(shell, 2, F("Tempsensor 1"), F_(degrees), Helpers::render_value(buffer, tempsensor1, 10)); + print_value(shell, 2, F("Tempsensor 2"), F_(degrees), Helpers::render_value(buffer, tempsensor2, 10)); + } + if (flags == EMS_DEVICE_FLAG_RC30_1) { + // settings parameters + if (ibaMainDisplay != EMS_VALUE_UINT_NOTSET) { + if (ibaMainDisplay == 0) { + shell.printfln(F(" Display: internal temperature")); + } else if (ibaMainDisplay == 1) { + shell.printfln(F(" Display: internal setpoint")); + } else if (ibaMainDisplay == 2) { + shell.printfln(F(" Display: external temperature")); + } else if (ibaMainDisplay == 3) { + shell.printfln(F(" Display: burner temperature")); + } else if (ibaMainDisplay == 4) { + shell.printfln(F(" Display: WW temperature")); + } else if (ibaMainDisplay == 5) { + shell.printfln(F(" Display: functioning mode")); + } else if (ibaMainDisplay == 6) { + shell.printfln(F(" Display: time")); + } else if (ibaMainDisplay == 7) { + shell.printfln(F(" Display: date")); + } else if (ibaMainDisplay == 9) { + shell.printfln(F(" Display: smoke temperature")); + } + } + + if (ibaLanguage != EMS_VALUE_UINT_NOTSET) { + if (ibaLanguage == 0) { + shell.printfln(F(" Language: German")); + } else if (ibaLanguage == 1) { + shell.printfln(F(" Language: Dutch")); + } else if (ibaLanguage == 2) { + shell.printfln(F(" Language: French")); + } else if (ibaLanguage == 3) { + shell.printfln(F(" Language: Italian")); + } + } + } + if (flags == EMS_DEVICE_FLAG_RC35 || flags == EMS_DEVICE_FLAG_RC30_1) { + + if (ibaCalIntTemperature != EMS_VALUE_INT_NOTSET) { + print_value(shell, 2, F("Offset int. temperature"), F_(degrees), Helpers::render_value(buffer, ibaCalIntTemperature, 2)); + } + + if (ibaMinExtTemperature != EMS_VALUE_INT_NOTSET) { + print_value(shell, 2, F("Min ext. temperature"), F_(degrees), Helpers::render_value(buffer, ibaMinExtTemperature, 0)); // min ext temp for heating curve, in deg. + } + + if (ibaBuildingType != EMS_VALUE_UINT_NOTSET) { + if (ibaBuildingType == 0) { + shell.printfln(F(" Building: light")); + } else if (ibaBuildingType == 1) { + shell.printfln(F(" Building: medium")); + } else if (ibaBuildingType == 2) { + shell.printfln(F(" Building: heavy")); + } + } } for (const auto & hc : heating_circuits_) { - shell.printfln(F(" Heating Circuit %d:"), hc->hc_num()); + shell.printfln(F(" Heating Circuit %d:"), hc->hc_num()); // different thermostat types store their temperature values differently uint8_t format_setpoint, format_curr; @@ -812,13 +868,13 @@ void Thermostat::show_values(uuid::console::Shell & shell) { break; } - print_value(shell, 2, F("Current room temperature"), F_(degrees), Helpers::render_value(buffer, hc->curr_roomTemp, format_curr)); - print_value(shell, 2, F("Setpoint room temperature"), F_(degrees), Helpers::render_value(buffer, hc->setpoint_roomTemp, format_setpoint)); + print_value(shell, 4, F("Current room temperature"), F_(degrees), Helpers::render_value(buffer, hc->curr_roomTemp, format_curr)); + print_value(shell, 4, F("Setpoint room temperature"), F_(degrees), Helpers::render_value(buffer, hc->setpoint_roomTemp, format_setpoint)); if (hc->mode != EMS_VALUE_UINT_NOTSET) { - print_value(shell, 2, F("Mode"), mode_tostring(hc->get_mode(flags)).c_str()); + print_value(shell, 4, F("Mode"), mode_tostring(hc->get_mode(flags)).c_str()); } if (hc->mode_type != EMS_VALUE_UINT_NOTSET) { - print_value(shell, 2, F("Mode Type"), mode_tostring(hc->get_mode_type(flags)).c_str()); + print_value(shell, 4, F("Mode Type"), mode_tostring(hc->get_mode_type(flags)).c_str()); } if ((flags == EMS_DEVICE_FLAG_RC35) || (flags == EMS_DEVICE_FLAG_RC30_1)) { @@ -828,72 +884,19 @@ void Thermostat::show_values(uuid::console::Shell & shell) { shell.printfln(F(" Program is set to Holiday mode")); } - print_value(shell, 2, F("Day temperature"), F_(degrees), Helpers::render_value(buffer, hc->daytemp, 2)); - print_value(shell, 2, F("Night temperature"), F_(degrees), Helpers::render_value(buffer, hc->nighttemp, 2)); - print_value(shell, 2, F("Vacation temperature"), F_(degrees), Helpers::render_value(buffer, hc->holidaytemp, 2)); + print_value(shell, 4, F("Day temperature"), F_(degrees), Helpers::render_value(buffer, hc->daytemp, 2)); + print_value(shell, 4, F("Night temperature"), F_(degrees), Helpers::render_value(buffer, hc->nighttemp, 2)); + print_value(shell, 4, F("Holiday temperature"), F_(degrees), Helpers::render_value(buffer, hc->holidaytemp, 2)); if (hc->offsettemp < 100) { - print_value(shell, 2, F("Offset temperature"), F_(degrees), Helpers::render_value(buffer, hc->offsettemp, 2)); + print_value(shell, 4, F("Offset temperature"), F_(degrees), Helpers::render_value(buffer, hc->offsettemp, 2)); } - print_value(shell, 2, F("Design temperature"), F_(degrees), Helpers::render_value(buffer, hc->designtemp, 2)); + print_value(shell, 4, F("Design temperature"), F_(degrees), Helpers::render_value(buffer, hc->designtemp, 0)); } // show flow temp if we have it if (hc->circuitcalctemp != EMS_VALUE_UINT_NOTSET) { - print_value(shell, 2, F("Calculated flow temperature"), F_(degrees), Helpers::render_value(buffer, hc->circuitcalctemp, 1)); - } - - // settings parameters - if (ibaMainDisplay != EMS_VALUE_UINT_NOTSET) { - if (ibaMainDisplay == 0) { - shell.printfln(F(" Display: internal temperature")); - } else if (ibaMainDisplay == 1) { - shell.printfln(F(" Display: internal setpoint")); - } else if (ibaMainDisplay == 2) { - shell.printfln(F(" Display: external temperature")); - } else if (ibaMainDisplay == 3) { - shell.printfln(F(" Display: burner temperature")); - } else if (ibaMainDisplay == 4) { - shell.printfln(F(" Display: WW temperature")); - } else if (ibaMainDisplay == 5) { - shell.printfln(F(" Display: functioning mode")); - } else if (ibaMainDisplay == 6) { - shell.printfln(F(" Display: time")); - } else if (ibaMainDisplay == 7) { - shell.printfln(F(" Display: date")); - } else if (ibaMainDisplay == 9) { - shell.printfln(F(" Display: smoke temperature")); - } - } - - if (ibaLanguage != EMS_VALUE_UINT_NOTSET) { - if (ibaLanguage == 0) { - shell.printfln(F(" Language: German")); - } else if (ibaLanguage == 1) { - shell.printfln(F(" Language: Dutch")); - } else if (ibaLanguage == 2) { - shell.printfln(F(" Language: French")); - } else if (ibaLanguage == 3) { - shell.printfln(F(" Language: Italian")); - } - } - - if (ibaCalIntTemperature != EMS_VALUE_INT_NOTSET) { - print_value(shell, 2, F("Offset int. temperature"), F_(degrees), Helpers::render_value(buffer, ibaCalIntTemperature, 2)); - } - - if (ibaMinExtTemperature != EMS_VALUE_INT_NOTSET) { - print_value(shell, 2, F("Min ext. temperature"), F_(degrees), Helpers::render_value(buffer, ibaMinExtTemperature, 10)); // min ext temp for heating curve, in deg. - } - - if (ibaBuildingType != EMS_VALUE_UINT_NOTSET) { - if (ibaBuildingType == 0) { - shell.printfln(F(" Building: light")); - } else if (ibaBuildingType == 1) { - shell.printfln(F(" Building: medium")); - } else if (ibaBuildingType == 2) { - shell.printfln(F(" Building: heavy")); - } + print_value(shell, 4, F("Calculated flow temperature"), F_(degrees), Helpers::render_value(buffer, hc->circuitcalctemp, 1)); } } } diff --git a/src/uart/emsuart_esp32.cpp b/src/uart/emsuart_esp32.cpp index 17685f969..b56b97e30 100644 --- a/src/uart/emsuart_esp32.cpp +++ b/src/uart/emsuart_esp32.cpp @@ -29,9 +29,12 @@ namespace emsesp { static intr_handle_t uart_handle; -static RingbufHandle_t buf_handle = NULL; -static bool drop_first_rx = true; -static uint8_t tx_mode_ = 0xFF; +static RingbufHandle_t buf_handle = NULL; +static bool drop_next_rx = true; +static uint8_t tx_mode_ = 0xFF; +static uint32_t emsRxTime; + +#define EMS_RX_TO_TX_TIMEOUT 20 /* * Task to handle the incoming data @@ -46,7 +49,7 @@ void EMSuart::emsuart_recvTask(void * para) { EMSESP::incoming_telegram(telegram, telegramSize); vRingbufferReturnItem(buf_handle, (void *)telegram); } - } + } } /* * UART interrupt, on break read the fifo and put the whole telegram to ringbuffer @@ -57,19 +60,21 @@ void IRAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) { if (EMS_UART.int_st.brk_det) { EMS_UART.int_clr.brk_det = 1; // clear flag - EMS_UART.conf0.txd_brk = 0; // if it was break from sending, clear bit - length = 0; + length = 0; while (EMS_UART.status.rxfifo_cnt) { - uint8_t rx = EMS_UART.fifo.rw_byte; // read all bytes into buffer + uint8_t rx = EMS_UART.fifo.rw_byte; // read all bytes from fifo if (length < EMS_MAXBUFFERSIZE) { rxbuf[length++] = rx; + } else { + drop_next_rx = true; // we have a overflow } } - if ((!drop_first_rx) && ((length == 2) || ((length > 4)))) { + if ((!drop_next_rx) && ((length == 2) || (length > 4))) { int baseType = 0; xRingbufferSendFromISR(buf_handle, rxbuf, length - 1, &baseType); + emsRxTime = millis(); } - drop_first_rx = false; + drop_next_rx = false; } } /* @@ -80,9 +85,7 @@ void EMSuart::start(uint8_t tx_mode) { restart(); return; } - tx_mode_ = tx_mode; - uart_config_t uart_config = { .baud_rate = EMSUART_BAUD, .data_bits = UART_DATA_8_BITS, @@ -93,17 +96,14 @@ void EMSuart::start(uint8_t tx_mode) { ESP_ERROR_CHECK(uart_param_config(EMSUART_UART, &uart_config)); ESP_ERROR_CHECK(uart_set_pin(EMSUART_UART, EMSUART_TXPIN, EMSUART_RXPIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); - EMS_UART.int_ena.val = 0; // disable all intr. + EMS_UART.int_ena.val = 0; // disable all intr. EMS_UART.int_clr.val = 0xFFFFFFFF; // clear all intr. flags - EMS_UART.idle_conf.tx_brk_num = 11; // breaklength 11 bit - EMS_UART.idle_conf.rx_idle_thrhd = 12; - - drop_first_rx = true; - - buf_handle = xRingbufferCreate(128, RINGBUF_TYPE_NOSPLIT); + EMS_UART.idle_conf.tx_brk_num = 11; // breaklength 11 bit + EMS_UART.idle_conf.rx_idle_thrhd = 256; + drop_next_rx = true; + buf_handle = xRingbufferCreate(128, RINGBUF_TYPE_NOSPLIT); ESP_ERROR_CHECK(uart_isr_register(EMSUART_UART, emsuart_rx_intr_handler, NULL, ESP_INTR_FLAG_IRAM, &uart_handle)); xTaskCreate(emsuart_recvTask, "emsuart_recvTask", 2048, NULL, 12, NULL); - EMS_UART.int_ena.brk_det = 1; // activate only break } @@ -119,8 +119,8 @@ void EMSuart::stop() { */ void EMSuart::restart() { if (EMS_UART.int_raw.brk_det) { - EMS_UART.int_clr.brk_det = 1; // clear flag - drop_first_rx = true; // and drop first frame + EMS_UART.int_clr.brk_det = 1; // clear flag + drop_next_rx = true; // and drop first frame } EMS_UART.int_ena.brk_det = 1; // activate only break }; @@ -129,10 +129,8 @@ void EMSuart::restart() { * Sends a 1-byte poll, ending with a */ void EMSuart::send_poll(uint8_t data) { - EMS_UART.conf0.txd_brk = 0; // just to make sure the bit is cleared EMS_UART.fifo.rw_byte = data; - //EMS_UART.idle_conf.tx_brk_num = 11; // breaklength 11 bit - EMS_UART.conf0.txd_brk = 1; // sending ends in a break + EMS_UART.conf0.txd_brk = 1; // after send } /* @@ -141,14 +139,14 @@ void EMSuart::send_poll(uint8_t data) { * returns code, 1=success */ EMSUART_STATUS EMSuart::transmit(uint8_t * buf, uint8_t len) { + if (millis() -emsRxTime > EMS_RX_TO_TX_TIMEOUT) { + return EMS_TX_WTD_TIMEOUT; + } if (len > 0) { - EMS_UART.conf0.txd_brk = 0; // just to make sure the bit is cleared for (uint8_t i = 0; i < len; i++) { EMS_UART.fifo.rw_byte = buf[i]; } - //uart_tx_chars(EMSUART_UART, (const char *)buf, len); - //EMS_UART.idle_conf.tx_brk_num = 11; // breaklength 11 bit - EMS_UART.conf0.txd_brk = 1; // sending ends in a break + EMS_UART.conf0.txd_brk = 1; // after send } return EMS_TX_STATUS_OK; } diff --git a/src/uart/emsuart_esp32.h b/src/uart/emsuart_esp32.h index dc7c78480..5a3a18189 100644 --- a/src/uart/emsuart_esp32.h +++ b/src/uart/emsuart_esp32.h @@ -39,8 +39,13 @@ #define EMSUART_BAUD 9600 // uart baud rate for the EMS circuit // customize the GPIO pins for RX and TX here +#ifdef WEMOS_D1_32 #define EMSUART_RXPIN 23 // 17 is UART2 RX. Use 23 for D7 on a Wemos D1-32 mini for backwards compatabilty -#define EMSUART_TXPIN 5 // 16 is UART2 TX. Use 5 for D8 on a Wemos D1-32 mini for backwards compatabilty +#define EMSUART_TXPIN 5 // 16 is UART2 TX. Use 5 for D8 on a Wemos D1-32 mini for backwards compatabilty +#else +#define EMSUART_RXPIN 17 // 17 is UART2 RX. Use 23 for D7 on a Wemos D1-32 mini for backwards compatabilty +#define EMSUART_TXPIN 16 // 16 is UART2 TX. Use 5 for D8 on a Wemos D1-32 mini for backwards compatabilty +#endif namespace emsesp { diff --git a/src/uart/emsuart_esp8266.cpp b/src/uart/emsuart_esp8266.cpp index 1b249f8ff..eb27cef33 100644 --- a/src/uart/emsuart_esp8266.cpp +++ b/src/uart/emsuart_esp8266.cpp @@ -28,10 +28,13 @@ os_event_t recvTaskQueue[EMSUART_recvTaskQueueLen]; // our Rx queue EMSuart::EMSRxBuf_t * pEMSRxBuf; EMSuart::EMSRxBuf_t * paEMSRxBuf[EMS_MAXBUFFERS]; -uint8_t emsRxBufIdx = 0; -uint8_t phantomBreak = 0; -uint8_t tx_mode_ = 0xFF; -bool drop_first_rx = true; +uint8_t emsRxBufIdx = 0; +uint8_t phantomBreak = 0; +uint8_t tx_mode_ = 0xFF; +bool drop_next_rx = true; +uint32_t emsRxTime; + +#define EMS_RX_TO_TX_TIMEOUT 20 // // Main interrupt handler @@ -39,47 +42,26 @@ bool drop_first_rx = true; // void ICACHE_RAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) { static uint8_t length = 0; - // static bool rx_idle_ = true; static uint8_t uart_buffer[EMS_MAXBUFFERSIZE + 2]; - /* - // is a new buffer? if so init the thing for a new telegram - if (rx_idle_) { - rx_idle_ = false; // status set to busy - length = 0; - } - // fill IRQ buffer, by emptying Rx FIFO - if (USIS(EMSUART_UART) & ((1 << UIFF) | (1 << UITO) | (1 << UIBD))) { - while ((USS(EMSUART_UART) >> USRXC) & 0xFF) { - uint8_t rx = USF(EMSUART_UART); - if (length < EMS_MAXBUFFERSIZE) - uart_buffer[length++] = rx; - } - - // clear Rx FIFO full and Rx FIFO timeout interrupts - USIC(EMSUART_UART) = (1 << UIFF) | (1 << UITO); - } -*/ - // BREAK detection = End of EMS data block - if (USIS(EMSUART_UART) & ((1 << UIBD))) { + if (USIS(EMSUART_UART) & ((1 << UIBD))) { // BREAK detection = End of EMS data block length = 0; - while ((USS(EMSUART_UART) >> USRXC) & 0xFF) { + while ((USS(EMSUART_UART) >> USRXC) & 0xFF) { // read fifo into buffer uint8_t rx = USF(EMSUART_UART); if (length < EMS_MAXBUFFERSIZE) { uart_buffer[length++] = rx; + } else { + drop_next_rx = true; } } - USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear bit - ETS_UART_INTR_DISABLE(); // disable all interrupts and clear them - USIC(EMSUART_UART) = (1 << UIBD); // INT clear the BREAK detect interrupt - if (!drop_first_rx) { + USIC(EMSUART_UART) = (1 << UIBD); // INT clear the BREAK detect interrupt + USC0(EMSUART_UART) &= ~(1 << UCBRK); // reset tx-brk + if (!drop_next_rx) { pEMSRxBuf->length = length; os_memcpy((void *)pEMSRxBuf->buffer, (void *)&uart_buffer, pEMSRxBuf->length); // copy data into transfer buffer, including the BRK 0x00 at the end - // rx_idle_ = true; // check set the status flag stating BRK has been received and we can start a new package + emsRxTime = millis(); } - drop_first_rx = false; - ETS_UART_INTR_ENABLE(); // re-enable UART interrupts - + drop_next_rx = false; system_os_post(EMSUART_recvTaskPrio, 0, 0); // call emsuart_recvTask() at next opportunity } } @@ -109,7 +91,7 @@ void ICACHE_FLASH_ATTR EMSuart::emsuart_recvTask(os_event_t * events) { // ignore double BRK at the end, possibly from the Tx loopback // also telegrams with no data value // then transmit EMS buffer, excluding the BRK - if ((length > 4) && (length <= EMS_MAXBUFFERSIZE + 1)) { + if (length > 4) { EMSESP::incoming_telegram((uint8_t *)pCurrent->buffer, length - 1); } } @@ -188,7 +170,7 @@ void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) { ETS_UART_INTR_ATTACH(emsuart_rx_intr_handler, nullptr); ETS_UART_INTR_ENABLE(); - drop_first_rx = true; + drop_next_rx = true; // LOG_INFO(F("UART service for Rx/Tx started")); } @@ -204,12 +186,11 @@ void ICACHE_FLASH_ATTR EMSuart::stop() { * re-start UART0 driver */ void ICACHE_FLASH_ATTR EMSuart::restart() { - if (USIS(EMSUART_UART) & ((1 << UIBD))) { + if (USIR(EMSUART_UART) & ((1 << UIBD))) { USIC(EMSUART_UART) = (1 << UIBD); // INT clear the BREAK detect interrupt - drop_first_rx = true; + drop_next_rx = true; } ETS_UART_INTR_ENABLE(); - // emsuart_flush_fifos(); } /* @@ -246,8 +227,9 @@ void ICACHE_FLASH_ATTR EMSuart::tx_brk() { * It's a bit dirty. there is no special wait logic per tx_mode type, fifo flushes or error checking */ void EMSuart::send_poll(uint8_t data) { + noInterrupts(); if (tx_mode_ == EMS_TXMODE_NEW) { - USC0(EMSUART_UART) &= ~(1 << UCBRK); // make sure bit is cleared + USC0(EMSUART_UART) &= ~(1 << UCBRK); // reset tx-brk USF(EMSUART_UART) = data; USC0(EMSUART_UART) |= (1 << UCBRK); // send at the end } else { @@ -255,6 +237,7 @@ void EMSuart::send_poll(uint8_t data) { delayMicroseconds(EMSUART_TX_BRK_WAIT); tx_brk(); // send } + interrupts(); } /* @@ -266,29 +249,37 @@ EMSUART_STATUS ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { if (len == 0) { return EMS_TX_STATUS_OK; // nothing to send } + if(millis() > (emsRxTime + EMS_RX_TO_TX_TIMEOUT)) { // send allowed within 20 ms + return EMS_TX_WTD_TIMEOUT; + } // new code from Michael. See https://github.com/proddy/EMS-ESP/issues/380 if (tx_mode_ == EMS_TXMODE_NEW) { - USC0(EMSUART_UART) &= ~(1 << UCBRK); // make sure bit is cleared + USC0(EMSUART_UART) &= ~(1 << UCBRK); // reset tx-brk + noInterrupts(); for (uint8_t i = 0; i < len; i++) { USF(EMSUART_UART) = buf[i]; } USC0(EMSUART_UART) |= (1 << UCBRK); // send at the end + interrupts(); return EMS_TX_STATUS_OK; } // EMS+ https://github.com/proddy/EMS-ESP/issues/23# if (tx_mode_ == EMS_TXMODE_EMSPLUS) { // With extra tx delay for EMS+ + noInterrupts(); for (uint8_t i = 0; i < len; i++) { USF(EMSUART_UART) = buf[i]; delayMicroseconds(EMSUART_TX_BRK_WAIT); // 2070 } tx_brk(); // send + interrupts(); return EMS_TX_STATUS_OK; } // Junkers logic by @philrich if (tx_mode_ == EMS_TXMODE_HT3) { + noInterrupts(); for (uint8_t i = 0; i < len; i++) { USF(EMSUART_UART) = buf[i]; @@ -300,6 +291,7 @@ EMSUART_STATUS ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { delayMicroseconds(EMSUART_TX_WAIT_BYTE - EMSUART_TX_LAG + EMSUART_TX_WAIT_GAP); // 1760 } tx_brk(); // send + interrupts(); return EMS_TX_STATUS_OK; } @@ -332,8 +324,8 @@ EMSUART_STATUS ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { // disable rx interrupt // clear Rx status register, resetting the Rx FIFO and flush it - ETS_UART_INTR_DISABLE(); - USC0(EMSUART_UART) |= (1 << UCRXRST); + noInterrupts(); + //ETS_UART_INTR_DISABLE(); emsuart_flush_fifos(); // send the bytes along the serial line @@ -345,12 +337,14 @@ EMSUART_STATUS ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { while (((USS(EMSUART_UART) >> USRXC) & 0xFF) == _usrxc) { delayMicroseconds(EMSUART_BUSY_WAIT); // burn CPU cycles... if (--wdc == 0) { - ETS_UART_INTR_ENABLE(); + interrupts(); + //ETS_UART_INTR_ENABLE(); return EMS_TX_WTD_TIMEOUT; } if (USIR(EMSUART_UART) & (1 << UIBD)) { USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ - ETS_UART_INTR_ENABLE(); + interrupts(); + //ETS_UART_INTR_ENABLE(); return EMS_TX_BRK_DETECT; } } @@ -377,7 +371,8 @@ EMSUART_STATUS ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { } } - ETS_UART_INTR_ENABLE(); // open up the FIFO again to start receiving + interrupts(); + //ETS_UART_INTR_ENABLE(); // open up the FIFO again to start receiving return result; // send the Tx status back } diff --git a/src/uart/emsuart_esp8266.h b/src/uart/emsuart_esp8266.h index c92ea6fd5..ecf1c3574 100644 --- a/src/uart/emsuart_esp8266.h +++ b/src/uart/emsuart_esp8266.h @@ -47,7 +47,7 @@ #define EMSUART_TX_LAG 8 #define EMSUART_BUSY_WAIT (EMSUART_BIT_TIME / 8) #define EMS_TX_TO_CHARS (2 + 20) -#define EMS_TX_TO_COUNT ((EMS_TX_TO_CHARS)*8) +#define EMS_TX_TO_COUNT ((EMS_TX_TO_CHARS) * 8) namespace emsesp {