Source Code: USBHost-Due-BT.tar.bz2
The Arduino Due uses an Atmel SAM3X8E microcontroller, and is capable of functioning as a USB host. Well, sort of: The USB Host library supplied with the Arduino IDE is apparently still a work in progress, so that it isn’t possible to attach a Bluetooth dongle and make it function as a BT serial adapter.
My goal was to be able to use the Due as a wireless serial port, for a Beaglebone that I wanted to use for a CNC controller project. It took three days of poring through the source code in /Applications/Arduino.app, the SAM3X8E technical reference manual, the USB 2.0 specification, and the Bluetooth 4.0 Core Specification to learn several things:
- The Arduino USBHost library is definitely work in progress – the USB Host Shield 2.0 library created by Kristian Lauszus of TKJ Electronics was written to work with another family of microcontrollers used in Arduinos (the Atmega AVRs). It doesn’t yet enable full use of the Arduino Due’s ‘native’ USB On-The-Go interface as a host interface;
- There is enough Atmel-supplied support library code, bundled with the Arduino IDE, to extend Lauszus’ SPP (serial port profile) and BTD (Bluetooth Device) classes, if you were willing to hack at the code;
- The USB Host Shield library Arduino code, when compiled for the Arduino Due, only speaks to endpoint zero, the USB control endpoint. Trying to read from the ill-named Interrupt endpoint (it’s actually polled) results in a timeout because initialization calls to set up data structures for endpoint zero were not applied to other endpoints on the Bluetooth device.
So what I ended up doing was extracting just three classes from Lauszus’ code – the SPP, BTD, and USBHost classes – and thrashing at the sample code to eventually yield this:
The Bluetooth dongle is attached to an Arduino Due using a USB OTG Host Cable, which in turn is powered by an external 12V power supply.
The code here (USBHost-Due-BT.tar.bz2, .tar.bz2) replaces the USB Host library. You can use a sketch similar to the one below to experiment with the library code (you’ll modify the .cpp and .h files containing classes SPP, BTD, and USBHost to hack the code into shape).
#include
#include
void serialEventRun(void) {
if (Serial.available())
serialEvent();
if (Serial1.available())
serialEvent1();
}
void serialEvent1() {
// Serial1 -> Host
while (Serial1.available()) {
Serial.write(Serial1.read());
}
}
void serialEvent() {
// Host -> Serial1
while (Serial.available()) {
Serial1.write(Serial.read());
}
}
USBHost usb;
BTD dongle(&usb,"Arduino Due","123456");
SPP spp(&dongle);
boolean firstMessage;
#define LED 13
#define RXLED 72
#define TXLED 73
void setup() {
pinMode(LED,OUTPUT);
pinMode(RXLED,OUTPUT);
pinMode(TXLED,OUTPUT);
digitalWrite(LED,LOW);
Serial.begin(115200);
Serial1.begin(115200);
firstMessage = true;
Serial.println("Arduino Due - Bluetooth SPP\r\n");
spp.Initialize(&dongle);
}
void loop() {
usb.Task();
digitalWrite(TXLED,usb.getNakFlag() ? HIGH : LOW);
/*
if(SerialBT.available()) {
if(firstMessage) {
firstMessage = false;
SerialBT.println(F("Hello from Arduino")); // Send welcome message
}
if(Serial.available())
SerialBT.write(Serial.read());
if(SerialBT.available())
Serial.write(SerialBT.read());
}
else
firstMessage = true;
*/
}