20  Bluetooth Implementations and Labs

In 60 Seconds

BLE implementation requires mastering three layers: scanning and advertising (device discovery), GATT services (data exchange via services and characteristics), and power optimization (connection intervals and scan duty cycling). Common pitfalls include not waiting for MTU negotiation, using continuous scanning on battery gateways, and treating RSSI as exact distance.

Key Concepts
  • BLE HAL (Hardware Abstraction Layer): Platform-specific low-level driver interfacing the BLE controller chip with the host OS or RTOS scheduler
  • GATT Server: Device hosting BLE services and characteristics that clients can discover, read, write, and subscribe to; typically the sensor/peripheral
  • GATT Client: Device initiating service discovery and reading/writing characteristics on a GATT server; typically the gateway or smartphone
  • BLE Bonding Database: Non-volatile storage (NVS on ESP32, bond store on nRF) containing LTK, IRK, CSRK, and CCCD state for each bonded peer
  • Connection Event: Scheduled time slot when master and slave exchange packets; the fundamental unit of BLE connection-state communication
  • Channel Selection Algorithm #2 (CSA#2): BLE 5.0 algorithm for selecting data channels using a pseudo-random hash function, providing better channel distribution than the BT4.x LE CSA#1
  • LE Power Control: BLE 5.4 feature allowing real-time TX power adjustment based on RSSI feedback, optimizing power consumption for varying link conditions
  • Bluetooth Qualification: Mandatory certification process by the Bluetooth SIG for any commercial product using Bluetooth; requires testing at a BQTF (Bluetooth Qualification Test Facility)
Minimum Viable Understanding

Master three BLE implementation layers: (1) scanning and advertising for device discovery, (2) GATT services for structured data exchange via services and characteristics, and (3) power optimization through connection intervals and scan duty cycling. Avoid these costly mistakes: always wait for MTU negotiation completion before sending large payloads, use windowed scanning (not continuous) on battery-powered gateways, and never treat RSSI as an exact distance – use zone-based proximity instead.

20.1 Learning Objectives

By the end of this section, you will be able to:

  • Implement BLE Applications: Build Python and embedded C applications for BLE scanning and connectivity
  • Configure GATT Services: Create custom services and characteristics for IoT sensor data
  • Demonstrate BLE Event Handling: Program connection, disconnection, and notification callbacks
  • Diagnose BLE Communication Issues: Use packet sniffers and diagnostic tools for troubleshooting
  • Calculate and Apply Power Optimization: Select connection intervals and advertising strategies for target battery life
  • Construct End-to-End Solutions: Design and build complete BLE sensor-to-cloud data pipelines
  • Evaluate Scan Duty Cycle Trade-offs: Analyze detection probability versus power consumption for given deployment requirements
  • Distinguish MTU Negotiation Phases: Justify why payloads must not be sent before the exchange completion callback

What is this section? Practical implementation exercises for Bluetooth Low Energy (BLE) development, organized into focused chapters.

When to use:

  • After understanding BLE fundamentals and GATT profiles
  • When ready to write actual BLE code
  • Before building your own BLE IoT project

Prerequisites:

  • Basic programming knowledge (C/Python)
  • Understanding of BLE concepts from fundamentals chapter
  • Access to BLE-capable hardware or simulator

Recommended Path:

  1. Review Bluetooth Fundamentals
  2. Work through the chapters below in order
  3. Test understanding with Bluetooth Review

“Theory is great, but now it is time to write actual code!” said Max the Microcontroller, opening his development environment. “BLE implementation has three layers you need to master: scanning and advertising for discovery, GATT services for data exchange, and power optimization for long battery life.”

Sammy the Sensor asked, “Where do I start?” Max recommended, “Begin with code examples – simple BLE servers and clients that you can run in a simulator. Then move to Python dashboards that connect to your BLE devices. Finally, tackle the advanced labs like indoor positioning and mesh networking.”

“Watch out for the common traps,” warned Lila the LED. “The biggest one is forgetting about MTU negotiation. The default BLE packet size is only 20 bytes, but after MTU negotiation, you can send up to 247 bytes per packet. If you try to send 100 bytes without negotiating first, your data gets silently truncated!”

