系统物联网的方案及功能设计_物联网系统设计-程序员宅基地

技术标签: 物联网  基于物联网的智慧光伏跟踪系统  单片机  

目录

1.1  通信协议的选择

1.1.1  MQTT的简介

1.1.2  MQTT的通信模型

 1.2  物联网服务平台的选择

1.2.1  注册物联网平台

1.3  Web端或手机端远程控制和监测跟踪装置

1.3.1  Node-RED设计      

1.3.2  移动端设计     

1.3.3  远程监视设计

1.3.4  代码实现

1.4  自适应天气运行控制策略

1.4.1  自适应天气运行的需求

1.4.2  自适应天气运行的设计原理

1.4.3  天气信息平台的选择

1.3.4  自适应天气运行的设计方案

1.4.5  代码实现

        1、使用心知天气数据服务的准备工作

        2、ESP8266获取并解析心知天气数据

        3、自适应天气运行+远程监控代码


物联网是通过ESP8266 nodeMCU来实现WiFi联网的,本系统是采用Arduino IDE来对ESP8266进行开发,因此本章的代码仅适用于Arduino IDE上。

1.1  通信协议的选择

        在物联网协议中,一般分为两大类,一类是传输协议,一类是通信协议。传输协议一般负责子网内设备间的组网及通信;通信协议则主要是运行在传统互联网TCP/IP协议之上的设备通讯协议,负责设备通过互联网进行数据交换及通信。MQTT是一种轻量级消息传输协议,它为物联网设备提供了一种简单的方法来传输数据信息。由于MQTT占用网络资源小,且适用于远程信息传输,MQTT在物联网(IoT)领域起着重要作用。

