Parsing telemetry from multiple message addresses


Recommended Posts

Hello. I have a question on how to best parse messages of comma-separated values from a serial port. My system has a variable number of devices that each have a high-side (H) and low-side (L) component. Each message sent over the serial port is a comma-separated telemetry string for a single high-side or low-side component.

I would like to take each telemetry string and display the data to the user so that high-side and low-side pairs are displayed on a single page together. I would also like to save data both as history and persist.

Below is the format of a single telemetry message:
SOF,<address>,<high=1/low=0>,<paired device address>,<value 0>,<value 1>,...,<value N>,EOF

So, a sequence of telemetry messages for a system with two devices would look like:
SOF,H1_ADDR,1,L1_ADDR,...,EOF
SOF,L1_ADDR,0,H1_ADDR,...,EOF
SOF,H2_ADDR,1,L2_ADDR,...,EOF
SOF,L2_ADDR,0,H2_ADDR,...,EOF

Because of the design of the system, devices can be added or removed at any time and so new devices must be detected (up to a maximum M number of devices). The system can be running an arbitrary amount of time before opening DAQFactory. And, if DAQFactory is closed and reopened during the lifetime of the system, the telemetry data must be appended to the correct persist arrays.

What is a reasonable way of parsing this data and displaying it? Is it possible to make all of the channels ahead of time and then somehow assign each component address to block of channels at runtime?

Thanks.

Link to comment
Share on other sites

OK, but first I have to say: DAQFactory can't collect data when it isn't running, and Windows won't buffer the data on the serial port, so there is no way for DAQFactory to acquire data on the serial port before it starts, or if it is closed and reopened.  This is a Windows limitation.

As to the question at hand, there are a number of posts on this forum to read data that constantly streams.  The general format is something like:

purge()
while(1)
   readUntil()
   parsedata
endwhile

where the while loop also generally contains a try/catch around the readuntil/parsedata portion, with a catch() that adds a small delay.  You don't need a delay otherwise, and don't want one as it can cause a backlog.  The readuntil() function will generate a delay while waiting for data.

As to the parsing, use the parse() function to parse each line by the comma.  Then it comes down to data manipulation.  So, do the high / low sides need to be combined, or do you want them in different channels?  If different channels, its pretty easy: either name your channels based on a convention based on the addressing, or use the channel.addValue() function to map the addressing to D# and Channel #'s.

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.