improved handling of telegram sizes

This commit is contained in:
proddy
2018-06-02 21:44:24 +02:00
parent d23851c37f
commit 555695d623
5 changed files with 57 additions and 53 deletions

View File

@@ -124,7 +124,7 @@ And lastly if you don't fancy building the circuit, [bbqkees](http://www.domotic
My circuit will work with both 3.3V and 5V. It's easiest though to power directly from the ESP's 3V3 line.
Powering the ESP89266 can be either via the USB from a PC or external 5V power supply or from the EMS line itself using a buck step-down converter. The EMS provides about 15V AC current. The advantage of using the EMS is obviously less power cables and it's neater to place inline with the thermostat. I use a [Pololu D24C22F5](https://www.pololu.com/product/2858) which is 5V/2A buck step-down module and probably slightly overkill for what we need. The additional part of the circuit is shown below along with an earlier breadboard prototype using a NodeMCU2 (with the additional LEDs):
Powering the ESP89266 can be either via the USB from a PC or external 5V power supply or from the EMS itself using a buck step-down converter. The EMS provides about a 15V AC current direct from the EMS line, or around 12V from the 3.5" service jack. The advantage of using the EMS for power is obviously the exclusion of an external power adapter and you can place the small circuit in line with the thermostat tucked away close to the boiler. The circuit's bridge rectifier will produce about 14.5V DC at UEMS (see schematic). I use a [Pololu D24C22F5](https://www.pololu.com/product/2858) which is 5V/2A buck step-down module and probably slightly overkill for what we need. The additional part of the circuit is shown below along with an earlier breadboard prototype using a NodeMCU2 (with the additional LEDs):
| Power circuit | Example |
| ------------------------------------------ | ---------------------------------------------------- |
@@ -218,7 +218,7 @@ Every telegram sent is echo'd back to Rx.
`ems.cpp` is the logic to read the EMS packets (telegrams), validates them and process them based on the type.
`boiler.ino` is the Arduino code for the ESP8266 that kicks it all off. This is where we have specific logic such as the code to monitor and alert on the Shower timer and light up the LEDs.
`boiler.ino` is the Arduino code for the ESP8266 that kicks it all off. This is where we have specific logic such as the code to monitor and alert on the Shower timer and light up the LEDs. LED support is enabled by setting the -DUSE_LED build flag.
`ESPHelper.cpp` is my customized version of [ESPHelper](https://github.com/ItKindaWorks/ESPHelper) with added Telnet support and some other minor tweaking.
@@ -242,7 +242,7 @@ Note the thermostat types are based on a RC20 model thermostat. If using an RC30
### Customizing
Most of the changes will be done in `boiler.ino` and `ems.cpp`.
* To add new handlers for data types, create a callback function and add to the `EMS_Types` at the top of the file `ems.cpp`
* To add new handlers for data types, create a callback function and add to the `EMS_Types` at the top of the file `ems.cpp` and modify `ems.h`
* To change your thermostat type set `EMS_ID_THERMOSTAT` in `ems.cpp`. The default is 0x17 for an RC20.
* The DEFINES `BOILER_THERMOSTAT_ENABLED`, `BOILER_SHOWER_ENABLED` and `BOILER_SHOWER_TIMER` enabled the thermostat logic, the shower logic and the shower timer alert logic respectively. 1 is on and 0 is off.

View File

@@ -4,7 +4,7 @@ env_default = nodemcuv2
[common]
platform = espressif8266
build_flags = -DMQTT_MAX_PACKET_SIZE=300
build_flags = -DMQTT_MAX_PACKET_SIZE=300 -DUSE_LED
build_flags_custom = '-DWIFI_SSID="my_ssid"' '-DWIFI_PASSWORD="my_password"' '-DMQTT_IP="my_broker_ip"' '-DMQTT_USER="my_broker_username"' '-DMQTT_PASS="my_broker_password"'
lib_deps =
Time

View File

@@ -579,7 +579,7 @@ bool ESPHelper::isCRLF(char character) {
// handler for Telnet
void ESPHelper::consoleHandle() {
// look for Client connect trial
// look for Client
if (telnetServer.hasClient()) {
if (telnetClient && telnetClient.connected()) {
// Verify if the IP is same than actual connection
@@ -614,7 +614,7 @@ void ESPHelper::consoleHandle() {
// Show the initial message
consoleShowHelp();
// Empty buffer in
// Empty buffer
while (telnetClient.available()) {
telnetClient.read();
}
@@ -625,7 +625,7 @@ void ESPHelper::consoleHandle() {
// Get command over telnet
if (_telnetConnected) {
char last = ' '; // To avoid process two times the "\r\n"
char last = ' '; // To avoid processing double "\r\n"
while (telnetClient.available()) { // get data from Client
@@ -663,7 +663,7 @@ void ESPHelper::consoleHandle() {
}
}
// Set help for commands over telnet setted by sketch
// Set help for commands over telnet
void ESPHelper::consoleSetHelpProjectsCmds(String help) {
_helpProjectCmds = help;
}
@@ -767,7 +767,7 @@ void ESPHelper::consoleShowHelp() {
"&=toggle verbose messages");
if (_helpProjectCmds != "" && (_consoleCallbackProjectCmds)) {
help.concat("\n\r* ");
help.concat("\n\r");
help.concat(_helpProjectCmds);
}
help.concat("\n\r");

View File

@@ -28,19 +28,20 @@ bool _process_RC20Temperature(uint8_t * data, uint8_t length);
bool _process_Version(uint8_t * data, uint8_t length);
const _EMS_Types EMS_Types[MAX_TYPECALLBACK] =
{{EMS_ID_BOILER, EMS_TYPE_UBAMonitorFast, "UBAMonitorFast", 36, _process_UBAMonitorFast},
{EMS_ID_BOILER, EMS_TYPE_UBAMonitorSlow, "UBAMonitorSlow", 28, _process_UBAMonitorSlow},
{EMS_ID_BOILER, EMS_TYPE_UBAMonitorWWMessage, "UBAMonitorWWMessage", 10, _process_UBAMonitorWWMessage},
{EMS_ID_BOILER, EMS_TYPE_UBAParameterWW, "UBAParameterWW", 10, _process_UBAParameterWW},
{EMS_ID_BOILER, EMS_TYPE_UBATotalUptimeMessage, "UBATotalUptimeMessage", 30, NULL},
{EMS_ID_BOILER, EMS_TYPE_UBAMaintenanceSettingsMessage, "UBAMaintenanceSettingsMessage", 30, NULL},
{EMS_ID_BOILER, EMS_TYPE_UBAParametersMessage, "UBAParametersMessage", 30, NULL},
{EMS_ID_BOILER, EMS_TYPE_UBAMaintenanceStatusMessage, "UBAMaintenanceStatusMessage", 30, NULL},
{ {EMS_ID_BOILER, EMS_TYPE_UBAMonitorFast, "UBAMonitorFast", _process_UBAMonitorFast},
{EMS_ID_BOILER, EMS_TYPE_UBAMonitorSlow, "UBAMonitorSlow", _process_UBAMonitorSlow},
{EMS_ID_BOILER, EMS_TYPE_UBAMonitorWWMessage, "UBAMonitorWWMessage", _process_UBAMonitorWWMessage},
{EMS_ID_BOILER, EMS_TYPE_UBAParameterWW, "UBAParameterWW", _process_UBAParameterWW},
{EMS_ID_BOILER, EMS_TYPE_UBATotalUptimeMessage, "UBATotalUptimeMessage", NULL},
{EMS_ID_BOILER, EMS_TYPE_UBAMaintenanceSettingsMessage, "UBAMaintenanceSettingsMessage", NULL},
{EMS_ID_BOILER, EMS_TYPE_UBAParametersMessage, "UBAParametersMessage", NULL},
{EMS_ID_BOILER, EMS_TYPE_UBAMaintenanceStatusMessage, "UBAMaintenanceStatusMessage", NULL},
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20StatusMessage, "RC20StatusMessage", 19, _process_RC20StatusMessage},
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Time, "RC20Time", 20, _process_RC20Time},
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Temperature, "RC20Temperature", 27, _process_RC20Temperature},
{EMS_ID_THERMOSTAT, EMS_TYPE_Version, "Version", 2, _process_Version}};
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20StatusMessage, "RC20StatusMessage", _process_RC20StatusMessage},
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Time, "RC20Time", _process_RC20Time},
{EMS_ID_THERMOSTAT, EMS_TYPE_RC20Temperature, "RC20Temperature", _process_RC20Temperature},
{EMS_ID_THERMOSTAT, EMS_TYPE_Version, "Version", _process_Version}
};
// reserve space for the data we collect from the Boiler and Thermostat
_EMS_Boiler EMS_Boiler;
@@ -48,7 +49,7 @@ _EMS_Thermostat EMS_Thermostat;
// CRC lookup table with poly 12 for faster checking
const uint8_t ems_crc_table[] =
{0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
{ 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
0x26, 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, 0x40, 0x42, 0x44, 0x46, 0x48, 0x4A,
0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E, 0x60, 0x62, 0x64, 0x66, 0x68, 0x6A, 0x6C, 0x6E, 0x70,
0x72, 0x74, 0x76, 0x78, 0x7A, 0x7C, 0x7E, 0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96,
@@ -61,7 +62,8 @@ const uint8_t ems_crc_table[] =
0x65, 0x67, 0x99, 0x9B, 0x9D, 0x9F, 0x91, 0x93, 0x95, 0x97, 0x89, 0x8B, 0x8D, 0x8F, 0x81, 0x83, 0x85, 0x87, 0xB9,
0xBB, 0xBD, 0xBF, 0xB1, 0xB3, 0xB5, 0xB7, 0xA9, 0xAB, 0xAD, 0xAF, 0xA1, 0xA3, 0xA5, 0xA7, 0xD9, 0xDB, 0xDD, 0xDF,
0xD1, 0xD3, 0xD5, 0xD7, 0xC9, 0xCB, 0xCD, 0xCF, 0xC1, 0xC3, 0xC5, 0xC7, 0xF9, 0xFB, 0xFD, 0xFF, 0xF1, 0xF3, 0xF5,
0xF7, 0xE9, 0xEB, 0xED, 0xEF, 0xE1, 0xE3, 0xE5, 0xE7};
0xF7, 0xE9, 0xEB, 0xED, 0xEF, 0xE1, 0xE3, 0xE5, 0xE7
};
extern ESPHelper myESP; // needed for the DEBUG statements below
#define myDebug(x, ...) myESP.printf(x, ##__VA_ARGS__);
@@ -208,7 +210,7 @@ void _debugPrintTelegram(const char * prefix, uint8_t * data, uint8_t len, const
}
time_t currentTime = now();
myDebug("[%02d:%02d:%02d] %s len=%02d, data: ", hour(currentTime), minute(currentTime), second(currentTime), prefix, len);
myDebug("[%02d:%02d:%02d] %s len=%d, data: ", hour(currentTime), minute(currentTime), second(currentTime), prefix, len);
for (int i = 0; i < len; i++) {
myDebug("%02x ", data[i]);
}
@@ -559,12 +561,13 @@ bool _process_RC20Temperature(uint8_t * data, uint8_t length) {
/*
* Version - type 0x02 - get the version of the Thermostat firmware
* We don't bother storing these values anywhere
*/
bool _process_Version(uint8_t * data, uint8_t length) {
uint8_t major = data[1];
uint8_t minor = data[2];
myDebug("Version %d.%d\n", major, minor); // TODO: finish this
myDebug("Version %d.%d\n", major, minor);
return true;
}
@@ -601,10 +604,12 @@ void _buildTxTelegram(uint8_t data_value) {
EMS_TxTelegram.data[2] = EMS_TxTelegram.type; // type
EMS_TxTelegram.data[3] = EMS_TxTelegram.offset; //offset
// data
EMS_TxTelegram.data[4] = data_value; // value, can be size
// data:
// for reading this is #bytes we want to read (the size)
// for writing its the value we want to write
EMS_TxTelegram.data[4] = data_value;
// crc
// crc:
EMS_TxTelegram.data[5] = _crcCalculator(EMS_TxTelegram.data, EMS_TxTelegram.length);
EMS_Sys_Status.emsTxStatus = EMS_TX_PENDING; // armed and ready to send
@@ -623,7 +628,7 @@ void ems_doReadCommand(uint8_t type) {
if (_checkWriteQueueFull())
return; // check if there is already something in the queue
uint8_t dest, size;
uint8_t dest;
// scan through known types
bool typeFound = false;
@@ -633,7 +638,6 @@ void ems_doReadCommand(uint8_t type) {
typeFound = true; // we have a match
// call callback to fetch the values from the telegram
dest = EMS_Types[i].src;
size = EMS_Types[i].size;
break;
}
i++;
@@ -642,10 +646,9 @@ void ems_doReadCommand(uint8_t type) {
// for adhoc calls use default values
if (!typeFound) {
dest = EMS_ID_BOILER; // default is boiler
size = 1;
myDebug("Requesting type (0x%02x) from dest 0x%02x for %d bytes\n", type, dest, size);
myDebug("Requesting type (0x%02x) from dest 0x%02x\n", type, dest);
} else {
myDebug("Requesting type %s(0x%02x) from dest 0x%02x for %d bytes\n", EMS_Types[i].typeString, type, dest, size);
myDebug("Requesting type %s(0x%02x) from dest 0x%02x\n", EMS_Types[i].typeString, type, dest);
}
EMS_TxTelegram.action = EMS_TX_READ; // read command
@@ -654,7 +657,7 @@ void ems_doReadCommand(uint8_t type) {
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH; // is always 6 bytes long (including CRC at end)
EMS_TxTelegram.type = type;
_buildTxTelegram(size); // we send the # bytes we want back
_buildTxTelegram(EMS_MAX_TELEGRAM_LENGTH); // we send the # bytes we want back
}
/*

View File

@@ -18,6 +18,7 @@
#define EMS_TYPE_NONE 0x00 // none
#define EMS_MIN_TELEGRAM_LENGTH 6 // minimal length for a validation telegram, including CRC
#define EMS_MAX_TELEGRAM_LENGTH 99 // max length of a telegram, including CRC
#define EMS_TX_MAXBUFFERSIZE 128 // max size of the buffer. packets are 32 bits
@@ -156,7 +157,7 @@ typedef struct {
uint8_t src;
uint8_t type;
const char typeString[50];
uint8_t size; // size of telegram, excluding the 4-byte header and crc
//uint8_t size; // size of telegram, excluding the 4-byte header and crc
EMS_processType_cb processType_cb;
} _EMS_Types;