Bella the Battery added her concerns. “And please do not use continuous scanning on my battery-powered gateways! Scanning draws almost as much power as transmitting. Use windowed scanning – scan for 100 milliseconds, sleep for 900 milliseconds. That cuts my power consumption by 90 percent while still catching most advertisements.”

20.2 Chapter Overview

This implementation guide is organized into three focused chapters:

20.2.1 BLE Code Examples and Simulators

Estimated time: 45 minutes

Get started with BLE development through working code examples:

  • Python BLE scanner using bleak library
  • Arduino ESP32 GATT server implementation
  • Interactive Wokwi simulators for hands-on practice
  • GATT structure (services, characteristics, descriptors)
  • BLE development stack overview

20.2.2 BLE Python Implementations

Estimated time: 60 minutes

Production-ready Python code for common BLE tasks:

  • Device filtering by RSSI and name patterns
  • GATT service exploration and characteristic reading
  • iBeacon and Eddystone beacon parsing
  • Zone-based proximity detection with RSSI smoothing
  • Power optimization decision framework

20.2.3 BLE Hands-On Labs

Estimated time: 2-3 hours

Complete project implementations:

  • Lab 1: ESP32 Heart Rate Monitor (standard GATT service)
  • Lab 2: Python Environmental Dashboard (real-time monitoring)
  • Lab 3: Indoor Positioning System (beacon trilateration)
  • Lab 4: Mesh Network Simulation (message flooding)
  • Worked examples: MTU optimization and power budget analysis

20.3 Common BLE Implementation Pitfalls

Pitfall: Sending Data Immediately After MTU Exchange Without Waiting for Completion

The Mistake: Requesting MTU exchange and then immediately sending large payloads using the requested (but not yet negotiated) MTU size, resulting in data truncation, protocol errors, or silent data loss.

Why It Happens: MTU exchange is an asynchronous operation. The request returns immediately, but the actual negotiated MTU is only valid after the exchange completes (indicated by a callback or event). Developers often assume the requested MTU is granted and start using it before confirmation.

The Fix: Treat MTU exchange as a state change. Start with the 23-byte default, request the larger MTU, and only send large values after the completion callback gives the effective negotiated value.

Stage Unsafe assumption Safer implementation pattern
Connection opens “I requested 247 bytes, so I can send 244 bytes now.” Reset to the 23-byte default and request an exchange.
Waiting period “A short delay is enough.” Do not use a timer; wait for the MTU exchange callback/event.
Completion callback “The requested MTU was accepted exactly.” Use the negotiated value, then subtract the 3-byte ATT header.
void on_mtu_exchanged(uint16_t conn_handle, uint16_t negotiated_mtu) {
    uint16_t max_payload = negotiated_mtu - 3;  // ATT header
    start_transfer_with_mtu(conn_handle, max_payload);
}

Note: The negotiated MTU is the minimum of what both sides support. A 247-byte request may result in 185 bytes if the central only supports that.

Pitfall: Using Continuous Scanning Without Duty Cycling on Battery-Powered Gateways

The Mistake: Running BLE scanning with 100% duty cycle (scan window = scan interval) on a battery-powered gateway or hub device, expecting to catch all advertisements while draining the battery in hours instead of days.

Why It Happens: Developers want to ensure no advertisements are missed, so they maximize scan window. But BLE scanning consumes 5-15mA continuously - comparable to active Wi-Fi. For mains-powered gateways this is fine, but battery-powered devices suffer severely.

The Fix: Calculate the trade-off between scan duty cycle and advertisement detection probability. The right answer depends on how fast you must detect a beacon.

Scanner strategy Example parameters Typical result
Continuous scan Interval 100 ms, window 100 ms Highest detection rate, about 12 mA continuous current, roughly 17 hours from a 200 mAh cell
Balanced duty cycle Interval 100 ms, window 30 ms Often catches frequent advertisements while cutting average current to about 4 mA
Power-optimized scan Interval 1000 ms, window 100 ms Much longer battery life, but slower discovery and weaker short-latency guarantees

Consider your beacon advertising interval when tuning scan parameters - you don’t need 100% duty cycle if beacons advertise frequently.

Calculating scan duty cycle vs advertisement detection probability:

