(超简单)ESP8266深度睡眠模式下远程采集温湿度信息

(超简单)ESP8266深度睡眠模式下远程采集温湿度信息

项目背景

自己用收纳箱做了一个用于存放3D打印耗材的干燥箱,想用闲置的ESP8266开发板和DHT11温湿度传感器做一个远程温湿度监测的小项目。
因为温湿度信息的采集并不需要太过频繁,另一方面为了降低整体的功耗,所以打算使用ESP8266的深度睡眠模式来每隔半个小时或一个小时上传一次温湿度的信息,这样能大大降低整个项目的功耗,延长使用时间。

相关技术

ESP8266深度睡眠模式

esp8266的三个睡眠模式包括调制解调器睡眠、轻度睡眠和深度睡眠(具体信息可以参考文章-ESP8266睡眠模式)。深度睡眠模式是8266三个主要睡眠模式中功耗最低的一种,在该模式下esp8266的所有应用程序数据都不会执行,相当于8266处于关机状态,只有8266的RST引脚接收到低电平信号后8266才会被唤醒(开机)。这里可以将8266的GPIO16(D0)引脚与RST引脚相连,通过GPIO16号引脚向RST引脚发送低电平将8266唤醒。
Alt
esp8266进入深度睡眠模式可以通过调用函数 ESP.deepSleep(30e6); (单位us,30e6表示睡眠30秒)来实现,深度睡眠模式下最多睡眠时长4,294,967,295 µs 也就是大概71分钟。

esp8266进入深度睡眠模式的示例代码如下:

void setup() {
  Serial.begin(115200);
  Serial.setTimeout(2000);

  // Wait for serial to initialize.
  while(!Serial) { }
  
  //Serial.println("即将进入深度睡眠模式,睡眠时长为30秒");
  //ESP.deepSleep(30e6); 

  Serial.println("即将进入深度睡眠模式,将一直处于深度睡眠状态,直到RST接收到低电平信号才被唤醒");
  ESP.deepSleep(0); 
}

void loop() {
  Serial.println("深度睡眠模式下,loop函数中的代码将不会被执行");
}

注意: 深度睡眠模式下,esp8266只会执行setup函数中位于deepSleep()函数之前的代码程序,loop中的代码将永远不会被执行。

DHT11温湿度采集

温湿度信息的采集主要由DHT11传感器来完成,传感器的data引脚接8266的GPIO4(D2)引脚,使用SimpleDHT库来实现温湿度信息的采集,主要代码如下:

void getHumChk()
{
  int err = SimpleDHTErrSuccess;
  if ((err = dht11.read(&temp_read, &humi_read, NULL)) != SimpleDHTErrSuccess)
  {
    Serial.print("Read DHT11 failed, err=");
    Serial.println(err);
    delay(1500);
    return;
  }
  Serial.print("hum:");
  Serial.print(humi_read);
  Serial.print("%");

  Serial.print("tem:");
  Serial.print(temp_read);
  Serial.println("*C");
}

MQTT数据收发

项目中数据的收发主要通过部署在阿里云服务器上的MQTT服务端来完成,我的阿里云服务器是windows系统(操作简单些,代码可以随时修改运行,主要也用于跑其他软件),也可以在自己的电脑上搭建,搭建非常简单,具体的搭建流程可以参考MQTT环境搭建

MQTT信息收发的测试使用MQTT.fx软件,非常方便。
ESP8266开发板通过MQTT发送信息的代码如下:

//发布MQTT信息
void pubMQTTmsg(String state)
{

  //建立发布主题。主题名称为“topic”
  String topic = "Mymqtt/module2/led";
  char publishTopic[topic.length() + 1];
  strcpy(publishTopic, topic.c_str());

  //建立发布信息。
  String sendMessage = state;
  char publishMsg[sendMessage.length() + 1];
  strcpy(publishMsg, sendMessage.c_str());

  //实现8266向主题发布信息
  if (mqttClient.publish(publishTopic, publishMsg))
  {
    Serial.print("Publish Topic:");
    Serial.println(publishTopic);
    Serial.print("Publish Message:");
    Serial.println(publishMsg);
  }
  else
  {
    Serial.println("Message Publish Failed.");
  }
}

