meterbus integrated but not working

This commit is contained in:
hg
2014-03-08 19:24:27 +01:00
parent d3d2c75541
commit b333be0cd9
5 changed files with 224 additions and 29 deletions

View File

@ -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);

View File

@ -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 ",
};

View File

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

View File

@ -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

View File

@ -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_ */