ZPA_elektromer_UARTtest/ZPAElectricity.cpp

119 lines
2.6 KiB
C++
Raw Normal View History

2019-06-13 15:19:31 +02:00
#include "ZPAElectricity.h"
// BCC is calculated as follows (source https://github.com/lvzon/dsmr-p1-parser/blob/master/doc/IEC-62056-21-notes.md):
// The BCC is calculated over the bytes after STX up to and including the ETX byte
// To calculate this BCC, take the first byte XOR 0xff
// XOR this value with the second byte, and so forth up to and including the last byte (include 0x03 ETX !!),
// and XOR the final value with 0xff.
// State flags
bool stateZPAreading = false;
uint32_t lastZPAcharRead = 0;
uint8_t localBCC;
String ZPAreadData = "";
bool ZPAreading() {
return stateZPAreading;
}
void ZPArequestData() {
Serial2.updateBaudRate(300);
Serial.println(F("Requesting data"));
Serial2.print(F("/?!\r\n"));
// Start reading, set up actual time
stateZPAreading = true;
lastZPAcharRead = millis();
}
void ZPAchangeBaudrate(char baud) {
int baudrate = 300;
switch (baud) {
case '1':
baudrate = 300;
break;
case '2':
baudrate = 1200;
break;
case '3':
baudrate = 2400;
break;
case '4':
baudrate = 4800;
break;
}
Serial.print(F("Change baudrate to "));
Serial.print(baud);
Serial.print(F(" ("));
Serial.print(baudrate);
Serial.println(F(")"));
Serial2.write(0x06);
Serial2.print(F("0"));
Serial2.print(baud);
Serial2.print(F("0\r\n"));
Serial2.flush();
Serial2.updateBaudRate(baudrate);
}
void handleZPASerial() {
if (!stateZPAreading)
return;
if (Serial2.available()) {
char r = Serial2.read();
lastZPAcharRead = millis();
if (r == 0x02) {
Serial.println(F("<STX>"));
localBCC = 0xFF;
ZPAreadData = "";
return;
}
if (r == 0x03) {
Serial.println(F("<ETX>"));
Serial.print(F("Checksum <BCC>: "));
uint8_t remoteBCC = Serial2.read();
Serial.print(remoteBCC, HEX);
Serial.println();
Serial.print(F("Calculated <BCC>: "));
localBCC = localBCC ^ r;
localBCC = localBCC ^ 0xFF;
Serial.print(localBCC, HEX);
Serial.println();
Serial.println();
Serial.println(F("Changing back baudrate to 300"));
Serial2.updateBaudRate(300);
stateZPAreading = false;
return;
}
// Calculate BCC checksum
localBCC = localBCC ^ r;
ZPAreadData += r;
Serial.write(r);
}
}
void handleZPA() {
handleZPASerial();
if (stateZPAreading && (millis() > lastZPAcharRead + ZPA_READ_TIMEOUT)) {
Serial.println(F("ZPA Read TIMEOUT, stopping, setting baudrate to 300"));
stateZPAreading = false;
ZPAreadData = "";
Serial2.updateBaudRate(300);
}
}