Various embedded experiments, including BLE Peripheral in Zephyr/C and Embassy/Rust, BLE Central (Rust), and async Rust.
- notifier (Zephyr, C): BLE Peripheral that advertises a 16‑bit service 0x183B with a single Notifiable characteristic (0x183C). It counts external events (button SW0 presses) and periodically notifies a 1‑byte value (sum of recent readings) every ~250 ms when a client subscribes.
- notifier (Embassy, Rust): BLE Peripheral that advertises a 16‑bit service 0x183B with a single Notifiable characteristic (0x183C). It counts external events (button SW0 presses) and periodically notifies a 1‑byte value (sum of recent readings) every ~250 ms when a client subscribes.
- subscriber (Rust): BLE Central that scans for the service, connects, subscribes to the first characteristic in the service, and collects three notifications (with a 10s timeout) using btleplug.
Service UUIDs (Bluetooth base UUID):
- Service: 0000183b-0000-1000-8000-00805f9b34fb
- Characteristic: 0000183c-0000-1000-8000-00805f9b34fb
embedded-workspace/*: Zephyr applications (C, CMake)embassy-experiment/: Rust async embedded BLE peripheral for nRF52840 using Embassy and nrf-softdevicesubscriber/: Rust workspace member (btleplug + tokio)pico-2w/: Minimal Rust embedded project for Raspberry Pi Pico W (rp235x-hal)
Install Rust and toolchain:
curl https://sh.rustup.rs -sSf | sh
rustup default stablePlatform specifics for BLE (btleplug):
- macOS: Works with CoreBluetooth. Grant Bluetooth permission to your terminal/IDE in System Settings > Privacy & Security > Bluetooth.
- Linux: Install BlueZ; ensure your user can access BLE (may need
bluetoothgroup and runningbluetoothd). - Windows: Uses Windows BLE APIs; run from a terminal with Bluetooth enabled.
- Uses Embassy async framework and nrf-softdevice for BLE
- Implements a custom GATT server and notification logic in async Rust
- Target: nRF52840 (see
Cargo.tomlfor dependencies)
Build & flash:
cd embassy-experiment
# Set up your toolchain for thumbv7em-none-eabi (see Embassy docs)
cargo build --release
# Use your preferred flashing tool (e.g., probe-rs, nrfjprog)
probe-rs download target/thumbv7em-none-eabihf/release/embassy-experiment --chip nRF52840_xxAA- Minimal Rust project using
rp235x-halanddefmtlogging - Example for getting started with embedded Rust on the Pico W
Build:
cd pico-2w
cargo build --release --target thumbv8m.main-none-eabihf
# Flash with your preferred tool- Install toolchain and West, reference the official guide (recommended): https://docs.zephyrproject.org/latest/develop/getting_started/index.html
cd embedded-workspace
python -m venv .venv
source .venv/bin/activate
pip install west
west init
west update
west zephyr-export
west packages pip --install
cd zephyr
west sdk install -t arm-zephyr-eabiThis repo (ble-experiments) contains a workspace app. You will build each embedded app from its own project directory.
From your project directory (e.g., embedded-workspace):
# Example for Nordic nRF52840 DK; change -b to your board (e.g., nrf52dk_nrf52832)
west build -p always -b nrf52840dk/nrf52840
west flash --runner jlinkRTT logging (optional):
west debugserver
west rttNotes
- The app enables RTT and disables UART console (
prj.conf). If your board lacks J‑Link/RTT, switch console to UART inprj.conf. - The app uses DT alias
sw0as the button input; ensure your board defines it (most Zephyr reference boards do).
From the repo root:
cargo run -p subscriberWhat it does
- Selects the first BLE adapter
- Scans for service 0000183b‑0000‑1000‑8000‑00805f9b34fb
- Connects, discovers services, subscribes to the first characteristic in that service
- Collects 3 notifications (times out after 10 s)
Expected behavior
- Press the board’s user button (SW0) a few times; the peripheral accumulates a 1‑byte sum and notifies periodically when subscribed.
- The subscriber logs three 1‑byte values and exits.
- Flash the Zephyr notifier to your board and power it on.
- Start RTT (optional) to see logs from the board.
- Run
cargo run -p subscriberon your desktop. - You should see a connection and three notifications within 10 seconds.
- Advertising name:
CONFIG_BT_DEVICE_NAMEinnotifier/prj.conf(default: "Notifier 1") - Advertising flags: General Discoverable, no BR/EDR
- Peripheral role, GATT dynamic DB, extended advertising enabled
- Notify period: ~250 ms (see
my_thread_entry_pointinnotifier/src/main.c) - Button: DT alias
sw0(notifier/src/external_readings.c) - Storage: simple heap‑backed list with a cap of 25 readings (
storage.c/.h)
- Subscriber can’t find adapters
- Ensure Bluetooth is enabled; on macOS grant Bluetooth permission to your terminal/IDE; on Linux ensure BlueZ is running.
- No notifications
- Ensure the client has subscribed; verify the service/characteristic UUIDs match; press SW0 to generate readings.
- Zephyr - no console output from the board
- Use RTT (requires J‑Link) or switch to UART console by updating
prj.conf.
- Use RTT (requires J‑Link) or switch to UART console by updating
MIT
This README was written and updated with the help of AI.