meterbusclient is working, SND_NKE will be answered
This commit is contained in:
@ -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();
|
||||||
}
|
}
|
||||||
|
3
Config.h
3
Config.h
@ -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);
|
||||||
|
@ -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: ",
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
14
Resources.h
14
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_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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
23
meterBusClientFrames.cpp
Normal 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() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user