I tried to simply run the code as-is, but I don't get any output.
After some investigation, it would appear that there is a limit to the amount of data that can be sent with SerialUSB.write() => if the length of the data is greater than 64, I am not getting any output.
I am using the very simple code below for testing:
#include <Arduino.h>
const int buf_size = 65;
uint16_t buf[buf_size];
void setup(){
SerialUSB.begin(0);
while(!SerialUSB);
for (int i = 0; i < buf_size; i++) {
buf[i] = 2000 + i;
}
}
void loop(){
SerialUSB.write((uint8_t *)buf, buf_size);
}
When buf_size is set to 64, I get the expected output. Try any value > 64, and there is no output whatsoever.
Is this the expected behavior? Apparently, this used to work in the past (the code linked at the beginning has been used by a lot of people).
Or am I doing something wrong?
NOTE: I am using an Arduino Due. In general, I code in vscode + pio, but I also tried with the Arduino IDE v2, same results.
My guess:
the 64 comes from the maximum size of an USB VCP packet (EP size).
Sending larger amount of data needs a loop, every USB chunk is max. 64 bytes.
You create array of buf_size * 2 bytes
but send buf_size bytes only
Yes, I am well aware of this, but that is not the point here. My goal was just to illustrate the fact that I cannot send more than 64 bytes. The code is not meant to do anything useful (or even correct). But thanks for pointing this out anyway!
@tjaekel : do you know if this is documented somewhere (I couldn't find any information on this)?
I also find this difficult to accept since this was working in the past (cf. arduino-due_high-speed-ADC.ino, first link that I provided). Shouldn't this be considered a regression instead?
Thanks.
But I was thinking about documentation on SerialUSB
What you sent is fairly low level, and I would expect this level of details to be hidden by the SerialUSB interface.
That said, you are certainly right, this might well be the root cause of the issue I am facing.
Potentially yes:
See this code: it sends in chunks, here the EPX_SIZE. This is potentially set to 64 bytes (as max. for VCP UART).
But: I do not trust the UDD_Send() function:
if this one does not wait for the previous chunk sent - just 64 bytes go through and next is "too early" and lost.
Try to do this (more for debug):
send max. 64 bytes
after sending 64 bytes and some more still to send- wait, e.g. 1 ms
try to send again the next (64 max. byte) chunk (or remaining part)
Or:
make sure never to send more as 64 bytes (entire string length to send)
have a delay somewhere, before you send the next string from somewhere else
USB VCP is a device: it just transmits the 64 bytes as one USB packet when host has requested it. So, if device sends faster and larger as requested - it is lost.
Just split into 64 byte chunks, wait a bit between two sends (e.g. 1 ms) ...
Just make your strings smaller, do not send so often ... and let's see if this works.
If it does, but with larger and faster - a bug in the LIB code.
You can also "stress the system" and test:
send a string with 128 characters, e.g. an incrementing pattern
send this in a fast loop
if it comes as all on PC (host) - all fine
if you lose parts, e.g. an USB packet - the implementation for USB VCP in LIB is wrong
(it does not wait for next available 64 byte chunk possible to send - actually requested by host)
You can "relax" the timing:
if you put your USB VCP sender into a thread/task
you send max. 64 bytes per chunk
but it has a FIFO: it stores the other additional characters and tries to send (a bit later) again
you need a criteria if last chunk was delivered, otherwise, wait 1 ms between chunks
so, the USB sender task sends your FIFO as 64 byte chunks, waits in between ...
but you can be faster as this thread - you need a "back pressure" (and stop your sender)
Just test the max. throughput you could get without lost data...
I assume: the LIB will not handle properly a "too fast" send (or too large string size).
Thanks for the suggestions.
I will investigate further as soon as I can, but I won't have access to my Due anymore for a few months. I won't be able to check how SerialUSB.write() behaves before long.