Bluetooth Smart (LE) 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.

Bluetooth LE module

I got the Bluetooth module on eBay, and there are many similar ones. Some identify themselves as HM-10. Mine looked like this: front of module
The back looks like this:
back of module
The ZS-040 is common to many of these. The device indicates that VCC can be from 3.6 to 6 V, however the RXD and TXD lines operate at 3.3V logic levels, regardless of VCC.

A closer look reveals that the chipset used is from Texas Instruments, specifically the CC2541.
CC2541 chip

Arduino connections

Arduino connections
The EN and STATE pins were 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:
arduino sketch

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 
	.
	. 
	.
Note that the dongle is originally configured as a slave. If we want to change it to a master:
bash-4.3#  hciconfig -a hci0 lm master
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:1496 acl:0 sco:0 events:43 errors:0
	TX bytes:187 acl:0 sco:0 commands:43 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: MASTER
	Name: ''
	Class: 0x000104
	Service Classes: Unspecified
	Device Class: Computer, Desktop workstation
	HCI Version: 2.0 (0x3)  Revision: 0xc5c
	LMP Version: 2.0 (0x3)  Subversion: 0xc5c
	Manufacturer: Cambridge Silicon Radio (10)
Note that is is now configured as a master. There is a lot of information given including the manufacturer.
Now that the device is working, we can look for BLE devices in the vicintiy:
bash-4.3#  hcitool lescan

LE Scan ...
CC:FF:11:11:66:22 (unknown)
CC:FF:11:11:66:22 (unknown)
CC:FF:11:11:66:22 MLT-BT05
	.
	. 
	.
One device shows up. It identifies itself as MLT-BT05. We can find out more about the device:
bash-4.3#  hcitool leinfo CC:FF:11:11:66:22

Requesting information ...
	Handle: 71 (0x0047)
	LMP Version: 4.0 (0x6) LMP Subversion: 0x132
	Manufacturer: Texas Instruments Inc. (13)
	Features: 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
(As mentioned above, the chipset manufacturer is identified as Texas Instruments.)
Does the dongle support BLE?
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. The following one does:
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)
	.
	. 
	.
	'Send Keypress Notification' 'IO Capability Request Negative Reply' 
	'Read Encryption Key Size' 'Read Enhanced Transmit Power Level' 
	'Read LE Host Support' 'Write LE Host Support' 'LE Set Event Mask' 
	'LE Read Buffer Size' 'LE Read Local Supported Features' 
	'LE Set Random Address' 'LE Set Advertising Parameters' 
	'LE Read Advertising Channel TX Power' 'LE Set Advertising Data' 
	'LE Set Scan Response Data' 'LE Set Advertise Enable' 
	'LE Set Scan Parameters' 'LE Set Scan Enable' 'LE Create Connection' 
	'LE Create Connection Cancel' 'LE Read White List Size' 
	'LE Clear White List' 'LE Add Device To White List' 
	'LE Remove Device From White List' 'LE Connection Update' 
	'LE Set Host Channel Classification' 'LE Read Channel Map' 
	'LE Read Remote Used Features' 'LE Encrypt' 'LE Rand' 
	'LE Start Encryption' 'LE Long Term Key Request Reply' 
	'LE Long Term Key Request Negative Reply' 'LE Read Supported States' 
	'LE Receiver Test' 'LE Transmitter Test' 'LE Test End' 
bash-4.3# 
All of the LE commands at the end indicate that this dongle supports BLE.

There are several commands that hcitool has specifically for BLE 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
	.
	.
	.
	clock	Read local or remote clock
	lescan	Start LE scan
	leinfo	Get LE remote information
	lewladd	Add device to LE White List
	lewlrm	Remove device from LE White List
	lewlsz	Read size of LE White List
	lewlclr	Clear LE White List
	lerladd	Add device to LE Resolving List
	lerlrm	Remove device from LE Resolving List
	lerlclr	Clear LE Resolving List
	lerlsz	Read size of LE Resolving List
	lerlon	Enable LE Address Resolution
	lerloff	Disable LE Address Resolution
	lecc	Create a LE Connection
	ledc	Disconnect a LE Connection
	lecup	LE Connection Update

For more information on the usage of each command use:
	hcitool <command> --help
bash-4.3$ 

To connect with the device:
bash-4.3#  hcitool lecc CC:FF:11:11:66:22

Connection handle 71
bash-4.3# 

You should see that the formerly flashing LED on the module now stays on, indicating a connection.

To disconnect from the device:
bash-4.3#  hcitool  ledc 71

bash-4.3# 

Arduino serial monitor test
To monitor traffic from the remote device:
bash-4.3#  hcidump --raw hci0

