USBHost_t36 and FTDI device - so close!

TeensyG

Member
I'm using a Teensy 4.1 with USBHost_t36 to control an 8-relay USB box, specifically a KMTronic box. It works great! So I bought another one.
Unbeknown to me the first KMTronic uses CDC, whereas the second one I bought uses FTDI and doesn't work.

I've spent days and days on this and it feels like I'm close to getting it working as I can see that the Teensy recognises the device and claims it, and my code is obviously sending something to the KMTronic as its comms lights flash, but it's just not working.

By way of some info, if I plug the KMTronic in to a Linux box it assigns it /dev/ttyUSB0 and so the following works just fine:

- Relay 3 ON
echo -e "\xFF\x03\x01" > /dev/ttyUSB0

- Relay 3 OFF (works)
echo -e "\xFF\x03\x00" > /dev/ttyUSB0

But this code on the Teensy, whilst clearly sending *something* to the KMTronic, fails to control it.

Help!

C++:
#include "USBHost_t36.h"
#define USBBAUD 9600
USBHost myusb;
USBSerial_BigBuffer userial(myusb, 1); 

byte rCmd[] = {255, 3, 1};

void setup() {
  myusb.begin();
  userial.begin(USBBAUD, USBHOST_SERIAL_8N1);
}

void loop() {
  myusb.Task();
  if (userial) {
    // Relay 3 ON
    rCmd[1] = 3;
    rCmd[2] = 1;
    userial.write(rCmd, 3);
    delay(1000);

    // Relay 3 OFF
    rCmd[1] = 3;
    rCmd[2] = 0;
    userial.write(rCmd, 3);
    delay(1000);
  }
}
 
I believe that, without the "-n" command line option included, the "echo" command in linux will terminate the data to be sent with either CR, or LF, and possibly CR/LF. You might try adding additional characters to your rCmd array & inserting 0x0a (10 decimal) and/or 0x0d (13 decimal), or possibly both to see if that makes any difference to the receiving device.

Mark J Culross
KD5RXT
 
I believe that, without the "-n" command line option included, the "echo" command in linux will terminate the data to be sent with either CR, or LF, and possibly CR/LF. You might try adding additional characters to your rCmd array & inserting 0x0a (10 decimal) and/or 0x0d (13 decimal), or possibly both to see if that makes any difference to the receiving device.

Mark J Culross
KD5RXT
Thanks for your reply. I have previously tried that by defining:

byte rCmd[] = {255, 3, 1, 13, 10};

and then,

userial.write(rCmd, 5);

But sadly it still doesn't work.
 
