samm_flynn
Well-known member
I've been working with the USBHost_t36 library on a Teensy and have written two sketches to test high-frequency USB serial communication.
The Master sends timestamped data packets to three USBSerial_BigBuffer ports at a fixed interval.
The Slave, connected through a USB hub, simply echoes back any received data.
Master Code : -
Slave Code (Simple Echo) :-
At rates (200Hz), everything works as expected,The Master sends a dot (.)The Slave echoes back three timestamped lines.
At high rates I observe: Many dots appearing in bursts. Then, a large block of echoed timestamps appearing all at once.
This suggests that data is being buffered and then processed in bursts rather than being handled as a steady stream.
Am I using myusb.Task() correctly?
Currently, I call it in the tick() function, which runs continuously.Should I be calling it differently for better synchronization?
Is there an event-driven way to handle USB serial data?
Should I be structuring the USB host code differently?
Given that I’m sending small, frequent packets at high speed, is there a more efficient way to handle USB transfers?
I’d appreciate any insights from those experienced with USBHost_t36.
Thanks in advance!
The Master sends timestamped data packets to three USBSerial_BigBuffer ports at a fixed interval.
The Slave, connected through a USB hub, simply echoes back any received data.
Master Code : -
C++:
#include <USBHost_t36.h>
USBHost myusb;
USBHub hub1(myusb), hub2(myusb), hub3(myusb);
USBSerial_BigBuffer uSerial1(myusb, 1), uSerial2(myusb, 2), uSerial3(myusb, 3);
#define U_BUFFER_SIZE 32768
char uBuffer[U_BUFFER_SIZE];
uint32_t uBufferLength = 0;
bool newData = false;
IntervalTimer ticker;
template<typename T>
void sendPacket(T* port, const uint8_t* data, uint32_t size) {
if (!port || port->availableForWrite() < static_cast<int>(size)) return;
port->write(data, size);
}
void sendIRQ() {
char timeStr[10];
snprintf(timeStr, sizeof(timeStr), "%lu\n", micros());
Serial.println(".");
sendPacket(&uSerial1, reinterpret_cast<const uint8_t*>(timeStr), strlen(timeStr));
sendPacket(&uSerial2, reinterpret_cast<const uint8_t*>(timeStr), strlen(timeStr));
sendPacket(&uSerial3, reinterpret_cast<const uint8_t*>(timeStr), strlen(timeStr));
}
void setup() {
while (!Serial) delay(1000);
myusb.begin();
while (!(uSerial1 && uSerial2 && uSerial3)) { myusb.Task(); delay(1); }
Serial.println("<READY>");
ticker.begin(sendIRQ, 500);
}
void loop() {
myusb.Task();tick();
}
void tick() {
if (uSerial1) readUSB(uSerial1);
if (uSerial2) readUSB(uSerial2);
if (uSerial3) readUSB(uSerial3);
processBuffer();
}
void readUSB(USBSerial_BigBuffer& serialPort) {
if (!serialPort.available()) return;
uint32_t bytesRead = serialPort.readBytes(uBuffer + uBufferLength, serialPort.available());
uBufferLength += bytesRead;
newData = true;
}
void processBuffer() {
if (!newData) return;
Serial.write(uBuffer, uBufferLength);
Serial.printf("bufferLength: %lu\n", uBufferLength);
uBufferLength = 0;
newData = false;
}
Slave Code (Simple Echo) :-
C++:
void setup() {
while (!Serial) delay(1);
}
void loop() {}
void serialEvent() {
int availableBytes = Serial.available();
if (!availableBytes) return;
char buffer[availableBytes];
int bytesRead = Serial.readBytes(buffer, availableBytes);
Serial.write(buffer, bytesRead);
}
At rates (200Hz), everything works as expected,The Master sends a dot (.)The Slave echoes back three timestamped lines.
At high rates I observe: Many dots appearing in bursts. Then, a large block of echoed timestamps appearing all at once.
This suggests that data is being buffered and then processed in bursts rather than being handled as a steady stream.
Am I using myusb.Task() correctly?
Currently, I call it in the tick() function, which runs continuously.Should I be calling it differently for better synchronization?
Is there an event-driven way to handle USB serial data?
Should I be structuring the USB host code differently?
Given that I’m sending small, frequent packets at high speed, is there a more efficient way to handle USB transfers?
I’d appreciate any insights from those experienced with USBHost_t36.
Thanks in advance!