基于IOT的供电房监控系统(实物)

news2024/9/20 8:07:34

aliyun_mqtt.cpp

        本次设计利用ESP8266作为系统主控,利用超声波检测门的状态,利用DHT11检测环境温湿度、烟雾传感器检测空气中的气体浓度,利用火焰报警器模块检测火焰状态,使用OLED进行可视化显示,系统显示传感器数据,以及们的状态等。如果环境中烟雾浓度过高,风扇会进行转动将烟雾进行驱散。

一、硬件设计

1、主控

        本次设计利用ESP8266作为系统主控,ESP8266是一款 WIFI开发板,可以利用Arduino IDE进行开发,由于ESP8266开发板对应arduino ide的标号与开发板显示标号有差异,因此为了方便进行开发,我们可以在此前创建一些静态变量完成其映射,参考如下:

static const uint8_t D0   = 16;
static const uint8_t D1   = 5;
static const uint8_t D2   = 4;
static const uint8_t D3   = 0;
static const uint8_t D4   = 2;
static const uint8_t D5   = 14;
static const uint8_t D6   = 12;
static const uint8_t D7   = 13;
static const uint8_t D8   = 15;
static const uint8_t D9   = 3;
static const uint8_t D10  = 1;

2、传感器

        本次设计利用的传感器包括烟雾传感器、火焰传感器、DHT11、超声波传感器四个传感器,借助arduino IDE框架,我们可以很轻松地获得这些传感器的驱动文件。

        烟雾传感器利用模数转换进行实现,由于ESP8266有且只有一个ADC口,借助该ADC口,我们可以实现烟雾传感器的值获取,值的范围大致在0-1024的区间。

烟雾传感器模块:

        火焰传感器有两种输出方式:模拟输出、数字输出,分别叫做 AO(模拟输出)、DO(数字输出),由于上面的烟雾传感器已经使用了ADC口,且ESP8266只有一个ADC口,因此火焰传感器只能使用数字输出口获取数据,当检测到火焰的时候,火焰传感器输出0,当没有检测到火焰的时候,火焰传感器输出1.

火焰传感器模块:

        DHT11是一种温湿度传感器,他只有一根数据传输线,使用单总线协议进行传输,借助Arduino IDE软件,我们可以方便地进行传感器数据的读取。

DHT11温湿度模块:

        超声波传感器模块使用简单,我们只需要发送10s左右的高电平,然后关闭,统计超声波传感器的 ECHIO端(接收端)的高电平时间,此时我们再根据声音在空气中的传播速度,进行距离的测算,实现非接触式测量。

超声波传感器模块:

3、风扇

        风扇一般使用直流电机进行驱动扇叶,直流电机是一种简单的点击器件,我们只要控制其导电方向,就可以实现风扇的正反转,如果直流电机两端电平一致,则电机停止。使用简单方便,如果需要实现不同挡位的电机速度,可以使用PWM进行驱动,改变其占空比,实现直流电机调速。

        L298N 是一种双H桥电机驱动模块,其中每个H桥可以提供2A的电流,功率部分的供电电压范围是2.5-48v,逻辑部分5v供电,接受5vTTL电平。一般情况下,功率部分的电压应大于6V否则芯片可能不能正常工作。

二、软件设计

1、ESP8266 Arduino IDE 程序设计

        ESP8266端作为核心部分,需要负责数据采集、可视化显示、控制器件、上传数据等,对于传感器部分可以借助Arduino IDE中的第三方库方便地完成硬件驱动,可视化器件使用OLED,为了显示中文,本次设计使用了U8G库,控制直流电机非常简单,只是单纯的高低电平,而上传数据到阿里云平台则需要借助 aliyun_mqtt 库这是一个第三方库且并没有上传到Arduino IDE官方,设计的时候我们还需要创建一个.cpp、一个.h文件。下面会附上代码:

#include <Arduino.h>  //引入Arduino开发板的基础头文件
//引入连接传感器需要使用的DHT库函数头文件
#include <Adafruit_Sensor.h>
#include <DHT.h> 
#include <U8g2lib.h> //引入连接OLED显示屏需要使用的U8g2库函数头文件
//引入Arduino底层SPI和I2C通信协议相关的库函数头文件
#include <SPI.h>
#include <Wire.h>

#include <ESP8266WiFi.h>   //引入连接WiFi网络需要使用的ESP8266 Arduino开发环境
#include <PubSubClient.h>  //引入连接MQTT服务器需要使用的PubSubClient库函数头文件
#include <ArduinoJson.h>   //引入使用JSON数据交互需要使用的ArduinoJson库函数头文件
#include "aliyun_mqtt.h" //引入连接阿里云物联网平台所需的MQTT库函数头文件
#include <AliyunIoTSDK.h>  //引入阿里云IoT SDK

