USBHost Bluetooth pairing with Mobile device

mellow231

Member
Hello,

I'm encountering some challenges while attempting to connect a Bluetooth dongle to a mobile device using a USBHost with a Teensy 4.0. I'm utilizing the USBHost_t36 library, which includes several excellent examples that have generally worked well for me. For instance, I've successfully connected a wireless mouse and keyboard to the USBHost without issues.

However, I'm running into problems when trying to pair my Bluetooth dongle with a mobile device—the program crashes during this process. I’ve experimented with two different approaches using the example code "USBBTDeviceInfo" from the library.

First, I attempted to pair the dongle directly with the mobile device using the code that handles the pairing process. Unfortunately, this resulted in the dongle not being detected at all. Next, I tried pairing the mobile device with the dongle while it was connected to my laptop, then connecting the dongle to the USBHost and attempting to connect from my phone. This method yielded slightly better results but ultimately still led to a crash.

Any insights or suggestions would be greatly appreciated.

I have used two different bluetooth dongles one being Asus USB BT500 and the other CSR 4.0 Dongle which is recommended by https://forum.pjrc.com/index.php?threads/t3-6-usb-host-bluetooth.49358/


Heres the example code:
C:
// HIDDeviceInfo - Simple HID device example
//
// This Simple test sketch is setup to print out HID information about a device
// The other two tabs are a simple C++ subclass of the USBHIDInput class that is part
// of the USBHost_t36 library.
//
// This subclass simply tries to connect to each different HID object and
// the only thing it does is to try to print out all of the data it receives
// in a reasonable way.
//
// The idea is that with the output from this sketch we can hopefully add support
// for some additional devices that are not currently supported or allows you to
// develop your own.
//
// You can use Serial Input to control how much data is displayed per each HID packet
// received by the sketch.
//
// By Default it displays both the RAW (Hex dump) of the data received, as well
// as the data as the HID interpreter walks through the data into the individual
// fields, which we then print out.
//
// There are options to turn off some of this output, also an option that you can
// toggle on or off (C) to only try to show the changed fields.
//
// This example is in the public domain

#include <USBHost_t36.h>
#include "BTHIDDumper.h"
#include "USBDeviceInfo.h"

USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
USBDeviceInfo dinfo(myusb);  // will never claim anything...
//BluetoothController bluet(myusb, false, "0000", true);   // Version does pairing to device
BluetoothController bluet(myusb);  // version assumes it already was paired

BTHIDDumpController hdc1(myusb, 1);
BTHIDDumpController hdc2(myusb, 2);

USBDriver *drivers[] = { &hub1, &hub2, &bluet };
#define CNT_DEVICES (sizeof(drivers) / sizeof(drivers[0]))
const char *driver_names[CNT_DEVICES] = { "Hub1", "Hub2", "BT" };
bool driver_active[CNT_DEVICES] = { false, false, false };

BTHIDDumpController *bthiddrivers[] = { &hdc1, &hdc2 };
#define CNT_BTHIDDEVICES (sizeof(bthiddrivers) / sizeof(bthiddrivers[0]))
const char *bthid_driver_names[CNT_BTHIDDEVICES] = { "HDC1", "HDC2" };
bool bthid_driver_active[CNT_BTHIDDEVICES] = { false, false };



bool show_changed_only = false;
void setup() {
  Serial1.begin(2000000);
  while (!Serial)
    ;  // wait for Arduino Serial Monitor
  if (CrashReport) Serial.print(CrashReport);
  Serial.println("\n\nUSB HID Device Info Program");
  Serial.println("\nThis Sketch shows information about plugged in HID devices");
  Serial.println("\n*** You can control the output by simple character input to Serial ***");
  Serial.println("R - Turns on or off showing the raw data");
  Serial.println("C - Toggles showing changed data only on or off");
  Serial.println("A - Try connecting and printing SDP data again");
  Serial.println("P - Start a normal Pairing operation with 0000");
  Serial.println("S - Start an SDP pairing operation");
  Serial.println("E - Erase Key pairing information");


  Serial.println("<anything else> - toggles showing the Hid formatted breakdown of the data\n");

  myusb.begin();
}