HCI sniffer - Bluetooth packet analyzer ver 5.40
device: hci0 snap_len: 1500 filter: 0xffffffff
> 02 47 20 0D 00 09 00 04 00 1B 25 00 74 65 73 74 0D 0A 
The string 74 65 73 74 translates to ASCII as test, (followed by carriage return (0D) linefeed (0A)), which was sent from the Arduino with the module.

Linux testing using bluetoothctl

bluetoothctl is an alternative Linux tool for testing Bluetooth.
bash-4.3#  bluetoothctl

[bluetooth]# 
Notice that it operates in interactive mode.
Find local controller:
[bluetooth]#  list

Controller 00:11:22:33:44:55 BlueZ 5.40 [default]
[bluetooth]# 
Look for remote devices:
[bluetooth]#  scan on

Discovery started
[CHG] Controller 00:1A:7D:DA:71:0A Discovering: yes
[CHG] Device CC:FF:11:11:66:22 RSSI: -58
[NEW] Device 57:3F:C6:DD:3B:63 57-3F-C6-DD-3B-63
[bluetooth]# 
Connect to remote device:
[bluetooth]#  connect CC:FF:11:11:66:22

Attempting to connect to CC:FF:11:11:66:22
[CHG] Device CC:FF:11:11:66:22 Connected: yes
Connection successful
[MLT-BT05]#
The prompt has changed to the name of the connected device.
Disconnecting is similar:
[MLT-BT05]#  disconnect 

Attempting to disconnect from CC:FF:11:11:66:22
Successful disconnected
[CHG] Device CC:FF:11:11:66:22 Connected: no
[bluetooth]#
The prompt has returned to its non-specific state.
If a device is already connected when the program is started, the prompt will reflect that:
bash-4.3#  bluetoothctl

[NEW] Controller 00:11:22:33:44:55 BlueZ 5.40 [default]
[NEW] Device CC:FF:11:11:66:22 MLT-BT05
[MLT-BT05]#
There are many commands:
[MLT-BT05]# help

Available commands:
  list                       List available controllers
  show [ctrl]                Controller information
  select <ctrl>              Select default controller
  devices                    List available devices
  paired-devices             List paired devices
  power  <on/off>            Set controller power
  pairable  <on/off>         Set controller pairable mode
  discoverable  <on/off>     Set controller discoverable mode
  agent  <on/off/capability> Enable/disable agent with given capability
  default-agent              Set agent as the default one
  set-scan-filter-uuids [uuid1 uuid2 ...] Set scan filter uuids
  set-scan-filter-rssi [rssi] Set scan filter rssi, and clears pathloss
  set-scan-filter-pathloss [pathloss] Set scan filter pathloss, and clears rssi
  set-scan-filter-transport [transport] Set scan filter transport
  set-scan-filter-clear      Clears discovery filter.
  scan  <on/off>             Scan for devices
  info [dev]                 Device information
  pair [dev]                 Pair with device
  trust [dev]                Trust device
  untrust [dev]              Untrust device
  block [dev]                Block device
  unblock [dev]              Unblock device
  remove  <dev>              Remove device
  connect  <dev>             Connect device
  disconnect [dev]           Disconnect device
  list-attributes [dev]      List attributes
  select-attribute  <attribute> Select attribute
  attribute-info [attribute] Select attribute
  read                       Read attribute value
  write  <data=[xx xx ...]>  Write attribute value
  notify  <on/off>           Notify attribute value
  register-profile  <UUID ...> Register profile to connect
  unregister-profile         Unregister profile
  version                    Display version
  quit                       Quit program
[MLT-BT05]#
The info command returns information about the remote device.
[MLT-BT05]# info

Device CC:FF:11:11:66:22
	Name: MLT-BT05
	Alias: MLT-BT05
	Paired: no
	Trusted: yes
	Blocked: no
	Connected: yes
	LegacyPairing: no
	UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
	UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
	UUID: Device Information        (0000180a-0000-1000-8000-00805f9b34fb)
	UUID: Unknown                   (0000ffe0-0000-1000-8000-00805f9b34fb)
	Modalias: bluetooth:v000Dp0000d0110
[MLT-BT05]# 

AT commands for module

You can see which AT commands this device supports (using AT+HELP):
AT commands supported
AT Version command
AT Version command reply

MLT-BT05 documentation

Here is my attempt at a translation of the original document. (Any corrections are welcome!)

Resources

To view pdf documents, you can download Adobe Acrobat Reader .
get Acrobat Reader
If you need to update a browser, you might try Firefox which is Get Firefox!
Since this page uses cascading style sheets for its layout, it will look best with a browser which supports the specifications as fully as possible.

If you are looking for an office package, with a word processor, spreadsheet, etc., you might try LibreOffice which is Get LibreOffice!

Go to the main page for the Department of Physics and Computer Science.

Valid XHTML 1.1

Valid CSS!

WCAG
2.0
(Level AA)

Wilfrid Laurier University