Seeking Methods to Increase Serial Throughput
-
- Posts: 163
- Joined: 24 March 2008, 23:33 PM
- Location: Southern California (Blue)
Seeking Methods to Increase Serial Throughput
I wrote code for the ZX-40a to capture time (gettime) and voltage (getadc) for 30 seconds from a photoresistor and transmit serially (debug.print) to Matlab. My goal is to capture time histories in Matlab and compute Power Spectral Density plots to resolve frequencies of a vibrating structure. I used ZX-40a's hardware COM1 (19200bps) for this operation. All worked as planned. However, I was surprised that the update rate captured in Matlab was only 100Hz. If I remove the gettime() command, the update rate improves to 200Hz. If I remove the debug.print command, the update rate is 2,000Hz. So the debug.print command and console.write dramatically slow the transmission. Is there a way to increase serial throughput? Thank you.
Re: Seeking Methods to Increase Serial Throughput
Up to a point, yes. You'll still be limited by the volume of characters that you're outputting. The minimum time required to transmit a character is 10 / baudRate (assuming 8 data bits, 1 stop bit). Obviously, you can reduce the aggregate transmission time by reducing the number of bytes transmitted or by increasing the baud rate.liam.zbasic wrote:Is there a way to increase serial throughput?
Assuming that you're using Com1, the other thing that might be helpful is to use a larger output queue. The default queue only has space for 4 bytes of data. That means that any time you add data to the queue, you're program will likely stall waiting for queue space.
Here is a snippet of code showing how to do that while retaining the default input queue.
Code: Select all
Dim com1OutQueue(1 to 50) as Byte
...
Call OpenQueue(com1OutQueue)
Call CloseCom(1)
Call OpenCom(1, 19200, CByteArray(Register.RxQueue), com1OutQueue)
- Don Kinzer
-
- Posts: 163
- Joined: 24 March 2008, 23:33 PM
- Location: Southern California (Blue)
You say you want FASTER, but how fast do you NEED it to be?
115200 baud is probably the fastest reliable connection you will get. If you just send 2 bytes of ADC data, the time to send those 2 bytes will be 20/115200 seconds. I.E. 5760 Hz. Most likely you get half that speed in real life. But, I think it might be possible to do the ~2900Hz.
With reasonable pacingof the timing of the ADC conversions, you might be able to use a very short output queue.
I would not use Debug.Print for this purpose. Open Com1 as a real com port. I believe it will work in the background while debug.print will not.
It would be interesting to see the difference in speed for the VM vs. Native Mode actual bandwidth.
-Tony
115200 baud is probably the fastest reliable connection you will get. If you just send 2 bytes of ADC data, the time to send those 2 bytes will be 20/115200 seconds. I.E. 5760 Hz. Most likely you get half that speed in real life. But, I think it might be possible to do the ~2900Hz.
With reasonable pacingof the timing of the ADC conversions, you might be able to use a very short output queue.
I would not use Debug.Print for this purpose. Open Com1 as a real com port. I believe it will work in the background while debug.print will not.
It would be interesting to see the difference in speed for the VM vs. Native Mode actual bandwidth.
-Tony
-
- Posts: 163
- Joined: 24 March 2008, 23:33 PM
- Location: Southern California (Blue)
You're right, there is a subtle difference between Debug.Print and PutQueueStr(). When Debug.Print is invoked, the calling task is effectively locked during time required to add the characters of the string to the queue. Note, however, that each element of a semi-colon separated sequence of strings is handled separately and a task switch may occur between the strings. Console.Write() and Console.WriteLine() have the same behavior. In contrast, PutQueueStr() will yield to another task if there is insufficient space in the queue for the entire string provided.spamiam wrote:I would not use Debug.Print for this purpose. Open Com1 as a real com port. I believe it will work in the background while debug.print will not.
The primary reason for this difference is so that Debug.Print/Console.Write can function with the relatively small default output queue size. If the output queue has enough empty space to accommodate the entire string, there is essentially no difference between Debug.Print/Console.Write() and PutQueueStr()
- Don Kinzer
Well, 2000Hz samples will be pushing the limits, I think. It is nearly 50% of the bandwidth of the 115200 baud connection right off the bat.dkinzer wrote:If the output queue has enough empty space to accommodate the entire string, there is essentially no difference between Debug.Print/Console.Write() and PutQueueStr()spamiam wrote:I would not use Debug.Print for this purpose. Open Com1 as a real com port. I believe it will work in the background while debug.print will not.
There will be VERY little room for additional info/control characters to go over the com port.
Since timing will be a bit of an issue to keep the interval between ADC samples very even, the com port should not require a big queue. Essentially only as large as all the data and control for one sample. If, on average, the data comes in faster than it can get out of the queue, eventually it will block or overrun.
I think it is potentially feasible to get close to 2KHz sampling. Probably the ADC unit will need to be set to do samples autonomously, then the ADC result gets read by the program at a specified interval. That 16 bit value gets put into the com queue, along with as little control data as possible.....
-Tony