1.1.1  MQTT的简介

        MQTT(Message Queuing Telemetry Transport, 消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议,该协议构建于TCP/IP协议上,属于应用层协议,因此只要是支持TCP/IP协议栈的地方,都可以使用MQTT。

        MQTT协议最大的特点就是,两个设备端(Client)之间不及进行直接通讯,而是将数据发送到服务端(Server),由服务器将设备端发送的数据传递给对应的设备端。

1.1.2  MQTT的通信模型

        MQTT协议提供一对多的消息发布,可以降低应用程序的耦合性,用户只需要编写极少量的应用代码就能完成一对多的消息发布与订阅,该协议是基于<客户端-服务器>模型,在协议中主要有三种身份:发布者(Publisher)、服务器(Broker)以及订阅者(Subscriber)。其中,MQTT消息的发布者和订阅者都是客户端,服务器只是作为一个中转的存在,将发布者发布的消息进行转发给所有订阅该主题的订阅者;发布者可以发布在其权限之内的所有主题,并且消息发布者可以同时是订阅者,实现了生产者与消费者的脱耦,发布的消息可以同时被多个订阅者订阅。MQTT通信模型如图1所示。

图1    MQTT通信模型

 1.2  物联网服务平台的选择

        本系统着重对个人开发者相对友好以及对Arduino的支持情况两个方面考虑,最终选择然也物联作为物联网服务平台。然也物联平台可提供社区版MQTT服务,其为面向个人用户的免费MQTT服务。社区版MQTT服务中的用户个人主题和信息传输受到用户名和密码保护。即,A用户的个人主题只有A用户可以发布和订阅,其他人不能对该主题进行订阅和发布,为个人开发者提供了很好的安全保护。

        然也物联平台还提供相应的手机APP的接入方式,使得用户可以更多元化的管理自己的设备和传感器,随时了解设备动态。

1.2.1  注册物联网平台

        进入然也物联的官网:http://www.ranye-iot.net

        在首页点击物联平台后会进行页面跳转,然后往下滑就可以找到 社区版MQTT服务

        最近好像没得注册用户了... 进而无法进行平台申请...也无法使用社区版MQTT服务了...

         服务端连接基本信息

         客户端连接信息(共有8组)

         专属个人主题

         社区版服务有效期为一年,届时会有工作人员联系。

1.3  Web端或手机端远程控制和监测跟踪装置

        光伏跟踪装置的远程监测控制系统可由感知层、网络层以及应用层组成。

        第一层为感知层,由单片机、传感器模块和ESP8266 WiFi模块所组成,对环境进行数据采集和对执行机构的控制,通过WiFi模块将数据传输到网络层。

        第二层为网络层,主要包括路由器和服务器,网络层主要用于处理不同层之间的数据交互,感知层的数据通过网络层可以传递到应用层,应用层的下行命令可以通过网络层传递到感知层。感知层中监测到的数据经过ESP8266 WiFi模块,通过路由器接入互联网,将数据发送到然也物联平台搭建的MQTT服务器上。

        感知层的数据通过基于TCP的MQTT协议上传到1个PubTopic,并通过订阅SubTopic以接收下行命令,进行执行器的控制。

        第三层为应用层,主要包括Web端和移动端的数据显示、管理和控制,在Web端通过Node-Red进行数据的远程监控和对装置的控制,在移动端也可以通过APP进行实时监测环境数据和向感知层下发下行命令以控制装置的执行机构运动。

1.3.1  Node-RED设计      

        通过mqtt in节点配置连接的服务器 IP 地址,确定 mqtt 连接的 Topic 主题和Qos方式后,便可以连接到传输层,得到感知层的环境数据和执行器的状态,然后通过文本显示节点,便可以将上述数据显示文本窗口。

        要完成以上步骤,首先需要下载node.js才可进入node-red,接下来如何使用node-red可观看以下视频,重点学习如何使用MQTT进行通信。

【太极创客】零基础入门学用物联网 - MQTT应用篇 3-1-5 用电脑搭建物联网控制台(上)https://www.bilibili.com/video/BV1VR4y1n7nj/?spm_id_from=333.999.0.0&vd_source=b4d125df2ebf1ab26fbed06ba725ac39

         Web端监控页面如下图所示。

1.3.2  移动端设计     

        本系统在移动端的监测控制是通过然也物联提供的移动应用平台所设计而成。首先,配置所要连接的服务器的客户端ID、 IP 地址、端口号、网络协议、用户名和密码,然后确定 mqtt 连接的 Topic 主题和Qos方式后进入到功能设计页面;可设置文本显示框架,便可以将服务器数据显示到文本窗口,还可设置控制按钮,配置下行命令;这样便可以连接到传输层,得到感知层的环境数据和执行器的状态,或将下行命令通过传输层下达到感知层,控制执行机构运动。

         要完成以上步骤,需先下载然也物联的APP,可观看以下视频进行学习,重点学习如何使用MQTT进行通信,视频里也会教如何下载APP。

【太极创客】零基础入门学用物联网 - MQTT应用篇 3-1-4 手机应用控制ESP8266(下)https://www.bilibili.com/video/BV1QT4y1R7uf/?spm_id_from=333.999.0.0&vd_source=b4d125df2ebf1ab26fbed06ba725ac39

        移动端监控页面如下图所示。

1.3.3  远程监视设计

        设置ESP32-CAM为STA模式,即可通过路由器接入互联网。在浏览器中输入其生成的IP地址,即可在Web端或移动端看到由ESP32-CAM拍摄所上传的画面,这样便可实现远程监视效果。

        这部分在CSDN搜索都有很多教程。

        视频监视效果如下图所示。

1.3.4  代码实现

        代码后的注释能解释清楚每一句代码的作用。

        初始化设置

#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <string.h>

// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid     = "SunFlower";               // 请将您需要连接的WiFi名填入引号中                                           
const char* password = "88888888";                // 请将您需要连接的WiFi密码填入引号中
const char* mqttServer = "iot.ranye-iot.net";     //连接MQTT服务器,iot开头代表是社区版服务端的地址

//建立两对象
WiFiClient wifiClient;                            // 连接网络
PubSubClient mqttClient(wifiClient);              // MQTT通信用的
 
// ****************************************************
// 注意!以下需要用户根据然也物联平台信息进行修改!否则无法工作!
// ****************************************************
const char* mqttUserName = "UserName";          // 服务端连接用户名(需要修改)
const char* mqttPassword = "password";           // 服务端连接密码(需要修改)
const char* clientId = "UserName_1_id";           // 客户端id (需要修改)
const char* subTopic1 = "UserName/phone";         // 订阅主题(需要修改)
const char* subTopic2 = "UserName/web";           // 订阅主题(需要修改)
const char* pubTopic1 = "UserName/esp8266_1";     // 发布主题(需要修改)
const char* pubTopic2 = "UserName/esp8266_2";     // 发布主题(需要修改)
const char* pubTopic3 = "UserName/esp8266_3";     // 发布主题(需要修改)
const char* pubTopic4 = "UserName/esp8266_4";     // 发布主题(需要修改)
const char* willTopic = "UserName/led_yz";        // 遗嘱主题名称(需要修改)
// ****************************************************
 
//遗嘱相关信息
const char* willMsg = "esp8266 offline";        // 遗嘱主题信息
const int willQos = 0;                          // 遗嘱QoS
const int willRetain = false;                   // 遗嘱保留
 
const int subQoS = 1;            // 客户端订阅主题时使用的QoS级别(截止2020-10-07,仅支持QoS = 1,不支持QoS = 2)
const bool cleanSession = false; // 清除会话(如QoS>0必须要设为false)                                          

//***************************************************** 
const char* host = "api.seniverse.com";     // 将要连接的服务器地址  
const int httpPort = 80;                    // 将要连接的服务器端口      
 
// 心知天气HTTP请求所需信息
String reqUserKey = "************";   // 私钥
String reqLocation = "你的城市所在地";            // 城市
String reqUnit = "c";                      // 摄氏/华氏
//***************************************************** 

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

  //设置ESP8266工作模式为无线终端模式
  WiFi.mode(WIFI_STA);

  // 连接WiFi
  connectWiFi();

  // 设置MQTT服务器和端口号
  mqttClient.setServer(mqttServer, 1883);
  mqttClient.setCallback(receiveCallback);
 
  // 连接MQTT服务器
  connectMQTTserver();
}

        由于主函数中涵盖了自适应天气运行部分的代码,因此具体代码放在文末与自适应天气部分一起放上。