//配置阿里云环境和WIFI
#define WIFI_SSID ""  //自己的WIFI ID
#define WIFI_PASSWD ""  //自己的WIFI密码
#define PRODUCT_KEY ""                         //自己的PRODUCT_KEY
#define DEVICE_NAME ""                             //自己的DEVICE_NAME
#define DEVICE_SECRET ""  //自己的DEVICE_SECRET
#define REGION_ID "cn-shanghai"                           //自己的REGION_ID
WiFiClient espClient;  //创建WIFI连接对象
PubSubClient mqttClient(espClient);  //创建MQTT连接对象
//订阅消息的TOPIC
#define ALINK_TOPIC_PROP_SET ""  
//发布数据的TOPIC
#define ALINK_TOPIC_PROP_POST ""  
 
//使用U8G2库驱动OLED显示屏
#ifdef U8X8_HAVE_HW_SPI
#endif
#ifdef U8X8_HAVE_HW_I2C
#endif
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);  

static const uint8_t D0   = 16;
static const uint8_t D1   = 5;
static const uint8_t D2   = 4;
static const uint8_t D3   = 0;
static const uint8_t D4   = 2;
static const uint8_t D5   = 14;
static const uint8_t D6   = 12;
static const uint8_t D7   = 13;
static const uint8_t D8   = 15;
static const uint8_t D9   = 3;
static const uint8_t D10  = 1;

//定义DHT11空气温湿度传感器引脚
#define DHTPIN D4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
#define Smoke_Pin A0
#define Flame_Pin D3
#define Trig  D5
#define Eoho  D6
#define Led  D7
#define Buz  D8

int HCSR04_GetDistance()
{
  int Min=0, cm=0;
  digitalWrite(Trig,LOW);
  delayMicroseconds(2);
  digitalWrite(Trig,HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig,LOW);
  Min = pulseIn(Eoho,HIGH);
  cm = Min/58;  
  return cm;
}

uint8_t start_flag=1;

void setup() {
  Serial.begin(9600);  //初始化串口
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  dht.begin();  //开启DHT11

  //配置超声波引脚
  pinMode(Trig,OUTPUT);
  pinMode(Eoho,INPUT);   

  //配置led和蜂鸣器引脚 
  pinMode(Led, OUTPUT); 
  pinMode(Buz, OUTPUT); 

  //关闭led和蜂鸣器
  digitalWrite(Led, LOW);
  digitalWrite(Buz, LOW);

  u8g2.begin();  //初始化U8G2库
  u8g2.enableUTF8Print();  //设置U8G2支持UTF-8编码的字符输出
  u8g2.setFont(u8g2_font_wqy15_t_gb2312);  //设置字体
  u8g2.clearBuffer();  //清除内部缓冲区

  u8g2.setCursor(0, 15);
  u8g2.print("正在联网");
  u8g2.sendBuffer();  //发送到显示屏
  init_wifi(WIFI_SSID, WIFI_PASSWD);  //初始化WIFI

  AliyunIoTSDK::begin(espClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET, REGION_ID);
  mqttClient.setCallback(mqtt_callback);  //MQTT回调函数,用来处理微信向ESP8266传的指令
}

uint8_t df=0;
uint8_t mode=0;

void loop() {
  if(start_flag==1){
    u8g2.clearBuffer();  //清除内部缓冲区
    u8g2.setCursor(0, 15);
    u8g2.print("正在连接MQTT");
    u8g2.sendBuffer();  //发送到显示屏    
    start_flag=0;
  }
  //配置MQTT
  mqtt_check_connect();//订阅
  mqttClient.loop();
  
  //DHT11空气温湿度传感器获取数据
  int t = dht.readTemperature();
  int h = dht.readHumidity();
  int s = map(analogRead(Smoke_Pin),0,1024,0,100);
  int f = digitalRead(Flame_Pin);
  int dis = HCSR04_GetDistance();

  //OLED显示屏显示
  u8g2.clearBuffer();  //清除内部缓冲区
  //OLED显示温度
  u8g2.setCursor(0, 15);
  u8g2.print("温度:");
  u8g2.print(t);   
  u8g2.print("C");  

  //OLED显示湿度
  u8g2.setCursor(0, 31);
  u8g2.print("湿度:");
  u8g2.print(h);   
  u8g2.print("%");  

  //OLED显示烟雾
  u8g2.setCursor(0, 47);
  u8g2.print("烟雾:");
  u8g2.print(s);   
  u8g2.print("%"); 

  //OLED显示火焰
  u8g2.setCursor(0, 63);
  u8g2.print("火焰:");
  if(f==0){
    u8g2.print("异常"); 
  }
  else{
    u8g2.print("正常");     
  }
    

  //OLED显示门状态
  u8g2.setCursor(70, 63);
  u8g2.print("门:");
  if(dis<10){
    u8g2.print("关");   
    df=0;  
  }
  else{
    u8g2.print("开"); 
    df=1;
  }

  u8g2.setCursor(80, 15);
  u8g2.print(dis);   
  u8g2.print("cm"); 
  u8g2.sendBuffer();  //发送到显示屏

  //自动模式下,通过温度调节风扇
  if(mode==0){
    if(s > 10){
      digitalWrite(Buz, HIGH);
      digitalWrite(Led, HIGH);
    }
    else{
      digitalWrite(Buz, LOW);
      digitalWrite(Led, LOW);
    }
  }
  mqtt_interval_post(t,h,s,f,df);//发布

  delay(500);
}

