当前位置: 首页 > news >正文

【物联网】BLE Fundamentals 核心概念总结-广告-读写特征-LED控制-传感器通知-上下游通信过程

BLE 开发完整指南与应用

一、BLE 核心概念总结

1. 角色定义

  • Peripheral(外设):Arduino Nano 33 IoT,作为数据提供者
  • Central(中心设备):树莓派/手机,作为数据消费者

2. 通信模式

  • Advertising(广告):设备广播自身存在
  • Connection(连接):建立稳定通信链路
  • GATT 通信:通过服务/特征进行数据交换

3. 数据操作类型

  • Read:中心设备读取数据
  • Write:中心设备写入命令
  • Notify:外设主动推送数据

二、核心库函数详解

1. BLE 初始化

#include <ArduinoBLE.h>  // 引入BLE库if (!BLE.begin()) {      // 初始化BLE模块Serial.println("Failed to initialize BLE!");while (true);        // 初始化失败则停止
}

2. 设备配置

// 设置设备标识(重要:使用唯一名称)
BLE.setDeviceName("Arduino_Sensor_xx");    // 内部设备名
BLE.setLocalName("Arduino_Sensor_xx");     // 广播显示名
BLE.setConnectable(true);                   // 允许连接(默认为true)

3. 服务与特征创建

// 定义UUID(必须唯一)
#define SERVICE_UUID        "12345678-1234-1234-1234-123456789abc"
#define SENSOR_CHAR_UUID    "87654321-4321-4321-4321-cba987654321"
#define COMMAND_CHAR_UUID   "11111111-2222-3333-4444-555555555555"// 创建服务
BLEService sensorService(SERVICE_UUID);// 创建特征(不同权限组合)
BLEStringCharacteristic sensorCharacteristic(SENSOR_CHAR_UUID,BLERead | BLENotify,  // 可读+通知100                   // 最大数据长度
);BLEStringCharacteristic commandCharacteristic(COMMAND_CHAR_UUID, BLEWrite,            // 只写20                   // 命令通常较短
);

4. 服务组装与广播

// 添加特征到服务
sensorService.addCharacteristic(sensorCharacteristic);
sensorService.addCharacteristic(commandCharacteristic);// 添加服务到BLE栈
BLE.addService(sensorService);// 设置广告服务并开始广播
BLE.setAdvertisedService(sensorService);
BLE.advertise();

5. 事件处理循环

void loop() {BLE.poll();  // 必须定期调用,处理BLE事件// 检查特征写入if (commandCharacteristic.written()) {String command = commandCharacteristic.value();processCommand(command);  // 处理接收到的命令}// 定期发送传感器数据static unsigned long lastSend = 0;if (millis() - lastSend > 5000) {  // 每5秒发送一次sendSensorData();lastSend = millis();}
}

三、四个示例代码的详细注释与应用

1. BLE_advertise.ino - 基础广告示例

// 作用:仅广播设备存在,不接受连接
// 应用:测试设备可见性,调试广播设置#include <ArduinoBLE.h>void setup() {Serial.begin(9600);if (!BLE.begin()) {Serial.println("Failed to initialize BLE!");while (true);}BLE.setDeviceName("YourName");      // 设置设备名BLE.setLocalName("YourName");       // 设置广播名BLE.setConnectable(false);          // 禁止连接,纯广播模式BLE.advertise();                    // 开始广播Serial.println("BLE advertising started...");
}void loop() {BLE.poll();  // 维持BLE栈运行// 纯广播模式,无其他操作
}

2. BLE_read-write.ino - 读写特征示例

