基于物联网的环境调节系统(ESP32-C3+Onenet+微信小程序)

这个是我最近做的一个课程设计,实时监测室内的温湿度和光照强度,在微信小程序上实时显示监测数据并下发命令控制风扇开关和舵机正反转(从而实现模拟窗帘的开关)。有两种模式控制,一个是手动控制,通过微信小程序远程控制设备开关,一个是设备自动控制,设定温湿度的阈值来控制风扇的开关,通过设定光照强度的阈值来控制舵机正反转(开关)。


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、效果展示

基于物联网的环境调节系统

结语

大概一整个物联网流程都搞定了,顺便把硬件无线集成化了,微信小程序的界面和功能都比以往升级和添加了新的东西,要是想要源码或者相关资料的可以私信我,但不是免费的,这是我个人努力摸索出来的,还请谅解。

  • 4
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
基于物联网设计的酒驾检测系统是一种利用物联网技术和STM32芯片为核心的智能酒驾检测设备。该系统能够通过测量驾驶员吹气中的酒精浓度,以确保驾驶者是否饮酒超过法定限制,并在必要时采取措施避免发生酒驾事故。 该系统的基本原理是通过一块搭载STM32芯片的传感器检测器来测量驾驶员吹气中的酒精浓度。传感器采用特殊的化学反应原理,可以准确地分析酒精浓度。传感器采集到的数据通过STM32芯片进行处理,并使用物联网技术将数据上传到云端平台。 在云端平台上,数据进行分析和处理,并与事先设定的法定限制值进行比较。如果酒精浓度超过限制值,系统会发出警报信号,提醒驾驶员自觉遵守交通规则,避免酒后驾驶。同时,系统还可以与警察部门等相关机构实现数据共享,以便及时采取必要的法律措施。 该系统的设计中还考虑了数据安全和隐私保护。所有传感器数据在上传到云端平台前都经过加密处理,确保数据传输的安全性。同时,驾驶员的个人信息也被严格保护,只有授权部门才能访问,并且遵循相关法律法规的要求。 基于物联网设计的酒驾检测系统具有实时、准确的特点,能够有效地避免酒驾事故的发生,保障道路交通安全。未来,随着物联网技术和智能化水平的不断提高,该系统还有望与车载导航系统、智能交通系统等进行联动,实现更强大的功能和更广泛的应用范围。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帕法西尔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值