基于ESP32测温湿度上传到OneNET并通过微信小程序控制,查看,下发指令 您所在的位置:网站首页 当前湿度查询app 基于ESP32测温湿度上传到OneNET并通过微信小程序控制,查看,下发指令

基于ESP32测温湿度上传到OneNET并通过微信小程序控制,查看,下发指令

2023-12-05 20:41| 来源: 网络整理| 查看: 265

项目背景

目前,科学技术发展十分迅速,其渗透到各行各业以及生活的方方面面,室内设计和高科技结合便出现了“智能家居”。所谓智能家居就是以居住场所为平台,利用物联网、传感器、智能控制技术将各种家用电器联系起来,实现居住环境的智能化、自动化、人性化。通过语音控制、远程控制、预约控制、个性化设计、一键控制等功能进一步提高生活的舒适性、便利性、安全性。

2.设计目标

本系统主要分为三大模块,分别为传感器监测模块,自动报警模块和远程控制模块。传感器监测模块包括对环境的温湿度和空气质量监测,用户可以在微信小程序上查看到实时传感数据;自动报警模块是当传感数据超过设置的阈值时会进行报警,提醒用户注意火灾的发生;远程控制模块可以通过微信小程序远程控制LED灯,风扇和加湿器的开关,实现了不在家也能远程控制家里的电器的开关。

3.设备端硬件设计

3.1硬件总体设计

硬件总体框架如下图所示。

3.2单片机选型及传感器选型

3.2.1 ESP32模块

SP32-WROOM-32 是一款通用型Wi-Fi+BT+BLE+MCU的模组,功能强大,用途广泛,可以用于低功耗传感器网络和要求极高的任务,例如语音编码、音频流和MP3解码等。ESP32还集成了丰富的外设,包括电容式触摸传感器、霍尔传感器、低噪声传感放大器,SD卡接口、以太网接口、高速SDIO/SPI、UART、I2S 和I2C等。

3.2.2 温湿度模块

本系统采集环境的温湿度选择 DHT11 温湿度传感器。DHT11 数字温湿度传感器采 用的是已校准数字信号输出,它能够同时检测温度和湿度,它使用专用的数字模块采集 技术和温湿度传感技术,能够确保产品的高可靠性与稳定性。 该传感器包括一个电阻式感湿元件和一个 NTC 测温元件,利用元件的电气特性随 温湿度的变化测量出环境的温湿度,元件与一个高性能 8 位单片机相连接。该产品具有 高品质、响应快、抗干扰强、性价比高等优点。低功耗与非常小的体积使得它能够被应 用于各种复杂的场景。DHT11 为 4 针单排引脚封装,连接方便。DHT11 温湿度模块实物图如下图所示。

         

4.直接上代码   4.1.1、设备怎么连上网 #include const char* ssid = "baby"; //wifi名称 const char* password = "13456789";//wifi密码 void setupWifi(){ delay(10); Serial.println("连接WIFI"); WiFi.begin(ssid, password); while (!WiFi.isConnected()) { Serial.print("."); delay(500); } Serial.println("OK"); Serial.println("Wifi连接成功"); }

  4.1.2、MQTT接入地址

 1、mqtt协议的接口端号是6002,而mqtts协议的接口端号是1883

const char *mqtt_server = "183.230.40.96"; //onenet 的 IP地址 const int port = 6002; //端口号

2、数据如何发送给onenet

这里我们需要查阅onenet的相关文档

OneNET - 中国移动物联网开放平台

#define mqtt_devid "945965335" //设备ID #define mqtt_pubid "577632" //产品ID //鉴权信息 #define mqtt_password "123456" //鉴权信息 char msg_buf[200]; //发送信息缓冲区 char msgJson[75]; //要发送的json格式的数据 unsigned short json_len = 0; //json长度 //信息模板 char dataTemplate[] = "{\"temp\":%.2f,\"humi\":%.2f,\"led\":%d}"; // temp humi led要与onenet相对应 void sendTempAndHumi() { if (client.connected()) { //dht.readHumidity() snprintf(msgJson,75,dataTemplate,dht.readTemperature(),dht.readHumidity(),god); 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

