Compare commits
4 Commits
MeterBusNo
...
MBC_WORKIN
Author | SHA1 | Date | |
---|---|---|---|
13d19d4e15 | |||
854d2f202a | |||
b333be0cd9 | |||
d3d2c75541 |
39
Config.cpp
39
Config.cpp
@ -8,6 +8,7 @@
|
||||
|
||||
#include <EEPROM.h>
|
||||
#include "Config.h"
|
||||
#include "Resources.h"
|
||||
|
||||
|
||||
|
||||
@ -83,6 +84,44 @@ void Config::setULong(int pos, unsigned long value) {
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char Config::getUChar(int pos) {
|
||||
u_uchar u;
|
||||
for (unsigned int i = 0; i < sizeof(unsigned char); i++) {
|
||||
u.e[i] = EEPROM.read(pos + i);
|
||||
}
|
||||
return u.c;
|
||||
}
|
||||
|
||||
void Config::setUChar(int pos, unsigned char value) {
|
||||
u_uchar u;
|
||||
u.c = value;
|
||||
for (unsigned int i = 0; i < sizeof(unsigned char); i++) {
|
||||
EEPROM.write(pos + i, u.e[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Config::initialize() {
|
||||
if (! isInitialized()) {
|
||||
Serial.println(getResource(CONFIG_INIT_KEY));
|
||||
setFloat(THERMOMETER_ALPHA, 1.0);
|
||||
setULong(THERMOMETER_PERIOD, 1000);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
setFloat(THERMOMETER_CAL[i], 1.0);
|
||||
}
|
||||
setBool(THERMOMETER_DEBUG, false);
|
||||
setBool(THERMOMETER_INFO, false);
|
||||
|
||||
|
||||
setUChar(METERBUSCLIENT_ADDRESS, 0);
|
||||
setBool(METERBUSCLIENT_DEBUG, false);
|
||||
setBool(METERBUSCLIENT_INFO, false);
|
||||
|
||||
setMagic();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Config::isInitialized() {
|
||||
unsigned int magic = getUInt(MAGIC);
|
||||
return magic == MAGIC_TOKEN;
|
||||
|
14
Config.h
14
Config.h
@ -39,6 +39,11 @@ typedef union {
|
||||
uint8_t e[sizeof(bool)];
|
||||
} u_bool;
|
||||
|
||||
typedef union {
|
||||
unsigned char c;
|
||||
uint8_t e[sizeof(unsigned char)];
|
||||
} u_uchar;
|
||||
|
||||
|
||||
namespace Config {
|
||||
const unsigned int MAGIC_TOKEN = 0xDEADBEEF;
|
||||
@ -49,6 +54,11 @@ namespace Config {
|
||||
const int THERMOMETER_CAL[4] = {12, 16, 20, 24}; // 4 x 4
|
||||
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);
|
||||
void setBool(int pos, bool value);
|
||||
@ -58,6 +68,10 @@ namespace Config {
|
||||
void setUInt(int pos, unsigned int value);
|
||||
unsigned long getULong(int pos);
|
||||
void setULong(int pos, unsigned long value);
|
||||
unsigned char getUChar(int pos);
|
||||
void setUChar(int pos, unsigned char value);
|
||||
|
||||
void initialize();
|
||||
|
||||
bool isInitialized();
|
||||
|
||||
|
@ -12,6 +12,78 @@
|
||||
|
||||
//String TEXT;
|
||||
|
||||
const String TEXT_RESOURCES[] = {
|
||||
"Text1",
|
||||
"PeriodMeasure (ms): ",
|
||||
"Alpha: ",
|
||||
"Calibration: ",
|
||||
"Info: ",
|
||||
"Debug: ",
|
||||
"COMPILE_TIME_DEBUG: ",
|
||||
"TimeOuts: ",
|
||||
"Cycles: ",
|
||||
"Period (ms): ",
|
||||
"Alpha: ",
|
||||
"index: ",
|
||||
"cal: ",
|
||||
"t: ",
|
||||
"ts: ",
|
||||
", ",
|
||||
" enable : enable the calibration mode",
|
||||
" disable : disable the calibration mode",
|
||||
" show : show parameters for calibration process",
|
||||
" r : set value of calibration resistor",
|
||||
" start <0..3>: start calibration on channel",
|
||||
" stop <0..3>: stop calibration on channel",
|
||||
" enabled : ",
|
||||
" r_cal : ",
|
||||
"setTemperature: i=",
|
||||
"t=",
|
||||
"t_smoothed=",
|
||||
"CONF: ",
|
||||
"MODE: ",
|
||||
"Initializing EEPROM",
|
||||
"State 0",
|
||||
"Switching to State 1",
|
||||
"Switching to State 10",
|
||||
"State 9",
|
||||
"Timeout: ",
|
||||
"State 10",
|
||||
"No, no, we are in calibration high mode, so directly switch to state 20",
|
||||
"Switching to state 11",
|
||||
"r_avg on channel ",
|
||||
"calibration factor: ",
|
||||
"Calibration stopped",
|
||||
"Save calibration factor for channel ",
|
||||
": ",
|
||||
"HELP List this help for all commands",
|
||||
"command not found",
|
||||
"Thermometer configuration operations",
|
||||
"Show thermometer measurement values",
|
||||
"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 ",
|
||||
"Unhandled frame",
|
||||
"s: ",
|
||||
"l: ",
|
||||
"c: ",
|
||||
"a: ",
|
||||
"ci: ",
|
||||
"u: ",
|
||||
" ",
|
||||
"frames: ",
|
||||
"my frames: ",
|
||||
"invalid frames: ",
|
||||
"invalid checksum: ",
|
||||
"mbus address: ",
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
const String& getResource(uint8_t key) {
|
||||
//TEXT = String("T") + key + String(": ");
|
||||
|
74
Resources.h
74
Resources.h
@ -41,7 +41,7 @@ const uint8_t SET_TEMPERATURE_DEBUG_2_KEY = 25;
|
||||
const uint8_t SET_TEMPERATURE_DEBUG_3_KEY = 26;
|
||||
const uint8_t CONF_COLON_KEY = 27;
|
||||
const uint8_t MODE_COLON_KEY = 28;
|
||||
const uint8_t THERMOMETER_BEGIN_1_KEY = 29;
|
||||
const uint8_t CONFIG_INIT_KEY = 29;
|
||||
const uint8_t STATE_0_KEY = 30;
|
||||
const uint8_t TO_STATE_1_KEY = 31;
|
||||
const uint8_t TO_STATE_10_KEY = 32;
|
||||
@ -61,60 +61,24 @@ const uint8_t THERMCONFIG_HELP_KEY = 45;
|
||||
const uint8_t THERMVALUES_HELP_KEY = 46;
|
||||
const uint8_t THERMCALIBRATE_HELP_KEY = 47;
|
||||
const uint8_t CALIBRATION_ZEOR_MODE_HINT_KEY = 48;
|
||||
|
||||
|
||||
const String TEXT_RESOURCES[] = {
|
||||
"Text1",
|
||||
"PeriodMeasure (ms): ",
|
||||
"Alpha: ",
|
||||
"Calibration: ",
|
||||
"Info: ",
|
||||
"Debug: ",
|
||||
"COMPILE_TIME_DEBUG: ",
|
||||
"TimeOuts: ",
|
||||
"Cycles: ",
|
||||
"Period (ms): ",
|
||||
"Alpha: ",
|
||||
"index: ",
|
||||
"cal: ",
|
||||
"t: ",
|
||||
"ts: ",
|
||||
", ",
|
||||
" enable : enable the calibration mode",
|
||||
" disable : disable the calibration mode",
|
||||
" show : show parameters for calibration process",
|
||||
" r : set value of calibration resistor",
|
||||
" start <0..3>: start calibration on channel",
|
||||
" stop <0..3>: stop calibration on channel",
|
||||
" enabled : ",
|
||||
" r_cal : ",
|
||||
"setTemperature: i=",
|
||||
"t=",
|
||||
"t_smoothed=",
|
||||
"CONF: ",
|
||||
"MODE: ",
|
||||
"Initializing EEPROM",
|
||||
"State 0",
|
||||
"Switching to State 1",
|
||||
"Switching to State 10",
|
||||
"State 9",
|
||||
"Timeout: ",
|
||||
"State 10",
|
||||
"No, no, we are in calibration high mode, so directly switch to state 20",
|
||||
"Switching to state 11",
|
||||
"r_avg on channel ",
|
||||
"calibration factor: ",
|
||||
"Calibration stopped",
|
||||
"Save calibration factor for channel ",
|
||||
": ",
|
||||
"HELP List this help for all commands",
|
||||
"command not found",
|
||||
"Thermometer configuration operations",
|
||||
"Show thermometer measurement values",
|
||||
"Thermometer calibration operations",
|
||||
"No, no, we are in calibration zero mode, so directly switch to state 20",
|
||||
};
|
||||
|
||||
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 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);
|
||||
|
@ -5,30 +5,29 @@
|
||||
#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();
|
||||
|
||||
|
||||
spiInit();
|
||||
|
||||
cmdServer.begin();
|
||||
#ifdef ENABLE_CONFIGURATION_INVALID_CMD
|
||||
configInvalidateCmd.registerYourself(&cmdServer);
|
||||
#endif
|
||||
uptime.begin(&cmdServer);
|
||||
thermometer.begin(&cmdServer);
|
||||
meterBusClient.begin(&cmdServer, &thermometer);
|
||||
}
|
||||
|
||||
|
||||
@ -36,4 +35,5 @@ void loop() {
|
||||
cmdServer.exec();
|
||||
uptime.exec();
|
||||
thermometer.exec();
|
||||
meterBusClient.exec();
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
#include <avr/interrupt.h>
|
||||
#include"fatal.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
333
meterBusClient.cpp
Normal file
333
meterBusClient.cpp
Normal file
@ -0,0 +1,333 @@
|
||||
/*
|
||||
* meterBusClient.cpp
|
||||
*
|
||||
* Created on: 08.03.2014
|
||||
* Author: wn
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "meterBusClient.h"
|
||||
|
||||
|
||||
const bool MBC_COMPILE_TIME_DEBUG = false;
|
||||
|
||||
|
||||
String MeterBusClientConfig::exec(String params) {
|
||||
String res = "done";
|
||||
|
||||
int space = params.indexOf(' ');
|
||||
String p1 = "";
|
||||
char pb1[128];
|
||||
if (space != -1) {
|
||||
params.toCharArray(pb1, 128, space+1);
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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, Thermometer *thermometer) {
|
||||
m_meterBusClientConfig.registerYourself(cmdServer);
|
||||
m_thermometer = thermometer;
|
||||
|
||||
Serial3.begin(1200);
|
||||
|
||||
|
||||
setAddress(Config::getUChar(Config::METERBUSCLIENT_ADDRESS));
|
||||
|
||||
}
|
||||
|
||||
void MeterBusClient::setAddress(unsigned char a) {
|
||||
Config::setUChar(Config::METERBUSCLIENT_ADDRESS, a);
|
||||
m_address = a;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Single Character: E5h
|
||||
*
|
||||
* Short Frame:
|
||||
* Start 10h
|
||||
* C-Field
|
||||
* A-Field
|
||||
* Check-Sum
|
||||
* Stop 16h
|
||||
*
|
||||
* Control Frame:
|
||||
* Start 68h
|
||||
* Length = 3
|
||||
* Length
|
||||
* Start 68h
|
||||
* C-Field
|
||||
* A-Field
|
||||
* CI-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
|
||||
*
|
||||
* Frames:
|
||||
* SND_NKE
|
||||
* Short Frame, C: 40h
|
||||
*
|
||||
* REQ_UD2
|
||||
* Short Frame, C: 5Bh
|
||||
*/
|
||||
|
||||
|
||||
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() {
|
||||
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
|
||||
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_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;
|
||||
static unsigned char userDataCnt = 0;
|
||||
|
||||
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_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_LONG_CTRL_FRAME:
|
||||
if (chi != -1) {
|
||||
if (subState == SUBSTATE_LENGTH) {
|
||||
m_frame.length = ch;
|
||||
if ((m_frame.length < 3) || (m_frame.length > 252)) {
|
||||
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;
|
||||
userDataCnt = 0;
|
||||
}
|
||||
} else if (subState == SUBSTATE_USERDATA) {
|
||||
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;
|
||||
} else if (subState == SUBSTATE_STOP) {
|
||||
if (ch == 0x16) {
|
||||
m_frame.valid = true;
|
||||
state = STATE_HANDLE;
|
||||
} else {
|
||||
state = STATE_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_INVALID:
|
||||
m_invalidFrameCnt++;
|
||||
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_DONE:
|
||||
// may be another useful message
|
||||
state = STATE_START;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
100
meterBusClient.h
Normal file
100
meterBusClient.h
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* meterBusClient.h
|
||||
*
|
||||
* Created on: 08.03.2014
|
||||
* Author: wn
|
||||
*/
|
||||
|
||||
#ifndef METERBUSCLIENT_H_
|
||||
#define METERBUSCLIENT_H_
|
||||
|
||||
|
||||
|
||||
#include "cmd.h"
|
||||
#include "Config.h"
|
||||
#include "Resources.h"
|
||||
#include "Thermometer.h"
|
||||
|
||||
class MeterBusClient;
|
||||
|
||||
|
||||
|
||||
class MeterBusClientConfig : public Cmd {
|
||||
public:
|
||||
MeterBusClientConfig(MeterBusClient *meterBusClient) : m_meterBusClient(meterBusClient) {};
|
||||
virtual String getCmdName() { return "MBCC"; }
|
||||
virtual String getHelp() { return getResource(MBC_CONFIG_HELP_KEY); }
|
||||
virtual String exec(String params);
|
||||
private:
|
||||
MeterBusClient *m_meterBusClient;
|
||||
};
|
||||
|
||||
|
||||
|
||||
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:
|
||||
MeterBusClient();
|
||||
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();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* METERBUSCLIENT_H_ */
|
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() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -253,17 +253,6 @@ void Thermometer::begin(CmdServer *cmdServer) {
|
||||
AD7190_Calibrate(AD7190_MODE_CAL_INT_FULL, AD7190_CH_AIN1P_AINCOM);
|
||||
|
||||
|
||||
if (! Config::isInitialized()) {
|
||||
Serial.println(getResource(THERMOMETER_BEGIN_1_KEY));
|
||||
Config::setFloat(Config::THERMOMETER_ALPHA, 1.0);
|
||||
Config::setULong(Config::THERMOMETER_PERIOD, 1000);
|
||||
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::setMagic();
|
||||
}
|
||||
|
||||
setAlpha(Config::getFloat(Config::THERMOMETER_ALPHA));
|
||||
setPeriodMeasure(Config::getULong(Config::THERMOMETER_PERIOD));
|
||||
@ -273,12 +262,7 @@ void Thermometer::begin(CmdServer *cmdServer) {
|
||||
setDebug(Config::getBool(Config::THERMOMETER_DEBUG));
|
||||
setInfo(Config::getBool(Config::THERMOMETER_INFO));
|
||||
|
||||
//setCalibrateFactor(0, 1.002999);
|
||||
//setCalibrateFactor(1, 1.001804);
|
||||
//setCalibrateFactor(2, 1.000794);
|
||||
//setCalibrateFactor(3, 1.001071);
|
||||
|
||||
// prepare
|
||||
prepareAdc();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user