Bluetooth Sensor Capture - Adafruit Circuit Playground Bluefruit

The following example demonstrates using an Adafruit Circuit Playground Bluefruit as a wireless sensor. The CircuitPython program uses only the onboard sensor hardware. The companion Python program runs on a host computer (e.g. desktop or laptop) and receives data. One example use case is to capture accelerometer motion sensor data for analysis.

Prerequisites

Related Information

  1. Site pages

  2. Tutorials

  3. Technical Documentation

  4. iOS apps

CircuitPython Remote Sensor

Direct download: cpb_ble_sensor.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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# cpb_ble_sensor.py

# Provide a remote sensing service over Bluetooth Low-Energy (BLE).
# This runs on an Adafruit Circuit Playground Bluefruit.

# This example works with either:
#  1. host_ble_receiver.py running on a host computer
#  2. the Plotter function of the Bluefruit Connect iOS app

# ----------------------------------------------------------------
# Import the standard Python time functions.
import time

# Import the board-specific input/output library.
from adafruit_circuitplayground import cp

# Import the Adafruit Bluetooth library.  Technical reference:
# https://circuitpython.readthedocs.io/projects/ble/en/latest/api.html
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService

# ----------------------------------------------------------------
# Initialize global variables for the main loop.

ble = BLERadio()
uart = UARTService()
advertisement = ProvideServicesAdvertisement(uart)

print("Radio:", ble)
ble.name = 'CPB-accel-1'
print("Radio name:", ble.name)

print("Advertisement:", advertisement)
print("UART:", uart)

# Flags for detecting state changes.
advertised = False
connected  = False

# The sensor sampling rate is precisely regulated using the following timer variables.
sampling_timer    = 0.0
last_time         = time.monotonic()
sampling_interval = 0.10

# ----------------------------------------------------------------
# Begin the main processing loop.

while True:

    # Read the accelerometer at regular intervals.  Measure elapsed time and
    # wait until the update timer has elapsed.
    now = time.monotonic()
    interval = now - last_time
    last_time = now
    sampling_timer -= interval
    if sampling_timer < 0.0:
        sampling_timer += sampling_interval
        x, y, z = cp.acceleration
    else:
        x = None

    if not advertised:
        ble.start_advertising(advertisement)
        print("Waiting for connection.")
        advertised = True

    if not connected and ble.connected:
        print("Connection received.")
        connected = True
        cp.red_led = True
        
    if connected:
        if not ble.connected:
            print("Connection lost.")
            connected = False
            advertised = False
            cp.red_led = False            
        else:
            if x is not None:
                uart.write(b"%.3f,%.3f,%.3f\n" % (x, y, z))

Host Sensor Receiver

The host-side script uses a version of the Adafruit Bluetooth libraries for regular Python so the essential code uses the same interface.

Direct download: host_ble_receiver.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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# Connect to a remote sensing service over Bluetooth Low-Energy (BLE).  This
# script runs in Python 3 on a desktop or laptop.  It scans for a connection,
# the prints incoming data to the console until the connection breaks.

# It assumes the following packages have been installed:
#
#  pip3 install adafruit-blinka-bleio
#  pip3 install adafruit-circuitpython-ble

# ----------------------------------------------------------------
# Import the Adafruit Bluetooth library, part of Blinka.  Technical reference:
# https://circuitpython.readthedocs.io/projects/ble/en/latest/api.html

from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService

# ----------------------------------------------------------------
# Initialize global variables for the main loop.
ble = BLERadio()
uart_connection = None

# ----------------------------------------------------------------
# Begin the main processing loop.

while True:
    if not uart_connection:
        print("Trying to connect...")
        for adv in ble.start_scan(ProvideServicesAdvertisement):
            print("Found advertisement: ", adv)
            print("  name:", adv.complete_name)
            if UARTService in adv.services:
                uart_connection = ble.connect(adv)
                print("Connected with ", uart_connection)
                break
        ble.stop_scan()

    if uart_connection and uart_connection.connected:
        uart_service = uart_connection[UARTService]
        while uart_connection.connected:
            print(uart_service.readline().decode("utf-8").rstrip())