基于ESP32-S2-Kaluga-1的物联网室内环境监测仪
[复制链接]
本帖最后由 dql2016 于 2022-10-30 22:53 编辑
一、作品简介
ps:本来计划使用的开发板是ESP32-S2-Kaluga-1,但是由于一些原因,换成了ESP32-S3-DevKitC-1,好在使用arduino软件进行开发,跨平台特性非常好。
设计名称:基于ESP32-S2-Kaluga-1的物联网室内环境监测仪
作品照片:
二、功能介绍
采用支持低功耗蓝牙5的esp32s3无线微控制器读取svm40传感器模块的VOC、温度和湿度数据,通过蓝牙通知的方式将数据发送到微信小程序。启动后,处于广播状态,等待客户端连接,连接成功后就开始将数据用通知方式发送给客户端。在微信小程序上可以看到采集数据,并能够对开发板进行控制。
三、系统框图
esp32s3为蓝牙server,微信小程序为蓝牙客户端,esp32s3通过i2c接口读取到传感器模块svm40的数据。首先开启蓝牙广播,等待客户端设备连接后,通过通知方式发送给蓝牙客户端。
四、各部分功能说明
esp32s3管脚图:使用了IO18、IO17作为i2c接口
svm40模块管脚图
arduino代码
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <SensirionI2CSvm40.h>
#include <Wire.h>
#define I2C_SDA 17
#define I2C_SCL 18
SensirionI2CSvm40 svm40;
BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint8_t value[8];
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
void setup() {
Serial.begin(115200);
Wire.begin(I2C_SDA, I2C_SCL,400000);
uint16_t error;
char errorMessage[256];
svm40.begin(Wire);
error = svm40.deviceReset();
if (error) {
Serial.print("Error trying to execute deviceReset(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
}
// Delay to let the serial monitor catch up
delay(2000);
uint8_t serialNumber[32];
uint8_t serialNumberSize = 32;
error = svm40.getSerialNumber(serialNumber, serialNumberSize);
if (error) {
Serial.print("Error trying to execute getSerialNumber(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
} else {
Serial.print("SerialNumber:");
Serial.println((char*)serialNumber);
}
uint8_t firmwareMajor;
uint8_t firmwareMinor;
bool firmwareDebug;
uint8_t hardwareMajor;
uint8_t hardwareMinor;
uint8_t protocolMajor;
uint8_t protocolMinor;
error = svm40.getVersion(firmwareMajor, firmwareMinor, firmwareDebug,
hardwareMajor, hardwareMinor, protocolMajor,
protocolMinor);
if (error) {
Serial.print("Error trying to execute getVersion(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
} else {
Serial.print("Firmware: ");
Serial.print(firmwareMajor);
Serial.print(".");
Serial.print(firmwareMinor);
Serial.print(" Debug: ");
Serial.println(firmwareDebug);
Serial.print("Hardware: ");
Serial.print(hardwareMajor);
Serial.print(".");
Serial.println(hardwareMinor);
Serial.print("Protocol: ");
Serial.print(protocolMajor);
Serial.print(".");
Serial.println(protocolMinor);
if (firmwareMajor < 2 || (firmwareMajor == 2 && firmwareMinor < 2)) {
Serial.println("Warning: Old firmware version which may return "
"constant values after a few hours of operation");
}
}
// Start Measurement
error = svm40.startContinuousMeasurement();
if (error) {
Serial.print("Error trying to execute startContinuousMeasurement(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
}
// Create the BLE Device
BLEDevice::init("ESP32");
// 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
pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID,BLECharacteristic::PROPERTY_WRITE |BLECharacteristic::PROPERTY_NOTIFY);
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
// Create a BLE Descriptor
pCharacteristic->addDescriptor(new BLE2902());
// Start the service
pService->start();
// Start advertising
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(false);
pAdvertising->setMinPreferred(0x0); // set value to 0x00 to not advertise this parameter
BLEDevice::startAdvertising();
Serial.println("Waiting a client connection to notify...");
}
void loop() {
uint16_t error;
char errorMessage[256];
// notify changed value
if (deviceConnected) {
int16_t vocIndex;
int16_t humidity;
int16_t temperature;
error = svm40.readMeasuredValuesAsIntegers(vocIndex, humidity, temperature);
if (error) {
Serial.print(
"Error trying to execute readMeasuredValuesAsIntegers(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
} else {
Serial.print("VocIndex:");
Serial.print(vocIndex / 10.0);
Serial.print("\t");
Serial.print("Humidity:");
Serial.print(humidity / 100.0);
Serial.print("\t");
Serial.print("Temperature:");
Serial.println(temperature / 200.0);
}
sprintf((char*)value, "%02x%02x%02x", (int)(temperature/200.0),(int)(humidity/100.0),(int)(vocIndex/10.0));
pCharacteristic->setValue((uint8_t*)value, 6);
pCharacteristic->notify();
delay(2000); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms
}
// disconnecting
if (!deviceConnected && oldDeviceConnected) {
delay(500); // give the bluetooth stack the chance to get things ready
pServer->startAdvertising(); // restart advertising
Serial.println("start advertising");
oldDeviceConnected = deviceConnected;
}
// connecting
if (deviceConnected && !oldDeviceConnected) {
// do stuff here on connecting
oldDeviceConnected = deviceConnected;
}
}
微信小程序蓝牙配网界面
设备界面
设备数据界面
微信小程序主要js程序
//加载事件通知库,用于不同页面发布和订阅事件
var event = require('../../utils/event.js')
var app=getApp()
Page({
data: {
charts: [{
id: 'wendu',
name: '温度',
data:'0',//温度值
unit:'℃'//温度单位
}, {
id: 'shidu',
name: '湿度',
data:'0',
unit:'%'
},
{
id: 'voc',
name: 'VOC指数',
data:'0',
unit:''
}],
checked: false,//风扇的状态,默认关闭
fanIcon:"/utils/img/fanOff.png",//显示风扇图标的状态,默认是关闭状态图标
},
//屏幕打开时执行的函数
onLoad: function () {
//接收别的页面传过来的数据
event.on('environmetDataChanged', this, function(data) {
//另外一个页面传过来的data是16进制字符串形式
console.log("接收到蓝牙设备发来的数据:"+data)
//温度 1byte
var a=parseInt(data[1]+data[3],16);
//湿度 1byte
var b=parseInt(data[5]+data[7],16);
//voc 1byte
var c=parseInt(data[9]+data[11],16);
//气压 4byte
//var c=parseInt(data[4]+data[5],16);
//var d=parseInt(data[6]+data[7],16);
//var e=c*256+d;
//空气质量 4byte
// var f=parseInt(data[8]+data[9],16);
//var g=parseInt(data[10]+data[11],16);
//var h=f*256+g;
//光照 4byte
//var i=parseInt(data[12]+data[13],16);
//var j=parseInt(data[14]+data[15],16);
//var k=i*256+j;
//声音 4byte
//var l=parseInt(data[16]+data[17],16);
//var m=parseInt(data[18]+data[19],16);
//var n=l*256+m;
//实时修改显示值
var up0 = "charts[" + 0 + "].data";
var up1 = "charts[" + 1 + "].data";
var up2 = "charts[" + 2 + "].data";
//var up3 = "charts[" + 3 + "].data";
//var up4 = "charts[" + 4 + "].data";
//var up5 = "charts[" + 5 + "].data";
this.setData({
[up0]:a,
[up1]:b,
[up2]:c,
// [up2]:e,
//[up3]:h,
// [up4]:k,
// [up5]:n,
});
})
},
onUnload: function() {
event.remove('environmetDataChanged', this);
event.remove('deviceConnectStatus', this);
},
//控制led的函数,小滑块点击后执行的函数
onChange({ detail }){
this.setData({
checked: detail,
});
if(detail == true){
//发送'fefe'给蓝牙设备 开
event.emit('EnvMonitorSendData2Device','fefe');
this.setData({
fanIcon: "/utils/img/fanOn.png",
});
}else{
//发送'0101'给蓝牙设备 关
event.emit('EnvMonitorSendData2Device','0101');
this.setData({
fanIcon: "/utils/img/fanOff.png",
});
}
},
})
五、作品源码
esp32s3代码
https://download.eeworld.com.cn/detail/dql2016/625315
微信小程序代码
https://download.eeworld.com.cn/detail/dql2016/625316
六、作品功能演示视频
https://training.eeworld.com.cn/course/67865
得捷物联网电子设计大赛2022-室内空气质量监测
七、项目总结(项目文字总结+帖子分享链接汇总)
使用arduino软件进行开发十分方便,自带例子十分丰富,只需要简单了解蓝牙相关知识就能根据例子开发自己的应用。
【基于ESP32-S2-Kaluga-1的物联网室内环境监测仪】读取svm40传感器模块数据
【基于ESP32-S2-Kaluga-1的物联网室内环境监测仪】蓝牙通知数据
【基于ESP32-S2-Kaluga-1的物联网室内环境监测仪】开发环境体验-Arduino
【基于ESP32-S2-Kaluga-1的物联网室内环境监测仪】开发环境体验-ESP-IDF
|