I encounter the following problem. The library that I'm using needs a whole "telegram". A telegram always starts with '/' and ends with '!' and is closed by a crc checksum of 4 characters.
This is what a telegram looks like:
/XMX5LGBBFG1012478418
1-3:0.2.8(42)
0-0:1.0.0(200329143717S)
0-0:96.1.1(4530303331303033323531323636363136)
1-0:1.8.1(009159.772kWh)
1-0:1.8.2(006069.669kWh)
1-0:2.8.1(000000.000kWh)
1-0:2.8.2(000000.000kWh)
0-0:96.14.0(0001)
1-0:1.7.0(00.409kW)
1-0:2.7.0(00.000kW)
0-0:96.7.21(00001)
0-0:96.7.9(00000)
1-0:99.97.0(0)(0-0:96.7.19)
1-0:32.32.0(00000)
1-0:32.36.0(00000)
0-0:96.13.1()
0-0:96.13.0()
1-0:31.7.0(003A)
1-0:21.7.0(00.409kW)
1-0:22.7.0(00.000kW)
0-1:24.1.0(003)
0-1:96.1.0(4730303139333430323930303538323136)
0-1:24.2.1(200329140000S)(05387.414m3)
!BE43
I adjusted my sketch to use a start marker '/' and an end marker '!' so I can catch the whole telegram. The start and end marker are also removed by the sketch but I don't want them to be removed because the library needs them.
#include <WiFi.h>
#include <WiFiMulti.h>
#include "dsmr.h"
WiFiMulti wifiMulti;
using MyData = ParsedData<
/* String */ identification,
/* String */ p1_version,
/* String */ timestamp,
/* String */ equipment_id,
/* FixedValue */ energy_delivered_tariff1,
/* FixedValue */ energy_delivered_tariff2,
/* FixedValue */ energy_returned_tariff1,
/* FixedValue */ energy_returned_tariff2,
/* String */ electricity_tariff,
/* FixedValue */ power_delivered,
/* FixedValue */ power_returned,
/* FixedValue */ electricity_threshold,
/* uint8_t */ electricity_switch_position,
/* uint32_t */ electricity_failures,
/* uint32_t */ electricity_long_failures,
/* String */ electricity_failure_log,
/* uint32_t */ electricity_sags_l1,
/* uint32_t */ electricity_sags_l2,
/* uint32_t */ electricity_sags_l3,
/* uint32_t */ electricity_swells_l1,
/* uint32_t */ electricity_swells_l2,
/* uint32_t */ electricity_swells_l3,
/* String */ message_short,
/* String */ message_long,
/* FixedValue */ voltage_l1,
/* FixedValue */ voltage_l2,
/* FixedValue */ voltage_l3,
/* FixedValue */ current_l1,
/* FixedValue */ current_l2,
/* FixedValue */ current_l3,
/* FixedValue */ power_delivered_l1,
/* FixedValue */ power_delivered_l2,
/* FixedValue */ power_delivered_l3,
/* FixedValue */ power_returned_l1,
/* FixedValue */ power_returned_l2,
/* FixedValue */ power_returned_l3,
/* uint16_t */ gas_device_type,
/* String */ gas_equipment_id,
/* uint8_t */ gas_valve_position,
/* TimestampedFixedValue */ gas_delivered,
/* uint16_t */ thermal_device_type,
/* String */ thermal_equipment_id,
/* uint8_t */ thermal_valve_position,
/* TimestampedFixedValue */ thermal_delivered,
/* uint16_t */ water_device_type,
/* String */ water_equipment_id,
/* uint8_t */ water_valve_position,
/* TimestampedFixedValue */ water_delivered,
/* uint16_t */ slave_device_type,
/* String */ slave_equipment_id,
/* uint8_t */ slave_valve_position,
/* TimestampedFixedValue */ slave_delivered
>;
struct Printer {
template<typename Item>
void apply(Item &i) {
if (i.present()) {
Serial.print(Item::name);
Serial.print(F(": "));
Serial.print(i.val());
Serial.print(Item::unit());
Serial.println();
}
}
};
const byte numChars = 5000;
char receivedChars[numChars]; // an array to store the received data
boolean newData = false;
//how many clients should be able to telnet to this ESP32
#define MAX_SRV_CLIENTS 10
const char* ssid = "xxxxx";
const char* password = "xxxxx";
WiFiServer server(23);
WiFiClient serverClients[MAX_SRV_CLIENTS];
HardwareSerial Serial_one(1); // UART1/Serial1 pins 16,17
void setup() {
Serial.begin(115200);
Serial_one.begin(115200, SERIAL_8N1, 2, 3, true);
Serial.println("\nConnecting");
wifiMulti.addAP(ssid, password);
wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2");
wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3");
Serial.println("Connecting Wifi ");
for (int loops = 10; loops > 0; loops--) {
if (wifiMulti.run() == WL_CONNECTED) {
Serial.println("");
Serial.print("WiFi connected ");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
break;
}
else {
Serial.println(loops);
delay(1000);
}
}
if (wifiMulti.run() != WL_CONNECTED) {
Serial.println("WiFi connect failed");
delay(1000);
ESP.restart();
}
//start UART and the server
server.begin();
server.setNoDelay(true);
Serial.print("Ready! Use 'telnet ");
Serial.print(WiFi.localIP());
Serial.println(" 23' to connect");
}
void loop() {
recvWithStartEndMarkers();
showNewData();
uint8_t i;
if (wifiMulti.run() == WL_CONNECTED) {
//check if there are any new clients
if (server.hasClient()){
for(i = 0; i < MAX_SRV_CLIENTS; i++){
//find free/disconnected spot
if (!serverClients[i] || !serverClients[i].connected()){
if(serverClients[i]) serverClients[i].stop();
serverClients[i] = server.available();
if (!serverClients[i]) Serial.println("available broken");
Serial.print("New client: ");
Serial.print(i); Serial.print(' ');
Serial.println(serverClients[i].remoteIP());
break;
}
}
if (i >= MAX_SRV_CLIENTS) {
//no free/disconnected spot so reject
server.available().stop();
}
}
//check clients for data
for(i = 0; i < MAX_SRV_CLIENTS; i++){
if (serverClients[i] && serverClients[i].connected()){
if(serverClients[i].available()){
//get data from the telnet client and push it to the UART
while(serverClients[i].available()) Serial1.write(serverClients[i].read());
}
}
else {
if (serverClients[i]) {
serverClients[i].stop();
}
}
}
}
else {
Serial.println("WiFi not connected!");
for(i = 0; i < MAX_SRV_CLIENTS; i++) {
if (serverClients[i]) serverClients[i].stop();
}
delay(1000);
}
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '/';
char endMarker = '!';
char rc;
while (Serial_one.available() > 0 && newData == false) {
rc = Serial_one.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\n'; // terminate the line
++ndx;
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
void showNewData() {
uint8_t i;
if (newData == true) {
Serial.print(receivedChars);
MyData data;
ParseResult<void> res = P1Parser::parse(&data, receivedChars, lengthof(receivedChars), true);
if (res.err) {
// Parsing error, show it
Serial.println(res.fullError(receivedChars, receivedChars + lengthof(receivedChars)));
} else {
// Parsed succesfully, print all values
data.applyEach(Printer());
}
//push UART data to all connected telnet clients
for(i = 0; i < MAX_SRV_CLIENTS; i++){
if (serverClients[i] && serverClients[i].connected()){
serverClients[i].write(receivedChars);
}
}
}
newData = false;
}
Is there another way to capture the whole telegram? If that's not possible, can I insert the removed start and end marker which are needed by the library?