1.4  自适应天气运行控制策略

1.4.1  自适应天气运行的需求

        为实现系统避风、避雪,保护支架、组件,减少装置的受损概率,延长支架、组件的使用寿命,延长发电寿命,增加发电收益。本系统针对天气对光伏发电的影响为跟踪装置设计了自适应天气运行,即适应天气的变化使跟踪装置作出相应的调整,以最大化地提高发电效益,力求将天气对光伏发电所带来的影响降到最低。

1.4.2  自适应天气运行的设计原理

        ①本系统采用的是混合跟踪方式,光电跟踪方式在尤其是在阴雨或者多云天气时,很难与太阳光线对正,有些情况下还会出现误跟踪、丢跟踪和往反跟踪等现象,没办法保证跟踪精度;而视日轨迹跟踪方式的主要缺点在于运行时会产生累积误差,该误差不能自行消除,往往需要人为定期调整跟踪累积误差。

        综合分析考虑决定,在晴朗天气下,系统将采用光电跟踪方式;而在阴天或多云天气时,系统将采用视日轨迹跟踪方式。

        ②本系统中配置风速风向监测仪用于监测光伏支架安装环境中风速的大小、风的方向(当接收到与风相关的天气信息方启动风速风向检测仪,以降低系统整体能耗);如果测量的风速大于设定值时,MCU即驱动执行机构,使太阳能电池板的侧面迎风,正面避开风的正面,减少迎风面积,从而减少受风力,降低受损概率;同时可以驱动俯仰角转动,使得俯仰角变小,张力变小,机械受外力不易损坏。

        ③本系统配置雨滴传感器用于检测雨雪量(当接收到与雨雪相关的天气信息方启动雨滴传感器,以降低系统整体能耗);如果雨雪量大于设定值时,容易造成组件或支架受雨雪压力受损,MCU即可驱动执行机构转动,使得太阳能电池板正面和地面垂直或接近垂直,雨雪就不容易积压到太阳能电池板表面上,严寒地区安装的组件表面也不易结冰,减少雨雪对组件的腐蚀和压力;当雨量小于设定值时,系统将采用视日轨迹跟踪方式,此时较小的雨量并不容易对组件造成损害,相反,还可利用雨水冲刷掉光伏组件表面的污垢和灰尘,从而增加光照强度,提高光伏发电系统的输出功率。

