Skip to content

Latest commit

 

History

History

readme.md

BoatMonitor ESP32

Firmware for the Seeed Studio XIAO ESP32C6 microcontroller providing BLE-controlled monitoring and LED features.

Hardware

  • Board: Seeed Studio XIAO ESP32C6
  • Framework: ESP-IDF via PlatformIO

Pin Assignments

Pin GPIO Function
D3 GPIO21 WS2814 RGBW LED strip data (100 addressable pixels)
D9 GPIO20 BLE connected indicator LED (active low)
D9 GPIO15 Status LED (blinking)
A0 GPIO0 Analog input 0 (with voltage divider)
A1 GPIO1 Analog input 1 (with voltage divider)
- GPIO14 Antenna switch (using onboard antenna)

Note: GPIO10 (D10) is tied to the internal flash on ESP32-C6 and cannot be used as a general GPIO output.

XIAO ESP32C6 Pinout Reference

Pin Label -> GPIO Number -> ADC Channel (if applicable)

A0  = GPIO0  = ADC1_CH0
A1  = GPIO1  = ADC1_CH1
A2  = GPIO2  = ADC1_CH2
D0  = GPIO0  = ADC1_CH0
D1  = GPIO1  = ADC1_CH1
D2  = GPIO2  = ADC1_CH2
D3  = GPIO21 = (no ADC)
D4  = GPIO22 = (no ADC)
D5  = GPIO23 = (no ADC)
D6  = GPIO16 = (no ADC)
D7  = GPIO17 = (no ADC)
D8  = GPIO19 = (no ADC)
D9  = GPIO20 = (no ADC)
D10 = GPIO10 = UNUSABLE (flash SPI)

Voltage Divider

Analog inputs A0 and A1 have external voltage dividers:

  • Top resistor: 82k ohm
  • Bottom resistor: 20k ohm
  • Division ratio: 5.1
  • Max measurable voltage: ~16.8V (3.3V * 5.1)

BLE Interface

Device Information

  • Device Name: BoatMonitor
  • Service UUID: 0x00FF (16-bit)

Characteristics

1. LED On/Off (0xFF01)

Controls the status LED on/off state.

Property Value
UUID 0xFF01
Permissions Read, Write
Data Length 1 byte

Data Format:

  • 0x00 = LED off
  • 0x01 = LED on (any non-zero value turns on)

Example:

Write: [0x01]  // Turn LED on
Write: [0x00]  // Turn LED off
Read:  [0x01]  // LED is currently on

2. Blink Rate (0xFF02)

Controls the blink rate of the status LED.

Property Value
UUID 0xFF02
Permissions Read, Write
Data Length 1 byte

Data Format:

  • Value range: 0-100
  • Delay calculation: value * 10 milliseconds per half-cycle
  • 0 = LED stays solid (no blinking)
  • 50 = 500ms on, 500ms off (1 Hz)
  • 100 = 1000ms on, 1000ms off (0.5 Hz)

Example:

Write: [0x32]  // Set blink rate to 50 (500ms delay)
Write: [0x00]  // Solid on (no blink)
Read:  [0x32]  // Current rate is 50

3. Analog Inputs (0xFF03)

Reads voltage from both analog inputs A0 (GPIO0) and A1 (GPIO1).

Property Value
UUID 0xFF03
Permissions Read only
Data Length 4 bytes

Data Format (Big Endian):

Byte 0: A0 voltage high byte
Byte 1: A0 voltage low byte
Byte 2: A1 voltage high byte
Byte 3: A1 voltage low byte

Values are in millivolts with voltage divider applied.

Example:

Read: [0x2E, 0xE0, 0x17, 0x70]
       A0 = 0x2EE0 = 12000 mV (12.0V)
       A1 = 0x1770 = 6000 mV (6.0V)

Parsing (pseudocode):

a0_mv = (data[0] << 8) | data[1]
a1_mv = (data[2] << 8) | data[3]
a0_volts = a0_mv / 1000.0
a1_volts = a1_mv / 1000.0

4. LED Strip (0xFF04)

Controls the WS2814 RGBW LED strip (100 addressable pixels on D3/GPIO21).

Property Value
UUID 0xFF04
Permissions Read, Write
Data Length 5 bytes

Data Format:

Byte 0: On/Off (0x00=off, 0x01=on)
Byte 1: Red (0-255)
Byte 2: Green (0-255)
Byte 3: Blue (0-255)
Byte 4: White (0-255) - Warm white LED channel

All 100 pixels are set to the same color. The 4-byte legacy format (without white) is also supported.

Example:

Write: [0x01, 0xFF, 0x00, 0x00, 0x00]  // Turn on, full red
Write: [0x01, 0x00, 0xFF, 0x00, 0x00]  // Turn on, full green
Write: [0x01, 0x00, 0x00, 0xFF, 0x00]  // Turn on, full blue
Write: [0x01, 0x00, 0x00, 0x00, 0xFF]  // Turn on, warm white only
Write: [0x01, 0xFF, 0xFF, 0xFF, 0xFF]  // Turn on, full RGBW
Write: [0x01, 0xFF, 0x00, 0x00]        // Legacy 4-byte format (no white)
Write: [0x00, 0x00, 0x00, 0x00, 0x00]  // Turn off
Write: [0x00]                          // Turn off (1 byte shorthand)
Read:  [0x01, 0xFF, 0x00, 0x00, 0x00]  // Strip is on, color is red

BLE Connected Indicator

GPIO20 (D9) operates as an active-low indicator:

  • LOW (0V) when a BLE client is connected - LED ON
  • HIGH (3.3V) when disconnected - LED OFF

Connect an LED with anode to 3.3V and cathode through a resistor to D9 for visual connection status.

Building and Flashing

# Build
pio run

# Upload
pio run -t upload

# Monitor serial output
pio device monitor

Quick Reference Table

Characteristic UUID R/W Bytes Description
LED On/Off 0xFF01 R/W 1 Status LED on/off
Blink Rate 0xFF02 R/W 1 Blink delay (0-100)
Analog Inputs 0xFF03 R 4 A0 and A1 in mV
LED Strip 0xFF04 R/W 5 Strip on/off + RGBW

Example BLE Client Code (Python)

import asyncio
from bleak import BleakClient

DEVICE_NAME = "BoatMonitor"
SERVICE_UUID = "000000ff-0000-1000-8000-00805f9b34fb"
CHAR_LED_UUID = "0000ff01-0000-1000-8000-00805f9b34fb"
CHAR_BLINK_UUID = "0000ff02-0000-1000-8000-00805f9b34fb"
CHAR_ANALOG_UUID = "0000ff03-0000-1000-8000-00805f9b34fb"
CHAR_STRIP_UUID = "0000ff04-0000-1000-8000-00805f9b34fb"

async def main():
    async with BleakClient("XX:XX:XX:XX:XX:XX") as client:
        # Turn on status LED
        await client.write_gatt_char(CHAR_LED_UUID, bytes([0x01]))

        # Set blink rate to 500ms
        await client.write_gatt_char(CHAR_BLINK_UUID, bytes([50]))

        # Read analog inputs
        data = await client.read_gatt_char(CHAR_ANALOG_UUID)
        a0_mv = (data[0] << 8) | data[1]
        a1_mv = (data[2] << 8) | data[3]
        print(f"A0: {a0_mv}mV, A1: {a1_mv}mV")

        # Set LED strip to blue (RGBW format: on, R, G, B, W)
        await client.write_gatt_char(CHAR_STRIP_UUID, bytes([0x01, 0x00, 0x00, 0xFF, 0x00]))

asyncio.run(main())