large volumes of serial data ?

Status
Not open for further replies.

Gadget999

Well-known member
I have a windows app that transmits pwm information to a Teensy 3.2 (it is a replacement for an older board)

i was finding some delays in the Teensy outputting the desired pwm and discovered the problem was related to the volume of data

by slowing down the transmission of data from the windows app the Teensy is happy and outputting clean pwm

however the delays have ruined the response of the app :(

you can see the discussion about it here -- https://forum.pjrc.com/threads/56198-analogWriteResolution

---------------------------------------------------------------------------------------------

from what i understand a uart port will make sure the latest data is sent and the previously sent data can get lost

the usb serial makes sure all data arrives in order - is this what is causing my delays

what is a good strategy for sending serial data and not getting delays

( i did try the Teensy with a UART port connected to pins 9 and 10 and there was no improvement, i do not seem to be able to get the uart to wok on high serial speeds ie 115200 )
 
For sure, it's not a Teensy problem. It happily runs its UART at 2 megabauds (tried it myself).
 
The other thread has useful back ground information to understand some of the issue here ... i.e continue there or add more details here perhaps.

to wit:: This needs to replcate the behavior of an exisiting system with some set of ASCII strings of about 10 characters - at the fastest how often is that string expected to arrive?

By Teensy standards 115200 is not high speed UART - it can reliably handle 4 or 10 or maybe 20 times that on T_3.2 Serial1 or Serial2.

The only issue would be data integrity and buffer overflow if the receive buffers are not kept empty, or not large enough to hold incoming data during other activity. Data buffers can be expanded beyond the default 40 or 64 bytes.


Also on that thread it was noted that USB is overall faster and more reliable for data integrity. But as Paul noted is harder to test from the PC side with timely sample data and timing.


Perhaps you could emulate the desired behavior on a single Teensy with a sample data stream including valid data and expected timing where messages are sent out Serial2 at some desired rate to match the required behavior. This would be a self contained sketch Paul or anyone coudl replicate.

Then Tie Serial1 Rx to Serial2 Tx and [the Tx to Rx in reverse] and set do a common .Begin(1152000) on both of those Serial1 and 2 ports.

Then read and parse Serial1 data string and print them as received to USB and execute the interpreted analogwrite commands.


Once that is working as needed the data stream from USB could be processed from USB's Serial [replacing Serial1 read in above emulation] - or from a source USB<>Serial adapter to feed UART of Serial1
 
thank you for your feedback and suggestions

using another teensy - thats a great idea !

i will program another teensy to send data and report back the results

( i am also investigating how to access the com port directly without using a custom control :) )
 
Indeed - works either way same or second Teensy - didn't want to assume you had another on hand.

A bit harder to manage maybe with all on one - but then it would be easier to have anyone repro and setup - and only one sketch to edit and upload.
 
Several years ago, back when Teensy 3.0 was the newest model, I published some benchmarks for sending large amounts of data from a PC to Teensy. While it was motivated by the many people wishing to control addressable LEDs, the info is probably applicable to your PWM output use.

https://www.pjrc.com/teensy/benchmark_usb_serial_receive.html

You can find the source code used for all the tests, linked right from that page. Maybe running those tests can help you confirm performance? Maybe the test code can give you a start on writing code to transmit data from your application?

As you can see on that page, on Windows you really must transmit data in fairly large chunks to have any hope of achieving the full USB performance. No matter how fast the Teensy side is, Windows does things very slowly if you write only 1 byte at a time. Very old legacy code which was originally designed to put 1 byte at a time directly into UART registers (like back in the days of DOS and Windows 3.1) may have been converted to run on modern windows by transmitting 1 byte at a time into the Windows API. As you can see in the results we published on that old page, that sort of writing runs extremely slow on Windows. Only Macintosh does well with single byte writes.
 
Hi Paul,

thanks for the information and link to the code

i am away for a few days and will think about a plan when i return

i will get 2x teensy to talk to each other first and then try and replicate the transmission of data from windows
 