OK, well shucks, did you also try these (in case the device doesn't like CR/LF together . . . hoping that one of them provides the missing magic):

byte rCmd[] = {255, 3, 1, 13};
- OR -

byte rCmd[] = {255, 3, 1, 10};

then using userial.write(rCmd, 4);

Mark J Culross
KD5RXT
 
I have noticed that using RealTerm under Windows I can get the same bad behaviour (flashing comms lights, but no control) if I set the BAUD to anything other than 9600 (8n1).

So this has me wondering, is this just an issue with the BAUD of the emulated serial channel and is there something else I need to explicitly do in my code to set it correctly?
 
OK, well shucks, did you also try these (in case the device doesn't like CR/LF together . . . hoping that one of them provides the missing magic):

byte rCmd[] = {255, 3, 1, 13};
- OR -

byte rCmd[] = {255, 3, 1, 10};

then using userial.write(rCmd, 4);

Mark J Culross
KD5RXT
No not explicitly although I have tried {255, 3, 1, 13, 10} and {255, 3, 1, 10, 13}, although using RealTerm (a great tool!) I can confirm that neither CR nor LF are needed, just the 3 numbers.
 
USBSerial_BigBuffer userial(myusb, 1);
You might try your tests using just "USBSerial serial(myusb);".

I suspect that the FTDI is only a Full-Speed link, not the 480Mb/second High-Speed for which USBSerial_BigBuffer was designed. Just today, I found that BigBuffer will crash the T4.1 if you don't add the ",1" after 'myusb', when connected to a full-speed device.
 
You are right, that the bigbuffer was setup to handle USB High Speed devices, which typically have transfers of 512 bytes instead of 64 bytes, as well as higher speeds. the ,1 was a hack as by default it will only claim high speed serial devices, which can be important if for example you are using multiple devices and only one of them is high speed, you don't want one of the other Low or Full speed devices to claim it...
So the ,1 will claim any serial device whose tx or rx transfer size is at least 1 byte...

It might help, if we know some additional USB Information about your device. like VID:pID, maybe
all of the information from command like: lsusb -v <device>

How is it failing? Is it not connecting to it? Or is the data that device receives wrong?

Have you turned on debug stuff within USBHost_t36.h?
That is edit the file and about line 63 you should see:
Code:
//#define USBHOST_PRINT_DEBUG

Uncomment it and rebuild and it should show more information, like it sees your device and the claim function within
the Serial object, should print out additional information about the device:

The Serial code has a VID:pID mapping table, that it uses to know what type of Serial device is connected. For FTDI it knows about 3
of them:
Code:
{0x0403, 0x6001, USBSerialBase::FTDI, 0},
    {0x0403, 0x8088, USBSerialBase::FTDI, 1},  // 2 devices try to claim at interface level
    {0x0403, 0x6010, USBSerialBase::FTDI, 1},  // Also Dual Serial, so claim at interface level

Two of the three actually are dual USB to Serial adapters, that is they create two USB Serial objects...

Kurt
 
You might try your tests using just "USBSerial serial(myusb);".

I suspect that the FTDI is only a Full-Speed link, not the 480Mb/second High-Speed for which USBSerial_BigBuffer was designed. Just today, I found that BigBuffer will crash the T4.1 if you don't add the ",1" after 'myusb', when connected to a full-speed device.

Thanks for the suggestion, but it hasn't made any difference unfortunately.
 
Last edited:
You are right, that the bigbuffer was setup to handle USB High Speed devices, which typically have transfers of 512 bytes instead of 64 bytes, as well as higher speeds. the ,1 was a hack as by default it will only claim high speed serial devices, which can be important if for example you are using multiple devices and only one of them is high speed, you don't want one of the other Low or Full speed devices to claim it...
So the ,1 will claim any serial device whose tx or rx transfer size is at least 1 byte...

It might help, if we know some additional USB Information about your device. like VID:pID, maybe
all of the information from command like: lsusb -v <device>

How is it failing? Is it not connecting to it? Or is the data that device receives wrong?

Have you turned on debug stuff within USBHost_t36.h?
That is edit the file and about line 63 you should see:
Code:
//#define USBHOST_PRINT_DEBUG

Uncomment it and rebuild and it should show more information, like it sees your device and the claim function within
the Serial object, should print out additional information about the device:

The Serial code has a VID:pID mapping table, that it uses to know what type of Serial device is connected. For FTDI it knows about 3
of them:
Code:
{0x0403, 0x6001, USBSerialBase::FTDI, 0},
    {0x0403, 0x8088, USBSerialBase::FTDI, 1},  // 2 devices try to claim at interface level
    {0x0403, 0x6010, USBSerialBase::FTDI, 1},  // Also Dual Serial, so claim at interface level

Two of the three actually are dual USB to Serial adapters, that is they create two USB Serial objects...

Kurt
Thanks for your reply. VID\PID = 0403:6001

I did run HIDDeviceInfo.ino with Debug:

Code:
port change: 10001803
    connect
  begin reset
port change: 10001005
  port enabled
  end recovery
new_Device: 12 Mbit/sec
new_Pipe
enumeration:
enumeration:
enumeration:
Device Descriptor:
  12 01 00 02 00 00 00 08 03 04 01 60 00 06 01 02 03 01
    VendorID = 0403, ProductID = 6001, Version = 0600
    Class/Subclass/Protocol = 0 / 0 / 0
    Number of Configurations = 1
enumeration:
enumeration:
Manufacturer: FTDI
enumeration:
Product: FT232R USB UART
enumeration:
Serial Number: B001JW7B
enumeration:
Config data length = 32
enumeration:
Configuration Descriptor:
  09 02 20 00 01 01 00 A0 2D
    NumInterfaces = 1
    ConfigurationValue = 1
  09 04 00 00 02 FF FF FF 02
    Interface = 0
    Number of endpoints = 2
    Class/Subclass/Protocol = 255 / 255 / 255
  07 05 81 02 40 00 00
    Endpoint = 1 IN
    Type = Bulk
    Max Size = 64
    Polling Interval = 0
  07 05 02 02 40 00 00
    Endpoint = 2 OUT
    Type = Bulk
    Max Size = 64
    Polling Interval = 0
enumeration:
USBHub memory usage = 960
USBHub claim_device this=2000B760
USBHub memory usage = 960
USBHub claim_device this=2000BB20

USBDeviceInfo claim this=2000CAC8

****************************************
** Device Level **
  vid=403
  pid=6001
  bDeviceClass = 0
  bDeviceSubClass = 0
  bDeviceProtocol = 0
09 04 00 00 02 FF FF FF 02 07 05 81 02 40 00 00 07 05 02 02 40 00 00
HIDParser claim this=200095A0
HIDParser claim this=20009C60
HIDParser claim this=2000A320
HIDParser claim this=2000A9E0
HIDParser claim this=2000B0A0
Descriptor 4 = INTERFACE

USBDeviceInfo claim this=2000CAC8

****************************************
** Interface Level **
09 04 00 00 02 FF FF FF 02 07 05 81 02 40 00 00 07 05 02 02 40 00 00
HIDParser claim this=200095A0
HIDParser claim this=20009C60
HIDParser claim this=2000A320
HIDParser claim this=2000A9E0
HIDParser claim this=2000B0A0
Descriptor 5 = ENDPOINT
Descriptor 5 = ENDPOINT
 
Back
Top