The objective of this ESP32 Bluetooth tutorial is to explain how to find the device programmatically using Pybluez, a Python module that allows us to use the Bluetooth resources of a computer. The tests of this tutorial were performed using a DFRobot’s ESP32 module device integrated in a ESP32 development board.
Introduction
The objective of this ESP32 Bluetooth tutorial is to explain how to find the device programmatically using Pybluez, a Python module that allows us to use the Bluetooth resources of a computer.
Although Pybluez is available via pip (a very easy to use Python package manager), I was not able to install it that way. So, the easiest way I found was downloading and running the .exe file available at the module’s package page.
In order to use the Bluetooth functionalities of the ESP32, we will use a port of the BTStack library and the ESP IDF. If you haven’t yet configured the BTStack on your environment, please consult this previous post which explains the steps in detail.
The tests of this tutorial were performed using a DFRobot’s ESP32 module device, integrated in a ESP32 development board. The operating system used was Windows 8.
The python code
We will start our code by importing the newly installed Python module, so we have access to all the functionality we need to discover Bluetooth devices.
import bluetooth
Doing the discovery of devices is pretty straightforward and we just need to call the discover_devices function of the module. This function has some optional parameters, which can be seen at the API documentation here.
We will make use of one of them, called lookup_names, which indicates if the discovery should also try to find the display name of the devices, additionally to their addresses [1]. Since the default value of this parameter is false [1], we will set it to true on the function call.
We will store the result of this function call on a variable, as can be seen in the code bellow. Note that the execution of this function will not be instantaneous because it will take some time to look for the nearby devices.
Note that the duration of the discovery can also be changed by passing as input the duration parameter, which defaults to 8 seconds. In our case, we will not change this value and we will use the default one.
devices = bluetooth.discover_devices(lookup_names=True)
The call to this function should return a list of the devices found, which we stored in a variable called devices. Just to confirm, we will print the type of this variable. We will see later at the testing section that it is indeed a list, but let’s assume that for now.
print(type(devices))
Next, since we already have a data structure with the information of all the devices found, we will check how many they are. To do so, since they are store in a list, we can just use the len function to obtain the total number of devices found and stored on the list.
print("Devices found: %s" % len(devices))
Note that we have used the Python string formatting operator in the code to avoid concatenating strings. This is one of the many ways of manipulating strings in Python.
Finally, we will iterate over all the devices found and print each one of them. To do so, we will just do a simple for in loop.
for item in devices:
print(item)
The final full code is shown bellow.
import bluetooth
devices = bluetooth.discover_devices(lookup_names=True)
print(type(devices))
print("Devices found: %s" % len(devices))
for item in devices:
print(item)
The ESP32 code
The ESP32 code will be basically the same we have covered in the first BTStack ESP32 tutorial. So I will not be explaining it in detail here. We will use the same setup and the previous hello_world project, so we don’t need to worry about additional configurations.
So, just as a quick sum up, we will first initialize the L2CAP and SDP layers of the Bluetooth protocol. Then, we specify some settings on the GAP layer to make our ESP discoverable for other Bluetooth devices and we also set its display name as “Hello world”. Naturally, you can change this name for something you want. Finally, we turn on the power of the hardware Bluetooth controller.
The full source code for the ESP32 can be seen bellow.
#include "btstack.h"
int btstack_main(int argc, const char * argv[]){
l2cap_init();
sdp_init();
gap_discoverable_control(1);
gap_set_local_name("Hello world");
hci_power_control(HCI_POWER_ON);
return 0;
}
Running the code
The first thing we need to to is upload the Bluetooth functionality code to the ESP32, so it can be then detected by our Python program. You can check the previous tutorial which explains in detail how to configure the IDF for the settings needed to upload the code to the FireBeetle / ESP-WROOM-32 module.
Once the configurations are finished, just hit the command bellow with the board connected and the program should be compiled and uploaded. Note however that you may need to reset or unplug and re-plug the power of the board because it may stay in download mode after the program is flashed.
make flash
After this, you should be able to find your device on your computer or cellphone, as can be seen in figure 1.
Figure 1 – ESP32 Bluetooth ready to pair with a computer.
Now we can run our Python code. In my case, I’m using IDLE, the Python IDE, but you can use other environment of your choice. Upon executing the code, you should get something similar to figure 2.As can be seen, our ESP32 is found as an available Bluetooth device, with the “Hello world” name we specified before. The strings on the left of each tuple are the addresses of the Bluetooth devices found.
Figure 2 – Output of the Python Bluetooth device lookup program.
Note that not only the ESP32 is found, but also other devices I have paired on my computer, which match the ones found by Windows and shown on figure 1.