A BLE gateway scans for beacons that advertise every 1000 ms. What scan duty cycle is needed to catch >95% of advertisements?

Beacon advertising:

  • Advertising interval: 1000 ms (1 second)
  • Advertisement duration: ~2 ms (includes 3 advertising channels)

Scanner with 10% duty cycle:

  • Scan interval: 1000 ms
  • Scan window: 100 ms
  • Probability of catching advertisement: $ P_{} = = = 0.102 = 10.2% $

That single-interval calculation is incomplete because the gateway gets repeated chances to catch future advertisements.

For a beacon advertising every 1000 ms with 2 ms advertisement duration, a scanner with scan window of 100 ms will catch it if the advertisement falls within any of the scan windows.

Since beacon advertisements happen at random offsets within the 1000 ms interval (due to ± 10ms randomization), the probability is: $ P_{} = = = 10% $

But we scan every second, so over 10 scan intervals (10 seconds): $ P_{} = 1 - (1 - 0.10)^{10} = 1 - 0.35 = 65% $

For >95% detection within 3 seconds, we need:

Let scan window be \(w\), with scan interval = 1000 ms. For 3 scans to have >95% cumulative detection: $ 1 - (1 - )^3 $

Solving: $ (1 - )^3 - $

Therefore \(w \geq 632\) ms. This means 63% duty cycle is needed for 95% detection within 3 seconds.

Power comparison (12 mA scan current, 2 mA idle):

100% duty cycle: 12 mA continuous 63% duty cycle: \((12 \times 0.63) + (2 \times 0.37) = 7.56 + 0.74 = 8.3\) mA 10% duty cycle: \((12 \times 0.10) + (2 \times 0.90) = 1.2 + 1.8 = 3.0\) mA

The 10% duty cycle reduces power by 64% \((1 - 3.0/8.3)\) compared to 63% duty cycle, but detection latency increases from 3 seconds to ~10 seconds.

Adjust scan parameters and beacon advertising interval to calculate detection probability and power consumption.

The Misconception: Many developers believe RSSI (Received Signal Strength Indicator) values can be directly converted to precise distances using simple formulas, and use raw RSSI readings for positioning without filtering.

Why This Fails (With Data):

1. RSSI Variance at Fixed Distance:

  • At 2 meters: RSSI can vary +/-8 dBm (range: -58 to -74 dBm)
  • Translation: Same physical position = 1.4m to 5.0m estimated distance
  • Error rate: Up to 150% distance error without filtering

2. Environmental Interference:

  • Human body: -5 to -15 dBm attenuation (doubles estimated distance)
  • Wall penetration: -10 to -30 dBm loss depending on material
  • Multipath fading: +/-6 dBm variance from reflections

The Correct Approach:

For Positioning:

  • Use zone-based proximity: Immediate (<0.5m), Near (0.5-3m), Far (>3m)
  • Require 3+ beacon measurements: Trilateration needs redundancy
  • Calibrate per environment: Measure path loss exponent (n) on-site
  • Apply time averaging: 5-10 samples over 2-5 seconds

Zone thresholds: Use >-60 dBm (immediate), -60 to -75 dBm (near), <-75 dBm (far)

20.3.1 Knowledge Check: BLE Scan Duty Cycling

20.3.2 Knowledge Check: MTU Exchange Timing

Question: What connection interval and peripheral latency should you use for your BLE device?

The Trade-off: Connection interval determines how often the central and peripheral communicate. Shorter intervals provide lower latency but consume more power. Peripheral latency allows devices to skip connection events to save power.

Use case Suggested connection behavior Why
Game controller or smart lock 7.5-100 ms interval, latency 0 Human-facing control needs fast response.
Keyboard, mouse, or active fitness display 15-50 ms interval, latency 0 Interaction feels immediate, but radio wakes often.
Temperature or slow environmental sensor 500-1000 ms interval, latency 4-10 Readings change slowly, so battery life matters more than sub-second response.
Asset tracking beacon 1000-4000 ms interval, latency 10-20 Position updates every few seconds are usually enough.
Industrial vibration sensor 50-100 ms interval, latency 0 Frequent samples need reliable low-latency transfer.