//回调函数-阿里云端数据发送过来之后,此函数进行解析
void mqtt_callback(char *topic, byte *payload, unsigned int length)
{
  if (strstr(topic, ALINK_TOPIC_PROP_SET)) {  //调用strstr函数判断topic字符串是否包含订阅消息的子串
    DynamicJsonDocument doc(100);  JSON对象用于保存从MQTT消息payload中解析出来的JSON数据
    DeserializationError error = deserializeJson(doc, payload);  //将payload所包含的JSON数据解析出来,并存储到doc对象中。
    //转换为JsonObject类型的对象,并从中提取"data"键对应的值,即WeChat_data
    JsonObject setAlinkMsgObj = doc.as<JsonObject>(); 
    int modeData = setAlinkMsgObj["mode"];  
    int WeChat_data = setAlinkMsgObj["fan"]; 
    //微信小程序发送消息自动浇水或远程浇水
    Serial.print("WeChat_data:");
    Serial.println(WeChat_data);
    Serial.print("modeData:");
    Serial.println(modeData);
    if(modeData==1){
      mode=1;
    } 
    else if(modeData==2){
      mode=0;
    }
    if(mode==1){
      if(WeChat_data==1){
        digitalWrite(Led, HIGH);
      }
      else if(WeChat_data==2){
        digitalWrite(Led, LOW);      
      }
    }
  }
}

//订阅topic,ESP8266接收来自阿里云的消息(接收微信小程序发的消息)
void mqtt_check_connect() {
  while (!mqttClient.connected()) {
    while (connect_aliyun_mqtt(mqttClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET)) {
      mqttClient.subscribe(ALINK_TOPIC_PROP_SET);  //引用订阅消息的topic,用来接收消息
    }
  }
}
//发布topic,ESP8266上传数据到阿里云(发送数据给微信小程序)
void mqtt_interval_post(int tem,int hum,int smoke, int flame, int door) {
  char param[512];
  char jsonBuf[1024];
  sprintf(param, "{\"currentTemperature\":%d,\"read\":%d,\"smoke\":%d, \"flame\":%d, \"door\":%d}", tem, hum, smoke, flame, door);
  Serial.println(param);  
  mqttClient.publish(ALINK_TOPIC_PROP_POST, param);  //引用上传数据的topic,jsonBuf这个是上传的数据
}

//连接WiFi
void init_wifi(const char *ssid, const char *password) {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi does not connect, try again ...");
    delay(500);
  }
}

aliyun_mqtt.cpp

/*
  Aliyun_mqtt.h - Library for connect to Aliyun MQTT server.
*/

#include "aliyun_mqtt.h"

#include <SHA256.h>

#define MQTT_PORT 1883
#define SHA256HMAC_SIZE 32

// Verify tool: http://tool.oschina.net/encrypt?type=2
static String hmac256(const String &signcontent, const String &ds)
{
  byte hashCode[SHA256HMAC_SIZE];
  SHA256 sha256;

  const char *key = ds.c_str();
  size_t keySize = ds.length();

  sha256.resetHMAC(key, keySize);
  sha256.update((const byte *)signcontent.c_str(), signcontent.length());
  sha256.finalizeHMAC(key, keySize, hashCode, sizeof(hashCode));

  String sign = "";
  for (byte i = 0; i < SHA256HMAC_SIZE; ++i)
  {
    sign += "0123456789ABCDEF"[hashCode[i] >> 4];
    sign += "0123456789ABCDEF"[hashCode[i] & 0xf];
  }

  return sign;
}

