hiii, I am getting serial data on my node mcu from the DC energy meter in the below form.
C1.8D1V0.0DWh0.0DAh0.0D
where C is current
V is voltage
wh is watthour
ah amperehour
I want to separate current, voltage, watt-hour and ampere-hour into Float values. So that i can link all these values to Blynk.
/*
Serial Receive Example
no start tag
[Tag Value ValueEndtag]
separated values by ValueEndeTag D
no dedicated end tag
C1.8D1V0.0DWh0.0DAh0.0D
where C is current
V is voltage
wh is watthour
ah amperehour
this variant parses each value during the incoming packet
by noiasca
2022-06-26 https://forum.arduino.cc/t/how-to-parse-serial-data-string-to-integers/1006661
*/
#define BLYNK_TEMPLATE_ID "TMPLC7diGR3d"
#define BLYNK_DEVICE_NAME "SOLAR POWER"
#define BLYNK_AUTH_TOKEN "74xTPoFU8i7s_Ea0NQ6zTnTJHdDgS7Zk"
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SoftwareSerial.h>
char auth[] = "74xTPoFU8i7s_Ea0NQ6zTnTJHdDgS7Zk";
char ssid[] = "Aamir";
char pass[] = "12345678";
SimpleTimer timer;
void myTimerEvent()
{
Blynk.virtualWrite(V1, millis() / 1000);
}
constexpr int dataSize = 16; // size of data array
class Receiver {
protected:
static const byte numChars = 36; // receiver buffer size ( we process just <+integer+blank so a short buffer is ok
char receivedChars[numChars]; // an array to store the received data
byte ndx = 0; // length of received message
//boolean newData = false; // flag to indicate when new data is complete
Stream &stream; // a reference to the serial interface
void (*cbOnNewData)(); // gets called after we received a full message
void delBuffer()
{
memcpy(receivedChars, "", sizeof(receivedChars));
ndx = 0;
}
void debugDataHex()
{
for (size_t i = 0; i < ndx; i++)
{
if (receivedChars[i] < 0x10) Serial.print('0');
Serial.print(receivedChars[i], HEX);
Serial.print(' ');
}
Serial.println();
}
void parseData() // parse data and store to internal variables
{
receivedChars[ndx] = '\0';
switch (receivedChars[0])
{
case 'C':
current = atof(receivedChars + 1);
break;
case 'V':
voltage = atof(receivedChars + 1);
break;
case 'W':
watthour = atof(receivedChars + 2);
break;
case 'A':
amperehour = atof(receivedChars + 2);
break;
}
delBuffer();
}
public:
// payload data
float current = 0;
float voltage = 0;
float watthour = 0;
float amperehour = 0;
Receiver (Stream &stream) : stream(stream)
{
delBuffer();
}
void setOnNewData(void (*cbOnNewData)()) // set a callback function. Gets called when new data was received
{
(*this).cbOnNewData = cbOnNewData;
}
void update() // run this member function in loop()
{
constexpr byte endMarker = 'D'; // end flag
if (stream.available() > 0) {
char rc = stream.read();
if (rc == 'C' || rc == 'V' || rc == 'W' || rc == 'A') // new message
{
delBuffer();
receivedChars[ndx] = rc;
ndx++;
}
else if (rc == endMarker) // end of value
{
receivedChars[ndx] = rc;
ndx++;
parseData(); // parse data after each delimiter
if (rc == endMarker && cbOnNewData) cbOnNewData(); // optional call callback when we have received a full message
}
else if (ndx < numChars) // append incoming character to receivedChars
{
receivedChars[ndx] = rc;
ndx++;
}
// sanity check
if (ndx >= numChars) delBuffer();
}
}
};
// create the sensor object and hand over the Serial interface to use:
HardwareSerial &mySerial = Serial; // just a refernce to Serial called "mySerial"
Receiver device(mySerial); // use Hardware Serial (for example for testing with the PC)
//#include <SoftwareSerial.h> // on an Uno you can use SoftSerial with SLOW speeds
//SoftwareSerial mySerial(3, 1); // RX, TX
//Receiver device(mySerial);
// On a Mega you can simply use
// a Reference to an existing HW Serial:
//HardwareSerial &mySerial = Serial1;
//Receiver device(mySerial);
void output() // simple output of data
{
Serial.println(device.current);
Serial.println(device.voltage);
Serial.println(device.watthour);
Serial.println(device.amperehour);
Blynk.virtualWrite(V0, device.current);
Blynk.virtualWrite(V1, device.voltage);
Blynk.virtualWrite(V2, device.watthour);
Blynk.virtualWrite(V3, device.amperehour);
}
void timerOutput() // a timer to output data to serial
{
static uint32_t previousMillis = 0; // time management
const uint16_t interval = 5000; // interval to display data
if (millis() - previousMillis >= interval)
{
previousMillis = millis();
output();
}
}
void setup() {
Serial.begin(9600);
mySerial.begin(9600);
Blynk.begin(auth, ssid, pass);
timer.setInterval(2000L, myfunction1);
//device.setOnNewData(output); // register a callback function which gets called when a new telegram was received
}
void myfunction1()
{
}
void loop() {
device.update(); // you must call the .update() method in your loop()
timerOutput();
Blynk.run();
timer.run();
}
I am able to parse data when and only if i type on the serial monitor and click on the send, then i get the floating values, as you can see i am getting serial data from the DC energy meter but it is not parsing.