void loop() {
  myusb.Task();

  if (Serial.available()) {
    int ch = Serial.read();  // get the first char.
    while (Serial.read() != -1)
      ;
    if (ch == 'r' || (ch == 'R')) {
      if (BTHIDDumpController::show_raw_data) {
        BTHIDDumpController::show_raw_data = false;
        BTHIDDumpController::show_formated_data = true;
        Serial.println("\n*** Turn off RAW output formatted data is on ***\n");
      } else {
        BTHIDDumpController::show_raw_data = true;
        Serial.println("\n*** Turn on RAW output ***\n");
      }
    } else if (ch == 'a' || (ch == 'A')) {
      Serial.println("\n>>>>>>>>>> Try to decode SDP Data <<<<<<<<<<");
      if (hdc1) hdc1.decode_SDP_Data(true);
      if (hdc2) hdc2.decode_SDP_Data(true);

    } else if (ch == 'C' || (ch == 'c')) {
      if (BTHIDDumpController::changed_data_only) {
        BTHIDDumpController::changed_data_only = false;
        Serial.println("***\n Now Showing all data ***\n");
      } else {
        BTHIDDumpController::changed_data_only = true;
        Serial.println("***\n Now Showing changed data only ***\n");
      }
    } else if (ch == 'P') {
      if (bluet.startDevicePairing("0000", false)) {
        Serial.println("Pairing operation started with SSP false");

      } else {
        Serial.println("Staring of Pairing operation failed");
      }

    } else if (ch == 'S') {
      if (bluet.startDevicePairing("0000", true)) {
        Serial.println("Pairing operation started with SSP true");

      } else {
        Serial.println("Staring of Pairing operation failed");
      }
    } else if (ch == 'E') {
      Serial.println("Erase Pairing Link Keys");
      bluet.writeLinkKey(nullptr, nullptr);  // which should clear all of them.  W
    } else {
      if (BTHIDDumpController::show_formated_data) {
        BTHIDDumpController::show_formated_data = false;
        BTHIDDumpController::show_raw_data = true;  // At least make sure raw raw data is output
        Serial.println("\n*** Turn off formatted output formated HID data is on ***\n");
      } else {
        BTHIDDumpController::show_formated_data = true;
        Serial.println("\n*** Turn on formated output ***\n");
      }
    }
  }

  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);
      }
    }
  }

  // Then Bluetooth devices
  for (uint8_t i = 0; i < CNT_BTHIDDEVICES; i++) {
    if (*bthiddrivers[i] != bthid_driver_active[i]) {
      if (bthid_driver_active[i]) {
        Serial.printf("*** BTHID Device %s - disconnected ***\n", bthid_driver_names[i]);
        bthid_driver_active[i] = false;
      } else {
        Serial.printf("*** BTHID Device %s %x:%x - connected ***\n", bthid_driver_names[i], bthiddrivers[i]->idVendor(), bthiddrivers[i]->idProduct());

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

        // lets dump the SDP data
        bthiddrivers[i]->decode_SDP_Data(false);
      }
    }
  }
}


Heres the outputs on the serial monitor:

1723795895935.png



Here I have just added the BDADDR, its still basically the same code:


1723795981705.png


Thanks :)
 
I put some information up about crashreports in one of your other postings on this:
Sorry, all I can tell you so far is something crashed.

@PaulStoffregen recently put up a page on PJRC about Crashreports,

Although looks like it is still missing one very important part, which is how to run addr2line.
Sorry, I don't know if you are using Windows/Mac/Ubuntu, on which IDE and which version of it likewise which version of Teensy code...

What I typically do, is find where the code was built and open up a command window at that location. You can find the directory in the
command lines that are executed during builds. At least when you run the build in verbose mode (option in the Arduino preferences dialog)
Or what I typically do on windows: Is open up a browser window. I then navigate to where the temporary files are generated on Arduino:
In my case I to to: %temp%\arduino\sketches
I look at the different directories there, which have names like:
View attachment 35466
And in my case, there was only one. I get into that directory.
I then open up a terminal window: I have the windows Terminal app installed from the Windows store.
So I just right click in the window and open up Terminal and search for the .elf file for the sketch you built.
Code:
 Directory of C:\Users\kurte\AppData\Local\Temp\arduino\sketches\5D50F9914F75299380EFCB4BAF8187B9