static String mqttBroker;
static String mqttClientID;
static String mqttUserName;
static String mqttPassword;

// call this function once
void mqtt_prepare(const char *timestamp,const char *productKey, const char *deviceName,const char *deviceSecret,const char *region)
{
  mqttBroker = productKey;
  mqttBroker += ".iot-as-mqtt.";
  mqttBroker += String(region);
  mqttBroker += ".aliyuncs.com";
  
  // Serial.println(mqttBroker);

  mqttUserName = deviceName;
  mqttUserName += '&';
  mqttUserName += productKey;
   //Serial.println(mqttUserName);
   
  mqttClientID = deviceName; // device name used as client ID
  mqttClientID += "|securemode=3,signmethod=hmacsha256,timestamp=";
  mqttClientID += timestamp;
  mqttClientID += '|';
   //Serial.println(mqttClientID);
}

bool connect_aliyun_mqtt_With_password(PubSubClient &mqttClient, const char *password)
{
  mqttClient.setServer(mqttBroker.c_str(), MQTT_PORT);

  byte mqttConnectTryCnt = 5;
  while (!mqttClient.connected() && mqttConnectTryCnt > 0)
  {
    Serial.println("Connecting to MQTT Server ...");
    if (mqttClient.connect(mqttClientID.c_str(), mqttUserName.c_str(), password))
    {

      // Serial.println("MQTT Connected!");
      return true;
    }
    else
    {
      byte errCode = mqttClient.state();
      Serial.print("MQTT connect failed, error code:");
      Serial.println(errCode);
      if (errCode == MQTT_CONNECT_BAD_PROTOCOL || errCode == MQTT_CONNECT_BAD_CLIENT_ID || errCode == MQTT_CONNECT_BAD_CREDENTIALS || errCode == MQTT_CONNECT_UNAUTHORIZED)
      {
        Serial.println("No need to try again.");
        break; // No need to try again for these situation
      }
      delay(3000);
    }
    mqttConnectTryCnt -= 1;
  }

  return false;
}

bool connect_aliyun_mqtt(
    PubSubClient &mqttClient,
    const char *productKey,
    const char *deviceName,
    const char *deviceSecret,
    const char *region)
{
  String timestamp = String(millis());
  mqtt_prepare(timestamp.c_str(), productKey, deviceName, deviceSecret, region);

  // Generate MQTT Password, use deviceName as clientID
  String signcontent = "clientId";
  signcontent += deviceName;
  signcontent += "deviceName";
  signcontent += deviceName;
  signcontent += "productKey";
  signcontent += productKey;
  signcontent += "timestamp";
  signcontent += timestamp;

  String mqttPassword = hmac256(signcontent, deviceSecret);

   //Serial.print("HMAC256 data: ");
   //Serial.println(signcontent);
   //Serial.print("HMAC256 key: ");
  // Serial.println(deviceSecret);
  // Serial.println(mqttPassword);

  return connect_aliyun_mqtt_With_password(mqttClient, mqttPassword.c_str());
}

aliyun_mqtt.h

/*
  Aliyun_mqtt.h - Library for connect to Aliyun MQTT server with authentication by
  product key, device name and device secret.

  https://www.alibabacloud.com/help/product/30520.htm
*/

#ifndef _ALIYUN_MATT_H
#define _ALIYUN_MATT_H

#include <Arduino.h>
#include <PubSubClient.h>

/**
 * Connect to Alibaba Cloud MQTT server. In connection process, it will try several times for
 * possible network failure. For authentication issue, it will return false at once.
 *
 * @param mqttClient: Caller provide a valid PubSubClient object (initialized with network client).

 * @param productKey: Product Key, get from Alibaba Cloud Link Platform.

 * @param deviceName: Device Name, get from Alibaba Cloud Link Platform.

 * @param deviceSecret: Device Secret, get from Alibaba Cloud Link Platform.
 *
 * @param region: Optional region, use "cn-shanghai" as default. It can be "us-west-1",
 *                "ap-southeast-1" etc. Refer to Alibaba Cloud Link Platform.
 *
 *
 * @return true if connect succeed, otherwise false.
 */
extern "C" bool connect_aliyun_mqtt(
    PubSubClient &mqttClient,
    const char *productKey,
    const char *deviceName,
    const char *deviceSecret,
    const char *region = "cn-shanghai");

/**
 * Two new added APIs are designed for devices with limited resource like Arduino UNO.
 * Since it is hard to calculate HMAC256 on such devices, the calculation can be done externally.
 *
 * These two APIs should be used together with external HMAC256 calculation tools, e.g.
 * http://tool.oschina.net/encrypt?type=2
 * They can be used together to replace connectAliyunMQTT on resource-limited devices.
 */

