Fun MQTT internet service ③ OneNET of things - the LED remote control (self-registration apparatus)

1. Theoretical basis

    Bo Bowen on the main line of reference:

  • Fun PubSubClient MQTT library
  • About Fun Things platform of OneNET
  • Fun Things OneNET platform of services ① MQTT
  • Fun Things OneNET platform of services ② MQTT

    In the previous post, bloggers mainly manually to create the device. The obvious disadvantage of this approach:

  • Artificial manual control, for developers extremely unfriendly;
  • If the number of devices a lot, are we going to manual operation is very many times;

    So, how to achieve self-registration equipment it? The so-called self-registration After connecting to the network device is automatically registered to OneNet cloud platform and device information acquisition device Id.

  • To distinguish the uniqueness, we use the combination of ESP-Mac address

2. Remote control LED, for device self-registration

2.1 Experimental Materials

  • ESP8266 NodeMcu
  • OneNet Mqtt debugging tools
  • OneNet platform

2.2 Experimental Procedure

2.2.1 Creating ESP8266 Intelligent Light System Product (MQTT agreement)

image

Notes :

  • Be sure to select MQTT agreement

    Once created, we click to view specific product information:

image

Notes :

  • You need to record product ID, which is a unique identifier used to distinguish products
  • Master-APIkey, network requests authentication information into the interface calls needed

2.2.2 NodeMcu programming code - MQTT terminal equipment

    In order to clearly distinguish the code function, Boge named project called P_OneNet_Exam04:

  • P_OneNet_Exam04.ino file:
/**
 *  功能:ESP8266 Mqtt客户端自注冊功能,订阅OneNet Mqtt工具发过来的控制Led消息
 *  作者:单片机菜鸟
 *  时间:2019-06-30
 *  描述:
 *      1.初始化工作:初始化网络配置,Mqtt客户端自注冊,连接鉴权,订阅主题
 *      2.订阅消息:获取发送过来的消息(json格式),解析消息,实现控制亮灭灯
*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <EEPROM.h>
#include <Ticker.h>
#include "H_project.h"

#define MAGIC_NUMBER 0xAA

int state;
WiFiClient espClient;

//声明方法
void initSystem();
void initOneNetMqtt();
void callback(char* topic, byte* payload, unsigned int length);
void saveConfig();
void loadConfig();
bool parseRegisterResponse();

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

void loop() {
  ESP.wdtFeed();
  state = connectToOneNetMqtt();
  if(state == ONENET_RECONNECT){
     //重连成功 需要重新注册
     mqttClient.subscribe(TOPIC,1);
     mqttClient.loop();
  }else if(state == ONENET_CONNECTED){
     mqttClient.loop();
  }
  delay(2000);
}

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:");
    Serial.println(ESP.getSdkVersion());
    wifi_station_set_auto_connect(0);//关闭自动连接
    ESP.wdtEnable(5000);
    WiFi.disconnect();
    delay(100);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
          delay(500);
          cnt++;
          Serial.print(".");
          if(cnt>=40){
            cnt = 0;
            //重启系统
            delayRestart(1);
          }
    }
    pinMode(LED_BUILTIN, OUTPUT);

    loadConfig();
    //还没有注册
    if(strcmp(config.deviceid,DEFAULT_ID) == 0){
        int tryAgain = 0;
        while(!registerDeviceToOneNet()){
          Serial.print(".");
          delay(500);
          tryAgain++;
          if(tryAgain == 5){
            //尝试5次
            tryAgain = 0;
            //重启系统
            delayRestart(1);
          }
        }
        if(!parseRegisterResponse()){
            //重启系统
            delayRestart(1);
            while(1);
        }
    }
}

void initOneNetMqtt(){
    mqttClient.setServer(mqttServer,mqttPort);
    mqttClient.setClient(espClient);
    mqttClient.setCallback(callback);

    initOneNet(PRODUCT_ID,API_KEY,config.deviceid);
}

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);
  }
}

/*
 * 保存参数到EEPROM
*/
void saveConfig()
{
  Serial.println("Save OneNet config!");
  Serial.print("deviceId:");
  Serial.println(config.deviceid);

  EEPROM.begin(150);
  uint8_t *p = (uint8_t*)(&config);
  for (int i = 0; i < sizeof(config); i++)
  {
    EEPROM.write(i, *(p + i));
  }
  EEPROM.commit();
}

