Bluetooth Programming with Python 3

written

This post presents basic techniques for communicating over Bluetooth with Python 3.3 and above (using Python sockets). Some simple examples of communicating over Bluetooth with sockets will be shown. PyBluez examples will also be presented for comparison.

The two options

Currently, the most widely documented way to communicate with Python over Bluetooth is to use PyBluez. Previously, PyBluez only supported Python 2. In January 2014, they released a Python 3 version.

Python 3.3’s native Python sockets support Bluetooth communication. Unfortunately, there is very little documentation available describing how to use Python sockets to communicate over Bluetooth. While using Bluetooth with these sockets might be easy for someone who already knows how to use Python sockets, the lack of documentation leaves many people unaware that this method of using Bluetooth even exists. Since PyBluez was ported to Python 3, the use of native Python sockets has limited use.

Required skill: finding the MAC address of a bluetooth adapter

To run the examples, the MAC address of the Bluetooth adapter used by the server must be known. The client application uses this address to connect to the server. On Linux, you can get a list of all available Bluetooth devices and their MAC addresses using the command hciconfig, like so:

hciconfig output

Client sever messaging

This application connects two devices over Bluetooth and allows one to send messages to the other. The sending device runs socketClient.py, and the receiving device runs socketServer.py. These scripts are shown below, first using Python sockets, then using PyBluez:

Python sockets

Client (socketClient.py)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"""
A simple Python script to send messages to a sever over Bluetooth using
Python sockets (with Python 3.3 or above).
"""

import socket

serverMACAddress = '00:1f:e1:dd:08:3d'
port = 3
s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
s.connect((serverMACAddress,port))
while 1:
    text = input()
    if text == "quit":
        break
    s.send(bytes(text, 'UTF-8'))
s.close()
Server (socketServer.py)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
"""
A simple Python script to receive messages from a client over
Bluetooth using Python sockets (with Python 3.3 or above).
"""

import socket

hostMACAddress = '00:1f:e1:dd:08:3d' # The MAC address of a Bluetooth adapter on the server. The server might have multiple Bluetooth adapters.
port = 3 # 3 is an arbitrary choice. However, it must match the port used by the client.
backlog = 1
size = 1024
s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
s.bind((hostMACAddress,port))
s.listen(backlog)
try:
    client, address = s.accept()
    while 1:
        data = client.recv(size)
        if data:
            print(data)
            client.send(data)
except:	
    print("Closing socket")	
    client.close()
    s.close()

As an aside, this code is almost identical to code required to create a client-server application over the internet. All that needs to be changed is the two lines:

1
2
3
4
5
6
7
8
9
# For the Server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("192.168.1.17",50001)) # The Bluetooth MAC Address and RFCOMM port is replaced with an IP Address and a TCP port.

# For the Client
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.1.17",50001))

# Note: these are arbitrary IP addresses and TCP ports.

PyBluez

To compare, below is the functionally identical application written using the PyBluez library.

Client (PyBluezClient.py)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"""
A simple Python script to send messages to a sever over Bluetooth
using PyBluez (with Python 2).
"""

import bluetooth

serverMACAddress = '00:1f:e1:dd:08:3d'
port = 3
s = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
s.connect((serverMACAddress, port))
while 1:
    text = raw_input() # Note change to the old (Python 2) raw_input
    if text == "quit":
    break
    s.send(text)
sock.close()
Server (PyBluezServer.py)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
"""
A simple Python script to receive messages from a client over
Bluetooth using PyBluez (with Python 2).
"""

import bluetooth

hostMACAddress = '00:1f:e1:dd:08:3d' # The MAC address of a Bluetooth adapter on the server. The server might have multiple Bluetooth adapters.
port = 3
backlog = 1
size = 1024
s = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
s.bind((hostMACAddress, port))
s.listen(backlog)
try:
    client, clientInfo = s.accept()
    while 1:
        data = client.recv(size)
        if data:
            print(data)
            client.send(data) # Echo back to client
except:	
    print("Closing socket")
    client.close()
    s.close()

Conclusion

PyBluez is the most effective way of communicating over Bluetooth using Python. Python sockets can now be used for Bluetooth communication (since Python 3.3).  For a simple application, the code is almost identical. For some tasks, however, such as device discovery and Bluetooth service advertisements, it does not seem possible to carry them out using Python sockets. Consequently, PyBluez surpassed Python sockets in most regards. This Stackoverflow question discusses some of the limitations of Python sockets for Bluetooth.

Further reading

There is little to no information on Bluetooth programming with Python sockets. There is plenty of information on PyBluez. The following are some useful resources:

Bluetooth Essentials for Programmers
Covers many programming languages and uses PyBluez with Python. Great for getting started fast and gaining understanding along the way.
PyBluez examples
Example code covering various Bluetooth tasks.

Comments