Selection Rules:

  1. Start with application latency requirement:
    • Real-time control (<50ms): Use 7.5-30ms interval
    • Interactive feedback (50-200ms): Use 30-100ms interval
    • Periodic monitoring (>200ms): Use 100-1000ms+ interval
  2. Apply peripheral latency for power optimization:
    • Formula: latency = (desired_update_interval / connection_interval) - 1
    • Example: Want 1-second updates with 100ms interval → latency = (1000/100) - 1 = 9
    • Constraint: iOS limits latency × interval ≤ 2 seconds
  3. Calculate supervision timeout:
    • Formula: timeout > (1 + latency) × interval × 2
    • Example: CI=100ms, latency=9 → timeout > (1+9) × 100ms × 2 = 2000ms
    • Use 4000ms for safety margin
  4. Verify iOS compatibility:
    • Interval: 15ms - 2000ms (Apple requires multiples of 15ms)
    • Latency: Max 30
    • Timeout: 2000ms - 6000ms
    • If outside range, iOS will silently modify parameters

Example Decision Process:

Scenario: Smart thermostat that displays temperature and allows user to adjust settings.

Decision Value for the thermostat Reason
Base interval 100 ms Keeps button response below 200 ms.
Peripheral latency 49 Wakes for routine temperature data every 50th event, or every 5 seconds.
Supervision timeout Above 10,000 ms Must exceed (1 + latency) x interval x 2; add margin for reliability.
Result Responsive controls with about 2% routine radio duty cycle The device stays sleepy until periodic data or a user command requires attention.

Key Insight: Don’t use a single connection interval for all use cases. Match the interval to your latency requirement, then use peripheral latency to save power during idle periods. Always test on iOS devices to catch parameter override issues.

20.3.3 Knowledge Check: BLE Connection Interval Selection

Worked Example: RSSI Calibration for Indoor Positioning System

Scenario: A museum deploys BLE beacons for visitor wayfinding. Initial deployment shows 5+ meter position errors. The team needs to calibrate RSSI-to-distance conversion for their specific environment.

Given:

  • Beacon hardware: Estimote Location Beacons, TX power = +4 dBm
  • Environment: Open gallery space with marble floors and 5-meter ceilings
  • Initial path loss exponent assumed: n = 2.0 (free space)
  • Reference RSSI at 1 meter (from datasheet): -59 dBm
  • Measured RSSI samples at known distances (10 samples each):
    • 1 meter: -61 dBm average, std dev = 2.1 dBm
    • 2 meters: -68 dBm average, std dev = 3.4 dBm
    • 4 meters: -76 dBm average, std dev = 4.2 dBm
    • 8 meters: -84 dBm average, std dev = 5.8 dBm

Steps:

  1. Calculate measured path loss at each distance:
    • PL(1m) = TxPower - RSSI = 4 - (-61) = 65 dB (reference)
    • PL(2m) = 4 - (-68) = 72 dB, expected free space: 65 + 20log(2) = 71 dB
    • PL(4m) = 4 - (-76) = 80 dB, expected free space: 65 + 20log(4) = 77 dB
    • PL(8m) = 4 - (-84) = 88 dB, expected free space: 65 + 20log(8) = 83 dB
  2. Fit path loss exponent using regression:
    • Path loss model: PL(d) = PL(d0) + 10 x n x log10(d/d0)
    • Using d0 = 1m, PL(d0) = 65 dB
    • Linear regression on log10(distance) vs path loss:
    • Slope = 10n = 28.3, therefore n = 2.83
  3. Update distance formula with calibrated values:
    • Old formula: d = 10^(((-59) - RSSI) / 20) (assumed n=2.0)
    • Calibrated formula: d = 10^(((-61) - RSSI) / 28.3) (n=2.83)
  4. Validate calibration with test points:
    • At RSSI = -72 dBm:
    • Old estimate: 10^((-59-(-72))/20) = 4.5 meters (error: +1.5m)
    • Calibrated: 10^((-61-(-72))/28.3) = 2.8 meters (actual: 3.0m, error: -0.2m)

Result: After calibration, positioning error reduced from 5+ meters to 1.8 meters average. The museum environment has path loss exponent n=2.83 (vs. 2.0 assumed), likely due to marble floor reflections increasing signal absorption.