1.4.3  天气信息平台的选择

        互联网上有很多天气信息平台,心知天气是信息最准确,服务最稳定的平台。更重要的是,心知天气所提供的基础服务是完全免费的,其免费的天气信息就包含3天的天气预报信息,实时天气以及生活指数。

1.3.4  自适应天气运行的设计方案

        ①对WiFi模块进行初始化设置,设置成STA模式,WiFi模块通过路由器/手机热点可连接互联网;建立“心知天气”API当前天气请求资源地址,通过互联网向“心知天气”服务器发送HTTP请求,并获取服务器返回的天气信息,从服务器响应中解析出天气代码(如图2所示)。

        ②设定特殊天气的转换程序,即将所需响应的天气情况所对应的天气代码转换为控制系统可识别的字符。此时WiFi模块同时作为上位机,与单片机进行串行通信,将可识别的天气字符传送给单片机。

图2    部分天气现象代码说明

        ③对单片机进行初始化设置,设计接收到不同的天气字符即运行不同的舵机驱动代码。当单片机接收到实时的天气信息后,配合雨滴传感器、风速风向传感器来确认天气信息属实后,才会驱动跟踪装置执行相应的动作。

        目前仅对四种天气情况进行了设置:

        晴天时,单片机将运行光电跟踪模式;

        阴天或多云时,单片机将运行视日轨迹跟踪模式,确保光伏板始终朝向太阳,以提供最佳的能量收集效果,最大限度地提高能量输出效率;

        雨天时,单片机将中断当前所执行的模式,转而驱动控制俯仰角的舵机将光伏电池板置于倾斜45°的状态,令雨水冲刷板面,以清理尘土、落叶等遮挡物, 从而减弱热斑效应,延长系统寿命。

        雪天时,单片机将中断当前所执行的模式,转而驱动控制俯仰角的舵机将光伏电池板置于垂直地面的状态,系统能够自动调整光伏板角度,使其正面和地面垂直或接近垂直,减少积雪对 组件的腐蚀和压力。

        自适应天气运行控制策略的流程图如图3所示。

图3    自适应天气运行控制策略的程序流程图

         补充:图中在执行雨雪天气时,漏了得先经过雨滴传感器的数据辅助判断当前天气情况是否属实这一步。

1.4.5  代码实现

        1、使用心知天气数据服务的准备工作

        ①注册心知天气账户

        打开心知天气网页:www.seniverse.com

         ②申请免费天气数据API服务

        完成注册后进行登录,然后从首页进入控制台页面(如下图所示)

         申请天气数据API免费版

         申请成功后可以在控制台中看到(如下图所示)

         点击该服务链接,进入天气数据API免费服务页面

        ③获取用户私钥、 

        点击私钥旁边的 闭合上的眼睛 即可查看自己的私钥信息 

        2、ESP8266获取并解析心知天气数据

        这里可以先使用“太极创客团队”的代码来实现 获取实时天气信息(温度、天气)

        要实现本系统的自适应天气运行功能,照搬太极创客的代码是行不通的。

#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
 
const char* ssid     = "taichimaker";       // 连接WiFi名(此处使用taichi-maker为示例)
                                            // 请将您需要连接的WiFi名填入引号中
const char* password = "12345678";          // 连接WiFi密码(此处使用12345678为示例)
                                            // 请将您需要连接的WiFi密码填入引号中
 
const char* host = "api.seniverse.com";     // 将要连接的服务器地址  
const int httpPort = 80;                    // 将要连接的服务器端口      
 
// 心知天气HTTP请求所需信息
String reqUserKey = "XXXXXXXXXXXXXXXXX";   // 私钥
String reqLocation = "Beijing";            // 城市
String reqUnit = "c";                      // 摄氏/华氏
 
void setup(){
  Serial.begin(9600);          
  Serial.println("");
  
  // 连接WiFi
  connectWiFi();
}
 
void loop(){
  // 建立心知天气API当前天气请求资源地址
  String reqRes = "/v3/weather/now.json?key=" + reqUserKey +
                  + "&location=" + reqLocation + 
                  "&language=en&unit=" +reqUnit;
 
  // 向心知天气服务器服务器请求信息并对信息进行解析
  httpRequest(reqRes);
  delay(3000);
}
 
