mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-14 19:59:53 +03:00
merged with dev 1.8.1
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
std::vector<ds_device_t> _devices;
|
||||
|
||||
DS18::DS18() {
|
||||
_wire = NULL;
|
||||
_wire = nullptr;
|
||||
_count = 0;
|
||||
_gpio = GPIO_NONE;
|
||||
_parasite = 0;
|
||||
|
||||
609
src/ems-esp.cpp
609
src/ems-esp.cpp
File diff suppressed because it is too large
Load Diff
642
src/ems.cpp
642
src/ems.cpp
File diff suppressed because it is too large
Load Diff
200
src/ems.h
200
src/ems.h
@@ -12,27 +12,90 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
/* debug helper for logic analyzer
|
||||
* create marker puls on GPIOx
|
||||
* ° for Rx, we use GPIO14
|
||||
* ° for Tx, we use GPIO12
|
||||
*/
|
||||
// clang-format off
|
||||
#ifdef LOGICANALYZER
|
||||
#define RX_MARK_PIN 14
|
||||
#define TX_MARK_PIN 12
|
||||
|
||||
#define RX_MARK_MASK (1 << RX_MARK_PIN)
|
||||
#define TX_MARK_MASK (1 << TX_MARK_PIN)
|
||||
#define MARKERS_MASK (RX_MARK_PIN | TX_MARK_PIN)
|
||||
|
||||
#define GPIO_H(mask) (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, (mask)))
|
||||
#define GPIO_L(mask) (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, (mask)))
|
||||
|
||||
#define RX_PULSE(pulse) \
|
||||
do { \
|
||||
GPIO_H(RX_MARK_MASK); \
|
||||
delayMicroseconds(pulse); \
|
||||
GPIO_L(RX_MARK_MASK); \
|
||||
} while (0)
|
||||
#define TX_PULSE(pulse) \
|
||||
do { \
|
||||
GPIO_H(TX_MARK_MASK); \
|
||||
delayMicroseconds(pulse); \
|
||||
GPIO_L(TX_MARK_MASK); \
|
||||
} while (0)
|
||||
#define LA_PULSE(pulse) \
|
||||
do { \
|
||||
GPIO_H(MARKERS_MASK); \
|
||||
delayMicroseconds(pulse); \
|
||||
GPIO_L(MARKERS_MASK); \
|
||||
} while (0)
|
||||
|
||||
#define INIT_MARKERS(void) \
|
||||
do { \
|
||||
pinMode(RX_MARK_PIN, OUTPUT); \
|
||||
pinMode(TX_MARK_PIN, OUTPUT); \
|
||||
GPIO_L(MARKERS_MASK); \
|
||||
} while (0)
|
||||
#else
|
||||
#define RX_PULSE(pulse) \
|
||||
{}
|
||||
#define TX_PULSE(pulse) \
|
||||
{}
|
||||
#define LA_PULSE(pulse) \
|
||||
{}
|
||||
#define INIT_MARKERS(void) \
|
||||
{}
|
||||
#define RX_MARK_MASK
|
||||
#define TX_MARK_MASK
|
||||
#define GPIO_H(mask)
|
||||
#define GPIO_L(mask)
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
#define EMS_ID_NONE 0x00 // used as a dest in broadcast messages and empty device IDs
|
||||
|
||||
// Fixed EMS IDs
|
||||
#define EMS_ID_ME 0x0B // our device, hardcoded as the "Service Key"
|
||||
#define EMS_ID_BOILER 0x08 // all UBA Boilers have 0x08
|
||||
#define EMS_ID_SM 0x30 // Solar Module SM10 and SM100
|
||||
#define EMS_ID_SM 0x30 // Solar Module SM10, SM100 and ISM1
|
||||
#define EMS_ID_HP 0x38 // HeatPump
|
||||
#define EMS_ID_GATEWAY 0x48 // KM200 Web Gateway
|
||||
|
||||
#define EMS_PRODUCTID_HEATRONICS 95 // ProductID for a Junkers Heatronic3 device
|
||||
|
||||
#define EMS_PRODUCTID_SM10 73 // ProductID for SM10 solar module
|
||||
#define EMS_PRODUCTID_SM100 163 // ProductID for SM10 solar module
|
||||
#define EMS_PRODUCTID_ISM1 101 // ProductID for SM10 solar module
|
||||
|
||||
#define EMS_MIN_TELEGRAM_LENGTH 6 // minimal length for a validation telegram, including CRC
|
||||
|
||||
// max length of a telegram, including CRC, for Rx and Tx.
|
||||
#define EMS_MAX_TELEGRAM_LENGTH 32
|
||||
|
||||
// default values
|
||||
// default values for null values
|
||||
#define EMS_VALUE_INT_ON 1 // boolean true
|
||||
#define EMS_VALUE_INT_OFF 0 // boolean false
|
||||
#define EMS_VALUE_INT_NOTSET 0xFF // for 8-bit ints
|
||||
#define EMS_VALUE_SHORT_NOTSET 0x8000 // for 2-byte signed shorts
|
||||
#define EMS_VALUE_INT_NOTSET 0xFF // for 8-bit unsigned ints/bytes
|
||||
#define EMS_VALUE_SHORT_NOTSET -32768 // for 2-byte signed shorts
|
||||
#define EMS_VALUE_USHORT_NOTSET 0x8000 // for 2-byte unsigned shorts
|
||||
#define EMS_VALUE_LONG_NOTSET 0xFFFFFF // for 3-byte longs
|
||||
|
||||
#define EMS_THERMOSTAT_WRITE_YES true
|
||||
@@ -57,8 +120,11 @@ typedef enum {
|
||||
} _EMS_RX_STATUS;
|
||||
|
||||
typedef enum {
|
||||
EMS_TX_STATUS_OK,
|
||||
EMS_TX_STATUS_IDLE, // ready
|
||||
EMS_TX_STATUS_WAIT // waiting for response from last Tx
|
||||
EMS_TX_STATUS_WAIT, // waiting for response from last Tx
|
||||
EMS_TX_WTD_TIMEOUT, // watchdog timeout during send
|
||||
EMS_TX_BRK_DETECT // incoming BRK during Tx
|
||||
} _EMS_TX_STATUS;
|
||||
|
||||
#define EMS_TX_SUCCESS 0x01 // EMS single byte after a Tx Write indicating a success
|
||||
@@ -74,11 +140,12 @@ typedef enum {
|
||||
|
||||
/* EMS logging */
|
||||
typedef enum {
|
||||
EMS_SYS_LOGGING_NONE, // no messages
|
||||
EMS_SYS_LOGGING_RAW, // raw data mode
|
||||
EMS_SYS_LOGGING_BASIC, // only basic read/write messages
|
||||
EMS_SYS_LOGGING_THERMOSTAT, // only telegrams sent from thermostat
|
||||
EMS_SYS_LOGGING_VERBOSE // everything
|
||||
EMS_SYS_LOGGING_NONE, // no messages
|
||||
EMS_SYS_LOGGING_RAW, // raw data mode
|
||||
EMS_SYS_LOGGING_BASIC, // only basic read/write messages
|
||||
EMS_SYS_LOGGING_THERMOSTAT, // only telegrams sent from thermostat
|
||||
EMS_SYS_LOGGING_SOLARMODULE, // only telegrams sent from thermostat
|
||||
EMS_SYS_LOGGING_VERBOSE // everything
|
||||
} _EMS_SYS_LOGGING;
|
||||
|
||||
// status/counters since last power on
|
||||
@@ -98,6 +165,7 @@ typedef struct {
|
||||
bool emsTxDisabled; // true to prevent all Tx
|
||||
uint8_t txRetryCount; // # times the last Tx was re-sent
|
||||
bool emsReverse; // if true, poll logic is reversed
|
||||
uint8_t emsTxMode; // handles Tx logic
|
||||
} _EMS_Sys_Status;
|
||||
|
||||
// The Tx send package
|
||||
@@ -148,20 +216,30 @@ const _EMS_TxTelegram EMS_TX_TELEGRAM_NEW = {
|
||||
{0x00} // data
|
||||
};
|
||||
|
||||
// where defintions are stored
|
||||
typedef struct {
|
||||
uint8_t model_id;
|
||||
uint8_t product_id;
|
||||
char model_string[50];
|
||||
} _Boiler_Type;
|
||||
|
||||
typedef struct {
|
||||
uint8_t model_id;
|
||||
uint8_t product_id;
|
||||
uint8_t device_id;
|
||||
char model_string[50];
|
||||
} _SolarModule_Type;
|
||||
|
||||
typedef struct {
|
||||
uint8_t product_id;
|
||||
uint8_t device_id;
|
||||
char model_string[50];
|
||||
} _Other_Type;
|
||||
|
||||
// Definition for thermostat devices
|
||||
typedef struct {
|
||||
uint8_t product_id;
|
||||
uint8_t device_id;
|
||||
char model_string[50];
|
||||
} _HeatPump_Type;
|
||||
|
||||
typedef struct {
|
||||
uint8_t model_id;
|
||||
uint8_t product_id;
|
||||
@@ -170,6 +248,7 @@ typedef struct {
|
||||
bool write_supported;
|
||||
} _Thermostat_Type;
|
||||
|
||||
// for consolidating all types
|
||||
typedef struct {
|
||||
uint8_t product_id;
|
||||
uint8_t device_id;
|
||||
@@ -189,8 +268,8 @@ typedef struct { // UBAParameterWW
|
||||
|
||||
// UBAMonitorFast
|
||||
uint8_t selFlowTemp; // Selected flow temperature
|
||||
int16_t curFlowTemp; // Current flow temperature
|
||||
int16_t retTemp; // Return temperature
|
||||
uint16_t curFlowTemp; // Current flow temperature
|
||||
uint16_t retTemp; // Return temperature
|
||||
uint8_t burnGas; // Gas on/off
|
||||
uint8_t fanWork; // Fan on/off
|
||||
uint8_t ignWork; // Ignition on/off
|
||||
@@ -206,14 +285,14 @@ typedef struct { // UBAParameterWW
|
||||
|
||||
// UBAMonitorSlow
|
||||
int16_t extTemp; // Outside temperature
|
||||
int16_t boilTemp; // Boiler temperature
|
||||
uint16_t boilTemp; // Boiler temperature
|
||||
uint8_t pumpMod; // Pump modulation
|
||||
uint32_t burnStarts; // # burner starts
|
||||
uint32_t burnWorkMin; // Total burner operating time
|
||||
uint32_t heatWorkMin; // Total heat operating time
|
||||
|
||||
// UBAMonitorWWMessage
|
||||
int16_t wWCurTmp; // Warm Water current temperature:
|
||||
uint16_t wWCurTmp; // Warm Water current temperature
|
||||
uint32_t wWStarts; // Warm Water # starts
|
||||
uint32_t wWWorkM; // Warm Water # minutes
|
||||
uint8_t wWOneTime; // Warm Water one time function on/off
|
||||
@@ -241,21 +320,39 @@ typedef struct { // UBAParameterWW
|
||||
* Telegram package defintions for Other EMS devices
|
||||
*/
|
||||
|
||||
// SM Solar Module - SM10Monitor/SM100Monitor
|
||||
typedef struct {
|
||||
bool SM; // set true if there is a Solar Module available
|
||||
bool HP; // set true if there is a Heat Pump available
|
||||
int16_t SMcollectorTemp; // collector temp
|
||||
int16_t SMbottomTemp; // bottom temp
|
||||
uint8_t SMpumpModulation; // modulation solar pump
|
||||
uint8_t SMpump; // pump active
|
||||
int16_t SMEnergyLastHour;
|
||||
int16_t SMEnergyToday;
|
||||
int16_t SMEnergyTotal;
|
||||
uint8_t HPModulation; // heatpump modulation in %
|
||||
uint8_t HPSpeed; // speed 0-100 %
|
||||
uint8_t device_id; // the device ID of the Heat Pump (e.g. 0x30)
|
||||
uint8_t model_id; // Solar Module / Heat Pump model (e.g. 3 > EMS_MODEL_OTHER )
|
||||
uint8_t product_id;
|
||||
char version[10];
|
||||
} _EMS_HeatPump;
|
||||
|
||||
typedef struct {
|
||||
uint8_t device_id;
|
||||
uint8_t model_id;
|
||||
uint8_t product_id;
|
||||
char version[10];
|
||||
} _EMS_Other;
|
||||
|
||||
// SM Solar Module - SM10/SM100/ISM1
|
||||
typedef struct {
|
||||
int16_t collectorTemp; // collector temp
|
||||
int16_t bottomTemp; // bottom temp
|
||||
uint8_t pumpModulation; // modulation solar pump
|
||||
uint8_t pump; // pump active
|
||||
int16_t setpoint_maxBottomTemp; // setpoint for maximum collector temp
|
||||
uint16_t EnergyLastHour;
|
||||
uint16_t EnergyToday;
|
||||
uint16_t EnergyTotal;
|
||||
uint32_t pumpWorkMin; // Total solar pump operating time
|
||||
uint8_t device_id; // the device ID of the Solar Module
|
||||
uint8_t model_id; // Solar Module
|
||||
uint8_t product_id;
|
||||
char version[10];
|
||||
} _EMS_SolarModule;
|
||||
|
||||
// Thermostat data
|
||||
typedef struct {
|
||||
uint8_t device_id; // the device ID of the thermostat
|
||||
@@ -300,39 +397,48 @@ void ems_sendRawTelegram(char * telegram);
|
||||
void ems_scanDevices();
|
||||
void ems_printAllDevices();
|
||||
void ems_printDevices();
|
||||
uint8_t ems_printDevices_s(char * buffer, uint16_t len);
|
||||
void ems_printTxQueue();
|
||||
void ems_testTelegram(uint8_t test_num);
|
||||
void ems_startupTelegrams();
|
||||
bool ems_checkEMSBUSAlive();
|
||||
void ems_clearDeviceList();
|
||||
void ems_setTxMode(uint8_t mode);
|
||||
|
||||
void ems_setThermostatTemp(float temperature, uint8_t temptype = 0);
|
||||
void ems_setThermostatMode(uint8_t mode);
|
||||
void ems_setThermostatHC(uint8_t hc);
|
||||
void ems_setWarmWaterTemp(uint8_t temperature);
|
||||
void ems_setFlowTemp(uint8_t temperature);
|
||||
void ems_setWarmWaterActivated(bool activated);
|
||||
void ems_setWarmTapWaterActivated(bool activated);
|
||||
void ems_setPoll(bool b);
|
||||
void ems_setLogging(_EMS_SYS_LOGGING loglevel);
|
||||
void ems_setEmsRefreshed(bool b);
|
||||
void ems_setWarmWaterModeComfort(uint8_t comfort);
|
||||
void ems_setModels();
|
||||
void ems_setTxDisabled(bool b);
|
||||
void ems_setThermostatTemp(float temperature, uint8_t temptype = 0);
|
||||
void ems_setThermostatMode(uint8_t mode);
|
||||
void ems_setThermostatHC(uint8_t hc);
|
||||
void ems_setWarmWaterTemp(uint8_t temperature);
|
||||
void ems_setFlowTemp(uint8_t temperature);
|
||||
void ems_setWarmWaterActivated(bool activated);
|
||||
void ems_setWarmTapWaterActivated(bool activated);
|
||||
void ems_setPoll(bool b);
|
||||
void ems_setLogging(_EMS_SYS_LOGGING loglevel);
|
||||
void ems_setEmsRefreshed(bool b);
|
||||
void ems_setWarmWaterModeComfort(uint8_t comfort);
|
||||
void ems_setModels();
|
||||
void ems_setTxDisabled(bool b);
|
||||
bool ems_getTxDisabled();
|
||||
uint8_t ems_getTxMode();
|
||||
|
||||
char * ems_getThermostatDescription(char * buffer);
|
||||
char * ems_getBoilerDescription(char * buffer);
|
||||
char * ems_getSolarModuleDescription(char * buffer);
|
||||
char * ems_getHeatPumpDescription(char * buffer);
|
||||
void ems_getThermostatValues();
|
||||
void ems_getBoilerValues();
|
||||
void ems_getOtherValues();
|
||||
void ems_getSolarModuleValues();
|
||||
bool ems_getPoll();
|
||||
bool ems_getTxEnabled();
|
||||
bool ems_getThermostatEnabled();
|
||||
bool ems_getBoilerEnabled();
|
||||
bool ems_getSolarModuleEnabled();
|
||||
bool ems_getHeatPumpEnabled();
|
||||
bool ems_getBusConnected();
|
||||
_EMS_SYS_LOGGING ems_getLogging();
|
||||
bool ems_getEmsRefreshed();
|
||||
uint8_t ems_getThermostatModel();
|
||||
uint8_t ems_getSolarModuleModel();
|
||||
void ems_discoverModels();
|
||||
bool ems_getTxCapable();
|
||||
uint32_t ems_getPollFrequency();
|
||||
@@ -342,12 +448,12 @@ uint8_t _crcCalculator(uint8_t * data, uint8_t len);
|
||||
void _processType(_EMS_RxTelegram * EMS_RxTelegram);
|
||||
void _debugPrintPackage(const char * prefix, _EMS_RxTelegram * EMS_RxTelegram, const char * color);
|
||||
void _ems_clearTxData();
|
||||
int _ems_findBoilerModel(uint8_t model_id);
|
||||
bool _ems_setModel(uint8_t model_id);
|
||||
void _removeTxQueue();
|
||||
|
||||
// global so can referenced in other classes
|
||||
extern _EMS_Sys_Status EMS_Sys_Status;
|
||||
extern _EMS_Boiler EMS_Boiler;
|
||||
extern _EMS_Thermostat EMS_Thermostat;
|
||||
extern _EMS_Other EMS_Other;
|
||||
extern _EMS_Sys_Status EMS_Sys_Status;
|
||||
extern _EMS_Boiler EMS_Boiler;
|
||||
extern _EMS_Thermostat EMS_Thermostat;
|
||||
extern _EMS_SolarModule EMS_SolarModule;
|
||||
extern _EMS_HeatPump EMS_HeatPump;
|
||||
extern _EMS_Other EMS_Other;
|
||||
|
||||
@@ -41,14 +41,17 @@
|
||||
#define EMS_OFFSET_UBASetPoints_flowtemp 0 // flow temp
|
||||
|
||||
// Other
|
||||
#define EMS_TYPE_SM10Monitor 0x97 // SM10Monitor
|
||||
#define EMS_TYPE_SM100Monitor 0x0262 // SM100Monitor
|
||||
#define EMS_TYPE_SM100Status 0x0264 // SM100Status
|
||||
#define EMS_TYPE_SM100Status2 0x026A // SM100Status2
|
||||
#define EMS_TYPE_SM100Energy 0x028E // SM100Energy
|
||||
#define EMS_TYPE_HPMonitor1 0xE3 // HeatPump Monitor 1
|
||||
#define EMS_TYPE_HPMonitor2 0xE5 // HeatPump Monitor 2
|
||||
#define EMS_TYPE_ISM1StatusMessage 0x0003 // Solar Module Junkers ISM1 Status
|
||||
#define EMS_TYPE_SM10Monitor 0x97 // SM10Monitor
|
||||
#define EMS_TYPE_SM100Monitor 0x0262 // SM100Monitor
|
||||
#define EMS_TYPE_SM100Status 0x0264 // SM100Status
|
||||
#define EMS_TYPE_SM100Status2 0x026A // SM100Status2
|
||||
#define EMS_TYPE_SM100Energy 0x028E // SM100Energy
|
||||
#define EMS_TYPE_HPMonitor1 0xE3 // HeatPump Monitor 1
|
||||
#define EMS_TYPE_HPMonitor2 0xE5 // HeatPump Monitor 2
|
||||
|
||||
#define EMS_TYPE_ISM1StatusMessage 0x0003 // Solar Module Junkers ISM1 Status
|
||||
#define EMS_TYPE_ISM1Set 0x0001 // for setting values of the solar module like max boiler temp
|
||||
#define EMS_OFFSET_ISM1Set_MaxBoilerTemp 6 // position of max boiler temp e.g. 50 in the following example: 90 30 FF 06 00 01 50 (CRC=2C)
|
||||
|
||||
/*
|
||||
* Thermostats...
|
||||
@@ -63,7 +66,7 @@
|
||||
#define EMS_TYPE_RC10Set 0xB0 // for setting values like temp and mode
|
||||
#define EMS_OFFSET_RC10Set_temp 4 // position of thermostat setpoint temperature
|
||||
#define EMS_OFFSET_RC10StatusMessage_setpoint 1 // setpoint temp
|
||||
#define EMS_OFFSET_RC10StatusMessage_curr 3 // current temp
|
||||
#define EMS_OFFSET_RC10StatusMessage_curr 2 // current temp
|
||||
|
||||
// RC20 specific
|
||||
#define EMS_TYPE_RC20StatusMessage 0x91 // is an automatic thermostat broadcast giving us temps
|
||||
@@ -109,6 +112,7 @@
|
||||
#define EMS_OFFSET_RCPLUSStatusMessage_setpoint 3 // setpoint temp
|
||||
#define EMS_OFFSET_RCPLUSStatusMessage_curr 0 // current temp
|
||||
#define EMS_OFFSET_RCPLUSGet_mode_day 8 // day/night mode
|
||||
#define EMS_OFFSET_RCPLUSStatusMessage_mode 0x0A // thermostat mode (auto, manual)
|
||||
|
||||
// Junkers FR10, FW100 (EMS Plus)
|
||||
#define EMS_TYPE_JunkersStatusMessage 0x6F // is an automatic thermostat broadcast giving us temps
|
||||
@@ -118,16 +122,19 @@
|
||||
|
||||
// Known EMS types
|
||||
typedef enum {
|
||||
EMS_MODEL_NONE,
|
||||
EMS_MODEL_ALL, // common for all devices
|
||||
EMS_MODEL_NONE, // unset
|
||||
EMS_MODEL_ALL, // common for all devices
|
||||
|
||||
// generic ID for the boiler
|
||||
// heatpump
|
||||
EMS_MODEL_HP,
|
||||
|
||||
// solar module
|
||||
EMS_MODEL_SM,
|
||||
|
||||
// boiler
|
||||
EMS_MODEL_UBA,
|
||||
|
||||
// generic ID for all the other weird devices
|
||||
EMS_MODEL_OTHER,
|
||||
|
||||
// and finally the thermostats
|
||||
// and the thermostats
|
||||
EMS_MODEL_ES73,
|
||||
EMS_MODEL_RC10,
|
||||
EMS_MODEL_RC20,
|
||||
@@ -135,7 +142,7 @@ typedef enum {
|
||||
EMS_MODEL_RC30,
|
||||
EMS_MODEL_RC35,
|
||||
EMS_MODEL_EASY,
|
||||
EMS_MODEL_RC310,
|
||||
EMS_MODEL_RC300,
|
||||
EMS_MODEL_CW100,
|
||||
EMS_MODEL_1010,
|
||||
EMS_MODEL_OT,
|
||||
@@ -147,56 +154,71 @@ typedef enum {
|
||||
|
||||
} _EMS_MODEL_ID;
|
||||
|
||||
// EMS types for known devices. This list will be extended when new devices are recognized.
|
||||
// EMS types for known boilers. This list will be extended when new devices are recognized.
|
||||
// The device_id is always 0x08
|
||||
// format is MODEL_ID, PRODUCT ID, DESCRIPTION
|
||||
// format is PRODUCT ID, DESCRIPTION
|
||||
const _Boiler_Type Boiler_Types[] = {
|
||||
|
||||
{EMS_MODEL_UBA, 72, "MC10 Module"},
|
||||
{EMS_MODEL_UBA, 123, "Buderus GB172/Nefit Trendline/Junkers Cerapur"},
|
||||
{EMS_MODEL_UBA, 115, "Nefit Topline Compact/Buderus GB162"},
|
||||
{EMS_MODEL_UBA, 203, "Buderus Logamax U122/Junkers Cerapur"},
|
||||
{EMS_MODEL_UBA, 208, "Buderus Logamax plus/GB192"},
|
||||
{EMS_MODEL_UBA, 64, "Sieger BK15/Nefit Smartline/Buderus GB152"},
|
||||
{EMS_MODEL_UBA, EMS_PRODUCTID_HEATRONICS, "Bosch Condens 2500/Junkers Heatronics3"}, // Junkers
|
||||
{EMS_MODEL_UBA, 122, "Nefit Proline"},
|
||||
{EMS_MODEL_UBA, 172, "Nefit Enviline"}
|
||||
|
||||
};
|
||||
|
||||
// Other EMS devices which are not considered boilers or thermostats
|
||||
const _Other_Type Other_Types[] = {
|
||||
|
||||
{EMS_MODEL_OTHER, 69, 0x21, "MM10 Mixer Module"},
|
||||
{EMS_MODEL_OTHER, 71, 0x11, "WM10 Switch Module"},
|
||||
{EMS_MODEL_OTHER, 160, 0x20, "MM100 Mixing Module"},
|
||||
{EMS_MODEL_OTHER, 160, 0x21, "MM100 Mixing Module"},
|
||||
{EMS_MODEL_OTHER, 159, 0x21, "MM50 Mixing Module"},
|
||||
{EMS_MODEL_OTHER, 68, 0x09, "BC10/RFM20 Receiver"},
|
||||
{EMS_MODEL_OTHER, 190, 0x09, "BC10 Base Controller"},
|
||||
{EMS_MODEL_OTHER, 114, 0x09, "BC10 Base Controller"},
|
||||
{EMS_MODEL_OTHER, 125, 0x09, "BC25 Base Controller"},
|
||||
{EMS_MODEL_OTHER, 152, 0x09, "Junkers Controller"},
|
||||
{EMS_MODEL_OTHER, 205, 0x02, "Nefit Moduline Easy Connect"},
|
||||
{EMS_MODEL_OTHER, 73, EMS_ID_SM, "SM10 Solar Module"},
|
||||
{EMS_MODEL_OTHER, 163, EMS_ID_SM, "SM100 Solar Module"},
|
||||
{EMS_MODEL_OTHER, 171, 0x02, "EMS-OT OpenTherm converter"},
|
||||
{EMS_MODEL_OTHER, 252, EMS_ID_HP, "HeatPump Module"}, // warning, fake product id!
|
||||
{EMS_MODEL_OTHER, 101, 0x30, "Junkers ISM1 Solar Controller"},
|
||||
{EMS_MODEL_OTHER, 189, EMS_ID_GATEWAY, "Web Gateway KM200"}
|
||||
{72, "MC10 Module"},
|
||||
{123, "Buderus GB172/Nefit Trendline/Junkers Cerapur"},
|
||||
{115, "Nefit Topline Compact/Buderus GB162"},
|
||||
{203, "Buderus Logamax U122/Junkers Cerapur"},
|
||||
{208, "Buderus Logamax plus/GB192"},
|
||||
{64, "Sieger BK15/Nefit Smartline/Buderus GB152"},
|
||||
{EMS_PRODUCTID_HEATRONICS, "Bosch Condens 2500/Junkers Heatronics3"},
|
||||
{122, "Nefit Proline"},
|
||||
{172, "Nefit Enviline"}
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* Known Solar Module types
|
||||
* format is PRODUCT ID, DEVICE ID, DESCRIPTION
|
||||
*/
|
||||
const _SolarModule_Type SolarModule_Types[] = {
|
||||
|
||||
{EMS_PRODUCTID_SM10, EMS_ID_SM, "SM10 Solar Module"},
|
||||
{EMS_PRODUCTID_SM100, EMS_ID_SM, "SM100 Solar Module"},
|
||||
{EMS_PRODUCTID_ISM1, EMS_ID_SM, "Junkers ISM1 Solar Module"}
|
||||
|
||||
};
|
||||
|
||||
// Other EMS devices which are not considered boilers, thermostats or solar modules
|
||||
// format is PRODUCT ID, DEVICE ID, DESCRIPTION
|
||||
const _Other_Type Other_Types[] = {
|
||||
|
||||
{69, 0x21, "MM10 Mixer Module"},
|
||||
{71, 0x11, "WM10 Switch Module"},
|
||||
{160, 0x20, "MM100 Mixing Module"},
|
||||
{160, 0x21, "MM100 Mixing Module"},
|
||||
{159, 0x21, "MM50 Mixing Module"},
|
||||
{68, 0x09, "BC10/RFM20 Receiver"},
|
||||
{190, 0x09, "BC10 Base Controller"},
|
||||
{114, 0x09, "BC10 Base Controller"},
|
||||
{125, 0x09, "BC25 Base Controller"},
|
||||
{152, 0x09, "Junkers Controller"},
|
||||
{205, 0x02, "Nefit Moduline Easy Connect"},
|
||||
{206, 0x02, "Bosch Easy Connect"},
|
||||
{171, 0x02, "EMS-OT OpenTherm converter"},
|
||||
{252, EMS_ID_HP, "HeatPump Module"},
|
||||
{189, EMS_ID_GATEWAY, "Web Gateway KM200"}
|
||||
|
||||
};
|
||||
|
||||
// heatpump
|
||||
// format is PRODUCT ID, DEVICE ID, DESCRIPTION
|
||||
const _HeatPump_Type HeatPump_Types[] = {{252, EMS_ID_HP, "HeatPump Module"}};
|
||||
|
||||
/*
|
||||
* Known thermostat types and their capabilities
|
||||
* format is MODEL_ID, PRODUCT ID, DEVICE ID, DESCRIPTION
|
||||
*/
|
||||
const _Thermostat_Type Thermostat_Types[] = {
|
||||
|
||||
// Easy devices - not currently supporting write operations
|
||||
{EMS_MODEL_EASY, 202, 0x18, "TC100/Nefit Easy", EMS_THERMOSTAT_WRITE_NO},
|
||||
{EMS_MODEL_EASY, 202, 0x18, "Logamatic TC100/Nefit Moduline Easy", EMS_THERMOSTAT_WRITE_NO},
|
||||
{EMS_MODEL_EASY, 203, 0x18, "Bosch EasyControl CT200", EMS_THERMOSTAT_WRITE_NO},
|
||||
{EMS_MODEL_EASY, 206, 0x02, "Bosch Easy", EMS_THERMOSTAT_WRITE_NO},
|
||||
{EMS_MODEL_CW100, 157, 0x18, "CW100", EMS_THERMOSTAT_WRITE_NO},
|
||||
{EMS_MODEL_CW100, 157, 0x18, "Bosch CW100", EMS_THERMOSTAT_WRITE_NO},
|
||||
|
||||
// Buderus/Nefit
|
||||
{EMS_MODEL_RC10, 79, 0x17, "RC10/Nefit Moduline 100", EMS_THERMOSTAT_WRITE_YES},
|
||||
@@ -204,7 +226,7 @@ const _Thermostat_Type Thermostat_Types[] = {
|
||||
{EMS_MODEL_RC20F, 93, 0x18, "RC20F", EMS_THERMOSTAT_WRITE_YES},
|
||||
{EMS_MODEL_RC30, 78, 0x10, "RC30/Nefit Moduline 400", EMS_THERMOSTAT_WRITE_YES},
|
||||
{EMS_MODEL_RC35, 86, 0x10, "RC35", EMS_THERMOSTAT_WRITE_YES},
|
||||
{EMS_MODEL_RC310, 158, 0x10, "RC3x0/Nefit Moduline 1010H", EMS_THERMOSTAT_WRITE_NO},
|
||||
{EMS_MODEL_RC300, 158, 0x10, "RC300/RC310/Nefit Moduline 3000", EMS_THERMOSTAT_WRITE_NO},
|
||||
{EMS_MODEL_1010, 165, 0x18, "Nefit Moduline 1010", EMS_THERMOSTAT_WRITE_NO},
|
||||
|
||||
// Sieger
|
||||
@@ -217,5 +239,4 @@ const _Thermostat_Type Thermostat_Types[] = {
|
||||
{EMS_MODEL_FR110, 108, 0x18, "Junkers FR110", EMS_THERMOSTAT_WRITE_NO},
|
||||
{EMS_MODEL_FW120, 192, 0x10, "Junkers FW120", EMS_THERMOSTAT_WRITE_NO}
|
||||
|
||||
|
||||
};
|
||||
|
||||
227
src/emsuart.cpp
227
src/emsuart.cpp
@@ -29,7 +29,7 @@ static void emsuart_rx_intr_handler(void * para) {
|
||||
EMS_Sys_Status.emsRxStatus = EMS_RX_STATUS_BUSY; // status set to busy
|
||||
length = 0;
|
||||
}
|
||||
|
||||
GPIO_H(RX_MARK_MASK);
|
||||
// fill IRQ buffer, by emptying Rx FIFO
|
||||
if (USIS(EMSUART_UART) & ((1 << UIFF) | (1 << UITO) | (1 << UIBD))) {
|
||||
while ((USS(EMSUART_UART) >> USRXC) & 0xFF) {
|
||||
@@ -39,20 +39,20 @@ static void emsuart_rx_intr_handler(void * para) {
|
||||
// clear Rx FIFO full and Rx FIFO timeout interrupts
|
||||
USIC(EMSUART_UART) = (1 << UIFF) | (1 << UITO);
|
||||
}
|
||||
GPIO_L(RX_MARK_MASK);
|
||||
|
||||
// BREAK detection = End of EMS data block
|
||||
if (USIS(EMSUART_UART) & ((1 << UIBD))) {
|
||||
ETS_UART_INTR_DISABLE(); // disable all interrupts and clear them
|
||||
|
||||
ETS_UART_INTR_DISABLE(); // disable all interrupts and clear them
|
||||
USIC(EMSUART_UART) = (1 << UIBD); // INT clear the BREAK detect interrupt
|
||||
|
||||
pEMSRxBuf->length = length;
|
||||
os_memcpy((void *)pEMSRxBuf->buffer, (void *)&uart_buffer, length); // copy data into transfer buffer, including the BRK 0x00 at the end
|
||||
EMS_Sys_Status.emsRxStatus = EMS_RX_STATUS_IDLE; // set the status flag stating BRK has been received and we can start a new package
|
||||
ETS_UART_INTR_ENABLE(); // re-enable UART interrupts
|
||||
|
||||
system_os_post(EMSUART_recvTaskPrio, 0, 0); // call emsuart_recvTask() at next opportunity
|
||||
|
||||
ETS_UART_INTR_ENABLE(); // re-enable UART interrupts
|
||||
RX_PULSE(EMSUART_BIT_TIME / 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,21 +63,22 @@ static void emsuart_rx_intr_handler(void * para) {
|
||||
*/
|
||||
static void ICACHE_FLASH_ATTR emsuart_recvTask(os_event_t * events) {
|
||||
_EMSRxBuf * pCurrent = pEMSRxBuf;
|
||||
uint8_t length = pCurrent->length; // number of bytes including the BRK at the end
|
||||
pEMSRxBuf = paEMSRxBuf[++emsRxBufIdx % EMS_MAXBUFFERS]; // next free EMS Receive buffer
|
||||
uint8_t length = pCurrent->length; // number of bytes including the BRK at the end
|
||||
pCurrent->length = 0;
|
||||
|
||||
// validate and transmit the EMS buffer, excluding the BRK
|
||||
if (length == 2) {
|
||||
// it's a poll or status code, single byte
|
||||
RX_PULSE(20);
|
||||
// it's a poll or status code, single byte and ok to send on
|
||||
ems_parseTelegram((uint8_t *)pCurrent->buffer, 1);
|
||||
} else if ((length > 4) && (pCurrent->buffer[length - 2] != 0x00)) {
|
||||
} else if ((length > 4) && (length <= EMS_MAXBUFFERSIZE + 1) && (pCurrent->buffer[length - 2] != 0x00)) {
|
||||
// ignore double BRK at the end, possibly from the Tx loopback
|
||||
// also telegrams with no data value
|
||||
RX_PULSE(40);
|
||||
ems_parseTelegram((uint8_t *)pCurrent->buffer, length - 1); // transmit EMS buffer, excluding the BRK
|
||||
}
|
||||
|
||||
memset(pCurrent->buffer, 0x00, EMS_MAXBUFFERSIZE); // wipe memory just to be safe
|
||||
|
||||
pEMSRxBuf = paEMSRxBuf[++emsRxBufIdx % EMS_MAXBUFFERS]; // next free EMS Receive buffer
|
||||
// memset(pCurrent->buffer, 0x00, EMS_MAXBUFFERSIZE); // wipe memory just to be safe
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -94,7 +95,7 @@ static inline void ICACHE_FLASH_ATTR emsuart_flush_fifos() {
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR emsuart_init() {
|
||||
ETS_UART_INTR_DISABLE();
|
||||
ETS_UART_INTR_ATTACH(NULL, NULL);
|
||||
ETS_UART_INTR_ATTACH(nullptr, nullptr);
|
||||
|
||||
// allocate and preset EMS Receive buffers
|
||||
for (int i = 0; i < EMS_MAXBUFFERS; i++) {
|
||||
@@ -117,11 +118,14 @@ void ICACHE_FLASH_ATTR emsuart_init() {
|
||||
|
||||
// conf1 params
|
||||
// UCTOE = RX TimeOut enable (default is 1)
|
||||
// UCTOT = RX TimeOut Threshold (7 bit) = want this when no more data after 2 characters (default is 2)
|
||||
// UCTOT = RX TimeOut Threshold (7 bit) = want this when no more data after 1 characters (default is 2)
|
||||
// UCFFT = RX FIFO Full Threshold (7 bit) = want this to be 31 for 32 bytes of buffer (default was 127)
|
||||
// see https://www.espressif.com/sites/default/files/documentation/esp8266-technical_reference_en.pdf
|
||||
USC1(EMSUART_UART) = 0; // reset config first
|
||||
USC1(EMSUART_UART) = (EMS_MAX_TELEGRAM_LENGTH << UCFFT) | (0x02 << UCTOT) | (1 << UCTOE); // enable interupts
|
||||
//
|
||||
// change: we set UCFFT to 1 to get an immediate indicator about incoming trafffic.
|
||||
// Otherwise, we're only noticed by UCTOT or RxBRK!
|
||||
USC1(EMSUART_UART) = 0; // reset config first
|
||||
USC1(EMSUART_UART) = (0x01 << UCFFT) | (0x01 << UCTOT) | (1 << UCTOE); // enable interupts
|
||||
|
||||
// set interrupts for triggers
|
||||
USIC(EMSUART_UART) = 0xFFFF; // clear all interupts
|
||||
@@ -138,9 +142,9 @@ void ICACHE_FLASH_ATTR emsuart_init() {
|
||||
system_set_os_print(0);
|
||||
|
||||
// swap Rx and Tx pins to use GPIO13 (D7) and GPIO15 (D8) respectively
|
||||
system_uart_swap();
|
||||
//system_uart_swap();
|
||||
|
||||
ETS_UART_INTR_ATTACH(emsuart_rx_intr_handler, NULL);
|
||||
ETS_UART_INTR_ATTACH(emsuart_rx_intr_handler, nullptr);
|
||||
ETS_UART_INTR_ENABLE();
|
||||
}
|
||||
|
||||
@@ -160,66 +164,155 @@ void ICACHE_FLASH_ATTR emsuart_start() {
|
||||
}
|
||||
|
||||
/*
|
||||
* set loopback mode and clear Tx/Rx FIFO
|
||||
* Send a BRK signal
|
||||
* Which is a 11-bit set of zero's (11 cycles)
|
||||
*/
|
||||
static inline void ICACHE_FLASH_ATTR emsuart_loopback(bool enable) {
|
||||
if (enable)
|
||||
USC0(EMSUART_UART) |= (1 << UCLBE); // enable loopback
|
||||
else
|
||||
USC0(EMSUART_UART) &= ~(1 << UCLBE); // disable loopback
|
||||
void ICACHE_FLASH_ATTR emsuart_tx_brk() {
|
||||
uint32_t tmp;
|
||||
|
||||
// must make sure Tx FIFO is empty
|
||||
while (((USS(EMSUART_UART) >> USTXC) & 0xFF) != 0)
|
||||
;
|
||||
|
||||
tmp = ((1 << UCRXRST) | (1 << UCTXRST)); // bit mask
|
||||
USC0(EMSUART_UART) |= (tmp); // set bits
|
||||
USC0(EMSUART_UART) &= ~(tmp); // clear bits
|
||||
|
||||
// To create a 11-bit <BRK> we set TXD_BRK bit so the break signal will
|
||||
// automatically be sent when the tx fifo is empty
|
||||
tmp = (1 << UCBRK);
|
||||
GPIO_H(TX_MARK_MASK);
|
||||
USC0(EMSUART_UART) |= (tmp); // set bit
|
||||
|
||||
if (EMS_Sys_Status.emsTxMode <= 1) { // classic mode and ems+ (0, 1)
|
||||
delayMicroseconds(EMSUART_TX_BRK_WAIT);
|
||||
} else if (EMS_Sys_Status.emsTxMode == 3) { // junkers mode
|
||||
delayMicroseconds(EMSUART_TX_WAIT_BRK - EMSUART_TX_LAG); // 1144 (11 Bits)
|
||||
}
|
||||
|
||||
USC0(EMSUART_UART) &= ~(tmp); // clear bit
|
||||
GPIO_L(TX_MARK_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send to Tx, ending with a <BRK>
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
||||
if (len == 0)
|
||||
return;
|
||||
_EMS_TX_STATUS ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
||||
_EMS_TX_STATUS result = EMS_TX_STATUS_OK;
|
||||
if (len) {
|
||||
LA_PULSE(50);
|
||||
// temp code until we get mode 2 working without resets
|
||||
if (EMS_Sys_Status.emsTxMode == 0) { // classic mode logic
|
||||
for (uint8_t i = 0; i < len; i++) {
|
||||
TX_PULSE(EMSUART_BIT_TIME / 4);
|
||||
USF(EMSUART_UART) = buf[i];
|
||||
}
|
||||
emsuart_tx_brk(); // send <BRK>
|
||||
} else if (EMS_Sys_Status.emsTxMode == 1) { // With extra tx delay for EMS+
|
||||
for (uint8_t i = 0; i < len; i++) {
|
||||
TX_PULSE(EMSUART_BIT_TIME / 4);
|
||||
USF(EMSUART_UART) = buf[i];
|
||||
delayMicroseconds(EMSUART_TX_BRK_WAIT); // https://github.com/proddy/EMS-ESP/issues/23#
|
||||
}
|
||||
emsuart_tx_brk(); // send <BRK>
|
||||
} else if (EMS_Sys_Status.emsTxMode == 3) { // Junkers logic by @philrich
|
||||
for (uint8_t i = 0; i < len; i++) {
|
||||
TX_PULSE(EMSUART_BIT_TIME / 4);
|
||||
USF(EMSUART_UART) = buf[i];
|
||||
|
||||
/*
|
||||
* based on code from https://github.com/proddy/EMS-ESP/issues/103 by @susisstrolch
|
||||
* we emit the whole telegram, with Rx interrupt disabled, collecting busmaster response in FIFO.
|
||||
* after sending the last char we poll the Rx status until either
|
||||
* - size(Rx FIFO) == size(Tx-Telegram)
|
||||
* - <BRK> is detected
|
||||
* At end of receive we re-enable Rx-INT and send a Tx-BRK in loopback mode.
|
||||
*/
|
||||
ETS_UART_INTR_DISABLE(); // disable rx interrupt
|
||||
// just to be safe wait for tx fifo empty (needed?)
|
||||
while (((USS(EMSUART_UART) >> USTXC) & 0xff) != 0)
|
||||
;
|
||||
|
||||
// clear Rx status register
|
||||
USC0(EMSUART_UART) |= (1 << UCRXRST); // reset uart rx fifo
|
||||
emsuart_flush_fifos();
|
||||
// wait until bits are sent on wire
|
||||
delayMicroseconds(EMSUART_TX_WAIT_BYTE - EMSUART_TX_LAG + EMSUART_TX_WAIT_GAP);
|
||||
}
|
||||
emsuart_tx_brk(); // send <BRK>
|
||||
} else if (EMS_Sys_Status.emsTxMode == 2) {
|
||||
/*
|
||||
*
|
||||
* based on code from https://github.com/proddy/EMS-ESP/issues/103 by @susisstrolch
|
||||
* we emit the whole telegram, with Rx interrupt disabled, collecting busmaster response in FIFO.
|
||||
* after sending the last char we poll the Rx status until either
|
||||
* - size(Rx FIFO) == size(Tx-Telegram)
|
||||
* - <BRK> is detected
|
||||
* At end of receive we re-enable Rx-INT and send a Tx-BRK in loopback mode.
|
||||
*
|
||||
* EMS-Bus error handling
|
||||
* 1. Busmaster stops echoing on Tx w/o permission
|
||||
* 2. Busmaster cancel telegram by sending a BRK
|
||||
*
|
||||
* Case 1. is handled by a watchdog counter which is reset on each
|
||||
* Tx attempt. The timeout should be 20x EMSUART_BIT_TIME plus
|
||||
* some smart guess for processing time on targeted EMS device.
|
||||
* We set EMS_Sys_Status.emsTxStatus to EMS_TX_WTD_TIMEOUT and return
|
||||
*
|
||||
* Case 2. is handled via a BRK chk during transmission.
|
||||
* We set EMS_Sys_Status.emsTxStatus to EMS_TX_BRK_DETECT and return
|
||||
*
|
||||
*/
|
||||
|
||||
// throw out the telegram...
|
||||
for (uint8_t i = 0; i < len;) {
|
||||
USF(EMSUART_UART) = buf[i++]; // send each Tx byte
|
||||
// wait for echo from busmaster
|
||||
while ((((USS(EMSUART_UART) >> USRXC) & 0xFF) < i || (USIS(EMSUART_UART) & (1 << UIBD)))) {
|
||||
delayMicroseconds(EMSUART_BIT_TIME); // burn CPU cycles...
|
||||
// shorter busy poll...
|
||||
#define EMSUART_BUSY_WAIT (EMSUART_BIT_TIME / 8)
|
||||
#define EMS_TX_TO_COUNT ((20 + 10000 / EMSUART_BIT_TIME) * 8)
|
||||
uint16_t wdc = EMS_TX_TO_COUNT;
|
||||
|
||||
ETS_UART_INTR_DISABLE(); // disable rx interrupt
|
||||
|
||||
// clear Rx status register
|
||||
USC0(EMSUART_UART) |= (1 << UCRXRST); // reset uart rx fifo
|
||||
emsuart_flush_fifos();
|
||||
|
||||
// throw out the telegram...
|
||||
for (uint8_t i = 0; i < len && result == EMS_TX_STATUS_OK;) {
|
||||
GPIO_H(TX_MARK_MASK);
|
||||
|
||||
wdc = EMS_TX_TO_COUNT;
|
||||
volatile uint8_t _usrxc = (USS(EMSUART_UART) >> USRXC) & 0xFF;
|
||||
USF(EMSUART_UART) = buf[i++]; // send each Tx byte
|
||||
// wait for echo from busmaster
|
||||
GPIO_L(TX_MARK_MASK);
|
||||
|
||||
while (((USS(EMSUART_UART) >> USRXC) & 0xFF) == _usrxc) {
|
||||
delayMicroseconds(EMSUART_BUSY_WAIT); // burn CPU cycles...
|
||||
if (--wdc == 0) {
|
||||
EMS_Sys_Status.emsTxStatus = result = EMS_TX_WTD_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
if (USIR(EMSUART_UART) & (1 << UIBD)) {
|
||||
USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ
|
||||
EMS_Sys_Status.emsTxStatus = result = EMS_TX_BRK_DETECT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we got the whole telegram in the Rx buffer
|
||||
// on Rx-BRK (bus collision), we simply enable Rx and leave it
|
||||
// otherwise we send the final Tx-BRK in the loopback and re=enable Rx-INT.
|
||||
// worst case, we'll see an additional Rx-BRK...
|
||||
if (result != EMS_TX_STATUS_OK) {
|
||||
LA_PULSE(200); // mark Tx error
|
||||
} else {
|
||||
// neither bus collision nor timeout - send terminating BRK signal
|
||||
GPIO_H(TX_MARK_MASK);
|
||||
if (!(USIS(EMSUART_UART) & (1 << UIBD))) {
|
||||
// no bus collision - send terminating BRK signal
|
||||
USC0(EMSUART_UART) |= (1 << UCLBE) | (1 << UCBRK); // enable loopback & set <BRK>
|
||||
|
||||
// wait until BRK detected...
|
||||
while (!(USIR(EMSUART_UART) & (1 << UIBD))) {
|
||||
delayMicroseconds(EMSUART_BUSY_WAIT);
|
||||
}
|
||||
|
||||
USC0(EMSUART_UART) &= ~((1 << UCBRK) | (1 << UCLBE)); // disable loopback & clear <BRK>
|
||||
USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ
|
||||
}
|
||||
GPIO_L(TX_MARK_MASK);
|
||||
}
|
||||
ETS_UART_INTR_ENABLE(); // receive anything from FIFO...
|
||||
}
|
||||
}
|
||||
|
||||
// we got the whole telegram in the Rx buffer
|
||||
// on Rx-BRK (bus collision), we simply enable Rx and leave it
|
||||
// otherwise we send the final Tx-BRK in the loopback and re=enable Rx-INT.
|
||||
// worst case, we'll see an additional Rx-BRK...
|
||||
if (!(USIS(EMSUART_UART) & (1 << UIBD))) {
|
||||
// no bus collision - send terminating BRK signal
|
||||
emsuart_loopback(true);
|
||||
USC0(EMSUART_UART) |= (1 << UCBRK); // set <BRK>
|
||||
|
||||
// wait until BRK detected...
|
||||
while (!(USIS(EMSUART_UART) & (1 << UIBD))) {
|
||||
delayMicroseconds(EMSUART_BIT_TIME);
|
||||
}
|
||||
|
||||
USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear <BRK>
|
||||
|
||||
USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ
|
||||
emsuart_loopback(false); // disable loopback mode
|
||||
}
|
||||
|
||||
ETS_UART_INTR_ENABLE(); // receive anything from FIFO...
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -8,16 +8,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <ems.h>
|
||||
|
||||
#define EMSUART_UART 0 // UART 0
|
||||
#define EMSUART_CONFIG 0x1C // 8N1 (8 bits, no stop bits, 1 parity)
|
||||
#define EMSUART_BAUD 9600 // uart baud rate for the EMS circuit
|
||||
|
||||
#define EMS_MAXBUFFERS 10 // buffers for circular filling to avoid collisions
|
||||
#define EMS_MAXBUFFERSIZE 32 // max size of the buffer. packets are max 32 bytes to support EMS 1.0
|
||||
#define EMS_MAXBUFFERS 5 // buffers for circular filling to avoid collisions
|
||||
#define EMS_MAXBUFFERSIZE (EMS_MAX_TELEGRAM_LENGTH + 2) // max size of the buffer. EMS packets are max 32 bytes, plus extra 2 for BRKs
|
||||
|
||||
#define EMSUART_BIT_TIME 104 // bit time @9600 baud
|
||||
|
||||
#define EMSUART_TX_BRK_WAIT 2070 // the BRK from Boiler master is roughly 1.039ms, so accounting for hardware lag using around 2078 (for half-duplex) - 8 (lag)
|
||||
#define EMSUART_TX_WAIT_BYTE EMSUART_BIT_TIME * 10 // Time to send one Byte (8 Bits, 1 Start Bit, 1 Stop Bit)
|
||||
#define EMSUART_TX_WAIT_BRK EMSUART_BIT_TIME * 11 // Time to send a BRK Signal (11 Bit)
|
||||
#define EMSUART_TX_WAIT_GAP EMSUART_BIT_TIME * 7 // Gap between to Bytes
|
||||
#define EMSUART_TX_LAG 8
|
||||
|
||||
#define EMSUART_recvTaskPrio 1
|
||||
#define EMSUART_recvTaskQueueLen 64
|
||||
|
||||
@@ -29,5 +36,5 @@ typedef struct {
|
||||
void ICACHE_FLASH_ATTR emsuart_init();
|
||||
void ICACHE_FLASH_ATTR emsuart_stop();
|
||||
void ICACHE_FLASH_ATTR emsuart_start();
|
||||
void ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len);
|
||||
_EMS_TX_STATUS ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len);
|
||||
void ICACHE_FLASH_ATTR emsuart_tx_poll();
|
||||
|
||||
@@ -41,12 +41,13 @@
|
||||
#define THERMOSTAT_CIRCUITCALCTEMP "thermostat_circuitcalctemp" // RC35 specific
|
||||
|
||||
// MQTT for boiler
|
||||
#define TOPIC_BOILER_DATA "boiler_data" // for sending boiler values to MQTT
|
||||
#define TOPIC_BOILER_TAPWATER_ACTIVE "tapwater_active" // if hot tap water is running
|
||||
#define TOPIC_BOILER_HEATING_ACTIVE "heating_active" // if heating is on
|
||||
#define TOPIC_BOILER_WWACTIVATED "wwactivated" // for receiving MQTT message to change water on/off
|
||||
#define TOPIC_BOILER_CMD_WWTEMP "boiler_cmd_wwtemp" // for received boiler wwtemp changes via MQTT
|
||||
#define TOPIC_BOILER_CMD_COMFORT "boiler_cmd_comfort" // for received boiler ww comfort setting via MQTT
|
||||
#define TOPIC_BOILER_DATA "boiler_data" // for sending boiler values to MQTT
|
||||
#define TOPIC_BOILER_TAPWATER_ACTIVE "tapwater_active" // if hot tap water is running
|
||||
#define TOPIC_BOILER_HEATING_ACTIVE "heating_active" // if heating is on
|
||||
#define TOPIC_BOILER_WWACTIVATED "wwactivated" // for receiving MQTT message to change water on/off
|
||||
#define TOPIC_BOILER_CMD_WWTEMP "boiler_cmd_wwtemp" // for received boiler wwtemp changes via MQTT
|
||||
#define TOPIC_BOILER_CMD_COMFORT "boiler_cmd_comfort" // for received boiler ww comfort setting via MQTT
|
||||
#define TOPIC_BOILER_CMD_FLOWTEMP "boiler_cmd_flowtemp" // for received boiler flowtemp value via MQTT
|
||||
|
||||
// MQTT for SM10/SM100 Solar Module
|
||||
#define TOPIC_SM_DATA "sm_data" // topic name
|
||||
@@ -57,6 +58,7 @@
|
||||
#define SM_ENERGYLASTHOUR "energylasthour" // energy last hour
|
||||
#define SM_ENERGYTODAY "energytoday" // energy today
|
||||
#define SM_ENERGYTOTAL "energytotal" // energy total
|
||||
#define SM_PUMPWORKMIN "pumpWorkMin" // Total minutes
|
||||
|
||||
// MQTT for HP (HeatPump)
|
||||
#define TOPIC_HP_DATA "hp_data" // topic name
|
||||
@@ -83,10 +85,15 @@
|
||||
// can be enabled and disabled via the 'set led' command and pin set by 'set led_gpio'
|
||||
#define EMSESP_LED_GPIO LED_BUILTIN
|
||||
|
||||
#ifdef LOGICANALYZER
|
||||
#define EMSESP_DALLAS_GPIO D1
|
||||
#define EMSESP_DALLAS_PARASITE false
|
||||
#else
|
||||
// set this if using an external temperature sensor like a DS18B20
|
||||
// D5 is the default on a bbqkees board
|
||||
#define EMSESP_DALLAS_GPIO D5
|
||||
#define EMSESP_DALLAS_PARASITE false
|
||||
#endif
|
||||
|
||||
// By default the EMS bus will be scanned for known devices based on the product ids in ems_devices.h
|
||||
// You can override the Thermostat and Boiler types here
|
||||
|
||||
@@ -49,7 +49,10 @@ static const char * TEST_DATA[] = {
|
||||
"90 00 FF 00 00 6F 03 01 00 BE 00 BF", // test 44 - FR10
|
||||
"08 00 E3 00 01 00 01 00 00 00 00 00 00 00 00 00 DF 00 64 55", // test 45 - heatpump Enviline
|
||||
"08 00 E5 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0A", // test 46 - heatpump Enviline
|
||||
"38 10 FF 00 03 2B 00 C7 07 C3 01" // test 47 - heatpump Enviline
|
||||
"38 10 FF 00 03 2B 00 C7 07 C3 01", // test 47 - heatpump Enviline
|
||||
"08 0B 19 00 00 F7 80 00 80 00 00 00 00 00 03 58 97 0C 7B 1F 00 00 00 06 C4 DF 02 64 48 80 00", // test 48 - outdoor temp check
|
||||
"88 00 19 00 00 DC 80 00 80 00 FF FF 00 00 00 21 9A 06 E1 7C 00 00 00 06 C2 13 00 1E 90 80 00", // test 49 - check max length
|
||||
"30 00 FF 00 02 8E 00 00 41 82 00 00 28 36 00 00 82 21" // test 50 - SM100
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
#pragma once
|
||||
|
||||
#define APP_NAME "EMS-ESP"
|
||||
#define APP_VERSION "1.8.0"
|
||||
#define APP_VERSION "1.8.1"
|
||||
#define APP_HOSTNAME "ems-esp"
|
||||
|
||||
Reference in New Issue
Block a user