Key Insight: Never use datasheet RSSI values for production positioning. Every environment has unique path loss characteristics. A one-time 15-minute calibration walk (measuring RSSI at 4-6 known distances) can improve accuracy by 60-70%.

Worked Example: BLE Beacon Density Optimization for Zone Detection

Scenario: A retail store wants to trigger personalized offers when shoppers enter specific departments. The goal is 85% zone detection accuracy (shopper in correct 10m x 10m zone) while minimizing beacon count and cost.

Given:

  • Store floor area: 2,000 square meters (50m x 40m)
  • Zone size: 10m x 10m (20 zones total)
  • Target accuracy: 85% correct zone identification
  • Beacon cost: $25 per beacon (including installation)
  • BLE range: ~30 meters (but RSSI unreliable beyond 10m)

Steps:

  1. Calculate baseline beacon density:
    • For zone-level accuracy, need 3+ beacons visible from each point
    • Basic grid: 1 beacon per zone center = 20 beacons
    • Detection rate with single beacon per zone: ~65% (RSSI variance causes mis-classification)
  2. Model zone boundary ambiguity:
    • At zone boundary (5m from two beacons), RSSI difference is minimal
    • RSSI at 5m: approximately -70 dBm (+/-4 dBm variance)
    • Probability of correct classification at boundary: 50% (random)
    • 30% of floor area is within 2m of zone boundary
  3. Add boundary beacons:
    • Place additional beacons at zone corners (shared by 4 zones)
    • Grid intersections: 6 x 5 = 30 beacons
    • Each point now sees 4 beacons minimum
    • Zone classification uses weighted voting from all visible beacons
  4. Calculate detection rate with boundary beacons:
    • Interior points (70% of area): 95% correct (strong RSSI difference)
    • Boundary points (30% of area): 70% correct (4-beacon voting)
    • Overall: 0.70 x 0.95 + 0.30 x 0.70 = 66.5% + 21% = 87.5%
  5. Optimize cost vs accuracy:
    • Option A: 20 beacons (center only) = $500, 65% accuracy
    • Option B: 30 beacons (intersections) = $750, 87.5% accuracy
    • Option C: 50 beacons (center + intersections) = $1,250, 92% accuracy
    • Recommendation: Option B meets 85% target at lowest cost

Result: Deploy 30 BLE beacons at zone corner intersections, achieving 87.5% zone detection accuracy for $750 total cost ($37.50 per zone).

Key Insight: For zone-based applications, beacon placement at zone boundaries (intersections) is more effective than zone centers. A beacon at the intersection of 4 zones contributes to classification accuracy for all 4 zones, while a center beacon only helps its own zone.

20.5 Summary

This section provides comprehensive BLE implementation guidance through three focused chapters:

  • Code Examples: Working Python and ESP32 code with interactive Wokwi simulators
  • Python Implementations: Production-ready scanner, GATT explorer, beacon manager, and proximity detector
  • Hands-On Labs: Complete projects for heart rate monitoring, dashboards, positioning, and mesh networks

Key implementation principles to carry forward: always await the MTU exchange completion callback before sending large payloads; apply scan duty cycling on battery-powered gateways; calibrate RSSI-to-distance conversion in the target environment; and match connection intervals to the latency requirements of each application.

20.6 What’s Next

Chapter Description Why Read It
BLE Code Examples and Simulators Python bleak scanner and ESP32 GATT server with Wokwi simulations Start here — run BLE code in a browser simulator before touching hardware
BLE Python Implementations Production-ready beacon parser, GATT explorer, and proximity detector Build real gateway software with iBeacon/Eddystone parsing and RSSI filtering
BLE Hands-On Labs Four complete projects: heart rate monitor, dashboard, IPS, mesh network End-to-end lab practice covering all major BLE application patterns
Bluetooth Fundamentals and Architecture BLE protocol stack, GATT hierarchy, advertising channels Review theory if implementation concepts feel unclear
Bluetooth Security Pairing modes, LE Secure Connections, key management Secure your implementations before deploying to production
Bluetooth Comprehensive Review MCQs and worked examples covering the full Bluetooth module Validate all implementation knowledge before moving to the next module