I am reading serial data from my electric meter over an IR interface. After finding the right setup for the hardware, I am at a point now where I get the meter data shown in the serial monitor. I am using SoftwareSerial and simple functions like Serial.read (byte by byte) and write this into the serial monitor.
My goal is to extract the actual power consumption and write it to a thingspeak channel later (will be done using ESP8266).
Situation: I get a long message each time I am sending a request for data to the meter. I need to extract the actual power consumption only and write it to a variable (float).
The message in the serial monitor looks like this (and is aprox. 100 lines in total):
But I just need the values in the bracket after indicator "1.7.0", so I tried to run this over if-cases, byte by byte. The code looks messy and it is not working, but I hope my intention gets clearer.
(This was to test if the serial monitor is now only showing the power readings.)
Question: Is there a better way (I am sure there is), and how might that look?
Thanks in advance!
void loop() {
float actual =0.000;
if (ir.available())
{
int inByte = ir.read();
if (inByte == '1') //Byte "1"
{
inByte = ir.read(); //Byte "."
if (inByte == '.')
{
inByte = ir.read();
if (inByte == '7') //Byte "7"
{
inByte = ir.read();
if (inByte == '.') //Byte "."
{
inByte = ir.read();
if (inByte == '0') //Byte "0"
{
inByte = ir.read(); // read and disregard, this is "("
inByte = ir.read(); // first digit of power
Serial.write(inByte);
//actual = ir.read();
Serial.write(0);
inByte = ir.read(); // first decimal
Serial.write(inByte);
//actual = actual + ir.read()/10;
inByte = ir.read(); // second decimal
Serial.write(inByte);
//actual = actual + ir.read()/100;
inByte = ir.read(); // third decimal
Serial.write(inByte);
//actual = actual + ir.read()/1000;
}
}
}
}
}
}
}
The use of String is restricted to big controllers, an ESP may be usable, but a char array for buffering a single line of text should be sufficient. This buffer can be searched for the delimiters and the numbers can be extracted as text. For number conversion, if required, the lower level atof() functions can be used, or simpler homebrew algorithm like the one already implemented in the comments.
@DrDiettrich
Is there any way to declare/allocate a limited, defined string and play around inside that string?
I have a background from Business Basic and other string friendly Basics like the old Quick Basic. There strings can be used nicely.
Handling of data in char arrays is a basic task in many C programs. I don't see how substrings will considerably simplify coding of text processing, in contrast to explicit indices or pointers and length.
Dear all, thank you very much for your valuable thoughts and the support! Great community!
@PaulRB: I really like your idea, it is simple and works very well! Thank you so much, this was exactly what I needed. I think I can take it from here.
One remaining question is: Would this also allow to search for a second string, i.e. "1.8.0" and put the float that follows after 1.8.0 into another variable? (So I can extract multiple floats out of the serial stream?)
le_1982:
Would this also allow to search for a second string, i.e. "1.8.0" and put the float that follows after 1.8.0 into another variable? (So I can extract multiple floats out of the serial stream?)
Yes, easy, provided that each & every message always contains all the values you need, and they are always in the same sequence (from your description, it sounds like that's true). Simply repeat the above code to search for and read each value in the order they appear in the message.