3、在 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; } if ((char)payload[0] == '1') { digitalWrite(led, HIGH); // god=1; } else{} }

  4.1.3、测温湿度

使用DHT11模块,调用库

#include "DHT.h"

定义DHT11,数据引脚我接在IO13口

#define DHTPIN 13 // io13 #define DHTTYPE DHT11 // DHT 11 DHT dht(DHTPIN, DHTTYPE);

 5、总代码(当然了这个是新手必备,只需要一个DHT11和一个LED灯就可以实现的)

#include #include "DHT.h" #include "PubSubClient.h" #include "Ticker.h" #define DHTPIN 13 #define DHTTYPE DHT11 // DHT 11 #define led 18 //灯的接口 DHT dht(DHTPIN, DHTTYPE); int god=0; const char *ssid = "baby"; //wifi名称 const char *password = "12345671";//wifi密码 const char *mqtt_server = "183.230.40.96"; //onenet 的 IP地址 const int port = 6002; //端口号 #define mqtt_devid "999999735" //设备ID #define mqtt_pubid "599995" //产品ID //鉴权信息 #define mqtt_password "123456" //鉴权信息 WiFiClient espClient; //创建一个WIFI连接客户端 PubSubClient client(espClient); // 创建一个PubSub客户端, 传入创建的WIFI客户端 char msg_buf[200]; //发送信息缓冲区 char msgJson[75]; //要发送的json格式的数据 unsigned short json_len = 0; //json长度 //信息模板 char dataTemplate[] = "{\"temp\":%.2f,\"humi\":%.2f,\"led\":%d}"; // temp humi要与onenet相对应 Ticker tim1; //定时器,用来循环上传数据 //连接WIFI void setupWifi(){ delay(10); Serial.println("连接WIFI"); WiFi.begin(ssid, password); while (!WiFi.isConnected()) { Serial.print("."); delay(500); } Serial.println("OK"); Serial.println("Wifi连接成功"); } void setup() { Serial.begin(115200); pinMode(led,OUTPUT);//输出 setupWifi(); //调用函数连接WIFI Serial.print(F("DHT11 test!")); dht.begin(); client.setServer(mqtt_server, port); //设置客户端连接的服务器,连接Onenet服务器, 使用6002端口 client.connect(mqtt_devid, mqtt_pubid, mqtt_password); //客户端连接到指定的产品的指定设备.同时输入鉴权信息 if (client.connected()) { Serial.print("OneNet is connected!");//判断以下是不是连好了. } //client.setCallback(callback); //设置好客户端收到信息是的回调 client.setCallback(callback); //订阅命令下发主题 tim1.attach(5, sendTempAndHumi); //定时每5秒调用一次发送数据函数sendTempAndHumi } void loop() { delay(5000); float h = dht.readHumidity(); float t = dht.readTemperature(); float f = dht.readTemperature(true); if (isnan(h) || isnan(t) || isnan(f)) { Serial.println(F("Failed to read from DHT sensor!\n")); return; } //可以让我们通过串口查看数据 Serial.print(F("Humidity: ")); Serial.print(h); Serial.print(F("% Temperature: ")); Serial.print(t); Serial.print(F("℃ \n ")); if (!WiFi.isConnected()) //先看WIFI是否还在连接 { setupWifi(); } if (!client.connected()) //如果客户端没连接ONENET, 重新连接 { clientReconnect(); delay(100); } client.loop(); //客户端循环检测 } void sendTempAndHumi() { if (client.connected()) { //dht.readHumidity() snprintf(msgJson,75,dataTemplate,dht.readTemperature(),dht.readHumidity(),god); 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); } } //收到主题下发的回调, 注意这个回调要实现三个形参 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; } if ((char)payload[0] == '1') { digitalWrite(led, HIGH); // god=1; } else{} } void clientReconnect() { while (!client.connected()) //再重连客户端 { Serial.print("reconnect MQTT..."); if (client.connect(mqtt_devid, mqtt_pubid, mqtt_password)) { Serial.print("connected"); } else { Serial.print("failed"); Serial.print(client.state()); Serial.print("try again in 5 sec"); delay(5000); } } }

6、微信开发者工具

 

 

自己创建一个项目,直接替换index.js,index.wxml,index.wxss

index.js

// index.js // 获取应用实例 const app = getApp() const mqtt=require('../../utils/mqtt') Page({ data: { motto: 'Hello World', userInfo: {}, hasUserInfo: false, canIUse: wx.canIUse('button.open-type.getUserInfo'), canIUseGetUserProfile: false, canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName') // 如需尝试获取用户信息可改为false }, // 事件处理函数 bindViewTap() { wx.navigateTo({ url: '../logs/logs' }) }, onLoad() { if (wx.getUserProfile) { this.setData({ canIUseGetUserProfile: true }) } }, getUserProfile(e) { // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗 wx.getUserProfile({ desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写 success: (res) => { console.log(res) this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } }) }, getUserInfo(e) { // 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息 console.log(e) this.setData({ userInfo: e.detail.userInfo, hasUserInfo: true }) }, points:function(e) { var that = this wx.request({ //设备ID //api-key url: 'http://api.heclouds.com/devices/xxxxxxxxxx/datapoints?', //xxxxxxxxxx这里填写你的设备id header:{ "api-key":"5oXSCXaNrBBlsQm6YNWU3wtHu1U=" //这里写你的api-key }, data:{ limit:1 }, method :"GET", //获取成功 success:function(res){ that.setData({ light:res.data.data.datastreams[0].datapoints[0].value, wendu:res.data.data.datastreams[1].datapoints[0].value, shidu:res.data.data.datastreams[3].datapoints[0].value, //这里的shidu要跟wxml{{shidu}} 名字相同 }) } }) }, openled:function(e){ let pafload if(e.detail.value==true) pafload = 1 else pafload =0 console.log(pafload) wx.request({ url: 'http://api.heclouds.com/cmds?device_id=xxxxxxxxxx', //*号这里写你设备id//设备ID//api-key header:{ 'content-type':'application/json', "api-key":"5oXSCXaNrQm6YNWU3wtHu1U=" //这里写你的api-key }, method :"POST", data:pafload,//数据1是为灯开 success(res){ console.log("控制成功,已开灯") console.log(res) console.log(res.data); } }) }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { this.points() //这个是我获取onenet数据的函数 var that=this setInterval(function(){ that.points(); },3000 //这里我设置3秒刷新一次 ) }, })

index.wxml

照明开关 当前温度:{{wendu}}°C 当前湿度:{{shidu}} %

index.wxss

/* pages/index/index.wxss */ page { background: #f6f6f6; display: flex; flex-direction: column; justify-content: flex-start; } .headTitle{ width: 100%; height: 80rpx; background-color: #ffffff; overflow:hidden ;/** 设置超出内容隐藏 */ white-space:nowrap; /*设置超出不换行 */ border-bottom :1px solid #F3F3F3; } .headTitle .titleItem{ display: inline-block; line-height:80rpx; color: #889999; font-size:34rpx; margin: 0 20rpx; } .headTitle .selctItem{ color: #000000; font-weight: bold; } .itemView{ width: 100%; height:180rpx; position: relative; border-bottom: 1px solid #F3F3F3; } .zm{ margin-top: 20rpx; border:1px solid#ebe4e286; width:750rpx; height: 100rpx; border-radius: 5px; font-size: 36; font-weight: bold; line-height: 80rpx; color: #32d5e0; text-align: center; display: flex; position: relative;/*父元素位置要设置为相对*/ } .login-btn{ width: 40%!important; background-color: #33ff33; color: white; font-weight: normal; } .content{ margin-top: 20rpx; border:1px solid#ebe4e286; width:750rpx; height: 600rpx; border-radius: 5px; font-size: 36; font-weight: bold; line-height: 80rpx; color: #32d5e0; text-align: center; flex-direction: column; display: flex; } .xia{ justify-content: space-between; } .zm1{ position: absolute; /* 要约束所在位置的子元素的位置要设置成绝对 */ left: 30rpx; /* 靠右调节 */ } .radio{ display:inline-block; /* 横向布局*/ } .kai{ position: absolute; /* 要约束所在位置的子元素的位置要设置成绝对 */ right: 100rpx; /* 靠右调节 */ } .mos{ left: 120rpx; /* 靠右调节 */ height: 200rpx; }

微信小程序链接

百度网盘



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有