// 向心知天气服务器服务器请求信息并对信息进行解析
void httpRequest(String reqRes){
  WiFiClient client;
 
  // 建立http请求信息
  String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" + 
                              "Host: " + host + "\r\n" + 
                              "Connection: close\r\n\r\n";
  Serial.println(""); 
  Serial.print("Connecting to "); Serial.print(host);
 
  // 尝试连接服务器
  if (client.connect(host, 80)){
    Serial.println(" Success!");
 
    // 向服务器发送http请求信息
    client.print(httpRequest);
    Serial.println("Sending request: ");
    Serial.println(httpRequest);  
 
    // 获取并显示服务器响应状态行 
    String status_response = client.readStringUntil('\n');
    Serial.print("status_response: ");
    Serial.println(status_response);
 
    // 使用find跳过HTTP响应头
    if (client.find("\r\n\r\n")) {
      Serial.println("Found Header End. Start Parsing.");
    }
    
    // 利用ArduinoJson库解析心知天气响应信息
    parseInfo(client); 
  } else {
    Serial.println(" connection failed!");
  }   
  //断开客户端与服务器连接工作
  client.stop(); 
}
 
// 连接WiFi
void connectWiFi(){
  WiFi.begin(ssid, password);                  // 启动网络连接
  Serial.print("Connecting to ");              // 串口监视器输出网络连接信息
  Serial.print(ssid); Serial.println(" ...");  // 告知用户NodeMCU正在尝试WiFi连接
  
  int i = 0;                                   // 这一段程序语句用于检查WiFi是否连接成功
  while (WiFi.status() != WL_CONNECTED) {      // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。 
    delay(1000);                               // 如果WiFi连接成功则返回值为WL_CONNECTED                       
    Serial.print(i++); Serial.print(' ');      // 此处通过While循环让NodeMCU每隔一秒钟检查一次WiFi.status()函数返回值
  }                                            // 同时NodeMCU将通过串口监视器输出连接时长读秒。
                                               // 这个读秒是通过变量i每隔一秒自加1来实现的。                                              
  Serial.println("");                          // WiFi连接成功后
  Serial.println("Connection established!");   // NodeMCU将通过串口监视器输出"连接成功"信息。
  Serial.print("IP address:    ");             // 同时还将输出NodeMCU的IP地址。这一功能是通过调用
  Serial.println(WiFi.localIP());              // WiFi.localIP()函数来实现的。该函数的返回值即NodeMCU的IP地址。  
}
 
// 利用ArduinoJson库解析心知天气响应信息
void parseInfo(WiFiClient client){
  const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 230;
  DynamicJsonDocument doc(capacity);
  
  deserializeJson(doc, client);
  
  JsonObject results_0 = doc["results"][0];
  
  JsonObject results_0_now = results_0["now"];
  const char* results_0_now_text = results_0_now["text"]; // "Sunny"
  const char* results_0_now_code = results_0_now["code"]; // "0"
  const char* results_0_now_temperature = results_0_now["temperature"]; // "32"
  
  const char* results_0_last_update = results_0["last_update"]; // "2020-06-02T14:40:00+08:00" 
 
  // 通过串口监视器显示以上信息
  String results_0_now_text_str = results_0_now["text"].as<String>(); 
  int results_0_now_code_int = results_0_now["code"].as<int>(); 
  int results_0_now_temperature_int = results_0_now["temperature"].as<int>(); 
  
  String results_0_last_update_str = results_0["last_update"].as<String>();   
 
  Serial.println(F("======Weahter Now======="));
  Serial.print(F("Weather Now: "));
  Serial.print(results_0_now_text_str);
  Serial.print(F(" "));
  Serial.println(results_0_now_code_int);
  Serial.print(F("Temperature: "));
  Serial.println(results_0_now_temperature_int);
  Serial.print(F("Last Update: "));
  Serial.println(results_0_last_update_str);
  Serial.println(F("========================"));
}

        3、自适应天气运行+远程监控代码

         代码后的注释能解释清楚每一句代码的作用。