其他完整代码可以点击文章末尾github链接查看。

Node.js前后端实现

后端

这次上位机及数据的显示使用Node.js来实现,后端用Node.js来接收MQTT消息,接收到温湿度消息后将相关数据存入到阿里云服务器上的MySql数据库,并通过前端网页来展示,前后端数据的交互使用socket来实现。

MySql配置信息如下:

var mysql = require('mysql')
var connection = mysql.createConnection({
  host: '你的服务器IP',
  user: '用户名',
  password: '密码',
  port: '端口,一般是3306',
  database: '数据库名称',
})
connection.connect()

MQTT配置信息如下:

var mqttUrl = 'mqtt://服务器IP:61613'
var option = {
  username: 'MQTT服务器用户名',
  password: 'MQTT服务器密码',
  clientId: '客户端ID',
}

订阅MQTT主题的代码如下:

//订阅的MQTT主题
client.subscribe('Mymqtt/module1/willMessage', { qos: 0 })    //设备一的状态信息
client.subscribe('Mymqtt/module1/DHT11', { qos: 0 })          //温湿度
client.subscribe('Mymqtt/module1/light', { qos: 0 })          //光照
client.subscribe('Mymqtt/module2/willMessage', { qos: 0 })    //设备二的状态信息
client.subscribe('Mymqtt/module2/led', { qos: 2 })            //灯的状态信息
console.log('订阅成功')

主题名称根据自己的需要改,不能与其他主题名称重复。(module2是我远程控制灯的项目)

接收MQTT消息并发送前端的部分代码如下:

   //监听MQTT消息
   client.on("message", function (topic, message) {
    if (topic == "Mymqtt/module1/willMessage") {
      nowtime = new Date().getTime();
      t = nowtime - lasttime;
      if (t > 3000) {
        willMessage1 = message.toString();
        time = new Date().toLocaleString("chinese", { hour12: false });
        console.log(time);
        console.log("主题:" + topic + "  消息:" + willMessage1);
        socket.emit("module1", { msg: willMessage1 });
        socket.emit("time", { msg: time });
      }
      lasttime = nowtime;
      } else if (topic == "Mymqtt/module2/willMessage") {
        willMessage2 = message.toString();
        console.log("主题:" + topic + "  消息:" + willMessage2);
        socket.emit("module2", { msg: willMessage2 });
      } else if (topic == "Mymqtt/module1/light") {
        light = message.toString();
        console.log("主题:" + topic + "  消息:" + light);
        socket.emit("light", { msg: light });

这里用到nowtime、lasttime、t是因为接收MQTT消息时有可能会同时接收多条相同的消息,所以3秒内只接收一条同一主题的消息。

温湿度信息插入数据库的代码如下:

//将温湿度信息插入到数据库中
var json = JSON.parse(message.toString());
var addDht11 = "INSERT INTO dht11(temperature,humidity) VALUES(?,?)";
var temperature = parseInt(json.temperature);
var humidity = parseInt(json.humidity);
var addSqlParams = [temperature, humidity];

connection.query(addDht11, addSqlParams, function (err, result) {
  if (err) {
    console.log("[INSERT ERROR] - ", err.message);
    return;
  }
  console.log("Insert successfully");
});

其他完整代码见文章末尾链接。

前端

前端的效果如图:
前端温湿度监测页面效果
页面上面可以显示设备的状态,即“离线”还是“在线”,也可以显示设备上次离线时的时间。下面可以显示传感器最近一次上报的温湿度信息,图表显示最近10次的温湿度信息,当有新的信息到来时也会动态更新。

这里的图表使用的是ECzharts的图表插件,可以根据数据的变化动态显示曲线,也可以在折线图和条形图之间进行切换,还可以放大某一区域或将当前数据画面下载。他们网站上有着各式各样的图表插件,可以很简单、方便地把自己的数据通过插件动态显示出来,这是他们的官网-ECharts官网

注: 本项目中开发板每10分钟上报一次温湿度信息,即8266上报一次温湿度信息后会进入深度睡眠模式,10分钟后被唤醒再次上报后进入深度睡眠,如此循环。

github地址:https://github.com/Fishghost98/TemHumProject
码云地址:https://gitee.com/Fishghost/TemHumProject

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>