Skip to content

sensboston/ble_server_demo

Repository files navigation

BLE Server Demo

An ESP32-C3 firmware project built with ESP-IDF. Combines a BLE GATT server, RGB LED control with animations, WiFi captive portal provisioning, NTP time sync, an OLED status display, and a browser-based monitoring/control interface — all running concurrently on a single chip.

20260228_001952

Hardware

Component Detail
SoC ESP32-C3 Mini (RISC-V, BLE 5.0, no Classic BT)
Flash 2 MB
LED WS2812 RGB — built into the board on GPIO 8 (no external wiring)
OLED SSD1306 128×32, I2C — SDA GPIO 5, SCL GPIO 6

Wiring

Wiring Diagram

The only external connection is the OLED display. The WS2812 RGB LED is built into the ESP32-C3 Mini board.

Signal ESP32-C3 pin OLED (SSD1306)
GND GND GND
3.3 V 3V3 VCC
I²C SDA GPIO 5 SDA
I²C SCL GPIO 6 SCL

Features

BLE GATT Server

Two characteristics under service UUID 0xFF00:

UUID Mode Description
0xFF01 R/W Persistent string value; cached in RAM, written to NVS on every BLE WRITE
0xFF03 R/W LED control command (see below); readable to query current state

LED feedback in status mode: green = connected, blue flash = read, red flash = write. Enable/disable BLE advertising at runtime from the web UI.

LED Control

Accepts commands via BLE (0xFF03) or the web UI:

Command Effect
RRGGBB Set static color (6-digit hex, e.g. FF0080); brightness-scaled and persisted to NVS
fade Smooth HSV hue sweep (~12 s cycle)
rainbow Fast hue cycle (~3 s)
fire Warm red/orange flicker
heartbeat Double-beat pulse (red), ~1.1 s period
breathe Triangle-wave brightness, cool blue, ~4 s cycle
morse Transmit the 0xFF01 value as Morse code (amber LED)
off Return to BLE status indication mode

The last set color is restored from NVS on reboot.

Morse Code

Writing morse to characteristic 0xFF03 (or pressing the Morse button in the web UI) begins transmitting the current 0xFF01 string as Morse code using the WS2812 LED. Cyrillic text is automatically transliterated to Latin before encoding.

All timing parameters are adjustable in the Settings tab and persisted to NVS:

Parameter Default Description
Dot 150 ms Dot element duration
Dash 500 ms Dash element duration
Sym gap 100 ms Gap between elements within a character
Char gap 500 ms Gap between characters
Word gap 900 ms Total silence between words

Web Monitor (http://<device-ip>/)

Tabbed interface, dark/light theme, mobile-friendly:

  • Demo tab — RGB color picker; animation buttons (Fade/Fire/Rainbow/Heartbeat/Breathe/Morse/Off); write BLE value
  • Log tab — live BLE event log with timestamps (real time after NTP sync, boot-relative before)
  • Settings tab — toggle BLE on/off, toggle logging, reset WiFi, configure Morse timing

WiFi Provisioning (Captive Portal)

When no WiFi credentials are stored, the device opens a SoftAP (ESP32_XXXXXX) and presents a captive portal:

  • DNS hijacking — all domains resolve to 192.168.4.1 (TTL=0, no caching)
  • TCP 443 fast-reject — RSTs HTTPS probes immediately, reducing Android detection delay from 10+ s to ~1–2 s
  • OS-specific probe handlers — iOS (/hotspot-detect.html), Android (/generate_204), Windows NCSI (/connecttest.txt)
  • WiFi scan with SSID dropdown; remembers last connected network across resets
  • Password field with show/hide toggle

OLED Status Display

128×32 SSD1306 driven over I2C with a custom driver (no external components):

  • 3 lines with gap spacing, rendered via cross-page bit-shifting across the 4 SSD1306 pages
  • Line 0 — BLE device name (static) / "WiFi Setup" during provisioning
  • Line 1 — BLE status: ADVERTISING / CONNECTED / DISABLED
  • Line 2 — WiFi: Connecting... → IP address; updated with last BLE op
  • Thread-safe: FreeRTOS mutex guards all I2C access from BLE callbacks and WiFi events

NTP Time Sync

  • Syncs on WiFi connect; timezone EST5EDT (configurable in config.h)
  • Log timestamps switch from boot-relative to real time automatically

Project Structure

main/
  config.h         — all tunable constants (UUIDs, GPIO, OLED, task stacks, log size)
  main.c           — app_main: NVS init, LED init, OLED init, launch BLE + WiFi tasks
  ble_server.c     — GATT server: data characteristic + LED control characteristic
  led_controller.c — WS2812 driver: static color, animations, Morse code, NVS persistence
  wifi_manager.c   — captive portal provisioning + normal STA connection
  ntp_sync.c       — SNTP client
  web_server.c     — HTTP monitor: tabbed UI, ring-buffer event log, LED control
  oled_display.c   — SSD1306 driver: I2C init, 5×7 font, cross-page line rendering
partitions.csv     — custom partition table (factory 1.875 MB, ~500 KB headroom)
sdkconfig.defaults — enables custom partition table

Build & Flash

Requires ESP-IDF v5.x.

# Build
idf.py build

# Flash (adjust port as needed)
idf.py -p /dev/ttyUSB0 flash

The easiest option on Windows is the ESP-IDF VS Code extension — use the Build / Flash buttons in the status bar. If you run idf.py from a MSYS/Git Bash shell on Windows, make sure MSYSTEM is unset first to avoid ESP-IDF environment conflicts.

Configuration

Edit main/config.h before building:

#define BLE_DEVICE_NAME      "ESP32-BLE"   // Advertised BLE name
#define BLE_SERVICE_UUID     0xFF00        // GATT service UUID
#define BLE_CHAR_UUID        0xFF01        // Main data characteristic UUID
#define BLE_LED_CHAR_UUID    0xFF03        // LED control characteristic UUID
#define LED_GPIO             8             // WS2812 data pin
#define LED_BRIGHTNESS       30            // Status mode brightness (0–255)
#define LED_DEMO_BRIGHTNESS  80            // Demo mode max brightness (0–255)

Usage

  1. First boot — connect to the ESP32_XXXXXX WiFi AP, then open http://192.168.4.1/ (or tap "Configure router" / "Sign in to WiFi" on mobile).
  2. Select your network, enter the password, tap Connect. The device reboots and connects automatically.
  3. Open the web monitor at the device's IP address.
  4. Use the Demo tab to set LED color or start an animation.
  5. Use any BLE client (nRF Connect, LightBlue, etc.) to read/write the GATT characteristics.
  6. To change WiFi networks: open Settings tab → Reset WiFi.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages