diff --git a/Resources.cpp b/Resources.cpp index 73dd304..68aec5f 100644 --- a/Resources.cpp +++ b/Resources.cpp @@ -80,6 +80,8 @@ const String TEXT_RESOURCES[] = { "invalid frames: ", "invalid checksum: ", "mbus address: ", + "collisions: ", + "r: ", }; diff --git a/Resources.h b/Resources.h index 7f40f94..cb026e9 100644 --- a/Resources.h +++ b/Resources.h @@ -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); diff --git a/ThermometerPro.cpp b/ThermometerPro.cpp index 5bf8866..b08c53a 100644 --- a/ThermometerPro.cpp +++ b/ThermometerPro.cpp @@ -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); } diff --git a/meterBusClient.cpp b/meterBusClient.cpp index cca01f2..883f8a4 100644 --- a/meterBusClient.cpp +++ b/meterBusClient.cpp @@ -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: diff --git a/meterBusClient.h b/meterBusClient.h index 2e092a6..1ad2b22 100644 --- a/meterBusClient.h +++ b/meterBusClient.h @@ -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(); diff --git a/meterBusClientFrames.cpp b/meterBusClientFrames.cpp index e1f021c..90dc0c1 100644 --- a/meterBusClientFrames.cpp +++ b/meterBusClientFrames.cpp @@ -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); } diff --git a/thermometer.cpp b/thermometer.cpp index 4b77571..7f6c538 100644 --- a/thermometer.cpp +++ b/thermometer.cpp @@ -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(); } diff --git a/thermometer.h b/thermometer.h index 3878e8c..f551afd 100644 --- a/thermometer.h +++ b/thermometer.h @@ -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];