ESP8266通过MQTT协议连接ONENET

  • 一、设计目标
  • 二、ONENET平台搭建
  • 三、硬件准备
  • 四、程序烧写
  • 五、ONENET平台控件配置




     本文将介绍通过MQTT协议连接ONENET,实现ESP8266与ONENET平台数据交互

一、设计目标

  1. 实现ESP8266通过MQTT协议连接ONENET
  2. 实现DHT11温湿度数据的获取,串口发送调试,并将数据上发ONENET平台,于平台控件中显示数据
  3. 实现ONENET平台对ESP8266板载LED亮灭的控制
  4. 实现可以通过WIFI_DEBUG选择是使用一键配网功能还是使用代码中写入的无线账号密码连接,该功能主要考虑程序的通用性

二、ONENET平台搭建

  1. 首先于ONENET平台注册账号,若已有账号直接登陆即可,登录后点击控制台
  2. esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_物联网

  3. 本次实验使用的是旧版本的平台,所以点击进入旧版
  4. esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_数据_02

  5. 进入控制台后点击多协议接入
  6. esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_数据_03

  7. 可以看到这个界面中有很多种协议,点击MQTT协议,然后点击添加产品,我的产品列表中已经有之前添加的一个产品了,新用户需要重新添加
  8. esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_单片机_04

  9. 产品信息中信息随意填写即可,联网方式选择wifi
  10. esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_数据_05

  11. 在产品概况中可以看到产品的ID和APIkey,记录下这两个数值,之后的代码需要用到
  12. esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_物联网_06

  13. 点击产品列表,按下添加设备,并输入设备名称和鉴权信息即可,最后按下添加
  14. esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_数据_07

  15. 添加设备成功后在设备列表中就可以看到产品的ID,这时候产品是还未在线的,记录下该设备的设备ID,之后代码需要用到
  16. esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_嵌入式_08

  17. 至此平台已经搭建完毕了,接下来需要进行硬件准备

三、硬件准备

  1. 如果使用ESP8266 NudoMCU等板载CH340等串口通信芯片的电路板,直接使用USB线连接电脑即可
  2. 如果使用的ESP8266电路板无板载串口通信芯片,则需要通过USB转TTL模块连接ESP8266

USB转TTL模块

ESP8266

VCC

VCC

GND

GND

TX

RX

RX

TX

  1. DHT11温湿度模块*1

四、程序烧写

  1. 完整代码
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <Ticker.h>
#include <dht11.h>

#define WIFI_DEBUG 1          //1:使用一键配网,其它值则使用默认无线账号密码
#define DHT11PIN 12           //设置DHT引脚为Pin 12
#define ONENET_DISCONNECTED 1 //已经断开
#define ONENET_CONNECTED 2    //已经连接上
#define ONENET_RECONNECT 3    //重连成功
#define VER  "ESP8266_MQTT_V1.0"  //版本号

const char* ssid = "********";//wifi账号
const char* password = "********";//wifi密码

/*OneNet*/
PubSubClient mqttClient;
const char* mqttServer = "183.230.40.39";//mqtt服务器
const uint16_t mqttPort = 6002;       //端口号
#define onenet_productId   "********" //产品ID
#define onenet_deviceId    "********" //设备ID
#define onenet_apiKey      "********" //API_KEY

int state;
Ticker delayTimer;
WiFiClient espClient;
dht11 DHT11;

/* 延时N秒 */
void delayNs(uint8_t m){
  for(uint8_t index = 0;index<m;index ++){
    delay(1000);
    ESP.wdtFeed();
  }
}


/* 延时重启 */
void delayRestart(float t) {
  Serial.print("Restart after ");
  Serial.print(t);
  Serial.println("s");
  delayTimer.attach(t, []() {
    Serial.println("\r\nRestart now!");
    ESP.restart();
  });
}

/* 自动连接 */
bool autoConfig()
{
  WiFi.begin();
  for (int i = 0; i < 20; i++)
  {
    if (WiFi.status() == WL_CONNECTED)
    {
      Serial.println("AutoConfig Success");
      Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str());
      Serial.printf("PSW:%s\r\n", WiFi.psk().c_str());
      WiFi.printDiag(Serial);
      return true;
    }
    else
    {
      Serial.print("AutoConfig Waiting......");
      Serial.println(WiFi.status());
      delay(1000);
    }
  }
  Serial.println("AutoConfig Faild!" );
  return false;
}

/* 一键配网 */
void smartConfig()
{
  WiFi.mode(WIFI_STA);
  Serial.println("\r\nWait for Smartconfig");
  WiFi.beginSmartConfig();
  while (1)
  {
    Serial.print(".");
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    if (WiFi.smartConfigDone())
    {
      Serial.println("SmartConfig Success");
      Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str());
      Serial.printf("PSW:%s\r\n", WiFi.psk().c_str());
      WiFi.setAutoConnect(true);  // 设置自动连接
      break;
    }
    delay(1000); // 这个地方一定要加延时,否则极易崩溃重启
  }
}

/* 连接OneNet */
int connectToOneNetMqtt(){
    int cnt = 0;
    while(!mqttClient.connected()){
       ESP.wdtFeed();
       cnt++;
       Serial.println("Connect to OneNet MQTT...");
       
       if (mqttClient.connect(onenet_deviceId,onenet_productId,onenet_apiKey)) {
             Serial.println("connect success!");
             return ONENET_RECONNECT;
        } else {
             Serial.print("connect fail!");
             Serial.println(" try again in 5 seconds");
             delayNs(5);
        }
        if(cnt >=10){
          //只做10次连接到OneNet,连接不上重启8266
          cnt = 0;
          delayRestart(1);
        }
    }
    return ONENET_CONNECTED;
}

