查看: 846|回复: 5

ESP8266+Onenet平台远程数据传输和控制

[复制链接]

签到天数: 12 天

[LV.3]偶尔看看II

发表于 2021-2-5 16:00 | 显示全部楼层 |阅读模式
这是我的第一个diy,主要功能实现了onenet云平台温湿度数据的传输和远程控制LED灯平台页面

效果图

效果图

硬件图

代码:

  1. #include <ESP8266WiFi.h>                         //esp8266wifi模块库
  2. #include <ESP8266WiFiMulti.h>                    //自动链接最强wifi库
  3. #include <DNSServer.h>                           //WiFiManager库要用的
  4. #include <PubSubClient.h>                        //MQTT协议中的库
  5. #include <Ticker.h>                              //时间记录库
  6. #include <ArduinoJson.h>                         //调用Json数据库
  7. #include <Wire.h>
  8. #include <WiFiManager.h>                         //WiFiManager库
  9. #include "DHTesp.h"                              //温度DHT11模块函数库
  10. #include "FastLED.h"                             //FastLED库用于调用随机函数库
  11. #include <stdlib.h>                              //接收数据的转化
  12. #include <stdio.h>

  13. #define PRODUCT_ID "400740"                      //Onenote产品名(需修改)
  14. #define API_KEY    "CDglbagwPMllUURDk9mO=qKTozU="//产品密钥(需修改)
  15. #define DEVICE_ID  "675088576"                   //设备名(需修改),与开发板没有关系,由平台生成的
  16. const char* mqttServer = "183.230.40.39";        //onenet地址(不修改)
  17. const uint16_t mqttPort = 6002;                  //mqtt接口端口(不修改)
  18. #define TOPIC      "ceshitopic1"                 //订阅主题

  19. #define LED1 D5
  20. #define LED2 D2

  21. ESP8266WiFiMulti wifiMulti;                      //自动链接wifi
  22. DHTesp dht;                                      //温度
  23. WiFiClient wifiClient;                           //
  24. PubSubClient mqttClient(wifiClient);             //
  25. Ticker ticker;                                   //用于记录时间

  26. int count=0,aa =0,bt=0;                               //定义参数变量
  27. char msgJson[120];//msgJson数据长度
  28. char msg_buf[200];//
  29. char dataTemplate[] = "{"temp":%.2f,"hum":%.2f,"rand":%d,"sin":%.2f,"butt":%d}"; //信息模板,(需修改)
  30. extern float temperature = 0.0, humidity = 0.0, bb=0;                                       

  31. void setup() {                                  //里面的函数只执行一次
  32.   Serial.begin(115200);
  33.   wifiMulti.addAP("CMCC-PbWq","9bf07201");//添加多个wifi网络
  34.   wifiMulti.addAP("FAST_602","dff@9410");
  35.   wifiMulti.addAP("esp8266","esp82661");
  36.         
  37.   pinMode(LED_BUILTIN, OUTPUT);                 //设置板上LED引脚为输出模式
  38.   pinMode(LED2, OUTPUT);                        //设置板上LED引脚为输出模式
  39.   WiFi.mode(WIFI_STA);                          //设置wifi模式
  40.   dht.setup(D4, DHTesp::DHT11);                 //温湿度模块DHT11初始化,D4脚位
  41.   connectWifi();                                //链接Wifi函数
  42.   mqttClient.setServer(mqttServer, mqttPort);   //mqttServer是onenet地址,mqtt接口端口mqttPort
  43.   mqttClient.setCallback(receiveCallback);      //设置MQTT订阅回调函数
  44.   connectMQTTServer();                          //链接MQTT服务器函数
  45.   ticker.attach(1, tickerCount);  
  46. }

  47. void loop() {                                   //里面的函数无限循环执行
  48.   if (mqttClient.connected()) {                 //如果开发板成功连接服务器   
  49.     // tickerCount();
  50.     if (count == 1){                            //每隔1秒钟发布一次信息
  51.       pubMQTTmsg();                             //调用pubMQTTmsg()函数发送数据到云端
  52.       count = 0;
  53.     }
  54.     mqttClient.loop();
  55.   } else {                                      //如果开发板未能成功连接服务器
  56.     connectMQTTServer();                        //则尝试连接服务器
  57.   }
  58. }

  59. int tickerCount() {
  60.   count++;
  61. }
  62. void connectMQTTServer() {                     //通过MQTT协议链接Onenet
  63.   String clientId = DEVICE_ID;
  64.   String productId = PRODUCT_ID;
  65.   String apiKey = API_KEY;
  66.   if (mqttClient.connect(clientId.c_str(), productId.c_str(), apiKey.c_str())) {//连接MQTT服务器
  67.     Serial.println("MQTT Server Connected.");
  68.     Serial.println("Server Address: ");
  69.     Serial.println(mqttServer);
  70.     Serial.println("ClientId:");
  71.     Serial.println(clientId);
  72.     subscribeTopic();                          //订阅指定主题
  73.   } else {
  74.     Serial.print("MQTT Server Connect Failed. Client State:");
  75.     Serial.println(mqttClient.state());
  76.     delay(3000);
  77.   }
  78. }
  79.                                                
  80. void subscribeTopic() {//订阅指定主题,主题名称以Taichi-Maker-Sub为前缀,后面添加设备的MAC地址
  81.   String topicString = "temperature"+ WiFi.macAddress();
  82.   char subTopic[topicString.length() + 1];
  83.   strcpy(subTopic, topicString.c_str());       //                                                
  84.   if (mqttClient.subscribe(subTopic)){         //通过串口监视器输出是否成功订阅主题以及订阅的主题名称
  85.     Serial.println("Subscrib Topic:");
  86.     Serial.println(subTopic);
  87.   } else {
  88.     Serial.print("Subscribe Fail...");
  89.   }
  90. }

  91. void receiveCallback(char* topic, byte* payload, unsigned int length) {//反调函数用于接收平台下发的消息
  92.   Serial.print("Message Received [");
  93.   Serial.print(topic);
  94.   Serial.print("]");               
  95.   for (int i = 0; i < length; i++){  //按字符一个一个输出
  96.     Serial.print((char)payload[i]);
  97.   }
  98.   Serial.println("");
  99.   Serial.print("Message Length(Bytes)");
  100.   Serial.println(length);
  101.   payload[length] = '\0'; // 添加一个空值使其转化为字符数组
  102.   String payload1=(char *)payload;
  103.   int aNumber = atoi((char *)payload);//将字符数组转化为整型数组
  104.   analogWrite(LED2, aNumber);  
  105.   if (payload1 == "21"){//测试下发数据,如果收到的信息以“1”为开始
  106.     digitalWrite(LED2, HIGH);  // 点亮LED。
  107.     Serial.println("LED ON");
  108.   } else if (payload1 == "20"){
  109.     digitalWrite(LED2, LOW);  //熄灭LED。
  110.     Serial.println("LED OFF");
  111.   }   
  112. }                                                                 
  113.                                                                            
  114. void pubMQTTmsg() {                              //onenet数据点上传系统主题
  115.   String topicString = "$dp";
  116.   char publishTopic[topicString.length() + 1];
  117.   strcpy(publishTopic, topicString.c_str());     //c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同,json数据转换为数组
  118.   temperature = dht.getTemperature(), humidity = dht.getHumidity();//获取温湿度数据
  119.   aa=random8();bb=bb+0.1;                        //人为制造变量
  120.   double sine = sin(bb);
  121.   snprintf(msgJson, 65, dataTemplate, temperature, humidity, aa, sine, bt);//将模拟温湿度数据套入dataTemplate模板中, 生成的字符串传给msgJson
  122.   int json_len = strlen(msgJson);                //msgJson的长度
  123.   msg_buf[0] = char(0x03);                       //要发送的数据必须按照ONENET的要求发送, 根据要求,数据第一位是3
  124.   msg_buf[1] = char(json_len >> 8);              //数据第二位是要发送的数据长度的高八位
  125.   msg_buf[2] = char(json_len & 0xff);            //数据第三位是要发送数据的长度的低八位
  126.   memcpy(msg_buf + 3, msgJson, strlen(msgJson)); //从msg_buf的第四位开始,放入要传的数据msgJson
  127.   msg_buf[3 + strlen(msgJson)] = 0;              //添加一个0作为最后一位, 这样要发送的msg_buf准备好了
  128.   Serial.print("public message:");Serial.println(msgJson);//向串口发送订阅信息
  129.   mqttClient.publish("$dp", (uint8_t *)msg_buf, 3 + strlen(msgJson)); //发送数据到主题$dp
  130.   Serial.println(strlen(msgJson));
  131. }

  132. void connectWifi() {                              //wifi连接函数  
  133.   Serial.print("Connecting...");
  134.   WiFiManager wifiManager;// 建立WiFiManager对象
  135.   //wifiManager.resetSettings();// 清除ESP8266所存储的WiFi连接信息以便测试WiFiManager工作效果
  136.   wifiManager.autoConnect("AutoConnectAP");// 自动连接WiFi。以下语句的参数是连接ESP8266时的WiFi名称  
  137.   int ii=0;  
  138.   while (wifiMulti.run() != WL_CONNECTED) {         //等待WiFi连接,成功连接后输出成功信息
  139.   delay(1000);
  140.   Serial.print("ii++");Serial.print(" ");
  141.   }
  142.   Serial.println('\n');                     // WiFi连接成功后
  143.   Serial.print("Connected to ");            // NodeMCU将通过串口监视器输出。
  144.   Serial.println(WiFi.SSID());              // 连接的WiFI名称
  145.   Serial.print("IP address:\t");            // 以及IP
  146.   Serial.println(WiFi.localIP());           // NodeMCU的IP地址  
  147. }