/**
 * This API should be called in setup() phase to init all MQTT parameters. Since HMAC256
 * calculation is executed extenrally, a fixed timestamp string should be provided, such
 * as "23668" etc. The same timestamp string is also used to calculate HMAC256 result.
 *
 * Other params are similar to them in connectAliyunMQTT.
 */
extern "C" void mqtt_prepare(
    const char *timestamp,
    const char *productKey,
    const char *deviceName,
    const char *deviceSecret,
    const char *region = "cn-shanghai");

/**
 * Use tools here to calculate HMAC256: http://tool.oschina.net/encrypt?type=2
 * The calculated result should be defined as constants and passed when call this function.
 */
extern "C" bool connect_aliyun_mqtt_With_password(PubSubClient &mqttClient, const char *password);

#endif

2、微信小程序设计

        本人作为嵌入式软件工程师,对于微信小程序的编写并没有特别了解,本次设计借助他人已经的微信小程序源码并再次基础上修改,得到属于我的小程序,参考如下:

index.xml

<view class="button-sp-are">
  <button class="weui-btn" style="background-color:{{buttonColor}}" type="primary" size="mini"  bindtap="onClickOpen">{{Text1}}</button>
  <button class="weui-btn" style="background-color:{{modeColor}}" type="primary" size="mini"  bindtap="onClickMode">{{Text2}}</button>
  <button class="TemDis" size="mini">温度:{{temperature}}℃</button>
  <button class="HumDis" size="mini">湿度:{{humidity}}</button>
  <button class="Smoke" size="mini" >烟雾:{{smoke_val}}</button>
  <button class="Flame" size="mini"  style="background-color:{{flameColor}}" >火焰:{{flame_val}}</button>
  <button class="Door" size="mini"  style="background-color:{{doorColor}}">门:{{door_val}}</button>
</view>

index.js

import mqtt from'../../utils/mqtt.js';
const aliyunOpt = require('../../utils/aliyun/aliyun_connect.js');

let that = null;
let btn = 0;
let modef = 0;

