usbhost_t36 Serial Comms with RF Receiver woes

cedd

Member
Hi Everyone
I'm continuing in my project to read and display (on an HTML page) data from a number of RF Receivers (Theatre radio microphones - remote monitoring of) using a Teensy. I initially had proof of concept of this project by using a set of Arduino Mega's to connect to the TTL on the processor side of the USB ship inside the receiver. I was able to receive and use the data I needed, and got it displaying on a really nice looking HTML/Canvas display, with bar graphs for signal strength and everything. It did however cause some noise issues on the receivers, I assume because I was connecting a noisy arduino via some 40cm long cables directly to the receiver, rather than passing through any buffering from the USB chip. I therefore set about using a Teensy 4.1 to do the same job via USB. Eventually there'll be up to 12 receivers in a rack, with a single Teensy connected to all of them via USB hubs.

I've already received help on this project for a very specific problem here;
https://forum.pjrc.com/threads/71413-usbhost_t36-with-FTDI-device-can-t-be-seen?p=315214#post315214
As you'll see, these receivers have a USB port on the back of them but the innards aren't standard FTDI and it didn't initially show up in the example Serial sketch. We solved that but now i'm facing another, different problem. Rather than tag on to that very specific thread I thought i'd start again with a more general project based one here.

I can see the USB chip, but when I send my data request ("R D" or 0x52, 0x00, 0x44) I get nothing back. I'm doing the most rudimentary of Serial Prints for whatever comes in from the USB Host serial port, but all i'm getting is -1's, which is to be expected as I don't think the receiver is even getting the data request.
I swapped out the RF Receiver for a standard FTDI USB serial port, and connected to hyperterminal. Sure enough, my "R D" requests are coming through, however i've noticed they're at the wrong baud rate. My initial experiment with the TTL method showed the receiver was operating at 57600 baud. I thought i'd specified that in my code, but it seems to always use 115200. This may or may not be the problem, but it's my only hunch at the minute. My code is below and i'll also post the receive code that I had working for the initial TTL version, as it may give some clues. I know my initial method of doing this was clunky. I put all of the receiver data in to an array, and as there are multiple receivers I do some counting and multiplying to put the data in to the right places.

At 115200 baud, if I type characters in hyperterminal they show up in my Teensy serial monitor, among the sea of -1's, so I know that i'm at least capable of receiving data.

Assuming we can fix whatever is stopping the above from working, I have a further problem. There aren't many examples out there of USB Host Serial reception, and i'm struggling to work out how best to get the received data to be usable values. I did a Serial.listen on my TTL version, then byte per byte put the data in to the relevant places in the array (you'll see some faffing about as byte 1 coming from the receiver would helpfully vanish if byte 0 wasn't 82 - never worked out the logic behind it, clearly means something to the manufacturer. Just used an if statement to fix it). Serial.listen doesn't seem to be possible with the USB Host library. Haven't done much playing with handling the received data yet, as i've not got any currently to play with, but i'm scratching my head a bit about how to do it.

The code started off life as the example t36 "Serial" sketch, and i've modified it to suit my needs. For the time being we're only playing with one receiver conencted (userial1) however eventually there will be more.
Code:
// Simple test of USB Host Mouse/Keyboard
//
// This example is in the public domain

#include "USBHost_t36.h"
#define USBBAUD 57600
uint32_t baud = USBBAUD;
uint32_t format = USBHOST_SERIAL_8N1;
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
USBHub hub3(myusb);
USBHub hub4(myusb);
USBSerial userial1(myusb);  
USBSerial userial2(myusb);
USBSerial userial3(myusb);
USBSerial userial4(myusb);
USBSerial userial5(myusb);
USBSerial userial6(myusb);
USBSerial userial7(myusb);
USBSerial userial8(myusb);
USBSerial userial9(myusb);
USBSerial userial10(myusb);
USBSerial userial11(myusb);
USBSerial userial12(myusb);

