meterbusclient is working, SND_NKE will be answered

This commit is contained in:
hg
2014-03-09 00:25:48 +01:00
parent 854d2f202a
commit 13d19d4e15
9 changed files with 158 additions and 30 deletions

View File

@ -114,6 +114,8 @@ void Config::initialize() {
setUChar(METERBUSCLIENT_ADDRESS, 0); setUChar(METERBUSCLIENT_ADDRESS, 0);
setBool(METERBUSCLIENT_DEBUG, false);
setBool(METERBUSCLIENT_INFO, false);
setMagic(); setMagic();
} }

View File

@ -55,6 +55,9 @@ namespace Config {
const int THERMOMETER_DEBUG = 28; // 1 const int THERMOMETER_DEBUG = 28; // 1
const int THERMOMETER_INFO = 29; // 1 const int THERMOMETER_INFO = 29; // 1
const int METERBUSCLIENT_ADDRESS = 30; // 1 const int METERBUSCLIENT_ADDRESS = 30; // 1
const int METERBUSCLIENT_DEBUG = 31; // 1
const int METERBUSCLIENT_INFO = 32; // 1
bool getBool(int pos); bool getBool(int pos);

View File

@ -67,6 +67,19 @@ const String TEXT_RESOURCES[] = {
"No valid frame available", "No valid frame available",
"Invalid checksum", "Invalid checksum",
"Not for me but for ", "Not for me but for ",
"Unhandled frame",
"s: ",
"l: ",
"c: ",
"a: ",
"ci: ",
"u: ",
" ",
"frames: ",
"my frames: ",
"invalid frames: ",
"invalid checksum: ",
"mbus address: ",
}; };

View File

@ -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_NO_VALID_FRAME_KEY = 51;
const uint8_t MBC_INVALID_CHECKSUM_KEY = 52; const uint8_t MBC_INVALID_CHECKSUM_KEY = 52;
const uint8_t MBC_NOT_FOR_ME_KEY = 53; 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); const String& getResource(uint8_t key);

View File

@ -27,7 +27,7 @@ void setup() {
configInvalidateCmd.registerYourself(&cmdServer); configInvalidateCmd.registerYourself(&cmdServer);
uptime.begin(&cmdServer); uptime.begin(&cmdServer);
thermometer.begin(&cmdServer); thermometer.begin(&cmdServer);
meterBusClient.begin(&cmdServer); meterBusClient.begin(&cmdServer, &thermometer);
} }

View File

@ -1,10 +1,11 @@
#include <avr/interrupt.h>
#include"fatal.h" #include"fatal.h"
#include <Arduino.h>
void fatal(uint8_t code) { void fatal(uint8_t code) {
// cli(); // cli();
// do something with the code and somehow show that there is a problem // do something with the code and somehow show that there is a problem
Serial.print("Fatal: "); Serial.println(code);
while (1); while (1);
} }

View File

