Edison to Edison Bluetooth

Intro

So, there’s a lot of information out there about how to get Bluetooth working on your Intel Edison. For example, Intel has published this incredibly 73 page document on using the Edison bluetooth. 73 pages?!

There’s also some info on the forums, but I couldn’t get any of the examples to work without significant modification. So, I’ve written my own examples here. This page contains information about Edison to Edison (or Edison to other Linux box) communication. There will be an accompanying Edison to smart phone tutorial on the way as well.

The First Connection Handshake

Before we can connect from the the Edisons directly from the command line, we need to pair these devices so that they make the handshake for the first time. Designate one Edison the “master” and the other one the “slave”. The master initiates the connection; the slave will get connected to.

So, go ahead and boot-up and log into both Edisons. The first thing is to unblock the bluetooth on both devices.

root@edison:~# rfkill unblock bluetooth

Check to make sure that this worked by listing the devices

root@edison:~# rfkill list
0: phy0: wlan
        Soft blocked: no
        Hard blocked: no
1: brcmfmac-wifi: wlan
        Soft blocked: no
        Hard blocked: no
2: bcm43xx Bluetooth: bluetooth
        Soft blocked: no
        Hard blocked: no
3: hci0: bluetooth
        Soft blocked: no
        Hard blocked: no

Next, we’ll use the command line utility bluetoothctl in order to make the preliminary pairing. You’re going to issue all the following commands on both devices until I tell you otherwise.

root@edison:~# bluetoothctl
[NEW] Controller XX:XX:XX:XX:XX:XX edison [default]

When bluetoothctl starts up, your Edison Bluetooth Mac address and name will pop up (I’ve listed the XX stuff in place of mine). The bluetoothctl command help will list all the possible program commands for you.

[bluetooth]# help
Available commands:
  list                       List available controllers
  show [ctrl]                Controller information
  select                     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
  scan <on/off>              Scan for devices
  info                       Device information
  pair                       Pair with device
  trust                      Trust device
  untrust                    Untrust device
  block                      Block device
  unblock                    Unblock device
  remove                     Remove device
  connect                    Connect device
  disconnect                 Disconnect device
  version                    Display version
  quit                       Quit program

When the two Edisons pair for the first time, they need user interaction to validate. This means we need to create an active keyboard agent to perform the confirmation.

[bluetooth]# agent KeyboardDisplay
Agent registered
[bluetooth]# default-agent
Default agent request successful

Now, on the slave device, change the settings so that the device is on, pairable, and discoverable. This will allow the master to “see” it and connect to it.

[bluetooth]# power on
Changing power on succeeded
[bluetooth]# pairable on
Changing pairable on succeeded
[bluetooth]# discoverable on
Changing discoverable on succeeded
[CHG] Controller 98:4F:EE:03:41:90 Discoverable: yes

Now, on the master side, start a scan and after a little bit of time you should see your Edison.

[bluetooth]# scan on
Discovery started
[CHG] Controller XX:XX:XX:XX:XX:XX Discovering: yes
[NEW] Device YY:YY:YY:YY:YY:YY 5C-F9-38-D7-8F-37
[NEW] Device AA:AA:AA:AA:AA:AA Kelsey’s MacBook Air
[NEW] Device BB:BB:BB:BB:BB:BB BlueZ 5.24

Once you’ve confirmed that you can see your other Edison and that it matches the Mac address you know to be true, turn the scan back off.

[bluetooth]# scan off

Go ahead and initiate the pairing from the master side:

[bluetooth]# pair AA:AA:AA:AA:AA:AA
Attempting to pair with AA:AA:AA:AA:AA:AA
[CHG] Device AA:AA:AA:AA:AA:AA Connected: yes
Request confirmation
[agent] Confirm passkey 719442 (yes/no): yes
[CHG] Device AA:AA:AA:AA:AA:AA Paired: yes
Pairing successful
[CHG] Device AA:AA:AA:AA:AA:AA Connected: no

Both Edisons will prompt you to confirm the passkey in the step above. This is why we needed the KeyboardInput as our default-agent. When you confirm on both ends, the pairing will take place. Note that we’re paired now, but we’re not yet connected.

To connect, first change the settings on the slave side to “trust” the master

[bluetooth]# trust XX:XX:XX:XX:XX:XX
[CHG] Device XX:XX:XX:XX:XX:XX Trusted: yes
Changing XX:XX:XX:XX:XX:XX trust succeeded