Ok - i made some progress today with getting to the bottom of the problem

i wrote some code to an arduino nano - to replace the windows app and talk to the serial port directly

Code:
int PWMVal = 0;
int I = 0;
int Step = 1;


void setup() {
 
Serial.begin(115200) ;  
}

void loop() {
  
  I  = I + Step;
  
  if (I <= 0 || I  >= 65535) {
    Step = -Step;
  }

Serial.print("PWM");
Serial.print(I);
Serial.print(",");
Serial.print(I);
Serial.println(",0,0");

 
}


i connected the tx/rx to the Serial2 ports of the teensy that is reading the values and converting them to pwm outputs on pins 5 and 6

same problem !!!!!!!!!!

the Teensy is stuttering stepping

My guess is the analogue write can only be written so fast !

i changed the code to the following with a 10 ms delay

Code:
int PWMVal = 0;
int I = 0;
int Step = 1;


void setup() {
 
Serial.begin(115200) ;  
}

void loop() {
  
  I  = I + Step;
  
  if (I <= 0 || I  >= 65535) {
    Step = -Step;
  }

Serial.print("PWM");
Serial.print(I);
Serial.print(",");
Serial.print(I);
Serial.println(",0,0");

delay(10);
 
}

problem gone !!


as a final test i will try this again using a Teensy 3.2 to send the data instead of a Nano
 
for some reason I don't seem able to get 2 Teensys to talk to each other like the Nano / Teensy did earlier :(

but either way i think this experiment shows the problem is in the Teensy not the Windows app feeding the Teensy with PWM commands.

is it worth trying a Teensy 3.5 / 3.6 ?
 
update - i tried the Nano sending data with a 5ms delay and the Teesny goes through periods of stuttering and then stuttering after a while it seems ok, then it struggles again (at 10ms delay there was no stuttering)
the periods of stuttering do appear to be related to smaller requests for PWM

i have programmed LED13 to flash on and off every other time it gets data - the led is stuttering at the same frequency as the PWM output appears to be stuttering
 
Just a glance but I only see that loop printing uncontrollably - except when adding a delay?

That makes sense as the PC is slower receiving than the Teensy is at sending USB data. And the Nano won't likely have the speed to do that.

I dodn't see any analog writing in the samples?
 
PaulStoffregen - what do you think is going wrong here ?

are the Serial interrupts interfering with the pwm timers ?
 
Maybe try bypassing the analogWrite() function and instead manipulate the FTM directly? First, in your setup() function, configure the FTM for the appropriate frequency / resolution. Then configure the port mux. After that, changing the PWM value in your main loop() is a single atomic write to the appropriate FTMx_CnV register. You can control exactly when that happens and no other registers need to be changed. Just be careful of 0 and the max PWM value.

EDIT:
Also, after you call 'ReadDataStream()' disable interrupts. Then, blast out all 4 FTMx_CnV values at the same time. Then, re-enable interrupts so that they're only disabled for those 4 register writes.
 
Last edited:
Maybe try bypassing the analogWrite() function and instead manipulate the FTM directly? First, in your setup() function, configure the FTM for the appropriate frequency / resolution. Then configure the port mux. After that, changing the PWM value in your main loop() is a single atomic write to the appropriate FTMx_CnV register. You can control exactly when that happens and no other registers need to be changed. Just be careful of 0 and the max PWM value.

EDIT:
Also, after you call 'ReadDataStream()' disable interrupts. Then, blast out all 4 FTMx_CnV values at the same time. Then, re-enable interrupts so that they're only disabled for those 4 register writes.

thank you for the advice - i will try disabling interrupts first :)
 
ok disabling interrupts did not work
i then tried ending serial and starting it again after the analogue reads - again no change

in the setup i set Serial.setTimeout(0); was set to 1

this appears to have solved the issue !

:) :) :) :) :) :) :) :) :) :)

gfvalvo - thanks for the suggestions it helped !

I am not really sure why this has has worked - is there a dedicated serial chip on the teensy ?
 
Status
Not open for further replies.
Back
Top