Skip to content

필사 모드: Seeed Studio XIAO nRF52840 Complete Guide — BLE IoT Projects in Practice

English
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

> This is the compact BLE edge-device track in the series. The point of XIAO nRF52840 is that it lets you prototype BLE, low-power behavior, and TinyML on a very small board with minimal setup. Start here if your focus is sensor nodes and wearables. If you want a larger system that includes PID control, sensor fusion, and autonomy, continue with [Complete Guide to Building a Drone & Control System with Arduino + Raspberry Pi](/blog/ai/2026-03-03-arduino-drone-control-system.en).

Introduction

**XIAO nRF52840** — an ultra-compact board measuring 21mm x 17.5mm with BLE 5.0, 6-axis IMU, microphone, and 256KB RAM. It is ideal for wearables, IoT sensors, and TinyML devices.

Spec Comparison

| Item | XIAO nRF52840 | XIAO nRF52840 Sense | XIAO ESP32C3 |

| --------- | -------------------- | -------------------- | --------------- |

| Processor | ARM Cortex-M4F 64MHz | ARM Cortex-M4F 64MHz | RISC-V 160MHz |

| RAM | 256KB | 256KB | 400KB |

| Flash | 1MB + 2MB QSPI | 1MB + 2MB QSPI | 4MB |

| Wireless | BLE 5.0 | BLE 5.0 | Wi-Fi + BLE 5.0 |

| IMU | No | Yes (LSM6DS3TR-C) | No |

| Mic | No | Yes (PDM) | No |

| Battery | Built-in Li charger | Built-in Li charger | No |

| Size | 21x17.5mm | 21x17.5mm | 21x17.5mm |

| Price | ~\$5.99 | ~\$15.99 | ~\$4.99 |

Development Environment Setup

Arduino IDE

1. Add Board Manager URL:

https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json

2. Board Manager → Install "Seeed nRF52 mbed-enabled Boards"

3. Select Board: "Seeed XIAO BLE - nRF52840"

4. Warning: Enter bootloader mode: quickly double-tap the RST pin

→ Orange LED fading = bootloader mode

BLE (Bluetooth Low Energy) Programming

BLE Fundamentals

BLE Structure:

├── GAP (Generic Access Profile) — Connection management

│ ├── Peripheral (Server): Provides data (sensor)

│ └── Central (Client): Requests data (smartphone)

└── GATT (Generic Attribute Profile) — Data structure

├── Service: Functional group (e.g., Temperature Service)

│ ├── Characteristic: Data point (e.g., temperature value)

│ │ ├── Value: Actual data

│ │ ├── Properties: Read/Write/Notify

│ │ └── Descriptor: Metadata

│ └── Characteristic: ...

└── Service: ...

BLE Sensor Server (Peripheral)

#include <ArduinoBLE.h>

// Custom service + characteristic definitions

BLEService envService("181A"); // Environmental Sensing

BLEFloatCharacteristic tempChar("2A6E", BLERead | BLENotify);

BLEFloatCharacteristic humChar("2A6F", BLERead | BLENotify);

BLEByteCharacteristic ledChar("2A57", BLERead | BLEWrite);

void setup() {

Serial.begin(115200);

BLE.begin();

// Device configuration

BLE.setLocalName("XIAO-Sensor");

BLE.setAdvertisedService(envService);

// Add characteristics

envService.addCharacteristic(tempChar);

envService.addCharacteristic(humChar);

envService.addCharacteristic(ledChar);

BLE.addService(envService);

// Initial values

tempChar.writeValue(0.0f);

humChar.writeValue(0.0f);

ledChar.writeValue(0);

// LED control callback

ledChar.setEventHandler(BLEWritten, onLedWrite);

BLE.advertise();

Serial.println("BLE Sensor Ready!");

}

void onLedWrite(BLEDevice central, BLECharacteristic characteristic) {

byte value = ledChar.value();

digitalWrite(LED_BUILTIN, value ? LOW : HIGH);

Serial.print("LED: "); Serial.println(value ? "ON" : "OFF");

}

void loop() {

BLEDevice central = BLE.central();

if (central) {

Serial.print("Connected: "); Serial.println(central.address());

while (central.connected()) {

// Read sensor (example: analog)

float temp = analogRead(A0) * 0.1; // In practice, use DHT22 etc.

float hum = analogRead(A1) * 0.1;

tempChar.writeValue(temp);

humChar.writeValue(hum);

delay(1000);

}

Serial.println("Disconnected");

}

}

Python BLE Client (Central)

