From 13d19d4e15b4508966fca36d90ff9114812e29b7 Mon Sep 17 00:00:00 2001 From: hg Date: Sun, 9 Mar 2014 00:25:48 +0100 Subject: [PATCH] meterbusclient is working, SND_NKE will be answered --- Config.cpp | 2 + Config.h | 3 ++ Resources.cpp | 13 +++++ Resources.h | 14 ++++- ThermometerPro.cpp | 2 +- fatal.cpp | 3 +- meterBusClient.cpp | 109 +++++++++++++++++++++++++++++---------- meterBusClient.h | 19 ++++++- meterBusClientFrames.cpp | 23 +++++++++ 9 files changed, 158 insertions(+), 30 deletions(-) create mode 100644 meterBusClientFrames.cpp diff --git a/Config.cpp b/Config.cpp index 0bacb44..abe5be9 100644 --- a/Config.cpp +++ b/Config.cpp @@ -114,6 +114,8 @@ void Config::initialize() { setUChar(METERBUSCLIENT_ADDRESS, 0); + setBool(METERBUSCLIENT_DEBUG, false); + setBool(METERBUSCLIENT_INFO, false); setMagic(); } diff --git a/Config.h b/Config.h index 50a6344..e07c3d1 100644 --- a/Config.h +++ b/Config.h @@ -55,6 +55,9 @@ namespace Config { const int THERMOMETER_DEBUG = 28; // 1 const int THERMOMETER_INFO = 29; // 1 const int METERBUSCLIENT_ADDRESS = 30; // 1 + const int METERBUSCLIENT_DEBUG = 31; // 1 + const int METERBUSCLIENT_INFO = 32; // 1 + bool getBool(int pos); diff --git a/Resources.cpp b/Resources.cpp index efd336e..73dd304 100644 --- a/Resources.cpp +++ b/Resources.cpp @@ -67,6 +67,19 @@ const String TEXT_RESOURCES[] = { "No valid frame available", "Invalid checksum", "Not for me but for ", + "Unhandled frame", + "s: ", + "l: ", + "c: ", + "a: ", + "ci: ", + "u: ", + " ", + "frames: ", + "my frames: ", + "invalid frames: ", + "invalid checksum: ", + "mbus address: ", }; diff --git a/Resources.h b/Resources.h index 1478031..7f40f94 100644 --- a/Resources.h +++ b/Resources.h @@ -66,7 +66,19 @@ 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 uint8_t MBC_UNHANDLED_FRAME_KEY = 54; +const uint8_t MBC_START_DELIMITER_KEY = 55; +const uint8_t MBC_LENGTH_KEY = 56; +const uint8_t MBC_CFIELD_KEY = 57; +const uint8_t MBC_ADDRESS_KEY = 58; +const uint8_t MBC_CIFIELD_KEY = 59; +const uint8_t MBC_USERDATA_KEY = 60; +const uint8_t SPACE_KEY = 61; +const uint8_t MBC_FRAMES_KEY = 62; +const uint8_t MBC_MYFRAMES_KEY = 63; +const uint8_t MBC_INVALID_FRAMES_KEY = 64; +const uint8_t MBC_INVALID_CHECKSUM_CNT_KEY = 65; +const uint8_t MBC_ADDRESS_LONG_KEY = 66; const String& getResource(uint8_t key); diff --git a/ThermometerPro.cpp b/ThermometerPro.cpp index 3c01146..5bf8866 100644 --- a/ThermometerPro.cpp +++ b/ThermometerPro.cpp @@ -27,7 +27,7 @@ void setup() { configInvalidateCmd.registerYourself(&cmdServer); uptime.begin(&cmdServer); thermometer.begin(&cmdServer); - meterBusClient.begin(&cmdServer); + meterBusClient.begin(&cmdServer, &thermometer); } diff --git a/fatal.cpp b/fatal.cpp index 6b8a122..1fca800 100644 --- a/fatal.cpp +++ b/fatal.cpp @@ -1,10 +1,11 @@ -#include #include"fatal.h" +#include void fatal(uint8_t code) { // cli(); // do something with the code and somehow show that there is a problem + Serial.print("Fatal: "); Serial.println(code); while (1); } diff --git a/meterBusClient.cpp b/meterBusClient.cpp index c73b539..4dda8b7 100644 --- a/meterBusClient.cpp +++ b/meterBusClient.cpp @@ -10,6 +10,8 @@ #include "meterBusClient.h" +const bool MBC_COMPILE_TIME_DEBUG = false; + String MeterBusClientConfig::exec(String params) { String res = "done"; @@ -24,6 +26,18 @@ String MeterBusClientConfig::exec(String params) { if (params.startsWith("a ") && (space != -1)) { unsigned int a = atoi(pb1); m_meterBusClient->setAddress(a); + } else if (params.startsWith("debug ") && (space != -1)) { + bool b = (strcmp(pb1, "on") == 0); + m_meterBusClient->setDebug(b); + } else if (params.startsWith("info ") && (space != -1)) { + bool b = (strcmp(pb1, "on") == 0); + m_meterBusClient->setInfo(b); + } else if (params.startsWith("show")) { + Serial.print(getResource(MBC_FRAMES_KEY)); Serial.print(m_meterBusClient->m_frameCnt); Serial.println(); + Serial.print(getResource(MBC_MYFRAMES_KEY)); Serial.print(m_meterBusClient->m_myFrameCnt); Serial.println(); + Serial.print(getResource(MBC_INVALID_FRAMES_KEY)); Serial.print(m_meterBusClient->m_invalidFrameCnt); Serial.println(); + Serial.print(getResource(MBC_INVALID_CHECKSUM_CNT_KEY)); Serial.print(m_meterBusClient->m_invalidChecksum); Serial.println(); + Serial.print(getResource(MBC_ADDRESS_LONG_KEY)); Serial.print(m_meterBusClient->getAddress()); Serial.println(); } else { res = "subcommand not found"; } @@ -34,15 +48,16 @@ String MeterBusClientConfig::exec(String params) { -MeterBusClient::MeterBusClient() : m_meterBusClientConfig(this), m_address(0) { +MeterBusClient::MeterBusClient() : m_meterBusClientConfig(this), m_address(0), + m_frameCnt(0), m_myFrameCnt(0), m_invalidFrameCnt(0), m_invalidChecksum(0) { } -void MeterBusClient::begin(CmdServer *cmdServer) { +void MeterBusClient::begin(CmdServer *cmdServer, Thermometer *thermometer) { m_meterBusClientConfig.registerYourself(cmdServer); - + m_thermometer = thermometer; Serial3.begin(1200); @@ -60,6 +75,24 @@ unsigned char MeterBusClient::getAddress() { return m_address; } +void MeterBusClient::setDebug(bool b) { + Config::setBool(Config::METERBUSCLIENT_DEBUG, b); + m_debug = b; +} + +bool MeterBusClient::getDebug() { + return m_debug; +} + +void MeterBusClient::setInfo(bool b) { + Config::setBool(Config::METERBUSCLIENT_INFO, b); + m_info = b; +} + +bool MeterBusClient::getInfo() { + return m_info; +} + /* @@ -112,23 +145,49 @@ bool isChecksumValid(MeterBusFrame frame) { 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)) { + m_frameCnt++; + if (! isChecksumValid(m_frame)) { Serial.println(getResource(MBC_INVALID_CHECKSUM_KEY)); + m_invalidChecksum++; + } else if (m_frame.aField != getAddress()) { + if (MBC_COMPILE_TIME_DEBUG && getDebug()) { Serial.print(getResource(MBC_NOT_FOR_ME_KEY)); Serial.print((int)m_frame.aField, 16); Serial.println();} } else { + m_myFrameCnt++; // 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); + if (MBC_COMPILE_TIME_DEBUG && getDebug()) { Serial.print(getResource(MBC_START_DELIMITER_KEY)); Serial.println(m_frame.startDelimiter, 16);} + if (MBC_COMPILE_TIME_DEBUG && getDebug()) { Serial.print(getResource(MBC_LENGTH_KEY)); Serial.println(m_frame.length, 16);} + if (MBC_COMPILE_TIME_DEBUG && getDebug()) { Serial.print(getResource(MBC_CFIELD_KEY)); Serial.println(m_frame.cField, 16);} + if (MBC_COMPILE_TIME_DEBUG && getDebug()) { Serial.print(getResource(MBC_ADDRESS_KEY)); Serial.println(m_frame.aField, 16);} + if (MBC_COMPILE_TIME_DEBUG && getDebug()) { Serial.print(getResource(MBC_CIFIELD_KEY)); Serial.println(m_frame.ciField, 16);} + + if (m_frame.length > 3) { + if (MBC_COMPILE_TIME_DEBUG && getDebug()) { Serial.print(getResource(MBC_USERDATA_KEY));} + for (unsigned char i = 0; i < (m_frame.length - 3); i++) { + if (MBC_COMPILE_TIME_DEBUG && getDebug()) { Serial.print(m_frame.userData[i], 16);} + if (MBC_COMPILE_TIME_DEBUG && getDebug()) { Serial.print(getResource(SPACE_KEY));} + } + if (MBC_COMPILE_TIME_DEBUG && getDebug()) { Serial.println();} + } + + + if (m_frame.startDelimiter == 0x10) { + if (m_frame.cField == 0x40) { + SND_NKE(); + } else if (m_frame.cField == 0x5b) { + REQ_UD2(); + } else { + Serial.println(getResource(MBC_UNHANDLED_FRAME_KEY)); + } + } } } typedef enum { - STATE_START, STATE_IDLE, STATE_SHORT_FRAME, STATE_LONG_CTRL_FRAME, STATE_HANDLE, STATE_INVALID, STATE_FOREIGN, STATE_DONE + STATE_START, STATE_IDLE, STATE_SHORT_FRAME, STATE_LONG_CTRL_FRAME, STATE_HANDLE, STATE_INVALID, STATE_DONE } e_meterBusClientState; typedef enum { @@ -140,7 +199,7 @@ typedef enum { void MeterBusClient::exec() { static e_meterBusClientState state = STATE_IDLE; static e_meterBusClientSubState subState = SUBSTATE_LENGTH; - bool done = false; + static unsigned char userDataCnt = 0; int chi = Serial3.read(); char ch = (char) chi; @@ -152,7 +211,7 @@ void MeterBusClient::exec() { m_frame.cField = 0; m_frame.aField = 0; m_frame.ciField = 0; - memset(m_frame.userData, 0, sizeof(m_frame.userData)); + //memset(m_frame.userData, 0, sizeof(m_frame.userData)); m_frame.valid = false; state = STATE_IDLE; break; @@ -160,17 +219,14 @@ void MeterBusClient::exec() { case STATE_IDLE: if (chi != -1) { if (ch == 0x10) { - Serial.println("switching to short frame, c field"); m_frame.startDelimiter = 0x10; state = STATE_SHORT_FRAME; subState = SUBSTATE_C_FIELD; } else if (ch == 0x68) { - Serial.println("switching to long frame, length"); m_frame.startDelimiter = 0x68; state = STATE_LONG_CTRL_FRAME; subState = SUBSTATE_LENGTH; } else { - Serial.println("switching to invalid"); state = STATE_INVALID; } } @@ -184,6 +240,9 @@ void MeterBusClient::exec() { } else if (subState == SUBSTATE_A_FIELD) { m_frame.aField = ch; 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; @@ -199,7 +258,7 @@ void MeterBusClient::exec() { if (chi != -1) { if (subState == SUBSTATE_LENGTH) { m_frame.length = ch; - if (m_frame.length < 3) { + if ((m_frame.length < 3) || (m_frame.length > 252)) { state = STATE_INVALID; } else { subState = SUBSTATE_LENGTH_REPEAT; @@ -228,10 +287,14 @@ void MeterBusClient::exec() { subState = SUBSTATE_CHECKSUM; } else { subState = SUBSTATE_USERDATA; + userDataCnt = 0; } } else if (subState == SUBSTATE_USERDATA) { - // count and collect - // then: subState = SUBSTATE_CHECKSUM + m_frame.userData[userDataCnt] = ch; + userDataCnt++; + if (userDataCnt >= (m_frame.length - 3)) { + subState = SUBSTATE_CHECKSUM; + } } else if (subState == SUBSTATE_CHECKSUM) { m_frame.checksum = ch; subState = SUBSTATE_STOP; @@ -247,12 +310,11 @@ void MeterBusClient::exec() { break; case STATE_INVALID: - Serial.println(getResource(MBC_INVALID_FRAME_KEY)); + m_invalidFrameCnt++; state = STATE_START; break; case STATE_HANDLE: - Serial.println("handle frame"); if (m_frame.valid) { handleFrame(); } else { @@ -261,11 +323,6 @@ void MeterBusClient::exec() { 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; diff --git a/meterBusClient.h b/meterBusClient.h index b906c0d..4ba04ca 100644 --- a/meterBusClient.h +++ b/meterBusClient.h @@ -13,6 +13,7 @@ #include "cmd.h" #include "Config.h" #include "Resources.h" +#include "Thermometer.h" class MeterBusClient; @@ -66,16 +67,32 @@ struct MeterBusFrame { class MeterBusClient { public: MeterBusClient(); - void begin(CmdServer *cmdServer); + void begin(CmdServer *cmdServer, Thermometer *thermometer); void exec(); friend class MeterBusClientConfig; private: MeterBusClientConfig m_meterBusClientConfig; + Thermometer *m_thermometer; unsigned char m_address; void setAddress(unsigned char address); unsigned char getAddress(); void handleFrame(); MeterBusFrame m_frame; + + unsigned long m_frameCnt; + unsigned long m_myFrameCnt; + unsigned long m_invalidFrameCnt; + unsigned long m_invalidChecksum; + + bool m_debug; + bool getDebug(); + void setDebug(bool b); + bool m_info; + bool getInfo(); + void setInfo(bool b); + + void SND_NKE(); + void REQ_UD2(); }; diff --git a/meterBusClientFrames.cpp b/meterBusClientFrames.cpp new file mode 100644 index 0000000..e1f021c --- /dev/null +++ b/meterBusClientFrames.cpp @@ -0,0 +1,23 @@ +/* + * meterBusClientFrames.cpp + * + * Created on: 09.03.2014 + * Author: wn + */ + +#include "meterBusClient.h" + + +void MeterBusClient::SND_NKE() { + Serial3.write(0xE5); +} + +void MeterBusClient::REQ_UD2() { + +} + + + + + +