在这篇分享中,我使用 Beetle ESP32 C6迷你开发板的ESP32-C6核心自带的温度传感器,结合ESP32-C6的BLE,实现标准的温度环境传感器功能。
当然,如果接上一个SHT30的话,那就可以进行实际的环境温度测量了。
一、BLE环境传感器了解
BLE环境传感器是一种利用蓝牙低功耗(Bluetooth Low Energy, BLE)技术来传输数据的传感器,它能够监测和记录环境参数,并通过无线方式将数据发送到接收设备,如智能手机、平板电脑或专用的监控系统。BLE环境传感器因其低功耗、易于集成和使用方便等特点,在智能家居、工业监测、环境研究等领域得到了广泛的应用。
在BLE标准的GATT定义中,有如下的部分:
其中,定义了环境传感器服务的UUID是 0x181A。环境传感器中温度特性对应的的UUID是0x2A6E,表示以0.01°C为单位的整型温度值。
了解了上面的两个定义,后面在实际创建BLE服务的时候,就需要用到。
二、ESP32-C6核心自带的温度传感器
ESP32-C6 内置1个温度传感器,用于测量芯片内部的温度。该温度传感器模组包含一个 8 位 Sigma-Delta 模拟-数字转换器 (ADC) 和一个数字-模拟转换器 (DAC),可以补偿测量结果,减少温度测量的误差。该温度传感器主要用于测量芯片内部的温度变化。芯片内部温度通常高于环境温度,并且受到微控制器的时钟频率或 I/O 负载、外部散热环境等因素影响。
详细的信息,可以从乐鑫文档了解:https://docs.espressif.com/projects/esp-idf/zh_CN/v5.1.2/esp32c6/api-reference/peripherals/temp_sensor.html
要在Arduino中使用该温度传感器,需要先添加对应的驱动库:
#include "driver/temperature_sensor.h"
然后启用温度传感器:
// 定义温度数据读取变量
temperature_sensor_handle_t temp_sensor = NULL;
temperature_sensor_config_t temp_sensor_config = TEMPERATURE_SENSOR_CONFIG_DEFAULT(10, 50);
// 启用内置温度传感器
ESP_ERROR_CHECK(temperature_sensor_install(&temp_sensor_config, &temp_sensor));
ESP_ERROR_CHECK(temperature_sensor_enable(temp_sensor));
启用后,就可以实际用于测量的,对应的代码如下:
// 获取温度值
ESP_ERROR_CHECK(temperature_sensor_get_celsius(temp_sensor, &tsens_value));
实际的温度值,将会读取到 tsens_value 变量中,直接为十进制的摄氏度浮点温度值。
如果需要对外输出华氏温度值,可以用下面的转换函数:
// 转换摄氏度到华氏度的函数
float celsiusToFahrenheit(float celsius) {
return (celsius * 9.0 / 5.0) + 32.0;
}
三、建立BLE 温度环境传感器服务
参考之前分享的使用BLE UATT服务,建立BLE 温度环境传感器服务步骤类似:
首先定义对应的UUID:
#define SERVICE_UUID (BLEUUID((uint16_t)0x181A))
#define CHARACTERISTIC_UUID_Temperature_Measurement (BLEUUID((uint16_t)0x2A6E))
然后定义对应的Characteristic和Descriptor:
// 定义温度的Characteristic和Descriptor
BLECharacteristic temperatureCharacteristics(CHARACTERISTIC_UUID_Temperature_Measurement, BLECharacteristic::PROPERTY_NOTIFY);
BLEDescriptor temperatureDescriptor(BLEUUID((uint16_t)0x2902));
定义好了以后,就可以依次进行:
创建服务端并设置回调:
// Create the BLE Server
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
创建服务:
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
添加Characteristic,设置Descriptor:
// Create a BLE Characteristic
pService->addCharacteristic(&temperatureCharacteristics);
temperatureCharacteristics.addDescriptor(&temperatureDescriptor);
最后启动服务和广播:
// Start the service
pService->start();
// Start advertising
pServer->getAdvertising()->start();
在loop中,当有蓝牙客户端连接后,则发送温度信息:
uint16_t temperatureTemp = (uint16_t)(tsens_value * 100);
temperatureCharacteristics.setValue(temperatureTemp);
temperatureCharacteristics.notify();
最终,完整的代码如下:
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include "driver/temperature_sensor.h"
BLEServer *pServer = NULL;
BLECharacteristic *pTxCharacteristic;
bool deviceConnected = false;
// 定义UUID
#define SERVICE_UUID (BLEUUID((uint16_t)0x181A))
#define CHARACTERISTIC_UUID_Temperature_Measurement (BLEUUID((uint16_t)0x2A6E))
// 设置设备名称
#define BLE_SERVER_NAME "ESP32-C6 Temperature Sensor"
// 设置温度类型
#define UNIT_C // C - 摄氏度 F - 华氏度
// 定义温度的Characteristic和Descriptor
BLECharacteristic temperatureCharacteristics(CHARACTERISTIC_UUID_Temperature_Measurement, BLECharacteristic::PROPERTY_NOTIFY);
BLEDescriptor temperatureDescriptor(BLEUUID((uint16_t)0x2902));
// 蓝牙连接/断开处理。当有连接/断开事件发生时自动触发
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer *pServer) { //当蓝牙连接时会执行该函数
Serial.println("蓝牙已连接");
deviceConnected = true;
};
void onDisconnect(BLEServer *pServer) { //当蓝牙断开连接时会执行该函数
Serial.println("蓝牙已断开");
deviceConnected = false;
delay(500); // give the bluetooth stack the chance to get things ready
pServer->startAdvertising(); // restart advertising
}
};
// 定义温度数据读取变量
temperature_sensor_handle_t temp_sensor = NULL;
temperature_sensor_config_t temp_sensor_config = TEMPERATURE_SENSOR_CONFIG_DEFAULT(10, 50);
// 转换摄氏度到华氏度的函数
float celsiusToFahrenheit(float celsius) {
return (celsius * 9.0 / 5.0) + 32.0;
}
void setup() {
Serial.begin(115200);
BLEBegin(); //初始化蓝牙
// 启用内置温度传感器
ESP_ERROR_CHECK(temperature_sensor_install(&temp_sensor_config, &temp_sensor));
ESP_ERROR_CHECK(temperature_sensor_enable(temp_sensor));
}
void loop() {
/****************数据发送部分*************/
/****************************************/
if (deviceConnected) { //如果有蓝牙连接,就发送数据
float tsens_value;
// 获取温度值
ESP_ERROR_CHECK(temperature_sensor_get_celsius(temp_sensor, &tsens_value));
#ifdef UNIT_C
Serial.print("Temperature Celsius value ");
Serial.print(tsens_value, 2);
Serial.println(" ℃");
#else
// 转换为华氏温度值
tsens_value = celsiusToFahrenheit(tsens_value);
Serial.print("Temperature Fahrenheit value ");
Serial.print(tsens_value, 2);
Serial.println(" °F");
#endif
uint16_t temperatureTemp = (uint16_t)(tsens_value * 100);
temperatureCharacteristics.setValue(temperatureTemp);
temperatureCharacteristics.notify();
delay(1000);
}
/****************************************/
/****************************************/
}
void BLEBegin() {
// Create the BLE Device
BLEDevice::init(/*BLE名称*/ BLE_SERVER_NAME);
// Create the BLE Server
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pService->addCharacteristic(&temperatureCharacteristics);
temperatureCharacteristics.addDescriptor(&temperatureDescriptor);
// Start the service
pService->start();
// Start advertising
pServer->getAdvertising()->start();
Serial.print("BLE Address: ");
Serial.println(BLEDevice::getAddress().toString().c_str());
Serial.println("Waiting a client connection to notify...");
}
编译烧录到Beetle ESP32 C6迷你开发板后,看到串口输出:
此时,就可以用手机客户端工具连接了。
四、手机BLE工具连接:
在手机上,使用ERF Connect,就能找到ESP32-C6 BLE设备:
点进连接,然后就能查看温度信息了:
串口监控也会输出对应的信息:
五、总结
上面的分享,就实现了一个基础的BLE环境传感器功能。
如果感兴趣的话,还可以多多了解BLE服务的知识,把温湿度传感器、燃气传感器、环境光传感器、压力传感器等等都可以实现出来。