Page({
    data:{
    
      buttonColor: '#E64340',
      modeColor: '#E64340',
      flameColor:"#2ADB71",
      doorColor:"#2ADB71",
      Text1:"风扇关",
      Text2:"自动模式",
      //设置温度值和湿度值 
      temperature:"",
      humidity:"",
      smoke_val:"",
      flame_val:"",
      door_val:"",

      client:null,//记录重连的次数
      reconnectCounts:0,//MQTT连接的配置
      options:{
        protocolVersion: 4, //MQTT连接协议版本
        clean: false,
        reconnectPeriod: 1000, //1000毫秒,两次重新连接之间的间隔
        connectTimeout: 30 * 1000, //1000毫秒,两次重新连接之间的间隔
        resubscribe: true, //如果连接断开并重新连接,则会再次自动订阅已订阅的主题(默认true)
        clientId: '',
        password: '',
        username: '',
      },

      aliyunInfo: {
        productKey: '', //阿里云连接的三元组 ,请自己替代为自己的产品信息!!
        deviceName: '', //阿里云连接的三元组 ,请自己替代为自己的产品信息!!
        deviceSecret: '', //阿里云连接的三元组 ,请自己替代为自己的产品信息!!
        regionId: 'cn-shanghai', //阿里云连接的三元组 ,请自己替代为自己的产品信息!!
        pubTopic: '', //发布消息的主题
        subTopic: '', //订阅消息的主题
      },
    },

  onLoad:function(){
    that = this;
    let clientOpt = aliyunOpt.getAliyunIotMqttClient({
      productKey: that.data.aliyunInfo.productKey,
      deviceName: that.data.aliyunInfo.deviceName,
      deviceSecret: that.data.aliyunInfo.deviceSecret,
      regionId: that.data.aliyunInfo.regionId,
      port: that.data.aliyunInfo.port,
    });

    console.log("get data:" + JSON.stringify(clientOpt));
    let host = 'wxs://' + clientOpt.host;
    
    this.setData({
      'options.clientId': clientOpt.clientId,
      'options.password': clientOpt.password,
      'options.username': clientOpt.username,
    })
    console.log("this.data.options host:" + host);
    console.log("this.data.options data:" + JSON.stringify(this.data.options));

    //访问服务器
    this.data.client = mqtt.connect(host, this.data.options);

    this.data.client.on('connect', function (connack) {
      wx.showToast({
        title: '连接成功'
      })
      console.log("连接成功");
    })

    //接收消息监听
    this.data.client.on("message", function (topic, payload) {
      console.log(" 收到 topic:" + topic + " , payload :" + payload);
      that.setData({
        //转换成JSON格式的数据进行读取
        temperature:JSON.parse(payload).currentTemperature,
        humidity:JSON.parse(payload).read,

        smoke_val:JSON.parse(payload).smoke,
        flame_val:JSON.parse(payload).flame,
        door_val:JSON.parse(payload).door,
      })
      if(that.data.flame_val == "1"){
        that.setData({
            flame_val:"正常",
            flameColor:"#2ADB71",
          })
          console.log(that.data.flame_val)
      }
      if(that.data.flame_val == "0"){
        that.setData({
            flame_val:"异常",
            flameColor:"#CB3C21",
        })
          console.log(that.data.flame_val)
      }

      if(that.data.door_val == "1"){
        that.setData({
            door_val:"打开",
            doorColor:"#2ADB71",
          })
          console.log(that.data.flame_val)
      }
      if(that.data.door_val == "0"){
        that.setData({
            door_val:"关闭",
            doorColor:"#CB3C21",
        })
          console.log(that.data.flame_val)
      }

/*       wx.showModal({
        content: " 收到topic:[" + topic + "], payload :[" + payload + "]",
        showCancel: false,
      }); */
    })

    //服务器连接异常的回调
    that.data.client.on("error", function (error) {
      console.log(" 服务器 error 的回调" + error)

    })
    //服务器重连连接异常的回调
    that.data.client.on("reconnect", function () {
      console.log(" 服务器 reconnect的回调")

    })
    //服务器连接异常的回调
    that.data.client.on("offline", function (errr) {
      console.log(" 服务器offline的回调")
    })
  },

  onClickMode(){
    if(modef==0){
        that.sendMode(1);
        this.setData({
            modeColor: '#2049EE',
            Text2:'手动模式',
        })
        modef=1;
        return;
      }
      else{
        that.sendMode(2);
        this.setData({
            modeColor: '#E64340',
            Text2:'自动模式',
        })
        modef=0;
        return;
      }
  },

  sendMode(cmd, data){
    let sendData = {
        mode: cmd
      }; 
      //发布消息
      if (this.data.client && this.data.client.connected) {
        this.data.client.publish(this.data.aliyunInfo.pubTopic, JSON.stringify(sendData));
        console.log("************************")
        console.log(this.data.aliyunInfo.pubTopic)
        console.log(JSON.stringify(sendData))
      } else {
        wx.showToast({
          title: '请先连接服务器',
          icon: 'none',
          duration: 2000
        })
      }
  },

  onClickOpen() {
      if(btn==0){
        that.sendCommond(1);
        this.setData({
            buttonColor: '#2049EE',
            Text1:'风扇开',
        })
        btn=1;
        return;
      }
      else{
        that.sendCommond(2);
        this.setData({
            buttonColor: '#E64340',
            Text1:'风扇关',
        })
        btn=0;
        return;
      }
  },
  
  sendCommond(cmd, data) {
    let sendData = {
      fan: cmd
    };


//此函数是订阅的函数,因为放在访问服务器的函数后面没法成功订阅topic,因此把他放在这个确保订阅topic的时候已成功连接服务器
//订阅消息函数,订阅一次即可 如果云端没有订阅的话,需要取消注释,等待成功连接服务器之后,在随便点击(开灯)或(关灯)就可以订阅函数
/*
     this.data.client.subscribe(this.data.aliyunInfo.subTopic,function(err){
      if(!err){
        console.log("订阅成功");
      };
      wx.showModal({
        content: "订阅成功",
        showCancel: false,
      })
    })  */
    

    //发布消息
    if (this.data.client && this.data.client.connected) {
      this.data.client.publish(this.data.aliyunInfo.pubTopic, JSON.stringify(sendData));
      console.log("************************")
      console.log(this.data.aliyunInfo.pubTopic)
      console.log(JSON.stringify(sendData))
    } else {
      wx.showToast({
        title: '请先连接服务器',
        icon: 'none',
        duration: 2000
      })
    }
  }
})

3、阿里云产品流转

三、项目演示

1、程序运行OLED显示数据

        由于是很久之前做的,现在东西已经拆除,所以只能在本人以前的视频中截屏,比较模糊。OLED显示信息,同时小程序也显示数据信息,分别是门的状态、风扇状态、温度、湿度、烟雾、火焰等信息,微信小程序数据和设备端同步变化。

