diff --git a/Config.cpp b/Config.cpp index 8d90f35..d84ac44 100644 --- a/Config.cpp +++ b/Config.cpp @@ -109,8 +109,8 @@ void Config::initialize() { for (int i = 0; i < 4; i++) { Config::setFloat(Config::THERMOMETER_CAL[i], 1.0); } - Config::setBool(Config::THERMOMETER_DEBUG, true); - Config::setBool(Config::THERMOMETER_INFO, true); + Config::setBool(Config::THERMOMETER_DEBUG, false); + Config::setBool(Config::THERMOMETER_INFO, false); Config::setUChar(Config::METERBUSCLIENT_ADDRESS, 0); diff --git a/Resources.h b/Resources.h index 696c23d..1a2b0bd 100644 --- a/Resources.h +++ b/Resources.h @@ -62,6 +62,10 @@ const uint8_t THERMVALUES_HELP_KEY = 46; const uint8_t THERMCALIBRATE_HELP_KEY = 47; const uint8_t CALIBRATION_ZEOR_MODE_HINT_KEY = 48; const uint8_t MBC_CONFIG_HELP_KEY = 49; +const uint8_t MBC_INVALID_FRAME_KEY = 50; +const uint8_t MBC_NO_VALID_FRAME_KEY = 51; +const uint8_t MBC_INVALID_CHECKSUM_KEY = 52; +const uint8_t MBC_NOT_FOR_ME_KEY = 53; const String TEXT_RESOURCES[] = { @@ -115,6 +119,10 @@ const String TEXT_RESOURCES[] = { "Thermometer calibration operations", "No, no, we are in calibration zero mode, so directly switch to state 20", "MeterBus Client Configuration", + "Invalid frame", + "No valid frame available", + "Invalid checksum", + "Not for me but for ", }; diff --git a/ThermometerPro.cpp b/ThermometerPro.cpp index 6c2a384..c837120 100644 --- a/ThermometerPro.cpp +++ b/ThermometerPro.cpp @@ -5,33 +5,31 @@ #include "thermometer.h" #include "Config.h" #include "spi.h" +// #include "meterBusClient.h" -#define ENABLE_CONFIGURATION_INVALID_CMD 1 - static CmdServer cmdServer(&Serial); -#ifdef ENABLE_CONFIGURATION_INVALID_CMD - static ConfigInvalidateCmd configInvalidateCmd; -#endif +// static ConfigInvalidateCmd configInvalidateCmd; static Uptime uptime; static Thermometer thermometer; - +// static MeterBusClient meterBusClient; void setup() { Serial.begin(9600); + // Config::initialize(); + delay(5000); + Serial.println("Hello world!"); - Config::initialize(); spiInit(); cmdServer.begin(); -#ifdef ENABLE_CONFIGURATION_INVALID_CMD - configInvalidateCmd.registerYourself(&cmdServer); -#endif + //configInvalidateCmd.registerYourself(&cmdServer); uptime.begin(&cmdServer); thermometer.begin(&cmdServer); +// meterBusClient.begin(&cmdServer); } @@ -39,4 +37,5 @@ void loop() { cmdServer.exec(); uptime.exec(); thermometer.exec(); +// meterBusClient.exec(); } diff --git a/meterBusClient.cpp b/meterBusClient.cpp index c8530ff..b082184 100644 --- a/meterBusClient.cpp +++ b/meterBusClient.cpp @@ -5,6 +5,9 @@ * Author: wn */ + +#if 0 + #include "meterBusClient.h" @@ -19,6 +22,7 @@ void MeterBusClient::begin(CmdServer *cmdServer) { setAddress(Config::getUChar(Config::METERBUSCLIENT_ADDRESS)); + } void MeterBusClient::setAddress(unsigned char a) { @@ -44,7 +48,7 @@ unsigned char MeterBusClient::getAddress() { * * Control Frame: * Start 68h - * Length + * Length = 3 * Length * Start 68h * C-Field @@ -74,24 +78,170 @@ unsigned char MeterBusClient::getAddress() { */ -void MeterBusClient::exec() { - static uint8_t state = 0; - bool done = false; - - if (Serial3.available()) { - int chi; - while ((chi = Serial3.read()) != -1) { - char ch = (char) chi; - switch (state) { - case 0: - break; - } - - if (done) { - } - } +bool isChecksumValid(MeterBusFrame frame) { + unsigned char ctrlsum = frame.aField + frame.cField + frame.ciField; + for (int i = 0; i < (frame.length - 3); i++) { + ctrlsum += frame.userData[i]; } + return (ctrlsum == frame.checksum); +} +void MeterBusClient::handleFrame() { + if (m_frame.aField != getAddress()) { + Serial.print(getResource(MBC_NOT_FOR_ME_KEY)); Serial.print((int)m_frame.aField, 16); Serial.println(); + } else if (! isChecksumValid(m_frame)) { + Serial.println(getResource(MBC_INVALID_CHECKSUM_KEY)); + } else { + // handle the frame + Serial.print("s: "); Serial.println(m_frame.startDelimiter, 16); + Serial.print("l: "); Serial.println(m_frame.length, 16); + Serial.print("c: "); Serial.println(m_frame.cField, 16); + Serial.print("a: "); Serial.println(m_frame.ciField, 16); + } } +typedef enum { + STATE_START, STATE_IDLE, STATE_SHORT_FRAME, STATE_LONG_CTRL_FRAME, STATE_HANDLE, STATE_INVALID, STATE_FOREIGN, STATE_DONE +} e_meterBusClientState; + +typedef enum { + SUBSTATE_LENGTH, SUBSTATE_LENGTH_REPEAT, SUBSTATE_START_REPEAT, SUBSTATE_C_FIELD, SUBSTATE_A_FIELD, SUBSTATE_CI_FIELD, + SUBSTATE_USERDATA, SUBSTATE_CHECKSUM, SUBSTATE_STOP +} e_meterBusClientSubState; + + +void MeterBusClient::exec() { + static e_meterBusClientState state = STATE_IDLE; + static e_meterBusClientSubState subState = SUBSTATE_LENGTH; + bool done = false; + + int chi = Serial3.read(); + char ch = (char) chi; + + switch (state) { + case STATE_START: + m_frame.startDelimiter = 0; + m_frame.length = 0; + m_frame.cField = 0; + m_frame.aField = 0; + m_frame.ciField = 0; + memset(m_frame.userData, 0, sizeof(m_frame.userData)); + m_frame.valid = false; + state = STATE_IDLE; + break; + + case STATE_IDLE: + if (chi != -1) { + if (ch == 0x10) { + m_frame.startDelimiter = 0x10; + state = STATE_SHORT_FRAME; + subState = SUBSTATE_C_FIELD; + } else if (ch == 0x68) { + m_frame.startDelimiter = 0x68; + state = STATE_LONG_CTRL_FRAME; + subState = SUBSTATE_LENGTH; + } else { + state = STATE_INVALID; + } + } + break; + + case STATE_SHORT_FRAME: + if (chi != -1) { + if (subState == SUBSTATE_C_FIELD) { + m_frame.cField = ch; + subState = SUBSTATE_A_FIELD; + } else if (subState == SUBSTATE_A_FIELD) { + m_frame.aField = ch; + subState = SUBSTATE_CHECKSUM; + } else if (subState == SUBSTATE_STOP) { + if (ch == 0x16) { + m_frame.valid = true; + state = STATE_HANDLE; + } else { + state = STATE_INVALID; + } + } + } + break; + + case STATE_LONG_CTRL_FRAME: + if (chi != -1) { + if (subState == SUBSTATE_LENGTH) { + m_frame.length = ch; + if (m_frame.length < 3) { + state = STATE_INVALID; + } else { + subState = SUBSTATE_LENGTH_REPEAT; + } + } else if (subState == SUBSTATE_LENGTH_REPEAT) { + if (ch == m_frame.length) { + subState = SUBSTATE_START_REPEAT; + } else { + state = STATE_INVALID; + } + } else if (subState == SUBSTATE_START_REPEAT) { + if (ch == 0x68) { + subState = SUBSTATE_C_FIELD; + } else { + state = STATE_INVALID; + } + } else if (subState == SUBSTATE_C_FIELD) { + m_frame.cField = ch; + subState = SUBSTATE_A_FIELD; + } else if (subState == SUBSTATE_A_FIELD) { + m_frame.aField = ch; + subState = SUBSTATE_CI_FIELD; + } else if (subState == SUBSTATE_CI_FIELD) { + m_frame.ciField = ch; + if (m_frame.length == 3) { + subState = SUBSTATE_CHECKSUM; + } else { + subState = SUBSTATE_USERDATA; + } + } else if (subState == SUBSTATE_USERDATA) { + // count and collect + // then: subState = SUBSTATE_CHECKSUM + } else if (subState == SUBSTATE_CHECKSUM) { + m_frame.checksum = ch; + subState = SUBSTATE_STOP; + } else if (subState == SUBSTATE_STOP) { + if (ch == 0x16) { + m_frame.valid = true; + state = STATE_HANDLE; + } else { + state = STATE_INVALID; + } + } + } + break; + + case STATE_INVALID: + Serial.println(getResource(MBC_INVALID_FRAME_KEY)); + state = STATE_START; + break; + + case STATE_HANDLE: + if (m_frame.valid) { + handleFrame(); + } else { + Serial.println(getResource(MBC_NO_VALID_FRAME_KEY)); + } + state = STATE_DONE; + break; + + case STATE_FOREIGN: + // not for me message + state = STATE_START; + break; + + case STATE_DONE: + // may be another useful message + state = STATE_START; + break; + } +} + +#endif + diff --git a/meterBusClient.h b/meterBusClient.h index 18209fa..aa614ec 100644 --- a/meterBusClient.h +++ b/meterBusClient.h @@ -9,6 +9,8 @@ #define METERBUSCLIENT_H_ +#if 0 + #include "cmd.h" #include "Config.h" #include "Resources.h" @@ -29,6 +31,38 @@ private: +struct MeterBusFrame { + /* + * Short Frame: + * Start 10h + * C-Field + * A-Field + * Check-Sum + * Stop 16h + * + * Long Frame: + * Start 68h + * Length + * Length + * Start 68h + * C-Field + * A-Field + * CI-Field + * User-Data + * Check-Sum + * Stop 16h + * + */ + unsigned char startDelimiter; + unsigned char length; + unsigned char cField; + unsigned char aField; + unsigned char ciField; + unsigned char userData[255]; + unsigned char checksum; + bool valid; +}; + class MeterBusClient { public: @@ -40,7 +74,11 @@ private: unsigned char m_address; void setAddress(unsigned char address); unsigned char getAddress(); + void handleFrame(); + MeterBusFrame m_frame; }; +#endif + #endif /* METERBUSCLIENT_H_ */