LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Fast data processing from serial port

Solved!
Go to solution

Hello everyone,

 

please can someone help me with following problem?

 

I´m using my own DAQ electronics for fast data sampling from magnetic probe and sending data over UART (using fast FT232H UART->USB converter IC). (Samplerate is now 64kSa/s, the goal is to get as high as 128kSa/s). DAQ digital resolution is 24 bit, so I need to send at least 3 Bytes of data (to synchronize packets I'm sending 5 Bytes ... 3 Bytes of data constrained to 7bit, then residue 3 bits + 8th bit, and just 0xAA value....).. All this together it means 64000x5x11 bites per second = 3,6Mbit/s... UART speed is now 6 Mbit/s (maximum is 12Mbit/s) ...so should be enough..

 

After troubleshooting slow UART reading (UART buffer always overflowed), now with fast timedloop, I'm reading data fast enough from UART and append them to queue. But I'm not able to do something with them so fast... (I'd like to calculate and see realtime spectrum - PSD and maybe Y-t plot... it would be needed to add some averaging or triggering - update rate of Y-t plot is uncomfortable high...)

 

Any ideas, why it is so slow, that it can not handle such samplerate? (queue size is increasing fastly with on time - it is possible to see increasing delay between real data and Y-t plot or PSD)

 

And one another (little) problem is that timedloop sometimes don't run as fast as it should (and then even UART reading is overflowing..), it seems to be about 1/4 cases... timed loop priority is set to maximum and VI execution priority seems to don't affect that (but it is on almost maximum, maximum don't support timed loops)...

 

I´m also attaching LV2015 project

 

 

Best Regards,

David N.

0 Kudos
Message 1 of 21
(7,386 Views)
Solution
Accepted by topic author teslista

David,

     Here are some suggestions.

  • Do not use Sequences -- they are unnecessary (the Error Lines provide all the sequencing you require) and contribute to Block Diagram Bloat.
  • Let your VISA Read "Self-Clock".  You have a Termination Character specified, so eliminate the unnecessary "Bytes at Port" property, tell VISA to read 1024 bytes (it will read far fewer, stopping when it gets the <LF>), so you now know you have an entire String to process, much simpler code.
  • Get rid of Timed Loops, which mainly have meaning in Real-Time Systems with Real-Time OS's (i.e. not Windows).  Let the top loop be a proper Producer loop that runs as fast as the VISA can spit out data.
  • Make the top loop a true Producer -- have the result put on a Queue for processing, and take all the additional computation out of that loop and put it in the less-time-critical Consumer loop.
  • Keep your loops "lean".  Do you really need to call the Precision Timer for every "tick", or can you call it every 1000th iteration (use the Remainder function on the loop index) and get an approximate rate?
  • Get rid of the Local Variables!
  • Learn better ways to stop multiple loops (without Local Variables).
  • When your Block Diagrams sprawl, it becomes very difficult to understand what you are trying to do.  In some cases, it may be "Log to Disk" or "Format for Chart", in which case they should be "encapsulated" into a 32x32 Pixel sub-VI (saving huge amounts of screen space).  If you create a simple Text Icon for each sub-VI (a Box with text saying "Log to Disk", for example), even an idiot could "guess" what you are trying to do.  Strive to get the entire Block Diagram on a single page.
  • Another way to save Block Diagram Space is to not wire default values to common Functions.  Obtain Queue, for example, usually needs only one input, the Queue Element Type (and, of course, Error In).
  • I just re-read your original post, and now have a UART question.  Your VISA is initialized to use a termination character (0x0A, LineFeed), yet you talk about transmitting 24-bit sampled data.  I haven't looked to see where/how you are handling the data, but how does your DAQ system send it?  You need to do something to guarantee you don't send the byte sequence 0x0A as "data", since this is reserved for EOL.  Are you transmitting the 24-bit number as an Ascii stream of characters?  Are you sending it as, say, 4 "chunks" of 7 bits at a time, always setting the MSB "true" (to prevent transmission of 0x0A as "data") and then sending 0x0A?  [This is consistent with the "send 5 bytes to get 24 bits across"].
  • If you are sending "encoded" 24-bit messages as I just suggested, I'd change the Producer and its Queue slightly.  Each VISA stream should consist of 4 data bytes and 0x0A.  I'd "pre-package" this String by converting the first four characters to U8s, ignoring the <LF>, and make the Queue an Array of U8.
  • As a side benefit, this provides you a very nice way to have an orderly shutdown of a multi-loop routine without Local Variables.  Proceed as follows:
    1. Make the Stop Button a Latch when Released button (you don't need to initialize it), and place it in the Producer Loop to stop the Producer.
    2. When the Producer exits, it shuts down VISA, and sends an empty Array to the Consumer using the Array-of-Bytes Queue.  It leaves the Queue intact.
    3. The Consumer (which is sitting there waiting to dequeue) checks the Array to see if it is empty.  If not, it processes it.  If it is empty, then the Consumer knows Stop has been pressed, so it can stop.  When it exits, it knows the Producer has stopped putting stuff in the Queue, so it can Release the Queue safely.
    4. You have a second Producer/Consumer Queue going from your lowest loop (Producer) to the upper-most (plotting, Consumer) Loop.  You can use a variant of this idea, called a "Sentinel", to get the bottom loop, when it exits, to tell the Top loop to stop and exit.

Bob Schor

Message 2 of 21
(7,350 Views)

Hello Bob,

 

thank you very much for such a fast respond and many advices,

 

one (little embarrassing) mistake I have made - termination character should be OFF! (my 5 Bytes chunk did not contain 0x0A - sometimes it did, but not purposely - just randomly - but in most cases yes, so it behaved like it worked..) - with only this change, it works pretty good - except writing to file - that make some trouble with lagging -  Y-t chart and PSD works properly until I add path to file to write... (too slow access to file?)

 

Purpose of timed-loop is reading data as fast at it can - while loop that read data from UART everytime when termination character arrive is too slow. After loop execute each one iteration, Windows take processor time from labview thread and assign it back after some time (about 10ms), and in this time UART (probably HW/driver) buffer overrun (0.01s x 5 x 64000 =  3200 Byte)... (Well, probably.. I don't understand OS very much...)

 

I'v tried to use structure "producer-consumer" as you suggested, but I came across slow reading problem again... I'm attaching that modification (I have also changed byte chunk to that you recommended - all bytes have MSB=1, only last byte is just 0x0A)..

 

I´m attaching new version with "producer-consumer" idea... "Average datarate" should be 64kS/s x 5B = 320kByte/s, but is about only 100kB/s.. wich indicates too slow reading)...

 

 

Thank you!

 

Best Regard,

David

 

0 Kudos
Message 3 of 21
(7,253 Views)

Are you insane?

 

seriously, 3 bytes at 7 bits = 21 much less than the 24bit ADC value. Then you actually set up the VISA port for 8 bits.  OK

 

Then you have a ridiculous rate of 6Mbaud ( i hope the phy layer is really short) a 10 second timeout and a 100k buffer. and expect it to not overflow the buffer? with 1 start bit 1 stop bit, 1 parity bit and 8 data bits  a 100K buffer gets filled a lot faster than 10 seconds.

 

6MBaud, I still can't quite wrap my head around that.  0ne 24 bit ADC value every 16.7n (Nano)-Seconds ?

I gotta get me one of those.


"Should be" isn't "Is" -Jay
Message 4 of 21
(7,243 Views)

Hello Jeff,

 

I really don't understand your little bit aggressive tone, I wrote, that I have 24bit@64kSa/s, not every 11,7n... if I would have 85MSa/s@24bit, then I would be a millionaire or something 🙂

 

And I do not have 3x7bit=21bit.. I wrote that I have 3x 8bit + rest of 24bit (3 bits) in another byte = 4x8bit (all have MSB=1) and then 1 byte with MSB=0 (0x10) to synchronizing packets... so... I really don't think that 6Mbaud is ridiculous... (5 Bytes @ 64k/s @ 11bit/Byte = 3,54 MBaud as theoretical minimum!) 

 

100k buffer is just random big value (I suppose that HAL layer will constrain it to its maximum, 4k or 32k.. I don't know)...

10s timeout is just again a random number, it means that if device will stop do anything, then after 10s VISA will timeout... Data are readed in timed loop every 1ms = 320 byte - HW buffer is 1k, SW buffer (maybe) 100k...

 

 

Best Regards,

David

0 Kudos
Message 5 of 21
(7,226 Views)

I wasn't trying to be offensive.  6 mega baud is crazy fast.  Most hardware cannot work with that speed over any distance.

 

I mearly meant for you to help clarify the real requirements.  

 

Seriously,what are you attached to?  How fast does the measurement change? 


"Should be" isn't "Is" -Jay
Message 6 of 21
(7,203 Views)

Jeff is right.  6Mb to 12 Mb/sec is crazy fast for a serial port.  If you think about it, that is the speed of low speed ethernet ports, and they rely on special hardware and twisted pair, low capacitance wire to achieve that.  Normal serial ports (are you talking RS-232 or RS-485) and wiring weren't designed for that.

 

Take a look at this.

http://digital.ni.com/public.nsf/allkb/D37754FFA24F7C3F86256706005B9BE7

 

You can see that NI-VISA can handle up to about 1 Mbit/sec on special hardware.  You're looking for 6-12 times faster.

Message 7 of 21
(7,193 Views)

Kudos for anyone​

 

I think it was John Candy that had a great line in Spaceballs the Movie.

 

We've gone to plaid.

 

As I recall plaid is faster than "ludicrous speed"


"Should be" isn't "Is" -Jay
Message 8 of 21
(7,183 Views)

Hello,

 

ok, althought HW works properly, let me explain the HW part... I have a tiny (about 4x8cm) DAQ board with ADC+MCU+FT232H ... MCU reads data from ADC over SPI (clocked to 12 Mb/s), then immediately sends them over UART (TTL, not RS232 levels) to FT232H IC (~2cm traces), I realy don't see problem with such speed for the distance... (If it would use RS232 levels and we talk about meters of distance, then ok.. 6M is really insane...)

 

And speed of VISA is limited by driver, right? Well, FT232H is designed for such purpose (supports 12Mbaud/s UART), so we can call it "specialized" HW 🙂

 

Best Regards,

David

0 Kudos
Message 9 of 21
(7,169 Views)

Hi David,

 

so you described the sender part of your RS232 communication.

What's the receiver at the other end (probably your PC)? Can it handle this baudrate?

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 10 of 21
(7,162 Views)