这个是我最近做的一个课程设计,实时监测室内的温湿度和光照强度,在微信小程序上实时显示监测数据并下发命令控制风扇开关和舵机正反转(从而实现模拟窗帘的开关)。有两种模式控制,一个是手动控制,通过微信小程序远程控制设备开关,一个是设备自动控制,设定温湿度的阈值来控制风扇的开关,通过设定光照强度的阈值来控制舵机正反转(开关)。
1、硬件系统总体框图
系统以MCU为核心器件设计感知控制节点。空气温湿度传感器、光照度传感器、气体传感器将采集到的模拟数字通过AD转换成数字量信号传输直接输入MCU的I/O口;所有感知数据通过WiFi模块发送到云端。同时通过设定参数来驱动控制设备。
2、硬件设计流程图
3、下位机软件设计流程图
4、器件选择
1、空气温湿度传感器
选用DHT11复合型数字化空气温湿度传感器,其内部集成有温湿度传感模块,传感器模块工作时会调用生产过程中已校验的系数进行校准。用的是右边的DHT11
2、 光照传感器:
光敏二极管LM393可以将光信号(光强度)转换为电信号;然后比较电路把经过光敏电阻的电压和经过电位器的电压进行比较,并向DO口输出高电压或低电压供用户使用;而AO口是直接经过光敏电阻降压后的电路,所以输出的是在GND和VCC之间的任一电压值;当然VCC和GND是模块元件和芯片正常工作的基本条件,不可或缺! 光照传感器如图10所示。
3、舵机选择
选用SG90舵机通过接收PWM信号,使其进入内部电路产生一个偏置电压,触发电机通过减速齿轮带动电位器移动,使电压差为零时,电机停转,从而达到伺服的效果。即给舵机一个特定的PWM信号,舵机旋转到特定角度。我买到是360可以旋转的舵机
4、风扇
我买的是两个线的这种
5、Onenet云平台
1、创建产品
控制台 —>多接入–>添加产品
关于产品名称、行业、类别那些自行选择即可,这里选用mqtt旧版协议
点击我们刚刚创建的dht11,然后点击产品概况,记住我们的产品id,后面用得上
2、创建设备
点击设备列表->点击右边的添加设备,设备名称和鉴权信息需要填写,鉴权信息设备连接onenet用的上,还有设备的id号
3、创建数据流
首先点击数据流,然后点击数据流模板管理,最后添加数据流模板
这里设置的数据流名称后面要用到,这里我创建了温度、湿度、灯、光照等等的数据流。
6、下位机代码编写
1、设备怎么连上网
这里可以调用wifi库
#include <WiFi.h>
const char* ssid = "3671"; //wifi名称
const char* password = "05210835";//wifi密码
2、温湿度
我传感器用的是DHT11,这里也可以调用库(可以去管理库下载DHT sersor library这个库)
#include "DHT.h"
定义DHT11,数据引脚我接在IO7口
#define DHTPIN 7 // io7
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
3、光敏
这里我选择的Io0口是带有模数转换器的io口,方便数据转换
#define LDR_PIN 0 //光敏接口0
const float GAMMA = 0.7;
const float RL10 = 50;
float guang(){
int analogValue = analogRead(LDR_PIN);
float voltage = analogValue / 1024. * 5;
float resistance = 2000 * voltage / (1 - voltage / 5);
float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
Serial.print(lux);
return lux;
}
4、舵机
// setting PWM properties
#define do 10 //舵机接口
const int freq = 5000;//设置频率
const int ledChannel = 0;//通道号,取值0 ~ 15
const int resolution = 8;//计数位数,取值0 ~ 20
unsigned long time1=544;
bool direction1=true;
setup函数
//舵机模块
pinMode(do, OUTPUT);
digitalWrite(do,HIGH);
delayMicroseconds(544);
digitalWrite(do,LOW);
loop函数
driection1是用来判断舵机现在的状态的开还是关的
//舵机
if(direction1 && vm <400)
{
time1+=10;
digitalWrite(do,HIGH);
delayMicroseconds(time1);
digitalWrite(do,LOW);
delay(5);
if (time1>=2600)
direction1=false;
dji=1;
}
if(direction1==false && vm >400)
{
time1-=10;
digitalWrite(do,HIGH);
delayMicroseconds(time1);
digitalWrite(do,LOW);
delay(5);
if (time1<=544)
direction1=true;
dji=0;
}
5、风扇
这里是通过继电器的高低电平来控制风扇开关的
const int fengshan=8; //继电器in接口
setup函数
pinMode(fengshan,OUTPUT);
loop函数
如果温度超过30就启动风扇
if(t>30){
digitalWrite(fengshan, HIGH); //
shan =1;
}
6、OLED
这个我之前的博客有详细介绍,没有环境配置或者不懂的可以点击下方链接跳转过去学习
https://blog.csdn.net/weixin_44107116/article/details/122491820
7 、接入地址
mqtt协议的接口端号是6002
const char *mqtt_server = "183.230.40.96"; //onenet 的 IP地址
const int port = 6002; //端口号
8、数据如何发送给onenet
这里我们需要查阅onenet的相关文档
https://open.iot.10086.cn/doc/v5/develop/detail/463
#define mqtt_devid "884337606" //设备ID
#define mqtt_pubid "487632" //产品ID
//鉴权信息
#define mqtt_password "20222222" //鉴权信息
char msg_buf[200]; //发送信息缓冲区
char msgJson[80]; //要发送的json格式的数据
unsigned short json_len = 0; //json长度
//信息模板
char dataTemplate[] = "{\"temp\":%.2f,\"humi\":%.2f,\"led\":%d,\"feng\":%d,\"guang\":%.2f,\"doji\":%d,\"Air\":%d}"; // temp humi等等要与onenet相对应
void sendTempAndHumi()
{
if (client.connected())
{
//dht.readHumidity()
snprintf(msgJson,80,dataTemplate,dht.readTemperature(),dht.readHumidity(),god,shan,guang(),dji,Air());
json_len = strlen(msgJson); //msgJson的长度
msg_buf[0] = char(0x03); //要发送的数据必须按照ONENET的要求发送, 根据要求,数据第一位是3
msg_buf[1] = char(json_len >> 8); //数据第二位是要发送的数据长度的高八位
msg_buf[2] = char(json_len & 0xff); //数据第三位是要发送数据的长度的低八位
memcpy(msg_buf + 3, msgJson, strlen(msgJson)); //从msg_buf的第四位开始,放入要传的数据msgJson
msg_buf[3 + strlen(msgJson)] = 0; //添加一个0作为最后一位, 这样要发送的msg_buf准备好了
Serial.print("public the data:");
Serial.print(msgJson);
client.publish("$dp", (uint8_t *)msg_buf, 3+strlen(msgJson));
//发送数据到主题
delay(500);
}
}
在 setup()函数定义了每5秒发送一次数据到onenet
tim1.attach(5, sendTempAndHumi); //定时每5秒调用一次发送数据函数sendTempAndHumi
9、下发命令
在 setup()函数订阅命令下发主题
client.setCallback(callback); //订阅命令下发主题
//收到主题下发的回调, 注意这个回调要实现三个形参 1:topic 主题, 2: payload: 传递过来的信息 3: length: 长度
void callback(char *topic, byte *payload, unsigned int length)
{
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
if ((char)payload[0] == '0') {
digitalWrite(led, LOW); //
god=0;
}
else if ((char)payload[0] == '1') {
digitalWrite(led, HIGH); //
god=1;
}
else if ((char)payload[0] == '2') {
digitalWrite(fengshan, HIGH); //
shan=1;
}
else if ((char)payload[0] == '3') {
digitalWrite(fengshan, LOW); //
shan=0;
}
//关
else if ((char)payload[0] == '5') {
for(time1;time1>=544;time1-=10){
digitalWrite(do,HIGH);
delayMicroseconds(time1);
digitalWrite(do,LOW);
delay(5);
if(time1<=544){
direction1=true;
dji=0;
delay(5000);
}
}
}
//开
else if ((char)payload[0] == '4') {
for(time1;time1<=2600;time1+=10){
digitalWrite(do,HIGH);
delayMicroseconds(time1);
digitalWrite(do,LOW);
delay(5);
if (time1>=2600){
direction1=false;
dji=1;
delay(5000);
}
}
}
else{
}
}
10、led灯
关于灯,本来想外接的,但是我在查看原理图后就想偷懒了,毕竟开发板有自带了两个灯和RGB灯。这里我选择的是18接口的灯,因为19的灯是常亮的,所以不选它。
const int led =18; //灯的接口
在setup()定义灯是输出的
pinMode(led,OUTPUT);//输出
我这里设置一个god变量,初始化是0,即灯没有开,等接收到指令再进行变化,1为灯开。
11、PCB板
因为器件太多,用杜邦线接不过来,用面包板也不美观,后面花了一点时间学了EDA,用嘉立创的立创EDA画了一个板出来用,这里安利一下嘉立创,真的好用,而且打板不超过十厘米完全免费,这个国产超nice!!!(右边的type-A接口用不了,仅供参考)
7、微信开发者工具
这个是微信提供的一个开发工具,有框架,也方便我们把项目部署到线上。这里我着重讲述怎么获取onene数据和发送指令
1、微信界面
2、获取Onenet的API接口
回到onenet的设备列表,然后在点击右边的详情就可以看到设备的详细信息,复制API地址和API-key,一个设备可以多个apikey,自行添加。
3、查询OneNet平台多协议接入文档,这里直接查看MQTT的API使用
4、我用ApiPost来进行测试是否能获取数据
5、微信小程序获取OneNet数据
1、在wxml里面我给按钮添加了点击事件,命名为points,相对应的在index.js里面也需要添加相对应函数
points:function(e) {
},
2、参考小程序文档,我这里采用wx.request 获取数据
points:function(e) {
var that = this
wx.request({
url: 'http://api.heclouds.com/devices/xxxxxxxxxx/datapoints?', //xxz这里填写你的设备id
//设备ID
//api-key
header:{
"api-key":"xxxxxxx" //这里写你的api-key
},
data:{
limit:1
},
method :"GET",
//获取成功
success:function(res){
that.setData({
wendu:res.data.data.datastreams[0].datapoints[0].value,
time:res.data.data.datastreams[0].datapoints[0].at,
shidu:res.data.data.datastreams[1].datapoints[0].value,
led:res.data.data.datastreams[2].datapoints[0].value, //这里的shidu要跟wxml{{shidu}} 名字相同
})
}
})
},
3、关于如何显示到具体数字,因人而异,下面我这两行代码是根据json数据来定位的
shidu:res.data.data.datastreams[0].datapoints[0].value,
wendu:res.data.data.datastreams[1].datapoints[0].value,
6、微信小程序下发命令
这里我也封装了两个函数,一个是发1值,一个发0值,因为我们的嵌入代码写是1代表打开灯,0代表关灯。这里以打开灯函数介绍
openled:function(e){
wx.request({
url: 'http://api.heclouds.com/cmds?device_id=*****',//*号这里写你设备id
//设备ID
//api-key
header:{
'content-type':'application/json',
"api-key":"xxxxxxx" //这里写你的api-key
},
method :"POST",
data:1,//数据1是为灯开
success(res){
console.log("控制成功,已开灯")
console.log(res)
console.log(res.data);
}
})
},
7、数据刷新
其实这些网上都有的函数例子,我试过页面刷新、定时刷新,如果页面没有点击事件的话都可以用我下面这两个方法。但是有点击事件的话还是用定时刷新
定时刷新
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.points() //这个是我获取onenet数据的函数
var that=this
setInterval(function(){
that.points();
},3000 //这里我设置3秒刷新一次
)
},
8、选择下拉列表相应指令发送数据
这里我单独写了一篇博客可点下方链接详细学习
https://blog.csdn.net/weixin_44107116/article/details/125520404
9、数据可视化
这里我是参考了另一个博主的博客做的,简单易懂,我这里稍微改进了一下,只显示日期,没有显示年份。点击图片就可以切换到可视化界面,我写了温度】我、湿度、光照这三个而已。
https://blog.csdn.net/qq_52827563/article/details/121726546?
10、检测设备是否在线
然后我在下拉列表的基础上设置了一个前提条件,只有设备在线才能发送指令,不然只会弹出信息提示框提示。
postdata:function(shuj){
wx.request({
url: 'https://api.heclouds.com/cmds?device_id=设备id',
//设备ID
//api-key
header:{
'content-type':'application/json',
"api-key":"你的api-key"
},
method :"POST",
data:shuj, //数据指令
success(res){
wx.showToast({
title: '已发送控制指令',
image:"/images/gong.png",
duration:2000,
mask:true
})
console.log("控制成功,已完成控制指令")
console.log(res)
console.log(res.data);
},
fail(res){
wx.showToast({
title: '请求失败',
image:"/images/errer.png",
duration:2000,
mask:true
})
console.log("请求失败")
console.log(res)
console.log(res.data);
}
})
},
devicedata:function(){
var that =this;
wx.request({
url: 'https://api.heclouds.com/devices/884337606',
//设备ID
//api-key
header:{
'content-type':'application/json',
"api-key":"9zHJfKbQN=dyGflCM0yaICWHmi8="
},
method :"GET",
success(res){
if (res.data.data.online){
console.log("设备已连接");
that.setData({deviceSwitch:1})
}
else{
console.log("设备未连接");
that.setData({deviceSwitch:0})
}
},
fail(res){
console.log("请求失败");
}
})
},
11、效果展示
基于物联网的环境调节系统文章来源:https://www.toymoban.com/news/detail-431291.html
结语
大概一整个物联网流程都搞定了,顺便把硬件无线集成化了,微信小程序的界面和功能都比以往升级和添加了新的东西,要是想要源码或者相关资料的可以私信我,但不是免费的,这是我个人努力摸索出来的,还请谅解。文章来源地址https://www.toymoban.com/news/detail-431291.html
到了这里,关于基于物联网的环境调节系统(ESP32-C3+Onenet+微信小程序)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!