This commit is contained in:
hg
2014-04-02 22:50:17 +02:00
parent 26b47b1159
commit db5cb1829a
8 changed files with 90 additions and 16 deletions

View File

@ -80,6 +80,8 @@ const String TEXT_RESOURCES[] = {
"invalid frames: ",
"invalid checksum: ",
"mbus address: ",
"collisions: ",
"r: ",
};

View File

@ -79,6 +79,8 @@ 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 uint8_t MBC_COLLISION_CNT_KEY = 67;
const uint8_t R_KEY = 68;
const String& getResource(uint8_t key);

View File

@ -8,6 +8,7 @@
#include "meterBusClient.h"
const unsigned char OK_LED_PIN = 2;
static CmdServer cmdServer(&Serial);
static ConfigInvalidateCmd configInvalidateCmd;
@ -16,6 +17,9 @@ static Thermometer thermometer;
static MeterBusClient meterBusClient;
void setup() {
pinMode(OK_LED_PIN, OUTPUT);
digitalWrite(OK_LED_PIN, LOW);
Serial.begin(9600);
Config::initialize();
@ -28,6 +32,8 @@ void setup() {
uptime.begin(&cmdServer);
thermometer.begin(&cmdServer);
meterBusClient.begin(&cmdServer, &thermometer);
digitalWrite(OK_LED_PIN, HIGH);
}

View File

@ -37,6 +37,7 @@ String MeterBusClientConfig::exec(String params) {
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_COLLISION_CNT_KEY)); Serial.print(m_meterBusClient->m_collisionCnt); Serial.println();
Serial.print(getResource(MBC_ADDRESS_LONG_KEY)); Serial.print(m_meterBusClient->getAddress()); Serial.println();
} else {
res = "subcommand not found";
@ -49,7 +50,8 @@ String MeterBusClientConfig::exec(String params) {
MeterBusClient::MeterBusClient() : m_meterBusClientConfig(this), m_address(0),
m_frameCnt(0), m_myFrameCnt(0), m_invalidFrameCnt(0), m_invalidChecksum(0) {
m_frameCnt(0), m_myFrameCnt(0), m_invalidFrameCnt(0), m_invalidChecksum(0),
m_collisionCnt(0) {
}
@ -59,7 +61,11 @@ void MeterBusClient::begin(CmdServer *cmdServer, Thermometer *thermometer) {
m_meterBusClientConfig.registerYourself(cmdServer);
m_thermometer = thermometer;
Serial3.begin(1200);
//Serial3.begin(1200);
//Serial3.begin(2400, SERIAL_8E1);
Serial3.begin(2400);
UART2_C1 |= UART_C1_PE | UART_C1_M;
setAddress(Config::getUChar(Config::METERBUSCLIENT_ADDRESS));
@ -147,7 +153,8 @@ bool isChecksumValid(MeterBusFrame frame) {
void MeterBusClient::handleFrame() {
bool MeterBusClient::handleFrame() {
bool res = false;
m_frameCnt++;
if (! isChecksumValid(m_frame)) {
Serial.println(getResource(MBC_INVALID_CHECKSUM_KEY));
@ -176,19 +183,22 @@ void MeterBusClient::handleFrame() {
if (m_frame.startDelimiter == 0x10) {
if (m_frame.cField == 0x40) {
SND_NKE();
res = true;
} else if (m_frame.cField == 0x5b) {
REQ_UD2();
res = true;
} else {
Serial.println(getResource(MBC_UNHANDLED_FRAME_KEY));
}
}
}
return res;
}
typedef enum {
STATE_START, STATE_IDLE, STATE_SHORT_FRAME, STATE_LONG_CTRL_FRAME, STATE_HANDLE, STATE_INVALID, STATE_DONE,
STATE_DELAYED_HANDLE, STATE_DELAY
STATE_DELAYED_RESPONSE, STATE_DELAY, STATE_RESPONSE, STATE_RECEIVE_ECHO
} e_meterBusClientState;
typedef enum {
@ -201,9 +211,13 @@ void MeterBusClient::exec() {
static e_meterBusClientState state = STATE_IDLE;
static e_meterBusClientSubState subState = SUBSTATE_LENGTH;
static unsigned char userDataCnt = 0;
static unsigned int echoReceiveCnt = 0;
static unsigned long receivedDoneTimestamp;
int chi = Serial3.read();
if (chi != -1) {
Serial.print("Received: "); Serial.println(chi, 16);
}
char ch = (char) chi;
switch (state) {
@ -312,28 +326,48 @@ void MeterBusClient::exec() {
break;
case STATE_INVALID:
Serial.println("INVALID FRAME");
m_invalidFrameCnt++;
state = STATE_START;
break;
case STATE_HANDLE:
state = STATE_DELAY;
receivedDoneTimestamp = millis();
state = STATE_DONE;
if (m_frame.valid) {
receivedDoneTimestamp = millis();
if (handleFrame()) {
state = STATE_DELAY;
}
}
break;
case STATE_DELAY:
if ((receivedDoneTimestamp + RESPONSE_DELAY) < millis()) {
state = STATE_DELAYED_HANDLE;
state = STATE_DELAYED_RESPONSE;
}
break;
case STATE_DELAYED_HANDLE:
if (m_frame.valid) {
handleFrame();
} else {
Serial.println(getResource(MBC_NO_VALID_FRAME_KEY));
case STATE_DELAYED_RESPONSE:
for (unsigned int i = 0; i < sendBufferLen; i++) {
Serial3.write(sendBuffer[i]);
}
echoReceiveCnt = 0;
state = STATE_RECEIVE_ECHO;
break;
case STATE_RECEIVE_ECHO:
if (chi != -1) {
Serial.println("echo character");
if (ch == sendBuffer[echoReceiveCnt]) {
echoReceiveCnt++;
if (echoReceiveCnt == sendBufferLen) {
state = STATE_DONE;
}
} else {
m_collisionCnt++;
state = STATE_DONE;
}
}
state = STATE_DONE;
break;
case STATE_DONE:

View File

@ -80,13 +80,19 @@ private:
unsigned char m_address;
void setAddress(unsigned char address);
unsigned char getAddress();
void handleFrame();
bool handleFrame();
MeterBusFrame m_frame;
unsigned char sendBuffer[265];
unsigned int sendBufferLen;
void aSB(unsigned char c); // append to send buffer
unsigned char calcSendChecksum();
unsigned long m_frameCnt;
unsigned long m_myFrameCnt;
unsigned long m_invalidFrameCnt;
unsigned long m_invalidChecksum;
unsigned long m_collisionCnt;
bool m_debug;
bool getDebug();

View File

@ -7,13 +7,34 @@
#include "meterBusClient.h"
inline void MeterBusClient::aSB(unsigned char c) {
sendBuffer[sendBufferLen++] = c;
}
unsigned char MeterBusClient::calcSendChecksum() {
unsigned char checksum = 0;
for (unsigned int i = 4; i < sendBufferLen; i++) {
checksum += sendBuffer[i];
}
return checksum;
}
void MeterBusClient::SND_NKE() {
Serial3.write(0xE5);
sendBufferLen = 0;
aSB(0xE5);
}
void MeterBusClient::REQ_UD2() {
sendBufferLen = 0;
aSB(0x68);
aSB(0x03);
aSB(0x03);
aSB(0x68);
aSB(0x01);
aSB(getAddress());
aSB(0x03);
aSB(calcSendChecksum());
aSB(0x16);
}

View File

@ -63,6 +63,7 @@ String ThermValues::exec(String params) {
for (unsigned int i = 0; i < NUM_OF_CHANNELS; i++) {
m_stream->print(getResource(INDEX_KEY)); m_stream->print(i); m_stream->print(getResource(COMMA_SPACE_KEY));
m_stream->print(getResource(CAL_KEY)); m_stream->print(m_thermometer->getCalibrateFactor(i), 6); m_stream->print(getResource(COMMA_SPACE_KEY));
m_stream->print(getResource(R_KEY)); m_stream->print(m_thermometer->m_r[i], 6); m_stream->print(getResource(COMMA_SPACE_KEY));
m_stream->print(getResource(T_KEY)); m_stream->print(m_thermometer->m_temperature[i], 6); m_stream->print(getResource(COMMA_SPACE_KEY));
m_stream->print(getResource(TS_KEY)); m_stream->print(m_thermometer->m_smoothedTemperature[i], 6);
m_stream->println();
@ -354,6 +355,7 @@ void Thermometer::exec() {
if (COMPILE_TIME_DEBUG && getDebug()) { Serial.print("calibrateFactor="); Serial.print(getCalibrateFactor(i), 6); Serial.print(getResource(COMMA_SPACE_KEY)); }
float r = (((float)(m_n[i] - ((i == 3) ? 0 : m_n[i + 1]))) / ((float)N_MAX)) * R_REF * getCalibrateFactor(i);
if (COMPILE_TIME_DEBUG && getDebug()) { Serial.print("r="); Serial.print(r); Serial.print(getResource(COMMA_SPACE_KEY)); }
m_r[i] = r;
float t = pt1000(r);
if (COMPILE_TIME_DEBUG && getDebug()) { Serial.print("t="); Serial.print(t); Serial.print(getResource(COMMA_SPACE_KEY)); }
if (COMPILE_TIME_DEBUG && getDebug()) { Serial.println(); }

View File

@ -85,6 +85,7 @@ private:
unsigned long m_n[NUM_OF_CHANNELS];
float m_calibrateFactor[NUM_OF_CHANNELS];
float m_r[NUM_OF_CHANNELS];
float m_temperature[NUM_OF_CHANNELS];
float m_lastSmoothedTemperature[NUM_OF_CHANNELS];
float m_smoothedTemperature[NUM_OF_CHANNELS];