How to use USBHost_t36 library.

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 : -

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!
 
While testing another script, I accidentally commented out myusb.Task() in loop() and instead added delayMicroseconds(40). Surprisingly, the Master could read data from the Slave at up to 2.5 kHz.
This makes me wonder:
How to use properly use myusb.Task()?
and
Does frequent polling of myusb.Task() actually interfere with data handling?

Will do further digging how the size of data read and sent and the relation between sending freq and delay duration.
 
Just found out that setting a flag in the timer and based on the flag, using uSerialN.flush() my problem., but I am still confused about the role of myusb.Task() function.
 
Just found out that setting a flag in the timer and based on the flag, using uSerialN.flush() my problem., but I am still confused about the role of myusb.Task() function.
Hi Sam,
I'm no help here but also starting to kick the tires on the USBHost_t36 library, want to communicate to a device that shows up as a serial port on my mac when plugged in. Thanks for posting this
 
Back
Top