1.前言
预设目标:通过ESP32S3完成联网上报数据到OneNet云平台,再通过APP获取数据,并通过云平台实现下发指令控制ESP32S3控制硬件,上报的数据能通过界面跳转实现历史数据查看,在app端实现多设备接入。
后期目标:软件端架设通用化框架,实现输入用户的设备ID和设备码,添加标识符和数据。增加视频流功能
硬件端:新增AI语音助手,实现智能语音交互。
1.1 ESP32S3简介
开发板选用的ESP32S3-DevKitC-1,主频高达240Mhz,拥有多个ADC采集通道,以及多个定时器以及串口,功能强大,适用于物联网入门,下面两张图分别是ESP32S3的实物图和其功能引脚分布图。
开发板中38号引脚连接着LED灯。
ESP32S3-DevKitC-1
ESP32S3-DevKitC-1功能引脚分布
1.2 开发环境简介
软件开发环境主要包括Arduino IDE,HBuilderX这两个软件,一个是用于编写ESP32S3运行代码,另一个则是负责编写APP端代码。
Arduino端需要安装ESP32支持包,可去B站搜索安装流程。HBuilderX在运行过程中需要安装多个插件,运行时会进行提醒,安装即可。
1.3 OneNet云平台简介
如果经常接触物联网,对于各类物联网云平台应该多少有些了解,华为云,阿里云,腾讯云,OneNet云,巴法云等物联网常用云平台。
本文连接的是OneNet云,运行代码适用于新版的OneNet云用户,大概是2023年7月后注册的用户,因为OneNet在2023年7月左右进行了一场大更新,传统的多协议接入没了,新用户接入不能照搬老版代码。
OneNet云平台创建的流程很简单
1.注册账户
2.创建产品
3.产品开发
4.设置物模型
5.保存并退出
具体的流程可去B站搜up:彼岸有船我们有光 新版OneNet云平台接入
里面关于OneNet云平台的物模型设置讲的很清晰,我这就只强调一个重点:
物模型的标识符尽量简洁且全英文
物模型标识符越短,占据的字节越少,一次能上报的就越多,反之越少。
比如温度:temp即可
对于开关,则需要设置成布尔变量。
下面放两张图,简单的看看物模型的设置
温度物模型
开关物模型
物模型设置完成之后保存退出,即可在设备管理中看见自己创建的物模型
OneNet云平台控制台
2.代码解析
2.1 ESP32S3端运行代码解析
ESP32S3在安装完环境后即可使用,但是无法直接进行开发板选择,按照下图中的路径进行开发板选择即可,选择完开发板,再选择串口。
ESP32S3直接运行工程代码需要大量的头文件,在建议提前安装这些库,不然会频繁报错,这些头文件包括了一些常用的传感器,比如说DHT11、SGP30、HX711以及一些用于解析下发指令的库比如“ArduinoJson.h”,以及用于定时上报数据的库“Ticker.h”。当然如果不需这些传感器,也可替换为其他的传感器即可。
#include <Wire.h>
#include <math.h>
#include <DHT.h>
#include <Arduino.h>
#include "WiFi.h"
#include "PubSubClient.h"
#include "Ticker.h"
#include "ArduinoJson.h"
#include <Wire.h>
#include "Adafruit_SGP30.h"
#include "HX711.h"
接下来是修改参数:wifi账号密码、上报主题、产品ID、产品名称、物模型名称、鉴权信息、数据解析物模型名称。
搜索修改快捷键,快速定位到修改词:Ctrl+F
1.wifi账号密码:自行修改为自己的账号密码(苹果无法提供热点进行联网)
const char* ssid = "Q"; //WIFI名称
const char* password = "12345678"; //WIFI密码
2.上报主题:将产品ID、设备名称替换成自己的即可
const char* topic = "$sys/NWDdb3WY8J/Q/thing/property/set";
3.修改产品ID、设备名称:将产品ID和设备名称替换成自己的
#define mqtt_pubid "NWDdb3WY8J" //产品ID
#define mqtt_devid "Q" //设备名称
下图中左上角的是设备名称、左下角是产品ID
4.物模型名称:物模型很多,这里只列出两个,这两个是浮点值、云平台的物模型也应该为浮点值,物模型背后我都写了备注。
float humi; //上传的湿度数据
float temp; //上传的温度数据
不同的物模型对应的数据类型不同,乱用数据类型会导致上传失败。
整数:
\"adcx\":{\"value\":%d}
浮点数:
\"temp\":{\"value\":%.2f}
布尔类型:
\"led\":{\"value\":%s}
5.鉴权信息: 鉴权信息需要时间戳,设备秘钥,设备ID,设备名称这几个参数才能生成。
#define mqtt_password "version=2018-10-31&res=products%2FNWDdb3WY8J%2Fdevices%2FQ&et=2035091490&method=md5&sign=KnWEBDQJRh6WttSDtyMVDw%3D%3D"
设备秘钥,产品名称,产品ID在OneNet云平台获取
时间戳进入网站:https://www.bejson.com/convert/unix/index.html
选择10年后,默认10位时间戳,点击转换。
使用token生成器,将参数填入,生成鉴权信息。
6.数据解析物模型数据:替换掉物模型标识符即可
解析开关信息
if ((place_temp = getmessage.indexOf("led")) != -1) {
String value = getmessage.substring(getmessage.indexOf(':', place_temp) + 1, getmessage.indexOf('}', place_temp));
Serial.println("get led:" + value);
if ((place_temp = value.indexOf("false")) != -1) {
Serial.println("解析结果为false");
r = 1;
};
if ((place_temp = value.indexOf("true")) != -1) {
Serial.println("解析结果为true");
r = 0;
};
}
解析数值信息
if ((place_temp = getmessage.indexOf("td")) != -1) {
String value = getmessage.substring(getmessage.indexOf(':', place_temp) + 1, getmessage.indexOf('}', place_temp));
Serial.println("get td:" + value);
td = value.toInt();
if (td > 1000) td = 1000;
}
为了降低联网难度,提供了两个版本的ESP32S3运行代码,一个是基础版本,上报DHT11温湿度,控制LED灯代码。另一个则是包含多数据上报、阈值控制,多外设控制的代码。
2.2 APP端效果预览
先预览效果图、由于软件制作时间不长,呈现效果比较粗糙,后续会进一步优化。
以上是软件交互的在电脑上的呈现效果,软件制造的完成度不高,后面有时间再一点点优化吧。
另一个版本:只有简单的数据接收框架,未进行界面美化,但是这是上面那个版本的基石。
2.3 APP端运行代码解析:
这是一个卡片信息的代码,其中包括,名称,单位,安全/异常提示。核心的语句是下面中的temp。
它表示这个卡片是用于显示温度信息的,将temp替换成别的词,即可完成更换显示数据。
<view class="dev-data">{{temp}} ℃<br />
<view class="dev-cart">
<view class="dev-cart" @click="goLineChartTemp">
<view class="">
<view class="dev-name">温度</view>
<image class="dev-logo" src="../../static/temp.png" mode=""></image>
</view>
<view class="dev-data">{{temp}} ℃<br />
<view style="font-size: 10px;">
<view class="dev-frame">
最佳生长范围:{{td}} ℃-{{tp}}℃
</view>
</view>
</view>
<view v-if="temp>tp" class="dev-box" style="background-color: red;">
<view class="dev-title">异常</view>
</view>
<view v-if="temp<td" class="dev-box" style="background-color: red;">
<view class="dev-title">异常</view>
</view>
<view v-else class="dev-box" style="background-color:green;">
<view class="dev-title">安全</view>
</view>
</view>
</view>
这是阈值调节滑动条,可以调节阈值信息,下面这句是核心语句,替换掉其中的tp即可更换阈值信息。它表示可以条件温度上限阈值。
<view class="dev-name">{{tp}}℃</view>
<view class="device-cart-l">
<view>
<view class="dev-name">温度上限</view>
<!-- 当前温度阈值显示 -->
<view class="dev-name">{{tp}}℃</view>
</view>
<view class="ctrl-slider">
<!-- 滑动条调用slider组件,实时更新阈值 -->
<slider :value="tp" @change="sliderChange($event, 'slider1')" min="0" max="100" step="1"
block-size="20" show-value />
</view>
</view>
设备ID、设备名称:将这个设备ID和设备名称替换成自己的
const product_id = "NWDdb3WY8J"
const device_name = "Q"
数据定义区域,根据自己的数据显示情况,确定自己需要显示哪些数据。
这个是设备秘钥和用户ID需要更换,这个在OneNet云平台中的账号信息中查看。
onLoad() {
const params = {
author_key: 'QUtaEhlK3r+Utodvpv0TLykuPugFlgGLJO2ql0MkZ9qW+U8rwtedoB0ra3vcZ8soyuU2uJtRdAbkQmNMrtXlPA==',
version: '2022-05-01',
user_id: '355595',
}
this.token = createCommonToken(params);
},
这个区域是获取数据,其中this后面跟着的是物模型标识符、data[0]、data[1]、data[2]……代表的是数据的位置,OneNet的物模型位置是从0开始算,第一个物模型的位置是0,然后从左往右递增。
比如说:温室光强对应的是data[0]、二氧化碳对应的则是data[1]、重量对应的则是data[4]
success: (res) => {
console.log(res.data);
console.log(res.data.data[0].value);
this.adcx = res.data.data[0].value;
this.carbon = res.data.data[1].value;
this.height = res.data.data[4].value;
this.humi = res.data.data[5].value;
this.smoke = res.data.data[8].value;
this.temp = res.data.data[11].value;
this.led = res.data.data[7].value === 'true';
}
这是滑动条的代码,不同的滑动条绑定不同的数据。
if (id == 'slider1') {
this.tp = e.detail.value
// 更新温度阈值
this.key_th = {
tp: this.tp,
};
}
if (id == 'slider2') {
this.td = e.detail.value
// 更新温度阈值
this.key_th = {
td: this.td,
};
}
if (id == 'slider3') {
this.hd = e.detail.value
// 更新湿度阈值
this.key_th = {
hd: this.hd,
};
}
if (id == 'slider4') {
this.ld = e.detail.value
// 更新湿度阈值
this.key_th = {
ld: this.ld,
};
}
if (id == 'slider6') {
this.cd = e.detail.value
// 更新湿度阈值
this.key_th = {
cd: this.cd,
};
} else if (id == 'slider5') {
this.sp = e.detail.value
// 更新湿度阈值
this.key_th = {
sp: this.sp,
};
}
下面是折线图跳转,确保跳转路径正确即可
goLineChartTemp() {
// 将认证令牌存储在本地,供其他页面使用
uni.setStorageSync('token', this.token);
// 页面跳转
uni.navigateTo({
url: '/pages/temp/temp'
});
},
折线图界面要修改设备名称和ID以及数据位置
const user_product_id = "NWDdb3WY8J"
const user_device_name = "Q"
this.smoke = res.data.data[8].value;
最后一个就是开关的设置,修改物模型标识符即可。
onledSwitch(event) {
console.log(event.detail.value);
let value = event.detail.value;
uni.request({
url: 'https://iot-api.heclouds.com/thingmodel/set-device-property', //仅为示例,并非真实接口地址。
method: 'POST',
data: {
product_id: product_id,
device_name: device_name,
params: {
"led": value
}
},
header: {
'authorization': this.token //自定义请求头信息
},
success: (res) => {
console.log('LED' + (value ? 'ON' : 'OFF') + '!');
}
});
最后选择原生APP打包即可
3.代码下载
通过百度网盘分享的文件:ESP32S3-AIOT方案.zip
链接:https://pan.baidu.com/s/14VAS5RIU1tnYkSnY1_pPAw
提取码:AIOT