From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

RT: Processing an incoming VISA RS232 stream

Good morning!

 

I am writing an application to process an incoming stream of serial data, an a cRIO RT platform (no FPGA).

 

I was wondering what might be the best architecture for this.  Essentially I need to read the stream as quickly as possible and search for a specific packet (there is no Termination character; I search for the Start byte, grab a packet length next and then read that length + 2 byte CRC.  If the CRC is good I know I have a valid packet).

 

Right  now my architecture looks like this:

Loop 1; Timed loop (10ms) with higher priority which checks the #Bytes at the port.  If no bytes, no code runs.  If enough bytes are there, the bytes are read and passed to an RT FIFO (as a [U8]).

Loop 2; WHILE loop checks the FIFO.  If no bytes, it will wait 10ms.  If there are bytes it will process the packet.

 

Is this the best architecture, in terms of how I use the FIFO reads and the timed loop/while loop?

Some considerations I made:

  • I check the #Bytes and only call read when there are enough bytes there.  I noticed that CPU is killed if I call READ and have to wait for bytes.
  • The FIFO Read is performed with a 0 sec timeout; if empty, I call the WAIT function.  Is there a better way of doing this?  Packets don't come in regularly, and I need to process them ASAP.

Ideas for improvement?

 

0 Kudos
Message 1 of 3
(2,351 Views)

I have sued the following on RT and cFP controller.

 

If no bytes at port, wait (short to keep system responsive).

If Bytes, read all bytes and append to a Byte buffer (small circular buffer I wrote, a string and shift register might also work)

Throw away any bytes prior to start byte for your packet (since they are not useful),  check for a fulll packet, ifso remove this from buffer and use as data.

 

This worked for GPS Nema streaming data as well as communication with a serial pump in LabViEW RT.

Paul Falkenstein
Coleman Technologies Inc.
CLA, CPI, AIA-Vision
Labview 4.0- 2013, RT, Vision, FPGA
0 Kudos
Message 2 of 3
(2,350 Views)

Thanks for your input.  This is basically what I am doing.  I was just wondering if there was a specifically efficient way of using a combination of timed loops and non-timed loops that would do what I need.

 

FYI, i added some code and here's a little more detail about what I did...

 

 

1) The serial read loop runs in a timed loop with a period of 10ms.

  • If there are no bytes, nothing else executes.
  • If there are bytes, they are read, up to 1024 bytes (non-fixed length)
  • These bytes are inserted into a 1025 byte, pre-allocated buffer.  The length is inserted into the first 4 bytes.
  • This is fed into an RT FIFO to be sent to another loop for processing.  Inserting the length lets the client loop know how many bytes are in this element.

 

2) The Client loop runs as a WHILE loop, and checks the FIFO on each pass.

  • If there is no FIFO element, there is a WAIT of 10ms
  • If there is an element, it is popped off the FIFO.  The element is decoded so that only the valid data is appended to the end of a preallocated 2048 byte buffer.  This is all done with in-place structrues.
  • This buffer is fed to the packet searcher.  If it finds a valid packet, the start byte of the packet is changed (in place structure) so that it will not be detected on a subsequent loop.

 

In this way...

1) If a large number of packets are sent to the serial port, they can be read in chunks up to 1024 bytes at a time.  This helps keep the CPU cycles low.

2) Messages are processed quickly!  If you read a fixed number of bytes, you will have a serial READ buffer sitting idle with < fixed bytes until more data is sent to you.  This way, any bytes will be read in.

3) The RT buffers are fixed length, and there is no new allocation (other then the serial read itself.  This cannot be helped, unless you read a fixed number of bytes).

 

 

I would still like to know if there are any better ideas about specific loop structures (WHILE vs Timed, etc) but this appears to be working well.

 

Now I just have to shoe-horn it into some other code!

0 Kudos
Message 3 of 3
(2,345 Views)