2、检测门状态

        超声波测算距离,可以判断门是否已经关闭,如果超声波测算的距离比较小,说明门靠近检测装置,门应当是关闭状态,反之门则是开启的状态,同时门如果关闭,显示屏显示关,小程序端门的框也会显示,同时会变红色,反之则是绿色。如下图:

3、检测火焰

        检测火焰类似,当打火机碰到火焰传感器,此时检测到火焰,OLED会显示,同时小程序端火焰的位置会变成红色,表示检测到火焰。

4、检测烟雾并自动打开散热

        检测到烟雾的时候会自动打开风扇,进行驱散,保持室内烟雾浓度适合。

5、远程控制功能

        微信小程序提供了两个按键,分别是模式切换(自动/手动模式),风扇开关,在手动模式下,模式按键是蓝色的,这时我们可以使用按键操作风扇,按钮为蓝色,风扇开,按键为红色,风扇关。

四、项目总结

        本次设计使用ESP8266作为主控制器,传感器有温湿度传感器、烟雾传感器、火焰传感器、超声波传感器,利用阿里云进行数据流转,微信小程序获取数据并执行操作,实现物联网。

详情可以参考本人的bilibili地址如下:

 esp8266+微信小程序_哔哩哔哩_bilibili

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2128104.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

同相放大器电路设计

1 简介 同相放大电路输入阻抗为运放的极高输入阻抗&#xff08;GΩ级&#xff09;&#xff0c;因此可处理高阻抗输入源信号。同相放大器的共模电压等于输入信号。 2 设计目标 2.1 输入 2.2 输出 2.3 频率 2.4 电源 3 电路设计 根据设计目标&#xff0c;最终设计的电路结构…

python-确定进制

题目描述 6 942 对于十进制来说是错误的&#xff0c;但是对于 13 进制来说是正确的。即 6(13)​ 9(13)​42(13)​&#xff0c;而 42(13)​4 13^12 13^054(10)​。 你的任务是写一段程序读入三个整数 p,q 和 r&#xff0c;然后确定一个进制 B(2≤B≤16) 使得 p qr 。如果 B 有…

Vue3: 使用ref自动补齐.value

目录 一.老版本&#xff08;已经弃用TypeScript Vue Plugin (Volar)&#xff09; 二.新版本&#xff08;Vue - Official&#xff09; 三.勾选后重启VScode 四.效果 VScode中搜索Vue - Official插件 一.老版本&#xff08;已经弃用TypeScript Vue Plugin (Volar)&#xff0…

学习之git的远程仓库操作的常用命令

1 git remote -v 查看当前所有远程地址别名 2 git remote add 别名 远程地址 3 git push 别名 分支&#xff08;本地分支名称&#xff09; 推送本地分支到远程仓库 4 git pull 远程库别名 远程分支别名 拉取远程库分支&#xff08;更新代码&#xff09; 5 git clone 远程库地址…

【时间盒子】-【6.任务页面】在同一个页面新建、编辑任务

Tips: Column组件的使用&#xff1b; color.json资源文件的使用。 一、页面布局 页面分为三个部分&#xff0c;从上往下分别是&#xff1a;标题菜单栏、时间选择器和任务列表。每个部分都可以设计为独立的组件&#xff0c;后续文章分别介绍。 二、新建页面 右击pages目录&…

Vue:指令

目录 指令概念内容渲染指令**{{ }}****v-text****v-html** 属性绑定指令 v-bind绑定属性**绑定class****绑定style**动态绑定属性**绑定对象** 事件绑定指令 v-onv-on 基础event**$event** 双向绑定指令 v-modelv-model 基础v-model 值绑定**v-model 指令的修饰符** 条件渲染指…

解锁全球机遇:澳大利亚服务器租用市场的独特魅力

在浩瀚的全球数字版图中&#xff0c;澳大利亚以其独特的地理位置、丰富的资源禀赋、以及日益增长的数字经济活力&#xff0c;成为了众多互联网企业竞相布局的重要市场。特别是当谈及服务器租用这一关键环节时&#xff0c;澳大利亚以其稳定的网络环境、先进的基础设施和开放的市…

使用原生HTML的drag实现元素的拖拽

HTML 拖放&#xff08;Drag and Drop&#xff09;接口使应用程序能够在浏览器中使用拖放功能。例如&#xff0c;用户可使用鼠标选择可拖拽&#xff08;draggable&#xff09;元素&#xff0c;将元素拖拽到可放置&#xff08;droppable&#xff09;元素&#xff0c;并释放鼠标按…

GPIO 简介(STM32F407)

一、GPIO简介 什么是GPIO GPIO即通用输入输出端口&#xff0c;全称General Purpose Input Output&#xff0c;是控制或者采集外部器件的信息的外设&#xff0c;即负责输入输出。 它按组分配存在&#xff0c;每组最多16个IO口&#xff0c;组数视芯片而定。比如STM32F407ZGT6是…