/* 云端下发 */
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] == '1') {
    digitalWrite(LED_BUILTIN, LOW);
  } else {
    digitalWrite(LED_BUILTIN, HIGH);
  }
}

/* 发布温度信息 */
void Temp_pubMQTTmsg(uint32_t data){
   long lastMsg = 0;

   char msg[50];
   char tmp[28];
   char d[3];
   snprintf(tmp,sizeof(tmp),"{\"Temp\":%d}",data);
   uint16_t streamLen= strlen(tmp);

   d[0]='\x03';
   d[1] = (streamLen >> 8);
   d[2] = (streamLen & 0xFF);
   snprintf(msg,sizeof(msg),"%c%c%c%s",d[0],d[1],d[2],tmp);
   mqttClient.publish("$dp", (uint8_t*)msg,streamLen+3,false);
}
/* 发布湿度信息 */
void Humi_pubMQTTmsg(uint32_t data){
   long lastMsg = 0;

   char msg[50];
   char tmp[28];
   char d[3];
   snprintf(tmp,sizeof(tmp),"{\"Humi\":%d}",data);
   uint16_t streamLen= strlen(tmp);

   d[0]='\x03';
   d[1] = (streamLen >> 8);
   d[2] = (streamLen & 0xFF);
   snprintf(msg,sizeof(msg),"%c%c%c%s",d[0],d[1],d[2],tmp);
   mqttClient.publish("$dp", (uint8_t*)msg,streamLen+3,false);
}

/* 初始化系统 */
void initSystem(){
    int cnt = 0;
    Serial.begin (115200);
    Serial.println("\r\n\r\nStart ESP8266 MQTT");
    Serial.print("Firmware Version:");
    Serial.println(VER);
    Serial.print("SDK Version:");
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH);
    Serial.println(ESP.getSdkVersion());
 
    ESP.wdtEnable(5000);
   
    if(WIFI_DEBUG==1)//开启一键配网模式
    {
       if (!autoConfig())
      {
        Serial.println("Start smartConfig");
        smartConfig();
      }
    }
    else
    {
        WiFi.begin(ssid, password);
        while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        cnt++;
        Serial.print(".");
        if(cnt>=40){
          cnt = 0;
          //重启系统
          delayRestart(1);
        }
        }
    }
    Serial.print("WIFI Connect \r\n");
}

/* 初始化ONENET通信 */
void initOneNetMqtt(){
    mqttClient.setServer(mqttServer,mqttPort);
    mqttClient.setClient(espClient);
    mqttClient.setCallback(callback);
}

/* 初始化 */
void setup() {
  initSystem();
  initOneNetMqtt();
}

/* 主函数 */
void loop() {
  ESP.wdtFeed();
  DHT11.read(DHT11PIN);
  state = connectToOneNetMqtt();
  Serial.println(WiFi.status());
  if(state == ONENET_RECONNECT){
     mqttClient.loop();
  }
  else if(state == ONENET_CONNECTED){
     printf("temp:%d \r\n",DHT11.temperature);
     printf("humi:%d \r\n",DHT11.humidity);
     Temp_pubMQTTmsg(DHT11.temperature);
     Humi_pubMQTTmsg(DHT11.humidity);
     mqttClient.loop();
  }
  delay(2000);
}
  1. 打开Arduino IDE ,点击上传即可,如果提示缺少部分库文件,复制头文件名称至管理库中下载即可
  2. esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_数据_09

  3. 代码中需要修改的地方:产品ID,APIkey,设备ID按照之前记录的数值一一对应填入即可。DHT11引脚设置为自己使用的引脚。WIFI_DEBUG根据自己需求配置,如果想使用一键配网功能则将该值设置为1,如果使用在代码中写入账号密码的方式,则将WIFI_DEBUG的值改为0,并将代码中的无线账号密码改为自己的
//以下内容需进行修改
const char* ssid = "********";//wifi账号
const char* password = "********";//wifi密码
#define onenet_productId   "********" //产品ID
#define onenet_deviceId    "********" //设备ID
#define onenet_apiKey      "********" //API_KEY
  1. 如果使用一键配网模式,则使用乐鑫官网的ESP-TOUCH进行一键配网,注意目前一键配网仅支持2.4G无线网络,5G无线网络暂不支持
  2. 代码上传成功后,打开Arduino IDE的串口监视器可以看到整个系统的运行过程

esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_数据_10

  1. 打开ONENET平台,在设备列表中即可看到设备在线

esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_物联网_11

五、ONENET平台控件配置

  1. 点击应用管理便可以添加自己的应用,本次实验通过添加温湿度仪表,折线图和按键开关来实现数据交互
  2. esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_数据_12

  3. 点击对应的控件图标即可对数据流进行配置,选择对应的Temp和Humi即可在仪表和折线图中显示数据
  4. esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_嵌入式_13

  5. 选择按键开关,开关开值设置为1,开关关值设置为0
  6. esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_物联网_14

  7. 设置完毕后按下保存即可关闭该网页,返回至应用详情界面,即可看到之前设置的控件
  8. esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_单片机_15

  9. 若配置无误,表盘会显示温湿度数据,折线图会显示温湿度变化,通过开关可以控制ESP8266板载LED亮灭
  10. 通过设备云APP登陆ONENET账号可以实现和网页端一样的功能,进行数据监控和亮灭控制

esp8266如何通过指令连接onenet服务器 esp8266与onenet连接的步骤_物联网_16

      至此本文介绍的内容就都结束了,不足之处还望各位大佬不吝赐教!