from bleak import BleakClient, BleakScanner

DEVICE_NAME = "XIAO-Sensor"

TEMP_UUID = "00002a6e-0000-1000-8000-00805f9b34fb"

HUM_UUID = "00002a6f-0000-1000-8000-00805f9b34fb"

LED_UUID = "00002a57-0000-1000-8000-00805f9b34fb"

async def main():

Scan

print("Scanning...")

device = await BleakScanner.find_device_by_name(DEVICE_NAME)

if not device:

print("Device not found!")

return

Connect

async with BleakClient(device) as client:

print(f"Connected: {device.address}")

Subscribe to notifications

def on_temp(sender, data):

temp = struct.unpack('<f', data)[0]

print(f" Temperature: {temp:.1f}°C")

await client.start_notify(TEMP_UUID, on_temp)

Turn on LED

await client.write_gatt_char(LED_UUID, bytes([1]))

await asyncio.sleep(30) # Monitor for 30 seconds

asyncio.run(main())

Low-Power Design

#include <nrf_power.h>

// Deep sleep mode (System OFF — 0.5uA!)

void enterDeepSleep(int wakeupPin) {

// Configure wakeup pin

nrf_gpio_cfg_sense_input(

digitalPinToInterrupt(wakeupPin),

NRF_GPIO_PIN_PULLUP,

NRF_GPIO_PIN_SENSE_LOW

);

// System OFF

NRF_POWER->SYSTEMOFF = 1;

// Halts here — reboots on wakeup

}

// Light sleep (System ON + WFE — 1.5uA)

void lightSleep(uint32_t ms) {

delay(ms); // WFE-based, maintains BLE connection

}

// Battery life calculation:

// 110mAh LiPo, average consumption 50uA (sleep with periodic BLE advertising)

// Life = 110mAh / 0.05mA = 2,200 hours = ~91 days!

Sensor Mesh Network

XIAO #1 (Living Room) XIAO #2 (Bedroom) XIAO #3 (Kitchen)

Temp/Humidity Light Level Gas Sensor

| | |

└──── BLE ─────────────┴──── BLE ─────────────┘

|

Raspberry Pi (Gateway)

|

MQTT → Home Assistant

|

Dashboard / Alerts

TinyML (XIAO Sense)

// Gesture recognition using the built-in IMU!

#include <LSM6DS3.h>

#include <gesture_model.h> // TensorFlow Lite model

LSM6DS3 imu(I2C_MODE, 0x6A);

tflite::MicroInterpreter* interpreter;

void loop() {

float ax, ay, az, gx, gy, gz;

imu.readAcceleration(ax, ay, az);

imu.readGyroscope(gx, gy, gz);

// Model input

input->data.f[0] = ax; input->data.f[1] = ay; input->data.f[2] = az;

input->data.f[3] = gx; input->data.f[4] = gy; input->data.f[5] = gz;

interpreter->Invoke();

// Gesture classification

int gesture = output->data.f[0] > 0.8 ? WAVE :

output->data.f[1] > 0.8 ? PUNCH : IDLE;

Serial.println(gestureName[gesture]);

}

Read Next in This Embedded Hands-On Series

- [Complete Guide to Building a Drone & Control System with Arduino + Raspberry Pi](/blog/ai/2026-03-03-arduino-drone-control-system.en)

Read this next if you want to step up from a single-board BLE project into a larger embedded control system with sensor fusion, PID tuning, and vision-assisted autonomy.

**Q1.** What is the difference between Peripheral and Central in BLE?

||Peripheral (server): The side that provides data and advertises (sensor). Central (client): The side that scans, connects, and requests data (smartphone)||

**Q2.** What is the relationship between Service, Characteristic, and Descriptor in GATT?

||Service: Functional group (Temperature Service). Characteristic: Actual data point (temperature value). Descriptor: Metadata (units, description). Hierarchical structure: Service > Characteristic > Descriptor||

**Q3.** What is the current draw in XIAO nRF52840's System OFF mode?

||0.5uA. Can run for approximately 91 days on a 110mAh battery. Reboots on wakeup (RAM contents are lost)||

**Q4.** What is the difference between BLE Notify and Read?

||Read: Value is sent only when Central requests it (polling). Notify: Peripheral automatically pushes when the value changes (event-driven). Notify is more efficient in terms of power and latency||

현재 단락 (1/151)

**XIAO nRF52840** — an ultra-compact board measuring 21mm x 17.5mm with BLE 5.0, 6-axis IMU, microph...

작성 글자: 0원문 글자: 6,370작성 단락: 0/151