void loop(){
//*****************************************************   
  // 建立心知天气API当前天气请求资源地址
  String reqRes = "/v3/weather/now.json?key=" + reqUserKey +
                  + "&location=" + reqLocation + 
                  "&language=en&unit=" +reqUnit;
 
  // 向心知天气服务器服务器请求信息并对信息进行解析
  httpRequest(reqRes);
//***************************************************** 

//***************************************************** 
  // 如果开发板未能成功连接服务器,则尝试连接服务器
  if (!mqttClient.connected()) {
    connectMQTTserver();
  }
 
  // 处理信息以及心跳
  mqttClient.loop();
//***************************************************** 
  char a[20] = ""; //定义字符数组,接受来自串口的数据
  char b;
  int i = 0;
  while (Serial.available()) //当发现缓存中有数据时,将数据送至字符数组a中
  {
    a[i] = Serial.read();   
    i++;
  }
  
  b = a[0];
  if (b == '1'){
    mqttClient.publish(pubTopic4, "YES"); //向Web端发送雨滴传感器的状态,有雨或无雨
    Serial.print('5');
  }else{
    mqttClient.publish(pubTopic4, "NO");
  }
  
  if(Serial.available() == 0){ 
    mqttClient.publish(pubTopic3, a);   //向Web端和移动端发送跟踪装置的俯仰角度和水平角度
  }

}
 
// 向心知天气服务器服务器请求信息并对信息进行解析
void httpRequest(String reqRes){
  WiFiClient client;
 
  // 建立http请求信息
  String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" + 
                              "Host: " + host + "\r\n" + 
                              "Connection: close\r\n\r\n";

  // 尝试连接服务器
  if (client.connect(host, 80)){
 
    // 向服务器发送http请求信息
    client.print(httpRequest);
 
    // 获取并显示服务器响应状态行 
    String status_response = client.readStringUntil('\n');
 
    // 使用find跳过HTTP响应头
    if (client.find("\r\n\r\n")) {
//      Serial.println("Found Header End. Start Parsing.");
    }
    
    // 利用ArduinoJson库解析心知天气响应信息
    parseInfo(client);
    delay(1000);
    
  } else {
//    Serial.println(" connection failed!");
  }   
  //断开客户端与服务器连接工作
  client.stop(); 
}
 
// 连接WiFi
void connectWiFi(){
  WiFi.begin(ssid, password);                  // 启动网络连接
  
  int i = 0;                                   // 这一段程序语句用于检查WiFi是否连接成功
  while (WiFi.status() != WL_CONNECTED) {      // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。 
  delay(1000);                                                  

  }                                            
  
}
 
// 利用ArduinoJson库解析心知天气响应信息
void parseInfo(WiFiClient client){
  const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2*JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 230;
  DynamicJsonDocument doc(capacity);
  
  deserializeJson(doc, client);
  
  JsonObject results_0 = doc["results"][0];
  
  JsonObject results_0_now = results_0["now"];
  const char* results_0_now_text = results_0_now["text"]; // "Sunny"
  const char* results_0_now_code = results_0_now["code"]; // "0"
  const char* results_0_now_temperature = results_0_now["temperature"]; // "32"
  
  const char* results_0_last_update = results_0["last_update"]; // "2020-06-02T14:40:00+08:00" 
 
  String results_0_now_text_str = results_0_now["text"].as<String>(); 
  int results_0_now_code_int = results_0_now["code"].as<int>(); 
  int results_0_now_temperature_int = results_0_now["temperature"].as<int>(); 
  
  String results_0_last_update_str = results_0["last_update"].as<String>();   
 
    mqttClient.publish(pubTopic2, results_0_now_text);//将天气情况发送到Web端,使其可显示当前天气情况
    
//转换成单片机可识别的天气状态字符,然后通过串口传给单片机
  if(results_0_now_code_int == 24 || results_0_now_code_int == 25)//雪天
  {
    Serial.print('3');
  }
  if(results_0_now_code_int == 13 || results_0_now_code_int == 14 || results_0_now_code_int == 15 || results_0_now_code_int == 16 || results_0_now_code_int == 17 || results_0_now_code_int == 18)//雨天
  {
    Serial.print('5');
  }
    if(results_0_now_code_int == 0)//晴天
  {
    Serial.print('0');
  }
  if(results_0_now_code_int == 4 || results_0_now_code_int == 5 || results_0_now_code_int == 6 || results_0_now_code_int == 7 || results_0_now_code_int == 8 || results_0_now_code_int == 9)//阴天
  {
    Serial.print('1');
  }    

//将天气情况发送到移动端,使其可显示当前天气情况
    char* pubMessage;
    pubMessage = "天气:";   
    if(mqttClient.publish(pubTopic1, results_0_now_text)){ 
       mqttClient.publish(pubTopic1, pubMessage);
    }
}

