Bluetooth with Arduino and Linux
Overview
This is a work in progress. I am working toward getting Bluetooth modules working with Arduino and Raspberry Pi, and I'm testing on a Linux computer. Many people testing Bluetooth modules are using Android devices or iPhones, or are connecting Bluetooth devices like mice and keyboards to Linux systems. What I'm trying to do seems relatively uncommon.
Classic Bluetooth and Bluetooth Smart, also known as Bluetooth LE (Low Energy)
(Note: "Classic" Bluetooth refers to versions below 4.0;
BLE refers to 4.0 and above.)
I won't go into the differences between these except to note
that if you are using Low Energy (BLE) devices, then both ends of the
connection need to be able to handle it. I have an older USB dongle that
doesn't handle BLE, and a newer one that does. If I'm connecting to a
BLE modules, I need a BLE-capable dongle.
This document is about Bluetooth Classic.
Bluetooth Classic module
I got the Bluetooth module on eBay, and there are many similar ones. Some identify themselves as HC-05. Mine looked like this:The back looks like this:
A closer look reveals that the chipset used is from Cambridge Silicon Radio, specifically the BC417.
Arduino connections
The chip datasheet indicates that VCC should be 3.3 V, however there are pins on the board for both 3.3 V and 5V, suggesting there is an onboard regulator. In either case, the RXD and TXD lines operate at 3.3V logic levels.
The KEY pin was left unconnected.
Since the Arduino Uno is a 5V device, the voltage divider on RXD was used to avoid overvoltage on the pin.
Arduino sketch
The Arduino sketch I used was very simple:Linux testing
First, see if you can locate the Bluetooth dongle on the computer:
bash-4.3# hcitool dev
Devices:
hci0 00:11:22:33:44:55
Now you can check the status of the device:
bash-4.3# hciconfig -a
hci0: Type: BR/EDR Bus: USB
BD Address: 00:11:22:33:44:55 ACL MTU: 339:8 SCO MTU: 128:2
DOWN
.
.
.
The last line above indicates the interface is down. To change that:
bash-4.3# hciconfig hci0 up bash-4.3# hciconfig -a hci0: Type: BR/EDR Bus: USB BD Address: 00:11:22:33:44:55 ACL MTU: 339:8 SCO MTU: 128:2 UP RUNNING RX bytes:930 acl:0 sco:0 events:35 errors:0 TX bytes:131 acl:0 sco:0 commands:35 errors:0 Features: 0xff 0x3e 0x85 0x30 0x18 0x18 0x00 0x00 Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3 Link policy: RSWITCH HOLD SNIFF Link mode: SLAVE ACCEPT . . .
Now that the device is working, we can look for Bluetooth Classic devices in the vicintiy:
bash-4.3# hcitool scan
Scanning ...
99:DD:33:22:44:66 HC-05
One device shows up.
It identifies itself as HC-05.
We can find out more about the device:
bash-4.3# hcitool info 99:DD:33:22:44:66
Requesting information ...
BD Address: 99:DD:33:22:44:66
OUI Company: Shenzhen Bolutek Technology Co.,Ltd. (98-D3-31)
Device Name: HC-05
LMP Version: 2.1 (0x4) LMP Subversion: 0x1735
Manufacturer: Cambridge Silicon Radio (10)
Features page 0: 0xff 0xff 0x8f 0xfe 0x9b 0xff 0x59 0x83
.
.
.
The board manufacturer is identified as Cambridge Silicon Radio.)
We can see a list of commands supported by the dongle:
bash-4.3# hciconfig hci0 commands
hci0: Type: BR/EDR Bus: USB
BD Address: 00:11:22:33:44:55 ACL MTU: 339:8 SCO MTU: 128:2
Commands: Octet 0 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 1 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 2 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 3 = 0x03 (Bit 0 1)
Octet 4 = 0xce (Bit 1 2 3 6 7)
Octet 5 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 6 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 7 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 8 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 9 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 10 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 11 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 12 = 0x33 (Bit 0 1 4 5)
Octet 13 = 0x0f (Bit 0 1 2 3)
Octet 14 = 0xe8 (Bit 3 5 6 7)
Octet 15 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 16 = 0x3f (Bit 0 1 2 3 4 5)
'Inquiry' 'Inquiry Cancel' 'Periodic Inquiry Mode'
'Exit Periodic Inquiry Mode' 'Create Connection' 'Disconnect'
'Add SCO Connection' 'Cancel Create Connection'
'Accept Connection Request' 'Reject Connection Request'
'Link Key Request Reply' 'Link Key Request Negative Reply'
'PIN Code Request Reply' 'PIN Code Request Negative Reply'
'Change Connection Packet Type' 'Authentication Requested'
'Set Connection Encryption' 'Change Connection Link Key'
'Master Link Key' 'Remote Name Request' 'Cancel Remote Name Request'
'Read Remote Supported Features' 'Read Remote Extended Features'
'Read Remote Version Information' 'Read Clock Offset'
'Read LMP Handle' 'Hold Mode' 'Sniff Mode' 'Exit Sniff Mode'
'QoS Setup' 'Role Discovery' 'Switch Role' 'Read Link Policy Settings'
'Write Link Policy Settings' 'Read Default Link Policy Settings'
'Write Default Link Policy Settings' 'Flow Specification'
'Set Event Mask' 'Reset' 'Set Event Filter' 'Flush' 'Read PIN Type'
'Write PIN Type' 'Create New Unit Key' 'Read Stored Link Key'
'Write Stored Link Key' 'Delete Stored Link Key' 'Write Local Name'
'Read Local Name' 'Read Connection Accept Timeout'
'Write Connection Accept Timeout' 'Read Page Timeout'
'Write Page Timeout' 'Read Scan Enable' 'Write Scan Enable'
'Read Page Scan Activity' 'Write Page Scan Activity'
'Read Inquiry Scan Activity' 'Write Inquiry Scan Activity'
'Read Authentication Enable' 'Write Authentication Enable'
'Read Encryption Mode' 'Write Encryption Mode' 'Read Class Of Device'
'Write Class Of Device' 'Read Voice Setting' 'Write Voice Setting'
'Read Automatic Flush Timeout' 'Write Automatic Flush Timeout'
'Read Num Broadcast Retransmissions'
'Write Num Broadcast Retransmissions' 'Read Hold Mode Activity'
'Write Hold Mode Activity' 'Read Transmit Power Level'
'Read Synchronous Flow Control Enable'
'Write Synchronous Flow Control Enable'
'Set Host Controller To Host Flow Control' 'Host Buffer Size'
'Host Number Of Completed Packets' 'Read Link Supervision Timeout'
'Write Link Supervision Timeout' 'Read Number of Supported IAC'
'Read Current IAC LAP' 'Write Current IAC LAP'
'Read Page Scan Period Mode' 'Write Page Scan Period Mode'
'Read Page Scan Mode' 'Write Page Scan Mode'
'Set AFH Channel Classification' 'Read Inquiry Scan Type'
'Write Inquiry Scan Type' 'Read Page Scan Type' 'Write Page Scan Type'
'Read AFH Channel Assessment Mode' 'Write AFH Channel Assessment Mode'
'Read Local Version Information' 'Read Local Supported Features'
'Read Local Extended Features' 'Read Buffer Size' 'Read Country Code'
'Read BD ADDR' 'Read Failed Contact Counter'
'Reset Failed Contact Counter' 'Get Link Quality' 'Read RSSI'
'Read AFH Channel Map' 'Read BD Clock' 'Read Loopback Mode'
'Write Loopback Mode' 'Enable Device Under Test Mode'
'Setup Synchronous Connection' 'Accept Synchronous Connection'
'Reject Synchronous Connection'
bash-4.3#
The above one does not handle Bluetooth LE.
There are several commands available for Bluetooth Classic devices:
bash-4.3# hcitool
hcitool - HCI Tool ver 5.40
Usage:
hcitool [options] <command> [command parameters]
Options:
--help Display help
-i dev HCI device
Commands:
dev Display local devices
inq Inquire remote devices
scan Scan for remote devices
name Get name from remote device
info Get information from remote device
spinq Start periodic inquiry
epinq Exit periodic inquiry
cmd Submit arbitrary HCI commands
con Display active connections
cc Create connection to remote device
dc Disconnect from remote device
sr Switch master/slave role
cpt Change connection packet type
rssi Display connection RSSI
lq Display link quality
tpl Display transmit power level
afh Display AFH channel map
lp Set/display link policy settings
lst Set/display link supervision timeout
auth Request authentication
enc Set connection encryption
key Change connection link key
clkoff Read clock offset
clock Read local or remote clock
.
.
.
For more information on the usage of each command use:
hcitool <command> --help
bash-4.3$
To connect with the device (Step 1):
bash-4.3# rfcomm bind /dev/rfcomm0 99:DD:33:22:44:66
bash-4.3#
To connect with the device (Step 2):
bash-4.3# sdptool records 99:DD:33:22:44:66
Service Name: Dev B
Service RecHandle: 0x10000
Service Class ID List:
"Serial Port" (0x1101)
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 1
Language Base Attr List:
code_ISO639: 0x656e
encoding: 0x6a
base_offset: 0x100
bash-4.3#
Note the Channel listed above; it gets used in the next
command.
To connect with the device (Step 3):
bash-4.3# sdptool add --channel=1 SP
bash-4.3#
To connect with the device:
bash-4.3# minicom -D /dev/rfcomm0
Welcome to minicom 2.7.1
OPTIONS: I18n
Compiled on Apr 18 2017, 22:26:16.
Port /dev/rfcomm0, 12:17:18
Press CTRL-A Z for help on special keys
You should see that the flashing of the LED on the module has changed, indicating a connection.
Typing in minicom will show up on the Arduino serial monitor:
Typing in the Arduino serial monitor and clicking "Send" will show up in minicom:
To end the minicom session, type CTRL-A X.
Module command mode
To put the module in command mode:- Turn off power to the module.
- Tie the KEY pin to VCC.
- Turn on power to the module.
- AT commands should work at 9600 baud (documentation conflicts on this; some says 38400 baud) with CR/LF after each command.
To exit command mode:
- Turn off power to the module.
- Disconnect the KEY pin from VCC.
- Turn on power to the module.