Mpraveenkumar61/ESP32-BLE-LED-Controller
GitHub: Mpraveenkumar61/ESP32-BLE-LED-Controller
一个基于 ESP32 和 ESP-IDF 的 BLE LED 控制器,通过自定义 GATT 服务实现手机与设备间的无线开关与状态查询。
Stars: 0 | Forks: 0
ESP32 BLE LED 控制器
使用 **nRF Connect** 应用通过蓝牙低功耗(BLE)控制板载 LED。通过自定义 GATT 服务发送文本命令,并实时接收确认响应。
## 概述
本项目运行在 **ESP32** 上,使用 ESP-IDF 框架和 Bluedroid BLE 栈。它暴露一个自定义 GATT 服务,包含两个特征值:
- 一个用于接收手机发来的命令(写)
- 一个用于发送响应回手机(通知)
ESP32 会广播自身为 `ESP32-praveen`,可随时与 iOS 上的 nRF Connect 等任意 BLE 扫描工具配对。
## 功能特性
- BLE GATT 服务器,支持自定义 RX(写)和 TX(通知)特征值
- 通过文本命令控制 LED 开关
- 支持闪烁、状态查询与运行时间上报
- 自动重启广播(断开连接后)
- 连接期间每 2 秒周期性广播运行时间
- 无需配对或绑定
## 硬件要求
| 组件 | 说明 |
|------|------|
| 开发板 | ESP32(任意带有板载 LED 的型号) |
| LED | GPIO 2 上的板载 LED |
| 电源 | USB 或 3.3V 供电 |
无需外部接线,默认使用 GPIO 2 的板载 LED。
## 软件要求
- [ESP-IDF v5.x](https://docs.espressif.com/projects/esp-idf/en/latest/)
- [nRF Connect for iOS](https://apps.apple.com/app/nrf-connect-for-mobile/id1054903597)(免费,来自 App Store)
- Python 3.8+(用于 idf.py 工具链)
## 项目结构
esp32-ble-led/
├── main/
│ └── main.c # 完整应用源码
├── CMakeLists.txt # 顶层 CMake 配置
├── main/CMakeLists.txt # 组件 CMake 配置
└── README.md
## BLE 架构
| 角色 | UUID | 权限 | 说明 |
|------|------|------|------|
| 服务 | `0x0001` | — | 自定义 GATT 服务 |
| RX 特征值 | `0x0002` | 写 / 写无响应 | 手机 → ESP32 命令 |
| TX 特征值 | `0x0003` | 通知 | ESP32 → 手机响应 |
| CCCD | `0x2902` | 读 / 写 | 启用通知 |
## 编译与烧录
```
# 设置 ESP-IDF 环境
. $HOME/esp/esp-idf/export.sh
# 克隆此仓库
git clone https://github.com/Mpraveenkumar61/ESP32-BLE-LED-Controller.git
cd ESP32-BLE-LED-Controller
# 构建
idf.py build
# 烧录(将 PORT 替换为您的串口)
idf.py -p PORT flash
# 监控串口输出
idf.py -p PORT monitor
```
烧录后预期的串口输出:
ESP32 BLE UART — iOS Compatible
Device: ESP32-praveen
App: nRF Connect (App Store, free)
I (xxx) BLE_LED: BLE advertising started
## nRF Connect 使用(iOS)
1. 从 App Store 安装 **nRF Connect**
2. 打开应用并切换到 **扫描器(Scanner)** 标签页
3. 找到 `ESP32-praveen` 并点击 **连接(Connect)**
4. 切换到 **服务(Services)** 标签页
5. 找到 UUID 为 `0x0001` 的服务
6. 点击 **TX 特征值(0x0003)**,然后点击 **铃铛/订阅图标** 以启用通知
7. 点击 **RX 特征值(0x0002)**,然后点击 **向上箭头(写入)图标**
8. 选择 **文本(UTF-8)**,输入如 `ON` 的命令并点击 **发送(Send)**
ESP32 的响应将实时显示在 TX 特征值下方。
## 命令参考
| 命令 | 操作 | 响应 |
|------|------|------|
| `ON` | 打开 LED | `ACK:ON` |
| `OFF` | 关闭 LED | `ACK:OFF` |
| `STATUS` | 查询 LED 状态 | `LED:ON` 或 `LED:OFF` |
| `HELLO` | ping 设备 | `Hi from ESP32-praveen!` |
| `BLINK` | 闪烁 LED 3 次 | `ACK:BLINK` |
| `UPTIME` | 获取运行时间(秒) | `UPTIME:42s` |
| *(其他任意内容)* | 未知命令 | `ERR:UNKNOWN` |
连接并启用通知后,设备会自动发送:
ESP32-praveen Connected!
Cmds: LED_ON LED_OFF STATUS HELLO BLINK UPTIME
## 配置
所有可配置参数位于 `main/main.c` 文件顶部:
```
#define DEVICE_NAME "ESP32-praveen" // BLE advertised name
#define LED_PIN GPIO_NUM_2 // GPIO for LED
```
修改 `DEVICE_NAME` 可重命名设备,或修改 `LED_PIN` 更换 GPIO。修改后需重新编译并烧录。
## 故障排查
**设备未在扫描器中显示**
- 在 iOS 设置中授予 nRF Connect 蓝牙与定位权限
- 按下 ESP32 复位键并重新扫描
**通知未收到**
- 必须在发送命令前点击 TX 特征值的 **订阅/铃铛图标**
- 同一时间仅允许一部手机连接
**LED 无响应**
- 确认开发板是否使用 GPIO 2 的 LED;部分开发板可能使用不同引脚
- 检查串口监视器中的 `CMD:` 日志,确认命令是否接收成功
**编译错误**
- 请确保使用 ESP-IDF v5.x 版本;v4.x 的 GATT API 不同
- 运行 `idf.py fullclean` 后重新编译
## 作者
**Praveen Kumar M**
GitHub:[@Mpraveenkumar61](https://github.com/Mpraveenkumar61)
## 许可证
MIT License — 可自由用于个人及商业项目。
标签:BLE, Bluedroid, ESP32, ESP-IDF, GATT, GPIO2, iOS, LED控制, nRF Connect, Uptime, 关键字优化, 写特征, 客户端加密, 广告, 手机应用, 文本命令, 无绑定, 板载LED, 物联网, 物联网开发, 特征值, 硬件控制, 移动端, 自定义服务, 蓝牙低功耗, 蓝牙开发, 通知, 配对, 重连