/*
 * 从EEPROM加载参数
*/
void loadConfig()
{
  EEPROM.begin(150);
  uint8_t *p = (uint8_t*)(&config);
  for (int i = 0; i < sizeof(config); i++)
  {
    *(p + i) = EEPROM.read(i);
  }
  EEPROM.commit();
  if (config.magic != MAGIC_NUMBER)
  {
    strcpy(config.deviceid, DEFAULT_ID);
    config.magic = MAGIC_NUMBER;
    saveConfig();
    Serial.println("Restore config!");
  }
  Serial.println("-----Read config-----");
  Serial.print("deviceId:");
  Serial.println(config.deviceid);
  Serial.println("-------------------");
}

/**
 * 解析注册返回结果
 */
bool parseRegisterResponse(){
   Serial.println("start parseRegisterResponse");
   StaticJsonBuffer<200> jsonBuffer;
     // StaticJsonBuffer 在栈区分配内存   它也可以被 DynamicJsonBuffer(内存在堆区分配) 代替
     // DynamicJsonBuffer  jsonBuffer;
   JsonObject& root = jsonBuffer.parseObject(response);

     // Test if parsing succeeds.
   if (!root.success()) {
       Serial.println("parseObject() failed");
       return false;
   }

   int errno = root["errno"];
   if(errno !=0){
       Serial.println("register failed!");
       return false;
   }else{
       Serial.println("register sucess!");
       strcpy(config.deviceid, root["data"]["device_id"]);
       saveConfig();
       return true;
   }
}
  • H_project.h Code:
#ifndef _MAIN_H__
#define _MAIN_H__


extern "C" {
#include "user_interface.h"
#include "smartconfig.h"
}

struct onenet_config
{
  char deviceid[15];
  uint8_t magic;
};

/************** ESP8266相关操作 **************************/
void delayRestart(float t);
void delayNs(uint8_t m);
/*********************************************************/

/*************** OneNet MQTT相关操作 ****************************/
void initOneNet(uint8_t *productId,uint8_t *apiKey,uint8_t *deviceId);
int connectToOneNetMqtt();
/*********************************************************/

/**************** OneNet Http相关操作 ***************************/
HTTPClient http;
String response;
const char* host = "api.heclouds.com";
bool registerDeviceToOneNet();
/****************************************************************/

#define ONENET_DISCONNECTED 1 //已经断开
#define ONENET_CONNECTED 2    //已经连接上
#define ONENET_RECONNECT 3    //重连成功

//常量
#define VER             "MQTT_LED_V1.0"
const char* ssid = "xxxxxxxx";//wifi账号
const char* password = "xxxxxxx";//wifi秘密

//OneNet相关
PubSubClient mqttClient;
const char* mqttServer = "183.230.40.39";//mqtt服务器
const uint16_t mqttPort = 6002;
#define PRODUCT_ID    "253190" //此为博哥自己的产品id 请新建自己的
#define API_KEY    "aat9ivuJls3gcAFWnLoxfbwW8bI="
#define DEFAULT_ID "123456"
#define TOPIC     "esp8266led"

unsigned long lastWiFiCheckTick = 0;
bool ledState = 0;

onenet_config config;

#endif

    All project code, Boge on personal QQ group.

image

Notes :

  • Here used JSON, please refer to the online Boge Bowen Fun ArduinoJson library V5 version ;
  • We used here to ESP8266 HttpClient encapsulated Http request;

    The works were burned into multiple NodeMcu (Boge burn the two here), then you can see the serial print content, as follows:

image

image

image

    Also, you can see the device in case OneNet platform, as follows:

    Then you can remotely control led by mqtt debugging tools.

3. Summary

On the basis of the agreement on the understanding MQTT herein, this is very easy to operate, but it also points to note:

  • Create your own OneNet products, do not create a Boge
  • Subscribe to understanding the meaning of the theme, try to use api interfaces onenet provided.

Guess you like

Origin www.cnblogs.com/danpianjicainiao/p/11111955.html