https://github.com/akilmarshall/esp32-ble-demo
A simple project to learn something about Bluetooth low energy and micropython.
https://github.com/akilmarshall/esp32-ble-demo
ble bluetooth bluetooth-low-energy eps32 esp32-wroom micropython
Last synced: about 2 months ago
JSON representation
A simple project to learn something about Bluetooth low energy and micropython.
- Host: GitHub
- URL: https://github.com/akilmarshall/esp32-ble-demo
- Owner: akilmarshall
- Created: 2020-10-06T04:58:17.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2020-10-06T05:07:19.000Z (over 4 years ago)
- Last Synced: 2025-03-26T08:11:29.569Z (2 months ago)
- Topics: ble, bluetooth, bluetooth-low-energy, eps32, esp32-wroom, micropython
- Language: Python
- Homepage:
- Size: 10.7 KB
- Stars: 10
- Watchers: 1
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# esp32-ble-demo
This is a demo project to learn about and implement a basic environmental sensor
with a controllable led using bluetooth low energy (ble).
This project is written in micropython.The environment is sampled using a bme280 or bmp280 sensor and served via a GATT server.
Additionally an l.e.d. can be blinked when the utf-8 string 'blink' is sent to the GATT server via the string characteristic.* [parts](#parts)
* [ble_environment.py](#ble_environmentpy)
* [BLEEnvironment class](#bleenvironment-class)
* [\_\_init\_\_](#__init_)
* [_irq](#irq)
* [set_environment_data](#set_environment_data)
* [read_act](#read_act)
* [_advertise](#advertise)
* [bme280_float.py](#bme280_floatpy)
* [gpio.py](#gpiopy)
* [ble_advertising.py](#ble_advertisingpy)## parts
- ESP32-WROOM-32 microcontroller
- bmp280 environmental sensor (temperature, pressure)
- led## ble_environment.py
This file defines the BLEEnvironment class that runs the application
```python
import bluetooth
import random
import struct
import time
from ble_advertising import advertising_payloadfrom micropython import const
import bme280_float as bme280
from machine import Pin, I2Cfrom gpio import blink
```
standard micropython and project specific libraries.
ble_advertising, bme280_float, and gpio will be explained in their own sections.```python
_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_INDICATE_DONE = const(20)```
Define event code constants.
```python
# org.bluetooth.service.environmental_sensing
_ENV_SENSE_UUID = bluetooth.UUID(0x181A)
```Use a predefined uuid for the enviornmental_sensing service.
```python
# org.bluetooth.characteristic.temperature
# temperature
_TEMP_CHAR = (
bluetooth.UUID(0x2A6E),
bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY | bluetooth.FLAG_INDICATE,
)# atmospheric pressure
# org.bluetooth.characteristic.pressure
_PRESSURE_CHAR = (
bluetooth.UUID(0x2A6D),
bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY | bluetooth.FLAG_INDICATE,
)# percentage humidity
# org.bluetooth.characteristic.humidity
_HUMIDITY_CHAR = (
bluetooth.UUID(0x2A6F),
bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY | bluetooth.FLAG_INDICATE,
)# communication channel
# org.bluetooth.characteristic.string
_STRING_CHAR = (
bluetooth.UUID(0x2A3D),
bluetooth.FLAG_READ | bluetooth.FLAG_WRITE,
)
```Also using predefine uuids define the characteristics the service will offer.
```python
_ENV_SENSE_SERVICE = (
_ENV_SENSE_UUID,
(_TEMP_CHAR, _PRESSURE_CHAR, _HUMIDITY_CHAR, _STRING_CHAR),
)# org.bluetooth.characteristic.gap.appearance.xml
_ADV_APPEARANCE_GENERIC_ENVIRONMENTAL_SENSOR = const(5696)```
Using the service and characteristics previously defined fully define the service
to be registered on the GATT server.### BLEEnvironment class
The following are methods of BLEEnvironment class.
#### \_\_init\_\_
```python
def __init__(self, ble, name="esp32-ble-demo"):
"""
__init__ :: BLEEnvironment -> bluetooth.BLE -> str -> BLEEnvironment
"""
self._ble = ble
self._ble.active(True)
# register the event handler for events in the BLE stack
self._ble.irq(self._irq)
# unpack the gatt handles returned from service registration
((self._temp_handle, self._pressure_handle, self._humidity_handle, self._string_handle),
) = self._ble.gatts_register_services((_ENV_SENSE_SERVICE,))
# a set to contain connections to enable the sending of notifications
self._connections = set()
# create the payload for advertising the server
self._payload = advertising_payload(
name=name,
services=[_ENV_SENSE_UUID],
appearance=_ADV_APPEARANCE_GENERIC_ENVIRONMENTAL_SENSOR
)
# begin advertising the gatt server
self._advertise()
```\_\_init\_\_ constructs an object of the BLEEnvironment class.
ble is a bluetooth.BLE object.
This method sets up and begins to advertise the device for bluetooth connections.#### _irq
```python
def _irq(self, event, data):
# callback function for events from the BLE stack
# Track connections so we can send notifications.
if event == _IRQ_CENTRAL_CONNECT:
conn_handle, _, _ = data
self._connections.add(conn_handle)
elif event == _IRQ_CENTRAL_DISCONNECT:
conn_handle, _, _ = data
self._connections.remove(conn_handle)
# Start advertising again to allow a new connection.
self._advertise()
elif event == _IRQ_GATTS_INDICATE_DONE:
conn_handle, value_handle, status = data
```Define a simple event handler for GATT stack events.
This method is used by bluethooth.BLE.irq#### set_environment_data
```python
def set_environment_data(self, temp, pressure, humidity, notify=False, indicate=False):# write fresh temperature, pressure, and humidity data to the GATT server characteristics
self._ble.gatts_write(
self._temp_handle, struct.pack(" function.obj)
# the functions could be written such that they can be spawned in a new thread so the main loop is not blocked.
# currently the action requested by a message blocks until the action completes.
if value == bytes('blink', 'utf-8'):
p = Pin(23, Pin.OUT)
for _ in range(3):
blink(p)# the channel is cleared
self._ble.gatts_write(self._string_handle, struct.pack("