Then go ahead and pair from the master side

[bluetooth]# connect 98:4F:EE:03:41:90
Attempting to connect to 98:4F:EE:03:41:90
[CHG] Device 98:4F:EE:03:41:90 Connected: yes
Connection successful

Stable connection from the command line

This is all fine and good, but I don’t want to have to do this every single time. This interactivity is kind of annoying.

So, to establish connections from the command line we can use the rfcomm tool. On both sides, we need to issue the following statements:

root@edison:~# rfkill unblock bluetooth
root@edison:~# hciconfig hci0 piscan
root@edison:~# hciconfig hci0 sspmode 1

The piscan command makes the Edisons discoverable, and the sspmode puts Edison into simple secure pairing mode. Now, on the slave side, we need to open a port and listen on this port for an incoming connection

root@edison:~# sdptool add --channel=22 SP
root@edison:~# rfcomm listen /dev/rfcomm0 22 & 

The & sign at the end of the first command runs the command in the background. This isn’t strictly necessary, though running it in the foreground will entirely take over your terminal so long as you’re connected and you won’t be able to do anything else. Running it in the background will still give the feedback in the console (hit enter to remove it from your current command prompt or get your prompt back). It’ll look something like this:

Waiting for connection on channel 22

Score! So now all we need to do is connect from the other side. On the master, issue the following:

root@edison:~# rfcomm connect /dev/rfcomm0 AA:AA:AA:AA:AA:AA 22 &

Again, I’m just using the & symbol to keep from tying up my entire console. You should now receive confirmation on both sides that you are connected!

Reading Bluetooth Data

My favorite tool for reading bluetooth data is the Python PySerial Library. It’s not in any of the opkg repos, so you’ve got to use pip to install it. Pip is in the opkg repos, but it’s not been installing correctly for me from there, so I use the command line:

root@edison:~# wget https://bootstrap.pypa.io/get-pip.py --no-check-certificate
root@edison:~# python get-pip.py
root@edison:~# pip install pyserial

Then, fire up python on both Edisons to send some bluetooth messages back and forth.

root@edison:~# python

Import the pyserial library and open the rfcomm0 port, which is the bluetooth port we chose on both Edisons. I usually set a timeout or else the thing will hang forever if the connection goes awry.

>>> import serial
>>> ser = serial.Serial("/dev/rfcomm0", timeout=0.5)
>>> ser.write("hello")
>>> ser.write([1,2,3,4,5])
>>> ser.read()
>>> ser.read(5)

Anything you write on one edison will be readable on the other. The write function takes strings or arrays and the read function reads one byte at a time unless an integer is specified as an argument.

And that’s it. Congratulations! Bluetooth is working :-)

WARNING: Edison uses the BlueZ stack to control the bluetooth. Sometimes Bluez can be a bit wild when you disconnect, basically freezing your Edison to everything but a power cycle. Don’t worry, your Edison is fine. Just power it on back up.

NOTE: You can actually control the bluetoothctl program from the command line by using echo statements, but I’ve had very little reliable success with this method:

root@edison:~# echo -e ‘power on\nconnect 98:4F:EE:03:41:90\nquit’ | bluetoothctl

Posted in Edison, Tech
2 comments on “Edison to Edison Bluetooth
  1. Evan J says:

    Hello,

    I am trying to connect my Edison (Running Ubilinux Debian) to my phone using first the bluetoothctl command. I get right up to the point where i call the “connect AA:AA:AA:AA:AA:AA” command and that is where I run into problems.

    I get the following when I call the connect command:

    org.bluez.Error.Failed

    I did successfully pair my device to my phone. I also do not see any device labeled /dev/rfcomm… it does not seem to be present.

    Any help would be greatly appreciated!

    • Stephanie Moyerman says:

      Sorry for the incredibly slow response on this. The process for connecting to a smart phone, as opposed to connecting to another Edison or Linux computer, is a little different. I’ve created a post here for you to follow: http://stephaniemoyerman.com/?p=120.

      Know that the rfcomm port doesn’t open until the pairing is actually made between the two devices. Since the pairing failed through bluetoothctl, the port is not opened, hence why you can’t find it.

      Let me know if you still run into problems following the other post!

Leave a Reply

Your email address will not be published. Required fields are marked *

*