// 连接MQTT服务器并订阅信息
void connectMQTTserver(){
  // 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
  
 
  /* 连接MQTT服务器
  boolean connect(const char* id, const char* user, 
                  const char* pass, const char* willTopic, 
                  uint8_t willQos, boolean willRetain, 
                  const char* willMessage, boolean cleanSession); 
  若让设备在离线时仍然能够让qos1工作,则connect时的cleanSession需要设置为false                
                  */
  if (mqttClient.connect(clientId, mqttUserName, 
                         mqttPassword, willTopic, 
                         willQos, willRetain, willMsg, cleanSession)) {    
    
    subscribeTopic(); // 订阅指定主题
  } else {
    delay(5000);
  }   
}
 
// 收到信息后的回调函数。
void receiveCallback(char* topic, byte* payload, unsigned int length) {

  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);     // 订阅了Web端和移动端发布的主题,当收到这两端发布信息后,便会通过串口传给单片机
  }

}
 
// 订阅指定主题
void subscribeTopic(){

  mqttClient.subscribe(subTopic1, subQoS); 
  mqttClient.subscribe(subTopic2, subQoS);
  
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Dkkkkk20/article/details/132452233

智能推荐

使用Python爬虫抓取某网站电影Top250并保存为Excel文件_all_li item.find-程序员宅基地

文章浏览阅读1k次。本文将介绍如何使用Python编写爬虫程序抓取某网站top前100的电影名称,将会使用Python的requests和BeautifulSoup库,获取某网站网站上电影名等信息_all_li item.find

记一次带有FSG壳的熊猫烧香病毒分析过程_火绒剑定位函数-程序员宅基地

文章浏览阅读5.6k次,点赞6次,收藏9次。样本概况样本信息测试环境以及工具分析目标具体行为分析0利用查壳工具查看1.利用PChunter2.手工清理3.利用火绒剑进行主要行为分析恶意行为的一个简要小结4.脱壳病毒恶意行为分析(OD结合IDA双剑合璧)知识点扩展1:知识点扩展1小结:知识点扩展2知识点扩展3知识点扩展4(编辑函数标签:)知识点扩展5(有关seh链的:)知识点扩展6(Del..._火绒剑定位函数

【Java】重写compareTo()方法给对象数组排序-程序员宅基地

文章浏览阅读1.3k次,点赞3次,收藏7次。这里定义了一个Student数组,数组大小为4,也就是说数组中有4个学生,然后分别实例化了4个学生,把他们的名字年龄和成绩都输入了进去,现在我们想以年龄或成绩进行排序,那应该怎么实现呢,还是用Arrays.sort()方法吗?我们进入这个第二行报的错,显示源码中第320行报错:源码中这几段代码的意思是取到数组中的某个值,把这个值转化为了一个Comparable类型(这个Comparable是一个接口),然后调用一个compareTo()方法。当我们把这个数组进行排序时,报错了,报了一个类型转换异常。_重写compareto

matlab仿真gmid电路,bandgap电路稳定性仿真---频响、相位裕度、环路增益-程序员宅基地

文章浏览阅读3.8k次。仿真需要对原理图稍作修改,需在运放的闭环路径中加入iprobe元件,电路中存在两个反馈电路,一个正反馈(如图1组成路径)一个负反馈(如图2组成路径),两个反馈都经过了运放的输出端,故我这儿加在了输出端,可以同时仿真出两个反馈环路的频率响应。环路总的增益在59dB,比较小;相位裕度关系到电路的稳定性,一般要求大于45°或60°,最小接近0°,不能太小,由于工艺的原因会导致小于0°,引起电路不稳定,处..._仿真环路各处增益

Intellij IDEA 安装Python插件 + 创建Python项目(Hello World!)_idea python 插件下载-程序员宅基地

文章浏览阅读3.4w次,点赞10次,收藏44次。 一、IDEA 2018 Ultimate edition (旗舰破解版下载地址) 百度网盘地址:https://pan.baidu.com/s/1d9ArRH6adhDUGiJvRqnZMw 二、Python插件下载 (1)建议手动安装插件 IDEA Pyhton插件地址:http://plugins.jetbr..._idea python 插件下载

国标28181:libosip2&libeXosip2编译使用_osip exosip-程序员宅基地

文章浏览阅读1.8k次。前言对讲设备作为一种专业无线通信工具,能进行一对一,多对多的群组即时通信,在应急调度和突发事故处理中是其他通信工具所不能替代的,在城市治理、公安、运输等行业有广泛的应用。对讲机按照通信方式分模拟对讲、数字对讲和IP 对讲,严格的说IP对讲属于数字对讲的一部分,数字对讲能解决模拟对讲传输距离有限、易受干扰、保密性差的问题,数字对讲也可以通过运营商的网络进行远距离传输。通信端到端的最简模型可以抽象出4个部分,如下图:音视频采集模块:摄像头、麦克风音视频播放模块:显示屏、扬声器或耳机编解码模块:为了_osip exosip

随便推点

什么是泛型中的限定通配符和非限定通配符 ?-程序员宅基地

文章浏览阅读722次。限定通配符对类型进行了限制。有两种限定通配符:<? extends T>它通过确保类型必须是T及T的子类来设定类型的上界; <? super T>它通过确保类型必须是T及T的父类设定类型的下界;非限定通配符:类型为<T>,可以用任意类型来替代..._什么是泛型中的限定通配符和非限定通配符

图形推理_本题目考察的是图形的种类。 每一行都有 3 种不同的图形。-程序员宅基地

文章浏览阅读7.5k次,点赞3次,收藏11次。图形推理的两大灵魂是数量关系和图形的转动。牢牢把握住这两大灵魂就基本把握了图形推理题目。在这两大灵魂统帅下的十大基本规律,是做图形推理题的必胜工具。图形推理的两大灵魂:数量关系和图形的转动。1. 答案:B分析:方法一,从图形旋转的角度来分析这个题目。顺时针方向看,会发现黑色小方框在作顺时针旋转。具体的说,第一行三个图形中,黑色小方框在作顺时_本题目考察的是图形的种类。 每一行都有 3 种不同的图形。

maven下载安装配置3.5.2-程序员宅基地

文章浏览阅读6.6k次,点赞8次,收藏17次。下载maven点击下载解压放入随意的一个目录即可,这里我放在D盘下配置环境变量MAVEN_HOME:D:\apache-maven-3.5.2现在就开始setting.xml的配置。首先配置的第一步是本地仓库的配置,打开setting.xml,我一般配置在maven安装目录下。D:\apache-maven-3.5.2\repo配置好本地仓库后,下一步配置中央仓库阿里云AliMavenaliyun mavenhttp://maven.aliyun.com/nexus/co

SICK西克变频器编码器调试程序 Hiperface接口指令详解 (小黄人软件)485模式VC调零设置零位 增加读出和保存所有数据复制数据-程序员宅基地

文章浏览阅读1.9w次,点赞6次,收藏28次。一、软件下载地址二、支持的型号SinCos SKS36、SKM36、SKS36 外置型和SKM36 外置型:HIPERFACE 接口系列伺服反馈编码器等 比如SICK SRS50-HFA0-K21,SRM50-HZZ0-S21等。三、支持的系统windows 2003 / XP / win7 / win8 /win10及以上四、需要的硬件:USB转RS485线比如像...

【论文阅读】A Comprehensive Survey on Schema-based Event Extraction with Deep Learning-程序员宅基地

文章浏览阅读900次。【论文阅读】A Comprehensive Survey on Schema-based Event Extraction with Deep Learning_a comprehensive survey on schema-based event extraction with deep learning

HEVC代码阅读- -predIntraLumaAng函数_hevc predintralumaang-程序员宅基地

文章浏览阅读175次。predIntraLumaAng函数功能:执行具体的亮度预测过程,包括角度模式预测、Planar模式预测和DC滤波操作。Void TComPrediction::predIntraLumaAng(TComPattern* pcTComPattern, UInt uiDirMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, TComDataCU* pcCU, Bool bAbove, Bool bLeft ){ Pel ._hevc predintralumaang

推荐文章

热门文章

相关标签