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.