@ -10,6 +10,8 @@
#include "meterBusClient.h" #include "meterBusClient.h"
const bool MBC_COMPILE_TIME_DEBUG = false;
String MeterBusClientConfig::exec(String params) { String MeterBusClientConfig::exec(String params) {
String res = "done"; String res = "done";
@ -24,6 +26,18 @@ String MeterBusClientConfig::exec(String params) {
if (params.startsWith("a ") && (space != -1)) { if (params.startsWith("a ") && (space != -1)) {
unsigned int a = atoi(pb1); unsigned int a = atoi(pb1);
m_meterBusClient->setAddress(a); 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 { } else {
res = "subcommand not found"; 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_meterBusClientConfig.registerYourself(cmdServer);
m_thermometer = thermometer;
Serial3.begin(1200); Serial3.begin(1200);
@ -60,6 +75,24 @@ unsigned char MeterBusClient::getAddress() {
return m_address; 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); return (ctrlsum == frame.checksum);
} }
void MeterBusClient::handleFrame() { void MeterBusClient::handleFrame() {
if (m_frame.aField != getAddress()) { m_frameCnt++;
Serial.print(getResource(MBC_NOT_FOR_ME_KEY)); Serial.print((int)m_frame.aField, 16); Serial.println(); if (! isChecksumValid(m_frame)) {
} else if (! isChecksumValid(m_frame)) {
Serial.println(getResource(MBC_INVALID_CHECKSUM_KEY)); 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 { } else {
m_myFrameCnt++;
// handle the frame // handle the frame
Serial.print("s: "); Serial.println(m_frame.startDelimiter, 16); if (MBC_COMPILE_TIME_DEBUG && getDebug()) { Serial.print(getResource(MBC_START_DELIMITER_KEY)); Serial.println(m_frame.startDelimiter, 16);}
Serial.print("l: "); Serial.println(m_frame.length, 16); if (MBC_COMPILE_TIME_DEBUG && getDebug()) { Serial.print(getResource(MBC_LENGTH_KEY)); Serial.println(m_frame.length, 16);}
Serial.print("c: "); Serial.println(m_frame.cField, 16); if (MBC_COMPILE_TIME_DEBUG && getDebug()) { Serial.print(getResource(MBC_CFIELD_KEY)); 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_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 { 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; } e_meterBusClientState;
typedef enum { typedef enum {
@ -140,7 +199,7 @@ typedef enum {
void MeterBusClient::exec() { void MeterBusClient::exec() {
static e_meterBusClientState state = STATE_IDLE; static e_meterBusClientState state = STATE_IDLE;
static e_meterBusClientSubState subState = SUBSTATE_LENGTH; static e_meterBusClientSubState subState = SUBSTATE_LENGTH;
bool done = false; static unsigned char userDataCnt = 0;
int chi = Serial3.read(); int chi = Serial3.read();
char ch = (char) chi; char ch = (char) chi;
@ -152,7 +211,7 @@ void MeterBusClient::exec() {
m_frame.cField = 0; m_frame.cField = 0;
m_frame.aField = 0; m_frame.aField = 0;
m_frame.ciField = 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; m_frame.valid = false;
state = STATE_IDLE; state = STATE_IDLE;
break; break;
@ -160,17 +219,14 @@ void MeterBusClient::exec() {
case STATE_IDLE: case STATE_IDLE:
if (chi != -1) { if (chi != -1) {
if (ch == 0x10) { if (ch == 0x10) {
Serial.println("switching to short frame, c field");
m_frame.startDelimiter = 0x10; m_frame.startDelimiter = 0x10;
state = STATE_SHORT_FRAME; state = STATE_SHORT_FRAME;
subState = SUBSTATE_C_FIELD; subState = SUBSTATE_C_FIELD;
} else if (ch == 0x68) { } else if (ch == 0x68) {
Serial.println("switching to long frame, length");
m_frame.startDelimiter = 0x68; m_frame.startDelimiter = 0x68;
state = STATE_LONG_CTRL_FRAME; state = STATE_LONG_CTRL_FRAME;
subState = SUBSTATE_LENGTH; subState = SUBSTATE_LENGTH;
} else { } else {
Serial.println("switching to invalid");
state = STATE_INVALID; state = STATE_INVALID;
} }
} }
@ -184,6 +240,9 @@ void MeterBusClient::exec() {
} else if (subState == SUBSTATE_A_FIELD) { } else if (subState == SUBSTATE_A_FIELD) {
m_frame.aField = ch; m_frame.aField = ch;
subState = SUBSTATE_CHECKSUM; subState = SUBSTATE_CHECKSUM;
} else if (subState == SUBSTATE_CHECKSUM) {
m_frame.checksum = ch;
subState = SUBSTATE_STOP;
} else if (subState == SUBSTATE_STOP) { } else if (subState == SUBSTATE_STOP) {
if (ch == 0x16) { if (ch == 0x16) {
m_frame.valid = true; m_frame.valid = true;
@ -199,7 +258,7 @@ void MeterBusClient::exec() {
if (chi != -1) { if (chi != -1) {
if (subState == SUBSTATE_LENGTH) { if (subState == SUBSTATE_LENGTH) {
m_frame.length = ch; m_frame.length = ch;
if (m_frame.length < 3) { if ((m_frame.length < 3) || (m_frame.length > 252)) {
state = STATE_INVALID; state = STATE_INVALID;
} else { } else {
subState = SUBSTATE_LENGTH_REPEAT; subState = SUBSTATE_LENGTH_REPEAT;
@ -228,10 +287,14 @@ void MeterBusClient::exec() {
subState = SUBSTATE_CHECKSUM; subState = SUBSTATE_CHECKSUM;
} else { } else {
subState = SUBSTATE_USERDATA; subState = SUBSTATE_USERDATA;
userDataCnt = 0;
} }
} else if (subState == SUBSTATE_USERDATA) { } else if (subState == SUBSTATE_USERDATA) {
// count and collect m_frame.userData[userDataCnt] = ch;
// then: subState = SUBSTATE_CHECKSUM userDataCnt++;
if (userDataCnt >= (m_frame.length - 3)) {
subState = SUBSTATE_CHECKSUM;
}
} else if (subState == SUBSTATE_CHECKSUM) { } else if (subState == SUBSTATE_CHECKSUM) {
m_frame.checksum = ch; m_frame.checksum = ch;
subState = SUBSTATE_STOP; subState = SUBSTATE_STOP;
@ -247,12 +310,11 @@ void MeterBusClient::exec() {
break; break;
case STATE_INVALID: case STATE_INVALID:
Serial.println(getResource(MBC_INVALID_FRAME_KEY)); m_invalidFrameCnt++;
state = STATE_START; state = STATE_START;
break; break;
case STATE_HANDLE: case STATE_HANDLE:
Serial.println("handle frame");
if (m_frame.valid) { if (m_frame.valid) {
handleFrame(); handleFrame();
} else { } else {
@ -261,11 +323,6 @@ void MeterBusClient::exec() {
state = STATE_DONE; state = STATE_DONE;
break; break;
case STATE_FOREIGN:
// not for me message
state = STATE_START;
break;
case STATE_DONE: case STATE_DONE:
// may be another useful message // may be another useful message
state = STATE_START; state = STATE_START;

View File

@ -13,6 +13,7 @@
#include "cmd.h" #include "cmd.h"
#include "Config.h" #include "Config.h"
#include "Resources.h" #include "Resources.h"
#include "Thermometer.h"
class MeterBusClient; class MeterBusClient;
@ -66,16 +67,32 @@ struct MeterBusFrame {
class MeterBusClient { class MeterBusClient {
public: public:
MeterBusClient(); MeterBusClient();
void begin(CmdServer *cmdServer); void begin(CmdServer *cmdServer, Thermometer *thermometer);
void exec(); void exec();
friend class MeterBusClientConfig; friend class MeterBusClientConfig;
private: private:
MeterBusClientConfig m_meterBusClientConfig; MeterBusClientConfig m_meterBusClientConfig;
Thermometer *m_thermometer;
unsigned char m_address; unsigned char m_address;
void setAddress(unsigned char address); void setAddress(unsigned char address);
unsigned char getAddress(); unsigned char getAddress();
void handleFrame(); void handleFrame();
MeterBusFrame m_frame; 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();
}; };

23
meterBusClientFrames.cpp Normal file
View File

@ -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() {
}