复制代码




该用户从未签到

发表于 2021-2-5 18:28 | 显示全部楼层
代码太长 可以考虑分一个文件抽离出来

签到天数: 12 天

[LV.3]偶尔看看II

 楼主| 发表于 2021-2-5 18:44 | 显示全部楼层
单片机菜鸟 发表于 2021-2-5 18:28
代码太长 可以考虑分一个文件抽离出来

第一次搞没经验,下次一定

签到天数: 12 天

[LV.3]偶尔看看II

 楼主| 发表于 2021-3-18 11:21 | 显示全部楼层
代码中Json数据格式编译时有问题,修改如下
char dataTemplate[] = "{\"temp\":%.2f,\"hum\":%.2f,\"rand\":%d,\"sin\":%.2f,\"butt\":%2d}";

该用户从未签到

发表于 2021-4-17 23:02 | 显示全部楼层
楼主,我想问一下 你这个是怎么连接手机热点呢?就是怎么联网呢

签到天数: 12 天

[LV.3]偶尔看看II

 楼主| 发表于 2021-4-26 15:51 | 显示全部楼层
开手机热点,输入热点名称和密码就行
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

arduino程序设计基础 blinker物联网解决方案

热门推荐

【分享】esp8266/32 炫彩LED氛围灯
【分享】esp8266/32 炫彩L
[md]# esp8266/32 炫彩LED氛围灯 - 作者:pengqiangsheng - 说明:基于太极创客智能
ESP32-CAM 推流直播【分享】
ESP32-CAM 推流直播【分享
# ESP32-CAM 推流直播 > 使用esp32-cam进行实时录像,然后通过obs推流到虎牙直播。
DS18B20温度传感器,资料分享
DS18B20温度传感器,资料
DS18B20温度传感器,需要资料的可以留下联系方式。
【分享】esp8266/32 网站快速生成器脚手架和mqtt web客户端
【分享】esp8266/32 网站
一、mqtt web客户端 先来分享一下mqtt web客户端吧: 下载后就解压里面有两个文件:
教你让OLED动起来!多重字符串版!
教你让OLED动起来!多重字
大家都知道:arduino单片机是单线程的 而上次教程中的多段字符串的运行速度必须一致
Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
快速回复 返回顶部 返回列表