Chapter 27 Bluetooth
This chapter mainly introduces how to make simple data transmission through Bluetooth of ESP32-WROVER and mobile phones.
Project 27.1 is classic Bluetooth and Project 27.2 is low power Bluetooth.If you are an iPhone user, please start with Project 27.2.
Project 27.1 Bluetooth Low Energy Data Passthrough
Component List
ESP32-WROVER x1
|
Micro USB Wire x1
|
In this tutorial we need to use a Bluetooth APP called Serial Bluetooth Terminal to assist in the experiment. If you’ve not installed it yet, please do so by clicking: https://www.appsapk.com/serial-bluetooth-terminal/ The following is its logo.
Lightblue
If you can’t install Serial Bluetooth on your phone, try LightBlue.If you do not have this software installed on your phone, you can refer to this link: https://apps.apple.com/us/app/lightblue/id557428110#?platform=iphone
Code
Move the program folder “Freenove_Ultimate_Starter_Kit_for_ESP32/Python/Python_Codes” to disk(D) in advance with the path of “D:/Micropython_Codes”.
Open “Thonny”, click “This computer” -> “D:” -> “Micropython_Codes” -> “27.1_BLE”. Select “ble_advertising.py”, right click your mouse to select “Upload to /”, wait for “ble_advertising.py” to be uploaded to ESP32-WROVER and then double click “BLE.py”.
27.1_BLE
Click run for BLE.py.
Turn ON Bluetooth on your phone, and open the Lightblue APP.
In the Scan page, swipe down to refresh the name of Bluetooth that the phone searches for. Click ESP32.
After Bluetooth is connect successfully, Shell will printer the information.
Click “Receive”. Select the appropriate Data format in the box to the right of Data Format. For example, HEX for hexadecimal, utf-string for character, Binary for Binary, etc. Then click SUBSCRIBE.
You can type “Hello” in Shell and press “Enter” to send.
And then you can see the mobile Bluetooth has received the message.
Similarly, you can select “Send” on your phone. Set Data format, and then enter anything in the sending box and click Write to send.
You can check the message from Bluetooth in “Shell”.
And now data can be transferred between your mobile phone and computer via ESP32-WROVER.
The following is the program code:
1# This example demonstrates a UART periperhal.
2
3import bluetooth
4import random
5import struct
6import time
7from ble_advertising import advertising_payload
8
9from micropython import const
10
11_IRQ_CENTRAL_CONNECT = const(1)
12_IRQ_CENTRAL_DISCONNECT = const(2)
13_IRQ_GATTS_WRITE = const(3)
14
15_FLAG_READ = const(0x0002)
16_FLAG_WRITE_NO_RESPONSE = const(0x0004)
17_FLAG_WRITE = const(0x0008)
18_FLAG_NOTIFY = const(0x0010)
19
20_UART_UUID = bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
21_UART_TX = (
22 bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E"),
23 _FLAG_READ | _FLAG_NOTIFY,
24)
25_UART_RX = (
26 bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E"),
27 _FLAG_WRITE | _FLAG_WRITE_NO_RESPONSE,
28)
29_UART_SERVICE = (
30 _UART_UUID,
31 (_UART_TX, _UART_RX),
32)
33
34
35class BLESimplePeripheral:
36 def __init__(self, ble, name="ESP32"):
37 self._ble = ble
38 self._ble.active(True)
39 self._ble.irq(self._irq)
40 ((self._handle_tx, self._handle_rx),) = self._ble.gatts_register_services((_UART_SERVICE,))
41 self._connections = set()
42 self._write_callback = None
43 self._payload = advertising_payload(name=name, services=[_UART_UUID])
44 self._advertise()
45
46 def _irq(self, event, data):
47 # Track connections so we can send notifications.
48 if event == _IRQ_CENTRAL_CONNECT:
49 conn_handle, _, _ = data
50 print("New connection", conn_handle)
51 print("\nThe BLE connection is successful.")
52 self._connections.add(conn_handle)
53 elif event == _IRQ_CENTRAL_DISCONNECT:
54 conn_handle, _, _ = data
55 print("Disconnected", conn_handle)
56 self._connections.remove(conn_handle)
57 # Start advertising again to allow a new connection.
58 self._advertise()
59 elif event == _IRQ_GATTS_WRITE:
60 conn_handle, value_handle = data
61 value = self._ble.gatts_read(value_handle)
62 if value_handle == self._handle_rx and self._write_callback:
63 self._write_callback(value)
64
65 def send(self, data):
66 for conn_handle in self._connections:
67 self._ble.gatts_notify(conn_handle, self._handle_tx, data)
68
69 def is_connected(self):
70 return len(self._connections) > 0
71
72 def _advertise(self, interval_us=500000):
73 print("Starting advertising")
74 self._ble.gap_advertise(interval_us, adv_data=self._payload)
75
76 def on_write(self, callback):
77 self._write_callback = callback
78
79
80def demo():
81 ble = bluetooth.BLE()
82 p = BLESimplePeripheral(ble)
83
84 def on_rx(rx_data):
85 print("RX", rx_data)
86
87 p.on_write(on_rx)
88
89 print("Please use LightBlue to connect to ESP32.")
90
91 while True:
92 if p.is_connected():
93 # Short burst of queued notifications.
94 tx_data = input("Enter anything: ")
95 print("Send: ", tx_data)
96 p.send(tx_data)
97
98
99if __name__ == "__main__":
100 demo()
Define the specified UUID number for BLE vendor.
1_UART_UUID = bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
2_UART_TX = (
3 bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E"),
4 _FLAG_READ | _FLAG_NOTIFY,
5)
6_UART_RX = (
7 bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E"),
8 _FLAG_WRITE | _FLAG_WRITE_NO_RESPONSE,
9)
Write an _irq function to manage BLE interrupt events.
1def _irq(self, event, data):
2 # Track connections so we can send notifications.
3 if event == _IRQ_CENTRAL_CONNECT:
4 conn_handle, _, _ = data
5 print("New connection", conn_handle)
6 print("\nThe BLE connection is successful.")
7 self._connections.add(conn_handle)
8 elif event == _IRQ_CENTRAL_DISCONNECT:
9 conn_handle, _, _ = data
10 print("Disconnected", conn_handle)
11 self._connections.remove(conn_handle)
12 # Start advertising again to allow a new connection.
13 self._advertise()
14 elif event == _IRQ_GATTS_WRITE:
15 conn_handle, value_handle = data
16 value = self._ble.gatts_read(value_handle)
17 if value_handle == self._handle_rx and self._write_callback:
18 self._write_callback(value)
Initialize the BLE function and name it.
1def __init__(self, ble, name="ESP32"):
When the mobile phone send data to ESP32 via BLE Bluetooth, it will print them out with serial port; When the serial port of ESP32 receive data, it will send them to mobile via BLE Bluetooth.
1def demo():
2 ble = bluetooth.BLE()
3 p = BLESimplePeripheral(ble)
4
5 def on_rx(rx_data):
6 print("RX", rx_data)
7
8 p.on_write(on_rx)
9
10 print("Please use LightBlue to connect to ESP32.")
11
12 while True:
13 if p.is_connected():
14 # Short burst of queued notifications.
15 tx_data = input("Enter anything: ")
16 print("Send: ", tx_data)
17 p.send(tx_data)
Project 27.2 Bluetooth Control LED
In this section, we will control the LED with Bluetooth.
Component List
ESP32-WROVER x1
|
GPIO Extension Board x1
|
|
Micro USB Wire x1
|
||
Breadboard x1
|
||
LED x1
|
Resistor 220Ω x1
|
Jumper M/M x2
|
Circuit
Connect Freenove ESP32 to the computer using a USB cable.
Schematic diagram |
|
Hardware connection |
If you need any support, please feel free to contact us via: support@freenove.com
|
Code
Move the program folder “Freenove_Ultimate_Starter_Kit_for_ESP32/Python/Python_Codes” to disk(D) in advance with the path of “D:/Micropython_Codes”.
Open “Thonny”, click “This computer” -> “D:” -> “Micropython_Codes” -> “27.2_BLE_LED”. Select “ble_advertising.py”, right click your mouse to select “Upload to /”, wait for “ble_advertising.py” to be uploaded to ESP32-WROVER and then double click “BLE_LED.py”.
27.2_BLE_LED
Compile and upload code to ESP32. The operation of the APP is the same as 27.1, you only need to change the sending content to “led_on” and “led_off” to operate LEDs on the ESP32-WROVER.
Data sent from mobile APP:
You can check the message sent by Bluetooth in “Shell”.
The phenomenon of LED
Attention: If the sending content isn’t “led_on’ or “led_off”, then the state of LED will not change. If the LED is on, when receiving irrelevant content, it keeps on; Correspondingly, if the LED is off, when receiving irrelevant content, it keeps off.
The following is the program code:
1# This example demonstrates a UART periperhal.
2
3import bluetooth
4import random
5import struct
6import time
7from ble_advertising import advertising_payload
8from machine import Pin
9from micropython import const
10
11_IRQ_CENTRAL_CONNECT = const(1)
12_IRQ_CENTRAL_DISCONNECT = const(2)
13_IRQ_GATTS_WRITE = const(3)
14
15_FLAG_READ = const(0x0002)
16_FLAG_WRITE_NO_RESPONSE = const(0x0004)
17_FLAG_WRITE = const(0x0008)
18_FLAG_NOTIFY = const(0x0010)
19
20_UART_UUID = bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
21_UART_TX = (
22 bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E"),
23 _FLAG_READ | _FLAG_NOTIFY,
24)
25_UART_RX = (
26 bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E"),
27 _FLAG_WRITE | _FLAG_WRITE_NO_RESPONSE,
28)
29_UART_SERVICE = (
30 _UART_UUID,
31 (_UART_TX, _UART_RX),
32)
33
34
35class BLESimplePeripheral:
36 def __init__(self, ble, name="ESP32"):
37 self._ble = ble
38 self._ble.active(True)
39 self._ble.irq(self._irq)
40 ((self._handle_tx, self._handle_rx),) = self._ble.gatts_register_services((_UART_SERVICE,))
41 self._connections = set()
42 self._write_callback = None
43 self._payload = advertising_payload(name=name, services=[_UART_UUID])
44 self._advertise()
45
46 def _irq(self, event, data):
47 # Track connections so we can send notifications.
48 if event == _IRQ_CENTRAL_CONNECT:
49 conn_handle, _, _ = data
50 print("New connection", conn_handle)
51 print("\nThe BLE connection is successful.")
52 self._connections.add(conn_handle)
53 elif event == _IRQ_CENTRAL_DISCONNECT:
54 conn_handle, _, _ = data
55 print("Disconnected", conn_handle)
56 self._connections.remove(conn_handle)
57 # Start advertising again to allow a new connection.
58 self._advertise()
59 elif event == _IRQ_GATTS_WRITE:
60 conn_handle, value_handle = data
61 value = self._ble.gatts_read(value_handle)
62 if value_handle == self._handle_rx and self._write_callback:
63 self._write_callback(value)
64
65 def send(self, data):
66 for conn_handle in self._connections:
67 self._ble.gatts_notify(conn_handle, self._handle_tx, data)
68
69 def is_connected(self):
70 return len(self._connections) > 0
71
72 def _advertise(self, interval_us=500000):
73 print("Starting advertising")
74 self._ble.gap_advertise(interval_us, adv_data=self._payload)
75
76 def on_write(self, callback):
77 self._write_callback = callback
78
79
80def demo():
81 ble = bluetooth.BLE()
82 p = BLESimplePeripheral(ble)
83
84 led=Pin(2,Pin.OUT)
85
86 def on_rx(rx_data):
87 print("Received: ", rx_data)
88 if rx_data == b'led_on':
89 led.value(0)
90 elif rx_data == b'led_off':
91 led.value(1)
92 else:
93 pass
94
95 p.on_write(on_rx)
96
97 print("Please use LightBlue to connect to ESP32.")
98
99
100if __name__ == "__main__":
101 demo()
Compare received message with “led_on” and “led_off” and take action accordingly.
1if rx_data == b'led_on':
2 led.value(0)
3elif rx_data == b'led_off':
4 led.value(1)