08/16/2024  04:40 AM    <DIR>          .
08/16/2024  04:39 AM    <DIR>          ..
08/16/2024  04:39 AM                 0 .last-used
08/16/2024  04:39 AM               600 build.options.json
08/16/2024  04:40 AM                34 Compare_565_888_color_ranges.ino.eep
08/16/2024  04:40 AM         1,196,124 Compare_565_888_color_ranges.ino.elf
08/16/2024  04:40 AM           852,651 Compare_565_888_color_ranges.ino.hex
08/16/2024  04:40 AM         1,576,947 Compare_565_888_color_ranges.ino.lst
08/16/2024  04:40 AM            34,666 Compare_565_888_color_ranges.ino.sym

In my case I have the above: If I use the command line:
Code:
C:\Users\kurte\AppData\Local\Temp\arduino\sketches\5D50F9914F75299380EFCB4BAF8187B9>addr2line -e Compare_565_888_color_ranges.ino.elf 0x8104
C:\Users\kurte\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\cores\teensy4/usb.c:506

In the case of the sketch I just built that address is into usb.c line 506.
It almost for sure would be some different file and line in your sketch.

However I cheated. I have a copy of the addr2line in a directory on my search path.
The Current version of the addr2line is installed where the Arduino tools for the Teensy are installed. And in my case on Windows,
using IDE2 with current stuff, it is located at:

Code:
C:\Users\kurte\AppData\Local\Arduino15\packages\teensy\tools\teensy-compile\11.3.1\arm\bin\arm-none-eabi-addr2line.exe

So the command line might instead be:

Code:
C:\Users\kurte\AppData\Local\Temp\arduino\sketches\5D50F9914F75299380EFCB4BAF8187B9>C:\Users\kurte\AppData\Local\Arduino15\packages\teensy\tools\teensy-compile\11.3.1\arm\bin\arm-none-eabi-addr2line.exe -e Compare_565_888_color_ranges.ino.elf 0x8104
C:\Users\kurte\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\cores\teensy4/usb.c:506

Alternative be in the directory where the addr2line is and use the long path name to where the .elf file is.

Hopefully - this will work and will point you to where the code crashed.

Note: It is best to keep the debugging of issues like this in one thread and not spread out over many.
This one is probably the best as it has better information in it.
 
I put some information up about crashreports in one of your other postings on this:


Note: It is best to keep the debugging of issues like this in one thread and not spread out over many.
This one is probably the best as it has better information in it.
Thank you I will continue on this thread. This is very helpful. What I have done is connect the Bluetooth dongle to my Windows PC and then pair it with my mobile device (iPhone). After pairing the dongle, I connected it back to the USB Host on the Teensy, and I intend to send raw data from my mobile device to the Bluetooth dongle. Is this possible to do with the library?
 
...I thought I’d reach out for some advice. I am trying to establish communication between a Teensy 4.0 and a mobile device to eventually send various data telegrams between them. How difficult is this to achieve, and which libraries can help? I have tried using USBHost_t36.h but don’t seem to get it working. Any response would be greatly appreciated. :)
Sorry, I have not been doing anything recently with the bluetooth stuff on the Teensy for a long time.
Especially with USBHost_t36. So far, we only implemented a small subset of the Bluetooth interfaces/Profiles. And I don't believe that
we did much if anything with the Serial type setup.

A year or two ago, @mjs513 and I were playing some with the ArduinoBLE library. I had a hacked up version of their library which I was
playing with: The fork/branch is up at:
I know we mentioned some of this in different threads like: https://forum.pjrc.com/index.php?threads/usbhost-bluetooth-ble-arduinoble.71503/

But as I mentioned this was awhile ago!
 
Sorry, I have not been doing anything recently with the bluetooth stuff on the Teensy for a long time.
Especially with USBHost_t36. So far, we only implemented a small subset of the Bluetooth interfaces/Profiles. And I don't believe that
we did much if anything with the Serial type setup.

A year or two ago, @mjs513 and I were playing some with the ArduinoBLE library. I had a hacked up version of their library which I was
playing with: The fork/branch is up at:
I know we mentioned some of this in different threads like: https://forum.pjrc.com/index.php?threads/usbhost-bluetooth-ble-arduinoble.71503/

But as I mentioned this was awhile ago!
Thank you I appreciate the reply I will look further into this. :)
 
Back
Top