// 作用:提供可读写的文本特征
// 应用:调试基本的BLE通信,测试命令传输#include <ArduinoBLE.h>#define SERVICE_UUID        "19B10000-E8F2-537E-4F6C-D104768A1214"
#define CHARACTERISTIC_UUID "19B10001-E8F2-537E-4F6C-D104768A1214"BLEService customService(SERVICE_UUID);                
BLECharacteristic rwCharacteristic(CHARACTERISTIC_UUID,BLERead | BLEWrite,  // 读写权限20                   // 最大20字节
);void setup() {Serial.begin(9600);if (!BLE.begin()) {Serial.println("Failed to initialize BLE!");while (true);}BLE.setDeviceName("YourName");BLE.setLocalName("YourName");BLE.setAdvertisedService(customService);customService.addCharacteristic(rwCharacteristic);BLE.addService(customService);rwCharacteristic.writeValue("Hello World");  // 设置初始值BLE.advertise();Serial.println("BLE advertising with read/write characteristic started...");
}void loop() {BLE.poll();if (rwCharacteristic.written()) {String newValue = String((const char*)rwCharacteristic.value());Serial.print("Characteristic written: ");Serial.println(newValue);// 在这里可以添加命令处理逻辑}delay(100);
}

3. BLE_LED-ctrl.ino - LED控制示例

// 作用:通过BLE控制LED
// 应用:学习如何通过BLE控制执行器#include <ArduinoBLE.h>#define SERVICE_UUID    "19B20000-E8F2-537E-4F6C-D104768A1214"
#define LED_CHAR_UUID   "19B20001-E8F2-537E-4F6C-D104768A1214"BLEService ledService(SERVICE_UUID);
BLECharacteristic ledCharacteristic(LED_CHAR_UUID,BLEWrite | BLERead,  // 读写权限1                    // 1字节数据(0或1)
);void setup() {Serial.begin(9600);pinMode(LED_BUILTIN, OUTPUT);digitalWrite(LED_BUILTIN, LOW);  // 初始关闭LEDif (!BLE.begin()) {Serial.println("Failed to initialize BLE!");while (true);}BLE.setDeviceName("YourName");BLE.setLocalName("YourName");BLE.setAdvertisedService(ledService);ledService.addCharacteristic(ledCharacteristic);BLE.addService(ledService);uint8_t off = 0;ledCharacteristic.writeValue(off);  // 设置初始值为0BLE.advertise();Serial.println("BLE LED Control service started");
}void loop() {BLE.poll();if (ledCharacteristic.written()) {uint8_t value = ledCharacteristic.value()[0];  // 读取第一个字节if (value == 1) {digitalWrite(LED_BUILTIN, HIGH);Serial.println("LED ON");} else {digitalWrite(LED_BUILTIN, LOW);Serial.println("LED OFF");}}
}

4. BLE_sensor-notify.ino - 传感器通知示例

// 作用:实时推送传感器数据
// 应用:学习如何实现实时数据流#include <ArduinoBLE.h>
#include <Arduino_LSM6DS3.h>  // IMU传感器库BLEService imuService("19B10000-E8F2-537E-4F6C-D104768A1214");
BLECharacteristic imuDataCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify,  // 可读+通知权限32                    // 足够存储传感器数据
);void setup() {Serial.begin(9600);if (!IMU.begin()) {  // 初始化IMU传感器Serial.println("Failed to initialize IMU!");while (1);}if (!BLE.begin()) {Serial.println("Starting BLE failed!");while (1);}BLE.setLocalName("YourName");BLE.setAdvertisedService(imuService);imuService.addCharacteristic(imuDataCharacteristic);BLE.addService(imuService);imuDataCharacteristic.setValue("0.00,0.00,0.00");  // 初始值BLE.advertise();Serial.println("BLE advertising with sensor notify characteristic started...");
}void loop() {BLEDevice central = BLE.central();  // 检查中心设备连接if (central) {Serial.print("Connected to central: ");Serial.println(central.address());while (central.connected()) {  // 保持连接时持续发送数据float x, y, z;if (IMU.accelerationAvailable()) {IMU.readAcceleration(x, y, z);// 格式化传感器数据String imuString = String(x, 2) + "," + String(y, 2) + "," + String(z, 2);Serial.println("Sending: " + imuString);// 更新特征值(会自动通知订阅的客户端)imuDataCharacteristic.setValue(imuString.c_str());}delay(100); // 10Hz更新频率}Serial.print("Disconnected from central: ");Serial.println(central.address());}
}

四、具体应用方案

1. 上游通信(传感器数据 → BLE → MQTT)

// Arduino端 - 传感器数据特征
BLEStringCharacteristic dhtCharacteristic(DHT_CHAR_UUID,BLERead | BLENotify,  // 可读+通知100
);// 定期更新传感器数据
void updateDHTData() {float temp = dht.readTemperature();float humidity = dht.readHumidity();String jsonData = "{\"temp\":" + String(temp) + ",\"humidity\":" + String(humidity) + "}";dhtCharacteristic.writeValue(jsonData);  // 自动通知订阅者
}

2. 下游通信(MQTT → BLE → 执行器控制)

// Arduino端 - 命令特征
BLEStringCharacteristic commandCharacteristic(COMMAND_CHAR_UUID,BLEWrite,  // 只写权限20
);// 处理接收到的命令
void loop() {BLE.poll();if (commandCharacteristic.written()) {String command = commandCharacteristic.value();if (command == "LED_ON") {digitalWrite(LED_PIN, HIGH);Serial.println("LED turned ON via BLE");} else if (command == "LED_OFF") {digitalWrite(LED_PIN, LOW);Serial.println("LED turned OFF via BLE");}else if (command == "BUZZER_BEEP") {playTone(1000, 200);Serial.println("Buzzer activated via BLE");}}
}

3. 完整的代码结构

#include <ArduinoBLE.h>
#include <DHT.h>// UUID定义
#define SERVICE_UUID        "你的服务UUID"
#define DHT_CHAR_UUID       "你的传感器特征UUID"  
#define CMD_CHAR_UUID       "你的命令特征UUID"// 引脚定义
#define DHT_PIN 2
#define LED_PIN LED_BUILTIN
#define BUZZER_PIN 5DHT dht(DHT_PIN, DHT11);
BLEService sensorService(SERVICE_UUID);
BLEStringCharacteristic dhtCharacteristic(DHT_CHAR_UUID, BLERead | BLENotify, 100);
BLEStringCharacteristic cmdCharacteristic(CMD_CHAR_UUID, BLEWrite, 20);void setup() {// 初始化串口、传感器、引脚// 初始化BLE并配置服务特征// 开始广播
}void loop() {BLE.poll();// 处理命令if (cmdCharacteristic.written()) {processCommand(cmdCharacteristic.value());}// 定期发送传感器数据static unsigned long lastSend = 0;if (millis() - lastSend > 5000) {sendSensorData();lastSend = millis();}
}void processCommand(String command) {// 处理各种控制命令
}void sendSensorData() {// 读取并发送传感器数据
}

五、调试与测试建议

1. 使用 nRF Connect 应用测试

  • 扫描确认设备可见性
  • 连接后查看服务特征结构
  • 测试读写操作
  • 订阅通知观察实时数据

2. 串口调试输出

Serial.println("BLE connected!");  // 连接事件
Serial.print("Received: ");        // 数据接收
Serial.println(receivedData);
Serial.print("Sending: ");         // 数据发送  
Serial.println(sensorData);

3. 分阶段测试

  1. 先测试BLE基础通信
  2. 再测试传感器数据读取
  3. 然后测试执行器控制
  4. 最后集成完整功能

这个完整的指南应该能帮助你在成功实现BLE通信功能。

http://www.dtcms.com/a/358639.html

相关文章:

  • CSDN博客语法(不常用但有用)
  • 年化225%,回撤9%,夏普4.32,3积分可查看参数
  • 【光照】[光照模型]是什么?以UnityURP为例
  • Excel工作技巧
  • 如何解决虚拟机异常退出后提示“获取所有权”错误
  • 企业为什么需要部署数据防泄露系统?
  • ModuleNotFoundError: No module named ‘cairosvg‘
  • 基于Spring Boot小型超市管理系统的设计与实现(代码+数据库+LW)
  • OpenCV DNN 模块完全指南:从理论基础到实战应用 —— 图像分类与目标检测的深度学习实现(含 Python/C++ 代码与性能分析)
  • MongoDB 聚合管道(Aggregation)高级用法:数据统计与分析
  • 用【Coze】实现文案提取+创作
  • 解决低版本CUDA与PyTorch之间的兼容性问题
  • Android FrameWork - 开机启动 SystemServer 进程
  • Preprocessing Model in MPC 3 - 基于同态加密的协议 - Over Rings 环
  • Linux系统编程--进程控制
  • 飞帆fvi.cn拖放配置实现卡片布局
  • GJB 11664-2024《装备数字样机通用要求》概述
  • 数字签名 digital signature
  • 第三十一天:数列求和取模
  • 达梦数据库-报错-03-viosocket_peer_addr getpeername error: 107
  • USB4 vs USB3.0:一场接口技术的革命性飞跃
  • 软件IIC与硬件IIC的区别
  • Visual Studio内置环境变量有哪些
  • 毕业项目推荐:47-基于yolov8/yolov5/yolo11的焊缝质量检测识别系统(Python+卷积神经网络)
  • 2025年- H102-Lc210--3658.奇数和与偶数和的最大公约数(gcd最大公约数)--Java版
  • OpenCV 轮廓分析实战:从检测到形状匹配的完整指南
  • 图像结构化拆分与格式标准化方案
  • 复现 RoboDK 机械臂几何校准(Staubli TX2‑90L / TX200)
  • 基于轴重转移补偿和多轴协调的粘着控制方法研究
  • 基于STM32单片机的OneNet物联网云平台农业土壤湿度控制系统