IoT indoor environment monitor based on ESP32-S2-Kaluga-1
[Copy link]
This post was last edited by dql2016 on 2022-10-30 22:53
1. Introduction
ps: The development board originally planned to be used was ESP32-S2-Kaluga-1, but due to some reasons, it was changed to ESP32-S3-DevKitC-1. Fortunately, Arduino software was used for development, and the cross-platform feature is very good.
Design name: IoT indoor environment monitor based on ESP32-S2-Kaluga-1
Works photos:
2. Function Introduction
The ESP32S3 wireless microcontroller supporting low-power Bluetooth 5 is used to read the VOC, temperature and humidity data of the SVM40 sensor module, and send the data to the WeChat applet via Bluetooth notification. After startup, it is in the broadcast state, waiting for the client to connect. After the connection is successful, it starts to send data to the client via notification. The collected data can be seen on the WeChat applet, and the development board can be controlled.
III. System Block Diagram
esp32s3 is the Bluetooth server, WeChat applet is the Bluetooth client, and esp32s3 reads the data of the sensor module svm40 through the i2c interface. First, turn on the Bluetooth broadcast, wait for the client device to connect, and then send it to the Bluetooth client through notification
.
ESP32S3 pin diagram: IO18 and IO17 are used as i2c interfaces
SVM40 module pin diagram
Arduino Code
#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;
}
}
WeChat applet Bluetooth network configuration interface
Device interface
Device data interface
WeChat applet main js program
//加载事件通知库,用于不同页面发布和订阅事件
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",
});
}
},
})
5. Source Code
esp32s3 code
https://download.eeworld.com.cn/detail/dql2016/625315
WeChat applet code
https://download.eeworld.com.cn/detail/dql2016/625316
6. Work function demonstration video
https://training.eeworld.com.cn/course/67865
得捷物联网电子设计大赛2022-室内空气质量监测
VII. Project Summary (Project Text Summary + Post Sharing Link Summary)
It is very convenient to use Arduino software for development. It comes with a lot of built-in examples. You only need to have a basic understanding of Bluetooth-related knowledge to develop your own applications based on the examples.
[IoT indoor environment monitor based on ESP32-S2-Kaluga-1] Reading data from svm40 sensor module
【IoT indoor environment monitor based on ESP32-S2-Kaluga-1】Bluetooth notification data
[IoT indoor environment monitor based on ESP32-S2-Kaluga-1] Development environment experience-Arduino
[IoT indoor environment monitor based on ESP32-S2-Kaluga-1] Development environment experience-ESP-IDF
|