mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
@@ -49,8 +49,9 @@ 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);
|
LOG_DEBUG(F("Registering new Boiler with device ID 0x%02X"), device_id);
|
||||||
|
|
||||||
// the telegram handlers...
|
// the telegram handlers...
|
||||||
register_telegram_type(0x10, F("UBAErrorMessage1"), false, nullptr);
|
register_telegram_type(0x10, F("UBAErrorMessage1"), false, std::bind(&Boiler::process_UBAErrorMessage, this, _1));
|
||||||
register_telegram_type(0x11, F("UBAErrorMessage2"), false, nullptr);
|
register_telegram_type(0x11, F("UBAErrorMessage2"), false, std::bind(&Boiler::process_UBAErrorMessage, this, _1));
|
||||||
|
register_telegram_type(0x12, F("UBAErrorMessage3"), false, std::bind(&Boiler::process_UBAErrorMessage, this, _1));
|
||||||
register_telegram_type(0x18, F("UBAMonitorFast"), false, 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(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(0x34, F("UBAMonitorWW"), false, std::bind(&Boiler::process_UBAMonitorWW, this, _1));
|
||||||
@@ -679,6 +680,12 @@ void Boiler::process_UBAMaintenanceStatus(std::shared_ptr<const Telegram> telegr
|
|||||||
void Boiler::process_UBAMaintenanceSettings(std::shared_ptr<const Telegram> telegram) {
|
void Boiler::process_UBAMaintenanceSettings(std::shared_ptr<const Telegram> telegram) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 0x10, 0x11, 0x12
|
||||||
|
// not yet implemented
|
||||||
|
void Boiler::process_UBAErrorMessage(std::shared_ptr<const Telegram> telegram) {
|
||||||
|
// data: displaycode(2), errornumner(2), year, month, hour, day, minute, duration(2), src-addr
|
||||||
|
}
|
||||||
|
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
// Set the warm water temperature 0x33
|
// Set the warm water temperature 0x33
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ class Boiler : public EMSdevice {
|
|||||||
void process_MC10Status(std::shared_ptr<const Telegram> telegram);
|
void process_MC10Status(std::shared_ptr<const Telegram> telegram);
|
||||||
void process_UBAMaintenanceStatus(std::shared_ptr<const Telegram> telegram);
|
void process_UBAMaintenanceStatus(std::shared_ptr<const Telegram> telegram);
|
||||||
void process_UBAMaintenanceSettings(std::shared_ptr<const Telegram> telegram);
|
void process_UBAMaintenanceSettings(std::shared_ptr<const Telegram> telegram);
|
||||||
|
void process_UBAErrorMessage(std::shared_ptr<const Telegram> telegram);
|
||||||
|
|
||||||
void process_UBADHWStatus(std::shared_ptr<const Telegram> telegram);
|
void process_UBADHWStatus(std::shared_ptr<const Telegram> telegram);
|
||||||
void process_HPMonitor1(std::shared_ptr<const Telegram> telegram);
|
void process_HPMonitor1(std::shared_ptr<const Telegram> telegram);
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ Mixing::Mixing(uint8_t device_type, uint8_t device_id, uint8_t product_id, const
|
|||||||
}
|
}
|
||||||
// EMS 1.0
|
// EMS 1.0
|
||||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_MM10) {
|
if (flags == EMSdevice::EMS_DEVICE_FLAG_MM10) {
|
||||||
register_telegram_type(0x00AA, F("MMConfigMessage"), false, nullptr);
|
register_telegram_type(0x00AA, F("MMConfigMessage"), false, std::bind(&Mixing::process_MMConfigMessage, this, _1));
|
||||||
register_telegram_type(0x00AB, F("MMStatusMessage"), true, std::bind(&Mixing::process_MMStatusMessage, this, _1));
|
register_telegram_type(0x00AB, F("MMStatusMessage"), true, std::bind(&Mixing::process_MMStatusMessage, this, _1));
|
||||||
register_telegram_type(0x00AC, F("MMSetMessage"), false, nullptr);
|
register_telegram_type(0x00AC, F("MMSetMessage"), false, std::bind(&Mixing::process_MMSetMessage, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// MQTT callbacks
|
// MQTT callbacks
|
||||||
@@ -131,8 +131,9 @@ void Mixing::process_MMPLUSStatusMessage_HC(std::shared_ptr<const Telegram> tele
|
|||||||
type_ = Type::HC;
|
type_ = Type::HC;
|
||||||
hc_ = telegram->type_id - 0x02D7 + 1; // determine which circuit this is
|
hc_ = telegram->type_id - 0x02D7 + 1; // determine which circuit this is
|
||||||
telegram->read_value(flowTemp_, 3); // is * 10
|
telegram->read_value(flowTemp_, 3); // is * 10
|
||||||
telegram->read_value(pumpMod_, 5);
|
telegram->read_value(flowSetTemp_, 5);
|
||||||
telegram->read_value(status_, 2); // valve status
|
telegram->read_value(pumpMod_, 2);
|
||||||
|
telegram->read_value(status_, 1); // valve status
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mixing module warm water loading/DHW - 0x0331, 0x0332
|
// Mixing module warm water loading/DHW - 0x0331, 0x0332
|
||||||
@@ -161,4 +162,19 @@ void Mixing::process_MMStatusMessage(std::shared_ptr<const Telegram> telegram) {
|
|||||||
telegram->read_value(flowSetTemp_, 0);
|
telegram->read_value(flowSetTemp_, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mixing on a MM10 - 0xAA
|
||||||
|
// e.g. Thermostat -> Mixing Module, type 0xAA, telegram: 10 21 AA 00 FF 0C 0A 11 0A 32 xx
|
||||||
|
void Mixing::process_MMConfigMessage(std::shared_ptr<const Telegram> telegram) {
|
||||||
|
hc_ = device_id() - 0x20 + 1;
|
||||||
|
// pos 0: active FF = on
|
||||||
|
// pos 1: valve runtime 0C = 120 sec in units of 10 sec
|
||||||
|
}
|
||||||
|
// Mixing on a MM10 - 0xAC
|
||||||
|
// e.g. Thermostat -> Mixing Module, type 0xAC, telegram: 10 21 AC 00 1E 64 01 AB
|
||||||
|
void Mixing::process_MMSetMessage(std::shared_ptr<const Telegram> telegram) {
|
||||||
|
hc_ = device_id() - 0x20 + 1;
|
||||||
|
// pos 0: flowtemp setpoint 1E = 30°C
|
||||||
|
// pos 1: position in %
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
@@ -49,6 +49,8 @@ class Mixing : public EMSdevice {
|
|||||||
void process_MMPLUSStatusMessage_HC(std::shared_ptr<const Telegram> telegram);
|
void process_MMPLUSStatusMessage_HC(std::shared_ptr<const Telegram> telegram);
|
||||||
void process_MMPLUSStatusMessage_WWC(std::shared_ptr<const Telegram> telegram);
|
void process_MMPLUSStatusMessage_WWC(std::shared_ptr<const Telegram> telegram);
|
||||||
void process_MMStatusMessage(std::shared_ptr<const Telegram> telegram);
|
void process_MMStatusMessage(std::shared_ptr<const Telegram> telegram);
|
||||||
|
void process_MMConfigMessage(std::shared_ptr<const Telegram> telegram);
|
||||||
|
void process_MMSetMessage(std::shared_ptr<const Telegram> telegram);
|
||||||
|
|
||||||
enum class Type {
|
enum class Type {
|
||||||
NONE,
|
NONE,
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s
|
|||||||
register_telegram_type(0x0362, F("SM100Monitor"), true, std::bind(&Solar::process_SM100Monitor, this, _1));
|
register_telegram_type(0x0362, F("SM100Monitor"), true, std::bind(&Solar::process_SM100Monitor, this, _1));
|
||||||
register_telegram_type(0x0364, F("SM100Status"), false, std::bind(&Solar::process_SM100Status, this, _1));
|
register_telegram_type(0x0364, F("SM100Status"), false, std::bind(&Solar::process_SM100Status, this, _1));
|
||||||
register_telegram_type(0x036A, F("SM100Status2"), false, std::bind(&Solar::process_SM100Status2, this, _1));
|
register_telegram_type(0x036A, F("SM100Status2"), false, std::bind(&Solar::process_SM100Status2, this, _1));
|
||||||
register_telegram_type(0x038E, F("SM100Energy"), false, std::bind(&Solar::process_SM100Energy, this, _1));
|
register_telegram_type(0x038E, F("SM100Energy"), true, std::bind(&Solar::process_SM100Energy, this, _1));
|
||||||
register_telegram_type(0x0003, F("ISM1StatusMessage"), true, std::bind(&Solar::process_ISM1StatusMessage, this, _1));
|
register_telegram_type(0x0103, F("ISM1StatusMessage"), true, std::bind(&Solar::process_ISM1StatusMessage, this, _1));
|
||||||
register_telegram_type(0x0001, F("ISM1Set"), false, std::bind(&Solar::process_ISM1Set, this, _1));
|
register_telegram_type(0x0101, F("ISM1Set"), false, std::bind(&Solar::process_ISM1Set, this, _1));
|
||||||
|
|
||||||
// MQTT callbacks
|
// MQTT callbacks
|
||||||
// register_mqtt_topic("cmd", std::bind(&Solar::cmd, this, _1));
|
// register_mqtt_topic("cmd", std::bind(&Solar::cmd, this, _1));
|
||||||
@@ -130,10 +130,11 @@ void Solar::process_SM10Monitor(std::shared_ptr<const Telegram> telegram) {
|
|||||||
telegram->read_value(bottomTemp_, 5); // bottom temp from SM10, is *10
|
telegram->read_value(bottomTemp_, 5); // bottom temp from SM10, is *10
|
||||||
telegram->read_value(pumpModulation_, 4); // modulation solar pump
|
telegram->read_value(pumpModulation_, 4); // modulation solar pump
|
||||||
telegram->read_value(pump_, 7, 1);
|
telegram->read_value(pump_, 7, 1);
|
||||||
|
telegram->read_value(pumpWorkMin_, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SM100Monitor - type 0x0162 EMS+ - for SM100 and SM200
|
* SM100Monitor - type 0x0262 EMS+ - for SM100 and SM200
|
||||||
* e.g. B0 0B FF 00 02 62 00 44 02 7A 80 00 80 00 80 00 80 00 80 00 80 00 00 7C 80 00 80 00 80 00 80
|
* e.g. B0 0B FF 00 02 62 00 44 02 7A 80 00 80 00 80 00 80 00 80 00 80 00 00 7C 80 00 80 00 80 00 80
|
||||||
* e.g, 30 00 FF 00 02 62 01 AC
|
* e.g, 30 00 FF 00 02 62 01 AC
|
||||||
* 30 00 FF 18 02 62 80 00
|
* 30 00 FF 18 02 62 80 00
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ MAKE_PSTR(master_thermostat_fmt, "Master Thermostat device ID = %s")
|
|||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
REGISTER_FACTORY(Thermostat, EMSdevice::DeviceType::THERMOSTAT);
|
REGISTER_FACTORY(Thermostat, EMSdevice::DeviceType::THERMOSTAT);
|
||||||
|
|
||||||
MAKE_PSTR(logger_name, "thermostat")
|
MAKE_PSTR(logger_name, "thermostat")
|
||||||
uuid::log::Logger Thermostat::logger_{F_(logger_name), uuid::log::Facility::CONSOLE};
|
uuid::log::Logger Thermostat::logger_{F_(logger_name), uuid::log::Facility::CONSOLE};
|
||||||
|
|
||||||
@@ -239,7 +238,6 @@ void Thermostat::thermostat_cmd(const char * message) {
|
|||||||
strlcpy(hc_name, "hc", 6);
|
strlcpy(hc_name, "hc", 6);
|
||||||
uint8_t hc_num = hc->hc_num();
|
uint8_t hc_num = hc->hc_num();
|
||||||
strlcat(hc_name, Helpers::itoa(s, hc_num), 6);
|
strlcat(hc_name, Helpers::itoa(s, hc_num), 6);
|
||||||
|
|
||||||
if (nullptr != doc[hc_name]["mode"]) {
|
if (nullptr != doc[hc_name]["mode"]) {
|
||||||
std::string mode = doc[hc_name]["mode"]; // first check mode
|
std::string mode = doc[hc_name]["mode"]; // first check mode
|
||||||
set_mode(mode, hc_num);
|
set_mode(mode, hc_num);
|
||||||
@@ -279,29 +277,29 @@ void Thermostat::thermostat_cmd(const char * message) {
|
|||||||
uint8_t ctrl = doc[hc_name]["control"];
|
uint8_t ctrl = doc[hc_name]["control"];
|
||||||
set_control(ctrl, hc_num);
|
set_control(ctrl, hc_num);
|
||||||
}
|
}
|
||||||
if (float ct = doc["calinttemp"]) {
|
}
|
||||||
set_settings_calinttemp((int8_t)(ct * 10));
|
if (float ct = doc["calinttemp"]) {
|
||||||
}
|
set_settings_calinttemp((int8_t)(ct * 10));
|
||||||
if (nullptr != doc["minexttemp"]) {
|
}
|
||||||
int8_t mt = doc["minexttemp"];
|
if (nullptr != doc["minexttemp"]) {
|
||||||
set_settings_minexttemp(mt);
|
int8_t mt = doc["minexttemp"];
|
||||||
}
|
set_settings_minexttemp(mt);
|
||||||
if (nullptr != doc["building"]) {
|
}
|
||||||
uint8_t bd = doc["building"];
|
if (nullptr != doc["building"]) {
|
||||||
set_settings_building(bd);
|
uint8_t bd = doc["building"];
|
||||||
}
|
set_settings_building(bd);
|
||||||
if (nullptr != doc["language"]) {
|
}
|
||||||
uint8_t lg = doc["language"];
|
if (nullptr != doc["language"]) {
|
||||||
set_settings_language(lg);
|
uint8_t lg = doc["language"];
|
||||||
}
|
set_settings_language(lg);
|
||||||
if (nullptr != doc["display"]) {
|
}
|
||||||
uint8_t dp = doc["display"];
|
if (nullptr != doc["display"]) {
|
||||||
set_settings_display(dp);
|
uint8_t dp = doc["display"];
|
||||||
}
|
set_settings_display(dp);
|
||||||
if (nullptr != doc["clockoffset"]) {
|
}
|
||||||
int8_t co = doc["clockoffset"];
|
if (nullptr != doc["clockoffset"]) {
|
||||||
set_settings_clockoffset(co);
|
int8_t co = doc["clockoffset"];
|
||||||
}
|
set_settings_clockoffset(co);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * command = doc["cmd"];
|
const char * command = doc["cmd"];
|
||||||
@@ -1023,17 +1021,17 @@ void Thermostat::process_JunkersMonitor(std::shared_ptr<const Telegram> telegram
|
|||||||
|
|
||||||
// type 0x02A5 - data from the Nefit RC1010/3000 thermostat (0x18) and RC300/310s on 0x10
|
// type 0x02A5 - data from the Nefit RC1010/3000 thermostat (0x18) and RC300/310s on 0x10
|
||||||
void Thermostat::process_RC300Monitor(std::shared_ptr<const Telegram> telegram) {
|
void Thermostat::process_RC300Monitor(std::shared_ptr<const Telegram> telegram) {
|
||||||
|
if (telegram->message_data[2] == 0x00) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
|
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
|
||||||
|
|
||||||
telegram->read_value(hc->curr_roomTemp, 0); // is * 10
|
telegram->read_value(hc->curr_roomTemp, 0); // is * 10
|
||||||
telegram->read_value(hc->mode_type, 10, 1);
|
telegram->read_value(hc->mode_type, 10, 1);
|
||||||
telegram->read_value(hc->mode, 10, 0); // bit 1, mode (auto=1 or manual=0)
|
telegram->read_value(hc->mode, 10, 0); // bit 1, mode (auto=1 or manual=0)
|
||||||
|
|
||||||
// setpoint is in offset 3 and also 7. We're sticking to 3 for now.
|
// setpoint is in offset 3 and also 7. We're sticking to 3 for now.
|
||||||
// also ignore if its 0 - see https://github.com/proddy/EMS-ESP/issues/256#issuecomment-585171426
|
// also ignore if its 0 - see https://github.com/proddy/EMS-ESP/issues/256#issuecomment-585171426
|
||||||
if (telegram->message_data[3] != 0) {
|
telegram->read_value8(hc->setpoint_roomTemp, 3); // is * 2, force as single byte
|
||||||
telegram->read_value8(hc->setpoint_roomTemp, 3); // is * 2, force as single byte
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// type 0x02B9 EMS+ for reading from RC300/RC310 thermostat
|
// type 0x02B9 EMS+ for reading from RC300/RC310 thermostat
|
||||||
@@ -1044,11 +1042,12 @@ void Thermostat::process_RC300Set(std::shared_ptr<const Telegram> telegram) {
|
|||||||
// manual is position 10
|
// manual is position 10
|
||||||
// comfort is position 2
|
// comfort is position 2
|
||||||
// I think auto is position 8?
|
// I think auto is position 8?
|
||||||
telegram->read_value8(hc->setpoint_roomTemp, 8); // single byte conversion, value is * 2 - auto?
|
// actual setpoint taken from RC300Monitor (Michael 12.06.2020)
|
||||||
telegram->read_value8(hc->setpoint_roomTemp, 10); // single byte conversion, value is * 2 - manual
|
// telegram->read_value8(hc->setpoint_roomTemp, 8); // single byte conversion, value is * 2 - auto?
|
||||||
|
// telegram->read_value8(hc->setpoint_roomTemp, 10); // single byte conversion, value is * 2 - manual
|
||||||
|
|
||||||
// check why mode is both in the Monitor and Set for the RC300. It'll be read twice!
|
// check why mode is both in the Monitor and Set for the RC300. It'll be read twice!
|
||||||
telegram->read_value(hc->mode, 0); // Auto = xFF, Manual = x00 eg. 10 00 FF 08 01 B9 FF
|
// telegram->read_value(hc->mode, 0); // Auto = xFF, Manual = x00 eg. 10 00 FF 08 01 B9 FF
|
||||||
|
|
||||||
telegram->read_value(hc->daytemp, 2); // is * 2
|
telegram->read_value(hc->daytemp, 2); // is * 2
|
||||||
telegram->read_value(hc->nighttemp, 4); // is * 2
|
telegram->read_value(hc->nighttemp, 4); // is * 2
|
||||||
@@ -1182,7 +1181,7 @@ void Thermostat::set_settings_building(const uint8_t bg) {
|
|||||||
// 0xA5 Set the language settings
|
// 0xA5 Set the language settings
|
||||||
void Thermostat::set_settings_language(const uint8_t lg) {
|
void Thermostat::set_settings_language(const uint8_t lg) {
|
||||||
if ((flags() & 0x0F) == EMS_DEVICE_FLAG_RC30_1) {
|
if ((flags() & 0x0F) == EMS_DEVICE_FLAG_RC30_1) {
|
||||||
LOG_INFO(F("Setting building to %d"), lg);
|
LOG_INFO(F("Setting language to %d"), lg);
|
||||||
write_command(EMS_TYPE_IBASettings, 1, lg);
|
write_command(EMS_TYPE_IBASettings, 1, lg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1199,8 +1198,10 @@ void Thermostat::set_control(const uint8_t ctrl, const uint8_t hc_num) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((flags() & 0x0F) == EMS_DEVICE_FLAG_RC35 || (flags() & 0x0F) == EMS_DEVICE_FLAG_RC30_1) {
|
if ((flags() & 0x0F) == EMS_DEVICE_FLAG_RC35 || (flags() & 0x0F) == EMS_DEVICE_FLAG_RC30_1) {
|
||||||
LOG_INFO(F("Setting Circuit-control for hc%d to %d"), hc_num, ctrl);
|
LOG_INFO(F("Setting circuit-control for hc%d to %d"), hc_num, ctrl);
|
||||||
write_command(set_typeids[hc->hc_num() - 1], 26, ctrl);
|
write_command(set_typeids[hc->hc_num() - 1], 26, ctrl);
|
||||||
|
} else {
|
||||||
|
LOG_INFO(F("Setting circuit-control not possible"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "mqtt.h"
|
#include "mqtt.h"
|
||||||
#include "roomcontrol.h"
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|||||||
@@ -728,8 +728,8 @@ void EMSESP::console_commands(Shell & shell, unsigned int context) {
|
|||||||
flash_string_vector{F_(set), F_(tx_mode)},
|
flash_string_vector{F_(set), F_(tx_mode)},
|
||||||
flash_string_vector{F_(n_mandatory)},
|
flash_string_vector{F_(n_mandatory)},
|
||||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||||
uint8_t tx_mode = (arguments[0]).at(0) - '0';
|
uint8_t tx_mode = std::strtol(arguments[0].c_str(), nullptr, 10);
|
||||||
if ((tx_mode > 0) && (tx_mode <= 4)) {
|
if ((tx_mode > 0) && (tx_mode <= 30)) {
|
||||||
Settings settings;
|
Settings settings;
|
||||||
settings.ems_tx_mode(tx_mode);
|
settings.ems_tx_mode(tx_mode);
|
||||||
settings.commit();
|
settings.commit();
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ char * Helpers::render_value(char * result, const uint32_t value, const uint8_t
|
|||||||
strlcat(result, ltoa(value, s, 10), 20);
|
strlcat(result, ltoa(value, s, 10), 20);
|
||||||
} else {
|
} else {
|
||||||
strlcat(result, ltoa(value / format, s, 10), 20);
|
strlcat(result, ltoa(value / format, s, 10), 20);
|
||||||
strlcat(result, ".", 2);
|
strlcat(result, ".", 20);
|
||||||
strlcat(result, ltoa(value % format, s, 10), 20);
|
strlcat(result, ltoa(value % format, s, 10), 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,21 +20,23 @@
|
|||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
uint32_t rc_time_ = 0;
|
static uint32_t rc_time_ = 0;
|
||||||
uint16_t hc_ = EMS_VALUE_USHORT_NOTSET;
|
static int16_t remotetemp[4] = {EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET};
|
||||||
int16_t remotetemp[4] = {EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET, EMS_VALUE_SHORT_NOTSET};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set the temperature,
|
* set the temperature,
|
||||||
*/
|
*/
|
||||||
void Roomctrl::set_remotetemp(uint8_t hc, int16_t temp) {
|
void Roomctrl::set_remotetemp(const uint8_t hc, const int16_t temp) {
|
||||||
|
if (hc > 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
remotetemp[hc] = temp;
|
remotetemp[hc] = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if remote control is active send the temperature every minute
|
* if remote control is active send the temperature every minute
|
||||||
*/
|
*/
|
||||||
void Roomctrl::send(uint8_t addr) {
|
void Roomctrl::send(const uint8_t addr) {
|
||||||
uint8_t hc_ = addr - ADDR;
|
uint8_t hc_ = addr - ADDR;
|
||||||
// check address, reply only on addresses 0x18..0x1B
|
// check address, reply only on addresses 0x18..0x1B
|
||||||
if (hc_ > 3) {
|
if (hc_ > 3) {
|
||||||
@@ -48,7 +50,7 @@ void Roomctrl::send(uint8_t addr) {
|
|||||||
rc_time_ = uuid::get_uptime(); // use EMS-ESP's millis() to prevent overhead
|
rc_time_ = uuid::get_uptime(); // use EMS-ESP's millis() to prevent overhead
|
||||||
temperature(addr, 0x00); // send to all
|
temperature(addr, 0x00); // send to all
|
||||||
} else {
|
} else {
|
||||||
// acknowledge every poll, otherwise the master shows error A11-822
|
// acknowledge every poll, otherwise the master shows error A22-816
|
||||||
EMSuart::send_poll(addr);
|
EMSuart::send_poll(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,19 +58,22 @@ void Roomctrl::send(uint8_t addr) {
|
|||||||
/**
|
/**
|
||||||
* check if there is a message for the remote room controller
|
* check if there is a message for the remote room controller
|
||||||
*/
|
*/
|
||||||
void Roomctrl::check(uint8_t addr, uint8_t * data) {
|
void Roomctrl::check(const uint8_t addr, const uint8_t * data) {
|
||||||
uint8_t hc_num = addr - ADDR;
|
uint8_t hc_ = (addr & 0x7F) - ADDR;
|
||||||
|
|
||||||
// check address, reply only on addresses 0x18..0x1B
|
// check address, reply only on addresses 0x18..0x1B
|
||||||
if (hc_num > 3) {
|
if (hc_ > 3) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// no reply if the temperature is not set
|
// no reply if the temperature is not set
|
||||||
if (remotetemp[hc_num] == EMS_VALUE_SHORT_NOTSET) {
|
if (remotetemp[hc_] == EMS_VALUE_SHORT_NOTSET) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// reply to writes with write nack byte
|
||||||
|
if(addr & 0x80) { // it's a write to us
|
||||||
|
nack_write(); // we don't accept writes.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for now we only reply to version and remote temperature
|
// for now we only reply to version and remote temperature
|
||||||
if (data[2] == 0x02) {
|
if (data[2] == 0x02) {
|
||||||
version(addr, data[0]);
|
version(addr, data[0]);
|
||||||
@@ -124,5 +129,13 @@ void Roomctrl::temperature(uint8_t addr, uint8_t dst) {
|
|||||||
data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC
|
data[7] = EMSbus::calculate_crc(data, 7); // apppend CRC
|
||||||
EMSuart::transmit(data, 8);
|
EMSuart::transmit(data, 8);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* send a nack if someone want to write to us.
|
||||||
|
*/
|
||||||
|
void Roomctrl::nack_write() {
|
||||||
|
uint8_t data[1];
|
||||||
|
data[0] = TxService::TX_WRITE_FAIL;
|
||||||
|
EMSuart::transmit(data, 1);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -20,17 +20,14 @@
|
|||||||
#define EMSESP_ROOMCONTROL_H
|
#define EMSESP_ROOMCONTROL_H
|
||||||
|
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
#include "telegram.h"
|
|
||||||
#include "uart/emsuart_esp8266.h"
|
|
||||||
#include "uart/emsuart_esp32.h"
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
class Roomctrl {
|
class Roomctrl {
|
||||||
public:
|
public:
|
||||||
static void send(uint8_t addr);
|
static void send(const uint8_t addr);
|
||||||
static void check(uint8_t addr, uint8_t * data);
|
static void check(const uint8_t addr, const uint8_t * data);
|
||||||
static void set_remotetemp(uint8_t hc, int16_t temp);
|
static void set_remotetemp(const uint8_t hc, const int16_t temp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint8_t ADDR = 0x18;
|
static constexpr uint8_t ADDR = 0x18;
|
||||||
@@ -39,6 +36,8 @@ class Roomctrl {
|
|||||||
static void version(uint8_t addr, uint8_t dst);
|
static void version(uint8_t addr, uint8_t dst);
|
||||||
static void unknown(uint8_t addr, uint8_t dst, uint8_t type, uint8_t offset);
|
static void unknown(uint8_t addr, uint8_t dst, uint8_t type, uint8_t offset);
|
||||||
static void temperature(uint8_t addr, uint8_t dst);
|
static void temperature(uint8_t addr, uint8_t dst);
|
||||||
|
static void nack_write();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -62,23 +62,72 @@ void System::mqtt_commands(const char * message) {
|
|||||||
LOG_DEBUG(F("MQTT error: payload %s, error %s"), message, error.c_str());
|
LOG_DEBUG(F("MQTT error: payload %s, error %s"), message, error.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// restart EMS-ESP
|
||||||
|
if (strcmp(message, "restart") == 0) {
|
||||||
|
LOG_INFO(F("Restart command received"));
|
||||||
|
restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doc["send"] != nullptr) {
|
||||||
|
const char * data = doc["send"];
|
||||||
|
EMSESP::send_raw_telegram(data);
|
||||||
|
LOG_INFO(F("Sending raw: %s"),data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(ESP8266)
|
||||||
|
const uint8_t d0_ = 16;
|
||||||
|
const uint8_t d1_ = 5;
|
||||||
|
const uint8_t d2_ = 4;
|
||||||
|
const uint8_t d3_ = 0;
|
||||||
|
#elif defined(ESP32)
|
||||||
|
const uint8_t d0_ = 26;
|
||||||
|
const uint8_t d1_ = 22;
|
||||||
|
const uint8_t d2_ = 21;
|
||||||
|
const uint8_t d3_ = 17;
|
||||||
|
#endif
|
||||||
|
if(doc["D0"] != nullptr) {
|
||||||
|
const int8_t set = doc["D0"];
|
||||||
|
pinMode(d0_, OUTPUT);
|
||||||
|
if (set == 1) digitalWrite(d0_, HIGH);
|
||||||
|
else if (set == 0) digitalWrite(d0_, LOW);
|
||||||
|
LOG_INFO(F("Port D0 set to %d"),set);
|
||||||
|
}
|
||||||
|
if(doc["D1"] != nullptr) {
|
||||||
|
const int8_t set = doc["D1"];
|
||||||
|
pinMode(d1_, OUTPUT);
|
||||||
|
if (set == 1) digitalWrite(d1_, HIGH);
|
||||||
|
else if (set == 0) digitalWrite(d1_, LOW);
|
||||||
|
LOG_INFO(F("Port D1 set to %d"),set);
|
||||||
|
}
|
||||||
|
if(doc["D2"] != nullptr) {
|
||||||
|
const int8_t set = doc["D2"];
|
||||||
|
pinMode(d2_, OUTPUT);
|
||||||
|
if (set == 1) digitalWrite(d2_, HIGH);
|
||||||
|
else if (set == 0) digitalWrite(d2_, LOW);
|
||||||
|
LOG_INFO(F("Port D2 set to %d"),set);
|
||||||
|
}
|
||||||
|
if(doc["D3"] != nullptr) {
|
||||||
|
const int8_t set = doc["D3"];
|
||||||
|
pinMode(d3_, OUTPUT);
|
||||||
|
if (set == 1) digitalWrite(d3_, HIGH);
|
||||||
|
else if (set == 0) digitalWrite(d3_, LOW);
|
||||||
|
LOG_INFO(F("Port D3 set to %d"),set);
|
||||||
|
}
|
||||||
|
|
||||||
const char * command = doc["cmd"];
|
const char * command = doc["cmd"];
|
||||||
if (command == nullptr) {
|
if (command == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// send raw command
|
||||||
// restart EMS-ESP
|
|
||||||
if (strcmp(message, "restart") == 0) {
|
|
||||||
restart();
|
|
||||||
}
|
|
||||||
|
|
||||||
// boiler ww comfort setting
|
|
||||||
if (strcmp(command, "send") == 0) {
|
if (strcmp(command, "send") == 0) {
|
||||||
const char * data = doc["data"];
|
const char * data = doc["data"];
|
||||||
if (data == nullptr) {
|
if (data == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
EMSESP::send_raw_telegram(data);
|
EMSESP::send_raw_telegram(data);
|
||||||
|
LOG_INFO(F("Sending raw: %s"),data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ void Telegram::read_value32(uint32_t & param, const uint8_t index) const {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
param = (uint32_t)((message_data[pos] << 24) + (message_data[pos] << 16) + (message_data[pos + 1] << 8) + (message_data[pos + 2]));
|
param = (uint32_t)((message_data[pos] << 24) + (message_data[pos + 1] << 16) + (message_data[pos + 2] << 8) + (message_data[pos + 3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// bit from an unsigned byte
|
// bit from an unsigned byte
|
||||||
@@ -290,7 +290,7 @@ void RxService::add(uint8_t * data, uint8_t length) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// its F9 or F7
|
// its F9 or F7
|
||||||
uint8_t shift = (data[4] != 0xFF); // true (1) if 5th byte is not 0xFF, then telegram is 1 byte longer
|
uint8_t shift = (data[4] != 0xFF) ? 1 : 0; // true (1) if 5th byte is not 0xFF, then telegram is 1 byte longer
|
||||||
type_id = (data[5 + shift] << 8) + data[6 + shift] + 256;
|
type_id = (data[5 + shift] << 8) + data[6 + shift] + 256;
|
||||||
message_data += 6 + shift; // there is a special byte after the typeID which we ignore for now
|
message_data += 6 + shift; // there is a special byte after the typeID which we ignore for now
|
||||||
if (length > (9 + shift)) {
|
if (length > (9 + shift)) {
|
||||||
@@ -468,7 +468,6 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) {
|
|||||||
|
|
||||||
// send the telegram to the UART Tx
|
// send the telegram to the UART Tx
|
||||||
uint16_t status = EMSuart::transmit(telegram_raw, length);
|
uint16_t status = EMSuart::transmit(telegram_raw, length);
|
||||||
|
|
||||||
#ifdef EMSESP_DEBUG
|
#ifdef EMSESP_DEBUG
|
||||||
// if watching in 'raw' mode
|
// if watching in 'raw' mode
|
||||||
if (EMSESP::watch() == 2) {
|
if (EMSESP::watch() == 2) {
|
||||||
@@ -614,6 +613,10 @@ void TxService::remember_tx(const uint8_t * data, const uint8_t length) {
|
|||||||
telegram_last_[i] = data[i];
|
telegram_last_[i] = data[i];
|
||||||
}
|
}
|
||||||
telegram_last_length_ = length;
|
telegram_last_length_ = length;
|
||||||
|
if (ems_mask() != EMS_MASK_UNSET) {
|
||||||
|
telegram_last_[0] ^= ems_mask();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add last Tx to tx queue and increment count
|
// add last Tx to tx queue and increment count
|
||||||
|
|||||||
@@ -30,8 +30,14 @@ namespace emsesp {
|
|||||||
|
|
||||||
static intr_handle_t uart_handle;
|
static intr_handle_t uart_handle;
|
||||||
static RingbufHandle_t buf_handle = NULL;
|
static RingbufHandle_t buf_handle = NULL;
|
||||||
static bool drop_next_rx = true;
|
static hw_timer_t * timer = NULL;
|
||||||
static uint8_t tx_mode_ = 0xFF;
|
bool drop_next_rx = true;
|
||||||
|
uint8_t tx_mode_ = 0xFF;
|
||||||
|
//portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
|
||||||
|
uint8_t emsTxBuf[EMS_MAXBUFFERSIZE];
|
||||||
|
uint8_t emsTxBufIdx;
|
||||||
|
uint8_t emsTxBufLen;
|
||||||
|
uint32_t emsTxWait;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Task to handle the incoming data
|
* Task to handle the incoming data
|
||||||
@@ -73,11 +79,39 @@ void IRAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) {
|
|||||||
drop_next_rx = false;
|
drop_next_rx = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IRAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() {
|
||||||
|
if (emsTxBufIdx > 32) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emsTxBufIdx++;
|
||||||
|
if (emsTxBufIdx < emsTxBufLen) {
|
||||||
|
EMS_UART.fifo.rw_byte = emsTxBuf[emsTxBufIdx];
|
||||||
|
timerAlarmWrite(timer, emsTxWait, false);
|
||||||
|
timerAlarmEnable(timer);
|
||||||
|
} else if (emsTxBufIdx == emsTxBufLen) {
|
||||||
|
EMS_UART.conf0.txd_brk = 1; // <brk> after send
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* init UART driver
|
* init UART driver
|
||||||
*/
|
*/
|
||||||
void EMSuart::start(uint8_t tx_mode) {
|
void EMSuart::start(uint8_t tx_mode) {
|
||||||
|
if (tx_mode == EMS_TXMODE_DEFAULT) {
|
||||||
|
emsTxWait = EMSUART_BIT_TIME * 11;
|
||||||
|
} else if (tx_mode == EMS_TXMODE_EMSPLUS) {
|
||||||
|
emsTxWait = EMSUART_BIT_TIME * 20;
|
||||||
|
} else if (tx_mode == EMS_TXMODE_HT3) {
|
||||||
|
emsTxWait = EMSUART_BIT_TIME * 17;
|
||||||
|
} else if(tx_mode > 10 ) {
|
||||||
|
emsTxWait = EMSUART_BIT_TIME * tx_mode;
|
||||||
|
} else if(tx_mode > 5 ) {
|
||||||
|
emsTxWait = EMSUART_BIT_TIME * tx_mode * 2;
|
||||||
|
}
|
||||||
if (tx_mode_ != 0xFF) { // uart already initialized
|
if (tx_mode_ != 0xFF) { // uart already initialized
|
||||||
|
tx_mode_ = tx_mode;
|
||||||
restart();
|
restart();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -101,6 +135,11 @@ void EMSuart::start(uint8_t tx_mode) {
|
|||||||
ESP_ERROR_CHECK(uart_isr_register(EMSUART_UART, emsuart_rx_intr_handler, NULL, ESP_INTR_FLAG_IRAM, &uart_handle));
|
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, configMAX_PRIORITIES - 1, NULL);
|
xTaskCreate(emsuart_recvTask, "emsuart_recvTask", 2048, NULL, configMAX_PRIORITIES - 1, NULL);
|
||||||
EMS_UART.int_ena.brk_det = 1; // activate only break
|
EMS_UART.int_ena.brk_det = 1; // activate only break
|
||||||
|
|
||||||
|
emsTxBufIdx = 0;
|
||||||
|
emsTxBufLen = 0;
|
||||||
|
timer = timerBegin(1, 80, true); // timer prescale to 1 µs, countup
|
||||||
|
timerAttachInterrupt(timer, &emsuart_tx_timer_intr_handler, true); // Timer with edge interrupt
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -108,6 +147,7 @@ void EMSuart::start(uint8_t tx_mode) {
|
|||||||
*/
|
*/
|
||||||
void EMSuart::stop() {
|
void EMSuart::stop() {
|
||||||
EMS_UART.int_ena.val = 0; // disable all intr.
|
EMS_UART.int_ena.val = 0; // disable all intr.
|
||||||
|
// timerAlarmDisable(timer);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -119,14 +159,24 @@ void EMSuart::restart() {
|
|||||||
drop_next_rx = true; // and drop first frame
|
drop_next_rx = true; // and drop first frame
|
||||||
}
|
}
|
||||||
EMS_UART.int_ena.brk_det = 1; // activate only break
|
EMS_UART.int_ena.brk_det = 1; // activate only break
|
||||||
|
emsTxBufIdx = 0;
|
||||||
|
emsTxBufLen = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sends a 1-byte poll, ending with a <BRK>
|
* Sends a 1-byte poll, ending with a <BRK>
|
||||||
*/
|
*/
|
||||||
void EMSuart::send_poll(uint8_t data) {
|
void EMSuart::send_poll(uint8_t data) {
|
||||||
EMS_UART.fifo.rw_byte = data;
|
if (tx_mode_ == EMS_TXMODE_NEW || tx_mode_ == 5) {
|
||||||
EMS_UART.conf0.txd_brk = 1; // <brk> after send
|
EMS_UART.fifo.rw_byte = data;
|
||||||
|
EMS_UART.conf0.txd_brk = 1; // <brk> after send
|
||||||
|
} else {
|
||||||
|
EMS_UART.fifo.rw_byte = data;
|
||||||
|
emsTxBufIdx = 0;
|
||||||
|
emsTxBufLen = 1;
|
||||||
|
timerAlarmWrite(timer, emsTxWait, false);
|
||||||
|
timerAlarmEnable(timer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -134,12 +184,24 @@ void EMSuart::send_poll(uint8_t data) {
|
|||||||
* buf contains the CRC and len is #bytes including the CRC
|
* buf contains the CRC and len is #bytes including the CRC
|
||||||
* returns code, 1=success
|
* returns code, 1=success
|
||||||
*/
|
*/
|
||||||
EMSUART_STATUS EMSuart::transmit(uint8_t * buf, uint8_t len) {
|
uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) {
|
||||||
if (len > 0) {
|
if (len == 0 || len > 32) {
|
||||||
|
return EMS_TX_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
if (tx_mode_ == EMS_TXMODE_NEW || tx_mode_ == 5) {
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
EMS_UART.fifo.rw_byte = buf[i];
|
EMS_UART.fifo.rw_byte = buf[i];
|
||||||
}
|
}
|
||||||
EMS_UART.conf0.txd_brk = 1; // <brk> after send
|
EMS_UART.conf0.txd_brk = 1; // <brk> after send
|
||||||
|
} else {
|
||||||
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
|
emsTxBuf[i] = buf[i];
|
||||||
|
}
|
||||||
|
EMS_UART.fifo.rw_byte = buf[0];
|
||||||
|
emsTxBufIdx = 0;
|
||||||
|
emsTxBufLen = len;
|
||||||
|
timerAlarmWrite(timer, emsTxWait, false);
|
||||||
|
timerAlarmEnable(timer);
|
||||||
}
|
}
|
||||||
return EMS_TX_STATUS_OK;
|
return EMS_TX_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
/*
|
/*
|
||||||
* ESP32 UART port by @ArwedL and improved by @MichaelDvP. See https://github.com/proddy/EMS-ESP/issues/380
|
* ESP32 UART port by @ArwedL and improved by @MichaelDvP. See https://github.com/proddy/EMS-ESP/issues/380
|
||||||
*/
|
*/
|
||||||
|
#if defined(ESP32)
|
||||||
|
|
||||||
#ifndef EMSESP_EMSUART_H
|
#ifndef EMSESP_EMSUART_H
|
||||||
#define EMSESP_EMSUART_H
|
#define EMSESP_EMSUART_H
|
||||||
@@ -37,6 +38,13 @@
|
|||||||
#define EMSUART_UART UART_NUM_2 // on the ESP32 we're using UART2
|
#define EMSUART_UART UART_NUM_2 // on the ESP32 we're using UART2
|
||||||
#define EMS_UART UART2 // for intr setting
|
#define EMS_UART UART2 // for intr setting
|
||||||
#define EMSUART_BAUD 9600 // uart baud rate for the EMS circuit
|
#define EMSUART_BAUD 9600 // uart baud rate for the EMS circuit
|
||||||
|
#define EMSUART_BIT_TIME 104 // bit time @9600 baud
|
||||||
|
|
||||||
|
#define EMS_TXMODE_DEFAULT 1
|
||||||
|
#define EMS_TXMODE_EMSPLUS 2
|
||||||
|
#define EMS_TXMODE_HT3 3
|
||||||
|
#define EMS_TXMODE_NEW 4 // for michael's testing
|
||||||
|
|
||||||
|
|
||||||
// customize the GPIO pins for RX and TX here
|
// customize the GPIO pins for RX and TX here
|
||||||
#ifdef WEMOS_D1_32
|
#ifdef WEMOS_D1_32
|
||||||
@@ -49,11 +57,8 @@
|
|||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
typedef enum {
|
#define EMS_TX_STATUS_OK 1
|
||||||
EMS_TX_STATUS_OK = 1,
|
#define EMS_TX_STATUS_ERROR 0
|
||||||
EMS_TX_WTD_TIMEOUT, // watchdog timeout during send
|
|
||||||
EMS_TX_BRK_DETECT, // incoming BRK during Tx
|
|
||||||
} EMSUART_STATUS;
|
|
||||||
|
|
||||||
class EMSuart {
|
class EMSuart {
|
||||||
public:
|
public:
|
||||||
@@ -64,13 +69,16 @@ class EMSuart {
|
|||||||
static void send_poll(uint8_t data);
|
static void send_poll(uint8_t data);
|
||||||
static void stop();
|
static void stop();
|
||||||
static void restart();
|
static void restart();
|
||||||
static EMSUART_STATUS transmit(uint8_t * buf, uint8_t len);
|
static uint16_t transmit(uint8_t * buf, uint8_t len);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void emsuart_recvTask(void * para);
|
static void emsuart_recvTask(void * para);
|
||||||
static void IRAM_ATTR emsuart_rx_intr_handler(void * para);
|
static void IRAM_ATTR emsuart_rx_intr_handler(void * para);
|
||||||
|
static void IRAM_ATTR emsuart_tx_timer_intr_handler();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -51,10 +51,8 @@ void ICACHE_RAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) {
|
|||||||
|
|
||||||
if (USIS(EMSUART_UART) & ((1 << UIBD))) { // BREAK detection = End of EMS data block
|
if (USIS(EMSUART_UART) & ((1 << UIBD))) { // BREAK detection = End of EMS data block
|
||||||
USC0(EMSUART_UART) &= ~(1 << UCBRK); // reset tx-brk
|
USC0(EMSUART_UART) &= ~(1 << UCBRK); // reset tx-brk
|
||||||
|
// just for testing if break isn't finished yet
|
||||||
// while((USS(EMSUART_UART) >> USRXD) == 0); // wait for idle state of pin
|
// while((USS(EMSUART_UART) >> USRXD) == 0); // wait for idle state of pin
|
||||||
// if((USS(EMSUART_UART) >> USRXD) == 0) { // if rx is not idle wait one bittime
|
|
||||||
// delayMicroseconds(EMSUART_TX_BIT_TIME);
|
|
||||||
// }
|
|
||||||
USIC(EMSUART_UART) = (1 << UIBD); // INT clear the BREAK detect interrupt
|
USIC(EMSUART_UART) = (1 << UIBD); // INT clear the BREAK detect interrupt
|
||||||
length = 0;
|
length = 0;
|
||||||
while ((USS(EMSUART_UART) >> USRXC) & 0x0FF) { // read fifo into buffer
|
while ((USS(EMSUART_UART) >> USRXC) & 0x0FF) { // read fifo into buffer
|
||||||
@@ -116,23 +114,40 @@ void ICACHE_FLASH_ATTR EMSuart::emsuart_flush_fifos() {
|
|||||||
|
|
||||||
// ISR to Fire when Timer is triggered
|
// ISR to Fire when Timer is triggered
|
||||||
void ICACHE_RAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() {
|
void ICACHE_RAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() {
|
||||||
|
if (emsTxBufIdx > 32) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
emsTxBufIdx++;
|
emsTxBufIdx++;
|
||||||
if (emsTxBufIdx < emsTxBufLen) {
|
if (emsTxBufIdx < emsTxBufLen) {
|
||||||
USF(EMSUART_UART) = emsTxBuf[emsTxBufIdx];
|
USF(EMSUART_UART) = emsTxBuf[emsTxBufIdx];
|
||||||
timer1_write(emsTxWait);
|
timer1_write(emsTxWait);
|
||||||
} else if (emsTxBufIdx == emsTxBufLen) {
|
} else if (emsTxBufIdx == emsTxBufLen) {
|
||||||
USC0(EMSUART_UART) |= (1 << UCBRK); // set <BRK>
|
USC0(EMSUART_UART) |= (1 << UCBRK); // set <BRK>
|
||||||
// timer1_write(emsTxWait);
|
if (tx_mode_ > 5 || tx_mode_ < 11) {
|
||||||
timer1_write(5 * EMSUART_TX_BRK_WAIT);
|
timer1_write(5 * EMSUART_TX_BIT_TIME * 11);
|
||||||
} else {
|
USIE(EMSUART_UART) &= ~(1 << UIBD); // disable break interrupt
|
||||||
|
}
|
||||||
|
} else if (USC0(EMSUART_UART) & (1 << UCBRK)) {
|
||||||
USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear <BRK>
|
USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear <BRK>
|
||||||
|
USIE(EMSUART_UART) |= (1 << UIBD); // enable break interrupt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* init UART0 driver
|
* init UART0 driver
|
||||||
*/
|
*/
|
||||||
void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) {
|
void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) {
|
||||||
if (tx_mode_ != 0xFF) { // it's a restart no need to configure rx
|
if (tx_mode > 10) {
|
||||||
|
emsTxWait = 5 * EMSUART_TX_BIT_TIME * tx_mode; // bittimes for tx_mode
|
||||||
|
} else if (tx_mode > 5) {
|
||||||
|
emsTxWait = 10 * EMSUART_TX_BIT_TIME * tx_mode; // bittimes for tx_mode
|
||||||
|
}
|
||||||
|
if (tx_mode == 5) {
|
||||||
|
USC0(EMSUART_UART) = 0x2C; // 8N1,5
|
||||||
|
} else {
|
||||||
|
USC0(EMSUART_UART) = EMSUART_CONFIG; // 8N1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tx_mode_ != 0xFF) { // it's a restart no need to configure uart
|
||||||
tx_mode_ = tx_mode;
|
tx_mode_ = tx_mode;
|
||||||
restart();
|
restart();
|
||||||
return;
|
return;
|
||||||
@@ -141,6 +156,7 @@ void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) {
|
|||||||
// allocate and preset EMS Receive buffers
|
// allocate and preset EMS Receive buffers
|
||||||
for (int i = 0; i < EMS_MAXBUFFERS; i++) {
|
for (int i = 0; i < EMS_MAXBUFFERS; i++) {
|
||||||
EMSRxBuf_t * p = (EMSRxBuf_t *)malloc(sizeof(EMSRxBuf_t));
|
EMSRxBuf_t * p = (EMSRxBuf_t *)malloc(sizeof(EMSRxBuf_t));
|
||||||
|
p->length = 0;
|
||||||
paEMSRxBuf[i] = p;
|
paEMSRxBuf[i] = p;
|
||||||
}
|
}
|
||||||
pEMSRxBuf = paEMSRxBuf[0]; // reset EMS Rx Buffer
|
pEMSRxBuf = paEMSRxBuf[0]; // reset EMS Rx Buffer
|
||||||
@@ -156,7 +172,6 @@ void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) {
|
|||||||
|
|
||||||
// set 9600, 8 bits, no parity check, 1 stop bit
|
// set 9600, 8 bits, no parity check, 1 stop bit
|
||||||
USD(EMSUART_UART) = (UART_CLK_FREQ / EMSUART_BAUD);
|
USD(EMSUART_UART) = (UART_CLK_FREQ / EMSUART_BAUD);
|
||||||
USC0(EMSUART_UART) = EMSUART_CONFIG; // 8N1
|
|
||||||
|
|
||||||
emsuart_flush_fifos();
|
emsuart_flush_fifos();
|
||||||
|
|
||||||
@@ -169,7 +184,6 @@ void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) {
|
|||||||
// change: we set UCFFT to 1 to get an immediate indicator about incoming traffic.
|
// change: we set UCFFT to 1 to get an immediate indicator about incoming traffic.
|
||||||
// Otherwise, we're only noticed by UCTOT or RxBRK!
|
// Otherwise, we're only noticed by UCTOT or RxBRK!
|
||||||
// change: don't care, we do not use these interrupts
|
// change: don't care, we do not use these interrupts
|
||||||
// change proddy 13-june-2020: add back USC1(EMSUART_UART) = 0;
|
|
||||||
USC1(EMSUART_UART) = 0; // reset config first
|
USC1(EMSUART_UART) = 0; // reset config first
|
||||||
// USC1(EMSUART_UART) = (0x7F << UCFFT) | (0x04 << UCTOT) | (1 << UCTOE); // enable interupts
|
// USC1(EMSUART_UART) = (0x7F << UCFFT) | (0x04 << UCTOT) | (1 << UCTOE); // enable interupts
|
||||||
|
|
||||||
@@ -200,9 +214,6 @@ void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) {
|
|||||||
// for sending with large delay in EMS+ mode we use a timer interrupt
|
// for sending with large delay in EMS+ mode we use a timer interrupt
|
||||||
timer1_attachInterrupt(emsuart_tx_timer_intr_handler); // Add ISR Function
|
timer1_attachInterrupt(emsuart_tx_timer_intr_handler); // Add ISR Function
|
||||||
timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE); // 5 MHz timer
|
timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE); // 5 MHz timer
|
||||||
|
|
||||||
// emsTxWait = 5 * EMSUART_TX_BIT_TIME * 20; // 20 bittimes for tx_mode 2
|
|
||||||
emsTxWait = 5 * EMSUART_TX_BIT_TIME * 11; // 20 bittimes for tx_mode 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -233,20 +244,19 @@ void ICACHE_FLASH_ATTR EMSuart::restart() {
|
|||||||
* Which is a 11-bit set of zero's (11 cycles)
|
* Which is a 11-bit set of zero's (11 cycles)
|
||||||
*/
|
*/
|
||||||
void ICACHE_FLASH_ATTR EMSuart::tx_brk() {
|
void ICACHE_FLASH_ATTR EMSuart::tx_brk() {
|
||||||
uint32_t tmp;
|
|
||||||
|
|
||||||
// must make sure Tx FIFO is empty
|
// must make sure Tx FIFO is empty
|
||||||
while (((USS(EMSUART_UART) >> USTXC) & 0xFF))
|
while (((USS(EMSUART_UART) >> USTXC) & 0xFF))
|
||||||
;
|
;
|
||||||
|
// do not clear buffers to get a echo back
|
||||||
tmp = ((1 << UCRXRST) | (1 << UCTXRST)); // bit mask
|
// tmp = ((1 << UCRXRST) | (1 << UCTXRST)); // bit mask
|
||||||
USC0(EMSUART_UART) |= (tmp); // set bits
|
// USC0(EMSUART_UART) |= (tmp); // set bits
|
||||||
USC0(EMSUART_UART) &= ~(tmp); // clear bits
|
// USC0(EMSUART_UART) &= ~(tmp); // clear bits
|
||||||
|
|
||||||
// To create a 11-bit <BRK> we set TXD_BRK bit so the break signal will
|
// To create a 11-bit <BRK> we set TXD_BRK bit so the break signal will
|
||||||
// automatically be sent when the tx fifo is empty
|
// automatically be sent when the tx fifo is empty
|
||||||
tmp = (1 << UCBRK);
|
ETS_UART_INTR_DISABLE();
|
||||||
USC0(EMSUART_UART) |= (tmp); // set bit
|
USC0(EMSUART_UART) |= (1 << UCBRK); // set bit
|
||||||
|
|
||||||
if (tx_mode_ == EMS_TXMODE_EMSPLUS) { // EMS+ mode
|
if (tx_mode_ == EMS_TXMODE_EMSPLUS) { // EMS+ mode
|
||||||
delayMicroseconds(EMSUART_TX_BRK_WAIT); // 2070
|
delayMicroseconds(EMSUART_TX_BRK_WAIT); // 2070
|
||||||
@@ -254,7 +264,8 @@ void ICACHE_FLASH_ATTR EMSuart::tx_brk() {
|
|||||||
delayMicroseconds(EMSUART_TX_BRK_WAIT_HT3); // 1144
|
delayMicroseconds(EMSUART_TX_BRK_WAIT_HT3); // 1144
|
||||||
}
|
}
|
||||||
|
|
||||||
USC0(EMSUART_UART) &= ~(tmp); // clear BRK bit
|
USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear BRK bit
|
||||||
|
ETS_UART_INTR_ENABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -262,17 +273,18 @@ 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
|
* 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) {
|
void EMSuart::send_poll(uint8_t data) {
|
||||||
if (tx_mode_ == EMS_TXMODE_NEW) {
|
// reset tx-brk, just in case it is accidently set
|
||||||
USC0(EMSUART_UART) &= ~(1 << UCBRK); // reset tx-brk
|
USC0(EMSUART_UART) &= ~(1 << UCBRK);
|
||||||
|
if (tx_mode_ > 5) { // timer controlled modes
|
||||||
|
USF(EMSUART_UART) = data;
|
||||||
|
emsTxBufIdx = 0;
|
||||||
|
emsTxBufLen = 1;
|
||||||
|
timer1_write(emsTxWait);
|
||||||
|
} else if (tx_mode_ >= EMS_TXMODE_NEW) { // hardware controlled modes
|
||||||
USF(EMSUART_UART) = data;
|
USF(EMSUART_UART) = data;
|
||||||
USC0(EMSUART_UART) |= (1 << UCBRK); // send <BRK> at the end
|
USC0(EMSUART_UART) |= (1 << UCBRK); // send <BRK> at the end
|
||||||
} else if (tx_mode_ == EMS_TXMODE_EMSPLUS) {
|
} else { // software controlled modes
|
||||||
USF(EMSUART_UART) = data;
|
// EMS1.0, EMS+ and HT3
|
||||||
emsTxBufIdx = 0;
|
|
||||||
emsTxBufLen = 1;
|
|
||||||
timer1_write(emsTxWait);
|
|
||||||
} else {
|
|
||||||
// EMS1.0 and HT3
|
|
||||||
USF(EMSUART_UART) = data;
|
USF(EMSUART_UART) = data;
|
||||||
delayMicroseconds(EMSUART_TX_BRK_WAIT);
|
delayMicroseconds(EMSUART_TX_BRK_WAIT);
|
||||||
tx_brk(); // send <BRK>
|
tx_brk(); // send <BRK>
|
||||||
@@ -285,8 +297,8 @@ void EMSuart::send_poll(uint8_t data) {
|
|||||||
* returns code, 0=success, 1=brk error, 2=watchdog timeout
|
* returns code, 0=success, 1=brk error, 2=watchdog timeout
|
||||||
*/
|
*/
|
||||||
uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) {
|
uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) {
|
||||||
if (len == 0) {
|
if (len == 0 || len > 32) {
|
||||||
return EMS_TX_STATUS_ERR; // nothing to send
|
return EMS_TX_STATUS_ERR; // nothing or to much to send
|
||||||
}
|
}
|
||||||
#ifdef EMSESP_DEBUG
|
#ifdef EMSESP_DEBUG
|
||||||
// LOG_INFO(F("[DEBUG] UART Response time: %d ms"), uuid::get_uptime() - emsRxTime);
|
// LOG_INFO(F("[DEBUG] UART Response time: %d ms"), uuid::get_uptime() - emsRxTime);
|
||||||
@@ -294,10 +306,23 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) {
|
|||||||
// if ((uuid::get_uptime() - emsRxTime) > EMS_RX_TO_TX_TIMEOUT)) { // send allowed within 20 ms
|
// if ((uuid::get_uptime() - emsRxTime) > EMS_RX_TO_TX_TIMEOUT)) { // send allowed within 20 ms
|
||||||
// return EMS_TX_STATUS_ERR;
|
// return EMS_TX_STATUS_ERR;
|
||||||
// }
|
// }
|
||||||
|
// reset tx-brk, just in case it is accidently set
|
||||||
|
USC0(EMSUART_UART) &= ~(1 << UCBRK);
|
||||||
|
|
||||||
|
// timer controlled modes with extra delay
|
||||||
|
if (tx_mode_ > 5) {
|
||||||
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
|
emsTxBuf[i] = buf[i];
|
||||||
|
}
|
||||||
|
emsTxBufIdx = 0;
|
||||||
|
emsTxBufLen = len;
|
||||||
|
USF(EMSUART_UART) = buf[0];
|
||||||
|
timer1_write(emsTxWait);
|
||||||
|
return EMS_TX_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// new code from Michael. See https://github.com/proddy/EMS-ESP/issues/380
|
// new code from Michael. See https://github.com/proddy/EMS-ESP/issues/380
|
||||||
if (tx_mode_ == EMS_TXMODE_NEW) {
|
if (tx_mode_ >= EMS_TXMODE_NEW) {
|
||||||
USC0(EMSUART_UART) &= ~(1 << UCBRK); // reset tx-brk
|
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
USF(EMSUART_UART) = buf[i];
|
USF(EMSUART_UART) = buf[i];
|
||||||
}
|
}
|
||||||
@@ -308,15 +333,10 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) {
|
|||||||
// EMS+ https://github.com/proddy/EMS-ESP/issues/23#
|
// EMS+ https://github.com/proddy/EMS-ESP/issues/23#
|
||||||
if (tx_mode_ == EMS_TXMODE_EMSPLUS) { // With extra tx delay for EMS+
|
if (tx_mode_ == EMS_TXMODE_EMSPLUS) { // With extra tx delay for EMS+
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
emsTxBuf[i] = buf[i];
|
USF(EMSUART_UART) = buf[i];
|
||||||
// USF(EMSUART_UART) = buf[i];
|
delayMicroseconds(EMSUART_TX_BRK_WAIT); // 2070
|
||||||
// delayMicroseconds(EMSUART_TX_WAIT_EMSPLUS); // 2070
|
|
||||||
}
|
}
|
||||||
emsTxBufIdx = 0;
|
tx_brk(); // send <BRK>
|
||||||
emsTxBufLen = len;
|
|
||||||
USF(EMSUART_UART) = buf[0];
|
|
||||||
timer1_write(emsTxWait);
|
|
||||||
// tx_brk(); // send <BRK>
|
|
||||||
return EMS_TX_STATUS_OK;
|
return EMS_TX_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,7 +372,7 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) {
|
|||||||
* 2. Busmaster cancel telegram by sending a BRK
|
* 2. Busmaster cancel telegram by sending a BRK
|
||||||
*
|
*
|
||||||
* Case 1. is handled by a watchdog counter which is reset on each
|
* Case 1. is handled by a watchdog counter which is reset on each
|
||||||
* Tx attempt. The timeout should be 20x EMSUART_TX_BIT_TIME plus
|
* Tx attempt. The timeout should be 20x EMSUART_TX_BIT_TIME plus
|
||||||
* some smart guess for processing time on targeted EMS device.
|
* some smart guess for processing time on targeted EMS device.
|
||||||
* We set Status to EMS_TX_WTD_TIMEOUT and return
|
* We set Status to EMS_TX_WTD_TIMEOUT and return
|
||||||
*
|
*
|
||||||
@@ -385,16 +405,18 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) {
|
|||||||
// neither bus collision nor timeout - send terminating BRK signal
|
// neither bus collision nor timeout - send terminating BRK signal
|
||||||
if (!(USIS(EMSUART_UART) & (1 << UIBD))) {
|
if (!(USIS(EMSUART_UART) & (1 << UIBD))) {
|
||||||
// no bus collision - send terminating BRK signal
|
// no bus collision - send terminating BRK signal
|
||||||
USC0(EMSUART_UART) |= (1 << UCLBE) | (1 << UCBRK); // enable loopback & set <BRK>
|
// USC0(EMSUART_UART) |= (1 << UCLBE) | (1 << UCBRK); // enable loopback & set <BRK>
|
||||||
|
USC0(EMSUART_UART) |= (1 << UCBRK); // set <BRK>
|
||||||
|
|
||||||
// wait until BRK detected...
|
// wait until BRK detected...
|
||||||
while (!(USIR(EMSUART_UART) & (1 << UIBD))) {
|
while (!(USIR(EMSUART_UART) & (1 << UIBD))) {
|
||||||
delayMicroseconds(EMSUART_TX_BIT_TIME);
|
delayMicroseconds(EMSUART_TX_BIT_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
USC0(EMSUART_UART) &= ~((1 << UCBRK) | (1 << UCLBE)); // disable loopback & clear <BRK>
|
USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear <BRK>
|
||||||
USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ
|
// USC0(EMSUART_UART) &= ~((1 << UCBRK) | (1 << UCLBE)); // disable loopback & clear <BRK>
|
||||||
phantomBreak = 1;
|
// USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ
|
||||||
|
// phantomBreak = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// interrupts();
|
// interrupts();
|
||||||
@@ -405,4 +427,4 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) {
|
|||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
#include <uuid/log.h>
|
#include <uuid/log.h>
|
||||||
|
|
||||||
#define EMSUART_UART 0 // UART 0
|
#define EMSUART_UART 0 // UART 0
|
||||||
#define EMSUART_CONFIG 0x1C // 8N1 (8 bits, no stop bits, 1 parity)
|
#define EMSUART_CONFIG 0x1C // 8N1 (8 bits, no parity, 1 stop bit)
|
||||||
#define EMSUART_BAUD 9600 // uart baud rate for the EMS circuit
|
#define EMSUART_BAUD 9600 // uart baud rate for the EMS circuit
|
||||||
|
|
||||||
#define EMS_MAXBUFFERS 3 // buffers for circular filling to avoid collisions
|
#define EMS_MAXBUFFERS 3 // buffers for circular filling to avoid collisions
|
||||||
@@ -84,4 +84,4 @@ class EMSuart {
|
|||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user