Parse Serial1 Data Stream - Help Needed

I have an AC inverter that spits out an ASCII text string of its current status every second.

I am tapping that data stream with a Photon via it’s Serial1 UART Line, via the GND and RX pins.

Using the code below from @rickkas7 Serial Guide Serial Tutorial

void setup() {
	Serial.begin(115200);
	delay(1000);
	Serial1.begin(19200, SERIAL_8N1);
}

void loop() {
	// Don't do this! Use a while loop instead of an if to make sure all
	// of the data is processed in each call to loop
	if (Serial1.available()) {
		Serial.write(Serial1.read());
	}

}

I get this output every second:

I wanted to ask the smarter guys on here what do you think is the most efficient way to parse everything except the Checksum line.

Here is what I used on an Arduino to parse the same type of data output from a different product but I’m not sure this is the best way to go about parsing the data.


void loop() {
  // main program loop


 Serial.flush();
 Serial.begin(19200); // I have now figured out that switching the serial port on and off is a better way to go. Switching the serial port on.


    // read each value from the serial port. The integers are defined according to the BMV datasheet to keep things simple.
    // I'm pretty sure that there is a more elegant way of doing this, but it works.

     while (Serial.available() == 0);
      {
        char ch = Serial.read();
        if(ch == 'V') // Wait for the capital V and ignore any detritus before it. The capital V (Voltage) marks the beginning of the data that what we actually want.
        {

   /*We can't use the "int" datatype below because some of the values from the Victron BVM-600 are more than 16 bit.
 For example lets assume the battery current is 28A or 28000mA as transmitted by the BVM, an int would work. As sson as the battery current goes above 32767mA, you'd
 get garbage returned to you. Use of the "long" (32 bit) datatype solves this problem. Similarly for the voltage reading, you'd be fine using an int datatype on a 12 volt or
 even a 24 volt system, but a 48 volt system would cause you problems.
 Therefore I have used the long datatype throughout, it may be a bit slower than int, but the code still runs plenty fast enough at 16MHz to not notice any problems :)
 Don't worry, "Serial.parseInt" despite it's name can still parse the 32 bit  data. */

   long V = Serial.parseInt(); //Battery Voltage

   long I = Serial.parseInt(); //Current in or out of the battery

   long CE = Serial.parseInt(); //Consumed Energy

   long SOC = Serial.parseInt(); //State of charge

   long TTG = Serial.parseInt(); //Time to Go

   long AR = Serial.parseInt(); //Alarm relay state

   long T = Serial.parseInt(); //°C5 Battery temperature

   long P = Serial.parseInt(); //W Instantaneous power

   long Ha = Serial.parseInt(); // This parses the "1" integer from "H1" The next line will parse actual the value of H1
   long H1 = Serial.parseFloat(); //Depth of Deepest Discharge mAh

   long Hb = Serial.parseInt(); // This parses the "2" integer from "H2" The next line will parse the actual value of H2 etc.
   long H2 = Serial.parseInt(); //Depth of Last Discharge (mAh)

   long Hc = Serial.parseInt();
   long H3 = Serial.parseInt(); //Depth of Average Discharge (mAh)

   long Hd = Serial.parseInt();
   long H4 = Serial.parseInt(); //Number of Charge cycles

   long He = Serial.parseInt();
   long H5 = Serial.parseInt(); //Number of full discharges

   long Hf = Serial.parseInt();
   long H6 = Serial.parseInt(); //Cumulative Ah from battery (mAh)

   long Hg = Serial.parseInt();
   long H7 = Serial.parseInt(); //Minimum battery voltage (mV)

   long Hh = Serial.parseInt();
   long H8 = Serial.parseInt(); //Maximum battery voltage (mV)

   long Hi = Serial.parseInt();
   long H9 = Serial.parseInt(); //Days since last full charge (seconds)

   long Hj = Serial.parseInt();
   long H10 = Serial.parseInt(); //Number of times BMV automatically synchronised

   long Hk = Serial.parseInt();
   long H11 = Serial.parseInt(); //Number of Low voltage alarms

   long Hl = Serial.parseInt();
   long H12 = Serial.parseInt(); //Number of High voltage alarms

   long Hm = Serial.parseInt();
   long H17 = Serial.parseInt(); //Amount of discharged energy

   long Hn = Serial.parseInt();
   long H18 = Serial.parseInt(); //Amount of charged energy

   long BMV = Serial.parseInt(); //The 600 part of 600S gets parsed as it is an integer

   long FW = Serial.parseInt(); //Firmware version gets parsed as it is an integer

   long PID = Serial.parseInt(); //Product ID


   //Serial.end(); // Then switch the serial port off, much more elegant.

This looks fine to me as long as the serial connection is steady. If you miss a value, then the remaining values are offset.

Are those tabs between the string and value?

I’m not sure if those are tabs between the labels & the actual data.

I couldn’t get the modified version of the code I posted to work but wanted to know if that type of parsing structure was ideal or not.

I need to play with this some more.

Can you capture about ten seconds and attach a file? I would be happy to take a look at this too.

1 Like