int rx1[10];
USBDriver *drivers[] = {&userial1, &userial2, &userial3, &userial4, &userial5, &userial6, &userial7, &userial8, &userial9, &userial10, &userial11, &userial12,&hub1, &hub2};
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char * driver_names[CNT_DEVICES] = {"USERIAL1", "USERIAL2", "USERIAL3", "USERIAL4", "USERIAL5", "USERIAL6", "USERIAL7", "USERIAL8", "USERIAL9", "USERIAL10", "USERIAL11", "USERIAL12","Hub1", "Hub2" };
bool driver_active[CNT_DEVICES] = {false, false,false,false,false,false,false,false,false,false,false,false,false,false};

void setup()
{
  pinMode(13, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  for (int i = 0; i < 5; i++) {
    digitalWrite(2, HIGH);
    delayMicroseconds(50);
    digitalWrite(2, LOW);
    delayMicroseconds(50);
  }
  while (!Serial && (millis() < 5000)) ; // wait for Arduino Serial Monitor
  Serial.println("\n\nUSB Host Testing - Serial");
  myusb.begin();
  userial1.begin(baud);
  Serial1.begin(115200);  // We will echo stuff Through Serial1...
delay(5000);
}


void loop()
{
  digitalWrite(13, !digitalRead(13));
  myusb.Task();
  // Print out information about different devices.
  for (uint8_t i = 0; i < CNT_DEVICES; i++) {
    if (*drivers[i] != driver_active[i]) {
      if (driver_active[i]) {
        Serial.printf("*** Device %s - disconnected ***\n", driver_names[i]);
        driver_active[i] = false;
      } else {
        Serial.printf("*** Device %s %x:%x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());
        driver_active[i] = true;

                

        const uint8_t *psz = drivers[i]->manufacturer();
        if (psz && *psz) Serial.printf("  manufacturer: %s\n", psz);
        psz = drivers[i]->product();
        if (psz && *psz) Serial.printf("  product: %s\n", psz);
        psz = drivers[i]->serialNumber();
        if (psz && *psz) Serial.printf("  Serial: %s\n", psz);    
        delay(50);

      }
    }
  }

        byte message[] = {0x52,0x00,0x44};
        userial1.write(message,sizeof(message));
        userial1.flush();
        delay(10);
        Serial.println("Request Sent");
        Serial.write(userial1.read());
        delay(10);
}


Initial TTL code (receiving section only). The first part is the important bit where I handle the received data. This version was hard wired to 8 receivers, whereas the USB version will need to detect the number in use, up to a maximum of say 12. All of the Serial printing is just me displaying the received data in a neater way for test purposes. I'm stepping through receivers and each receiver has a certain amount of spaces reserved in the array, hence the rxcount and numvals multiplication/shuffling to get me to the required bytes in the array;
Code:
void getserial(){
switch(rxcount){
  case 0:
  currentrx = &rx0;
  break;
    case 1:
  currentrx = &rx1;
  break;
    case 2:
  currentrx = &rx2;
  break;
    case 3:
  currentrx = &rx3;
  break;
    case 4:
  currentrx = &rx4;
  break;
    case 5:
  currentrx = &rx5;
  break;
    case 6:
  currentrx = &rx6;
  break;
    case 7:
  currentrx = &rx7;
  break;
}
currentrx->write(message, sizeof(message));
currentrx->listen();
delay(10);
if(currentrx->available()){
rxvals[0+(rxcount * numvals)] = 1;
rxvals[1+(rxcount * numvals)] = currentrx->read();
if(rxvals[1+(rxcount * numvals)] != 82){
  rxvals[3+(rxcount * numvals)] = currentrx->read();
}
else{
rxvals[2+(rxcount * numvals)] = currentrx->read();
rxvals[3+(rxcount * numvals)] = currentrx->read();
}
rxvals[4+(rxcount * numvals)] = currentrx->read(); 
rxvals[5+(rxcount * numvals)] = currentrx->read();
rxvals[6+(rxcount * numvals)] = currentrx->read();
rxvals[7+(rxcount * numvals)] = currentrx->read();
rxvals[8+(rxcount * numvals)] = currentrx->read();
rxvals[9+(rxcount * numvals)] = currentrx->read();
rxvals[10+(rxcount * numvals)] = currentrx->read();
rxvals[11+(rxcount * numvals)] = currentrx->read();
rxvals[12+(rxcount * numvals)] = currentrx->read();
rxvals[13+(rxcount * numvals)] = currentrx->read();
rxvals[14+(rxcount * numvals)] = currentrx->read();

if (rxvals[8+(rxcount * numvals)] == 83){
  return;
}
else
{
//batt1=map(batt1, 114, 175, 1, 175);
Serial.print(rxcount); 
Serial.print(",");
Serial.print("RFA,");
Serial.print(rxvals[4+(rxcount * numvals)]);
Serial.print(",");
Serial.print("RFB,");
Serial.print(rxvals[5+(rxcount * numvals)]);
Serial.print(",");
Serial.print("AF,");
Serial.print(rxvals[7+(rxcount * numvals)]);
Serial.print(",");
Serial.print("Batt,");
Serial.print(rxvals[8+(rxcount * numvals)]);
Serial.print(",");
Serial.print("RX,");
if (rxvals[9+(rxcount * numvals)] == 96 || rxvals[9+(rxcount * numvals)] == 224){
  Serial.print("M");
  rxvals[15+(rxcount * numvals)] = 3;
  rxvals[16+(rxcount * numvals)]--;
    if(rxvals[16+(rxcount * numvals)]<0){
      rxvals[16+(rxcount * numvals)] = 0;
    }
    rxvals[8+(rxcount * numvals)]=0;
}
if (rxvals[9+(rxcount * numvals)] == 64){
  Serial.print("B");
  rxvals[15+(rxcount * numvals)] = 2;
  rxvals[16+(rxcount * numvals)] = mutetime;
}
if (rxvals[9+(rxcount * numvals)] == 192){
  Serial.print("A");
  rxvals[15+(rxcount * numvals)] = 1;
  rxvals[16+(rxcount * numvals)] = mutetime;
}
if (rxvals[16+(rxcount * numvals)] == 0){
  rxvals[15+(rxcount * numvals)] = 0;
}

Serial.print(",");
Serial.print("Freq,");
Serial.print(rxvals[10+(rxcount * numvals)]);
Serial.print(rxvals[11+(rxcount * numvals)]);
Serial.print(rxvals[12+(rxcount * numvals)]);
if(rxvals[12+(rxcount * numvals)] == 0){
  Serial.print("0");
}
Serial.println(",");

}
}
else{                                         // if no coms, set values to zero (except frequency)
  rxvals[0+(rxcount * numvals)] = 0;
  //Serial.print(rxcount);
  Serial.println("0,RFA,0,RFB,0,AF,0,Batt,0,RX,M,Freq,000000,");
  rxvals[7+(rxcount * numvals)]=0;
  rxvals[4+(rxcount * numvals)]=0;
  rxvals[5+(rxcount * numvals)]=0;
  rxvals[8+(rxcount * numvals)]=0;
  
  
}
}

Huge thanks in advance for any assistance!
 
Sorry to bump, but hoping somebody with some insight sees this. The above is very wordy but I think if I could prioritise one question it'd be this; how do I set the baud rate on the USB Host serial port? I thought I was setting it correctly but it appears to default to 115200.
If somebody also happened to have some examples of receiving serial data from usb serial and putting values from the incoming string in to variables, that would be hugely helpful. The way I did it with ttl serial is above, but I don't appear to have an equivalent of serial.listen available using usb Host serial.

Huge thanks
Chris
 
Sorry, it has been awhile since I looked at the USB Host Serial code.

I think there is sort of a chicken and the egg problem.

It does appear like the code does default to 115200 when the object first connects.

It probably would work if your code, first detected that userial1 was valid and then call begin with the desired baud rate.

Something like:
Code:
bool userial1_previous = false;
void loop() {
    if (userial1) {
        if (!userial1_previous) {
            userial1_previous = true;
            userial1.begin(USBBAUD);
        }
    }
...
 
Another simpler option for you maybe to try:
That is if you call begin() before it is there, maybe we should still try to use that baud rate when it does connect:

If you go into the USBHost project sources on your machine and look in serial.cpp:
At or about line 204, there is:
Code:
		baudrate = 115200;
Try commenting it out.

Better yet, move it into the
void USBSerialBase::init()

function: near the line:
Code:
	format_ = USBHOST_SERIAL_8N1;

If it works for you we could maybe create a github Pull request with this and try to get it into the next release.
 
Back
Top