今年中秋节买什么东西划算?精选五款好物清单合集推荐!

谈及中秋佳节选购什么好物&#xff0c;你可真是找对人了&#xff01;作为一位专注于节日氛围与生活美学的博主&#xff0c;对于哪些中秋好物能为您的佳节增添温馨与喜悦&#xff0c;我可是了如指掌。恰逢中秋佳节临近&#xff0c;各大商家纷纷推出精彩纷呈的优惠活动&#xff0…

AI产品经理必备技能:技术与能力升级图谱

目 录 CONTENTS 前言 第1章 AI产品经理——不是简单的“当产品经理遇上“AI” 001 1.1 三大浪潮看AI技术发展 002 1.2 AI产品和AI产品经理 003 1.3 成为AI产品经理三步走 011 1.3.1 第一步&#xff1a;找到自己的糖山 011 1.3.2 第二步&#xff1a;找到自己的比较优势 …

联合谱低秩先验和深度空间先验的高光谱图像无监督去噪

高光谱图像&#xff08;Hyperspectral Image, HSI&#xff09;具有丰富的光谱信息&#xff0c;广泛应用于遥感、环境监测和医学成像等领域。然而&#xff0c;高光谱图像常常受到噪声的干扰&#xff0c;这会影响后续的数据分析和应用。因此&#xff0c;设计有效的去噪算法是高光…

计算机毕业设计选题推荐-线上花店系统-鲜花配送系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

玩归龙潮手机配置低、卡顿发烫、内存不足 GameViewer远程助你手机畅玩归龙潮

国潮RPG动作游戏《归龙潮》终于在9月13日迎来公测&#xff01;要是你担心自己的手机配置低&#xff0c;会出现卡顿发烫、内存不足等问题&#xff0c;可以通过网易GameViewer远程助你手机远控电脑畅玩归龙潮。 GameViewer远程作为专为游戏玩家打造的远程控制软件&#xff0c;用它…

价值流:从理论框架到实践落地的系统化指南

价值流如何从理论转化为实践中的企业增长引擎 随着全球化和数字化进程的加快&#xff0c;企业面临的竞争压力日益加剧。如何在竞争激烈的市场中立足并实现持续增长&#xff0c;已经成为每一个企业管理者需要面对的重要议题。作为一种强调客户价值创造的工具&#xff0c;《价值…

2024年8月国产数据库大事记-墨天轮

本文为墨天轮社区整理的2024年8月国产数据库大事件和重要产品发布消息。 目录 2024年8月国产数据库大事记 TOP102024年8月国产数据库大事记&#xff08;时间线&#xff09;产品/版本发布兼容认证代表厂商大事记厂商活动 【VLDB2024分享和相关论文】其它活动相关资料 厂商财报…

【STM32】OLED

OLED显示原理 OLED使用的是I2C协议&#xff0c;使用ssd1306芯片对所有灯进行控制&#xff0c;如果一个灯需要一个引脚的话&#xff0c;屏幕分为8页&#xff0c;每页有128列&#xff0c;8行 . 共有128* 88个灯 这样引脚是算不过来的&#xff0c;所以我们使用了ssd1306芯片&…

C/C++语言基础--预编译指令、宏定义(带参宏、宏函数)、头文件重复包含解决方法等

本专栏目的 更新C/C的基础语法&#xff0c;包括C的一些新特性 前言 宏定义是C/C最伟大的发明之一&#xff0c;甚至有人认为他比指针还伟大&#xff0c;它能够极大简化代码&#xff0c;因此学习宏定义是非常有必要的但是由于他只是简单的替换&#xff0c;故在C的efficiency书籍中…

说话人脸生成

说话人脸生成是一种技术&#xff0c;它通过音频信号来驱动和合成视频中的人脸图像&#xff0c;使得人脸的口型和表情与音频中的声音同步。这种技术主要应用于视频制作、虚拟现实、动画电影等领域&#xff0c;能够提升视听媒体的自然性和沉浸感。 使用的技术 说话人脸生成通常…

跨界融合:EasyDSS+无人机视频直播推流技术助力行业多场景应用

随着科技的飞速发展&#xff0c;无人机技术与流媒体技术的结合正逐步改变着多个行业的运作模式。其中&#xff0c;EasyDSS互联网视频云服务与无人机视频直播推流技术的结合&#xff0c;更是为警务安防、赛事直播、农业监测等多个领域带来了前所未有的变革。本文将深入探讨EasyD…