玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(设备自注册)+ Android App控制

授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石。。。

QQ技术互动交流群:ESP8266&32 物联网开发 群号622368884,不喜勿喷

一、你如果想学基于Arduino的ESP8266开发技术

一、基础篇

  1. ESP8266开发之旅 基础篇① 走进ESP8266的世界
  2. ESP8266开发之旅 基础篇② 如何安装ESP8266的Arduino开发环境
  3. ESP8266开发之旅 基础篇③ ESP8266与Arduino的开发说明
  4. ESP8266开发之旅 基础篇④ ESP8266与EEPROM
  5. ESP8266开发之旅 基础篇⑤ ESP8266 SPI通信和I2C通信
  6. ESP8266开发之旅 基础篇⑥ Ticker——ESP8266定时库

二、网络篇

  1. ESP8266开发之旅 网络篇① 认识一下Arduino Core For ESP8266
  2. ESP8266开发之旅 网络篇② ESP8266 工作模式与ESP8266WiFi库
  3. ESP8266开发之旅 网络篇③ Soft-AP——ESP8266WiFiAP库的使用
  4. ESP8266开发之旅 网络篇④ Station——ESP8266WiFiSTA库的使用
  5. ESP8266开发之旅 网络篇⑤ Scan WiFi——ESP8266WiFiScan库的使用
  6. ESP8266开发之旅 网络篇⑥ ESP8266WiFiGeneric——基础库
  7. ESP8266开发之旅 网络篇⑦ TCP Server & TCP Client
  8. ESP8266开发之旅 网络篇⑧ SmartConfig——一键配网
  9. ESP8266开发之旅 网络篇⑨ HttpClient——ESP8266HTTPClient库的使用
  10. ESP8266开发之旅 网络篇⑩ UDP服务
  11. ESP8266开发之旅 网络篇? WebServer——ESP8266WebServer库的使用
  12. ESP8266开发之旅 网络篇? 域名服务——ESP8266mDNS库
  13. ESP8266开发之旅 网络篇? SPIFFS——ESP8266 Flash文件系统
  14. ESP8266开发之旅 网络篇? web配网
  15. ESP8266开发之旅 网络篇? 真正的域名服务——DNSServer
  16. ESP8266开发之旅 网络篇? 无线更新——OTA固件更新

三、应用篇

  1. ESP8266开发之旅 应用篇① 局域网应用 ——炫酷RGB彩灯
  2. ESP8266开发之旅 应用篇② OLED显示天气屏
  3. ESP8266开发之旅 应用篇③ 简易版WiFi小车

四、高级篇

  1. ESP8266开发之旅 进阶篇① 代码优化 —— ESP8266内存管理
  2. ESP8266开发之旅 进阶篇② 闲聊Arduino IDE For ESP8266配置
  3. ESP8266开发之旅 进阶篇③ 闲聊 ESP8266 Flash
  4. ESP8266开发之旅 进阶篇④ 常见问题 —— 解决困扰
  5. ESP8266开发之旅 进阶篇⑤ 代码规范 —— 像写文章一样优美
  6. ESP8266开发之旅 进阶篇⑥ ESP-specific APIs说明

1.理论基础

????参考博主线上博文:

????在前面的博文中,博主主要通过手动方式去创建设备。这种方式的缺点明显:

  • 人为手动控制,对于开发者来说极度不友好;
  • 如果设备数量很多,岂不是要手动操作非常多次;

????那么,如何实现设备自注册呢?所谓自注册就是设备连入网络后自动往OneNet云平台注册设备信息并获取设备Id。

  • 为了区分唯一性,我们采用ESP-Mac地址的组合形式
  • 同时为了操作方便,博主花了个周末的时间做了一个对应的app,理论上不限制ESP8266接入点的数量

????本篇博文的目的就在于教会大家如何和app通信,完成MQTT协议下的App远程控制LED灯,并且LED灯的数量可以随意接入,用户可以在app端修改设备名字以便方便操作。

  • 博主极度建议大家从第一篇看起,有个大概了解,因为本系列教程都是有相联系的

????先上个概念图:

2.远程控制LED,实现设备自注册

2.1 实验材料

  • ESP8266 NodeMcu
  • Android手机
  • OneNet平台

2.2 实验步骤

2.2.1 创建 ESP8266智能灯系统 产品(MQTT协议)

注意点

  • 务必选择MQTT协议

????创建完毕后,我们点击查看具体的产品信息:

注意点

  • 需要记录产品ID,其用来区分产品唯一标识符,这个ID待会需要填入App
  • Master-APIkey,网络请求鉴权信息,接口调用需要带入,这个ID待会需要填入App

2.2.2 NodeMcu烧录代码 —— MQTT设备端

????为了明确区分代码功能,博哥命名工程名为P_OneNet_Exam05:

  • P_OneNet_Exam05.ino文件:
/**
 *  功能:ESP8266 Mqtt客户端自注冊功能,通过配套App控制Led消息,理论上可以接入无数个esp8266
 *  作者:单片机菜鸟
 *  时间:2019-10-27
 *  描述:
 *      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 parseOneNetMqttResponse(char* payload);

/**
 * 初始化
 */
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();
  parseOneNetMqttResponse((char *)payload);
}

/*
 * 保存参数到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("-------------------");
}

/**
 * 解析mqtt数据
 */
void parseOneNetMqttResponse(char* payload){
   Serial.println("start parseOneNetMqttResponse");
   StaticJsonBuffer<100> jsonBuffer;
     // StaticJsonBuffer 在栈区分配内存   它也可以被 DynamicJsonBuffer(内存在堆区分配) 代替
     // DynamicJsonBuffer  jsonBuffer;
   JsonObject& root = jsonBuffer.parseObject(payload);

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

   String deviceId = root["Did"];
   int status = root["sta"];

   if(strcmp(config.deviceid,deviceId.c_str()) == 0){
        if (status == 1) {
            digitalWrite(LED_BUILTIN, LOW);
        } else {
            digitalWrite(LED_BUILTIN, HIGH);
        }
    }
}

/**
 * 解析注册返回结果
 */
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 代码:
#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    "xxxxxx"
#define DEFAULT_ID "123456"
#define TOPIC     "esp8266led"

unsigned long lastWiFiCheckTick = 0;
bool ledState = 0;

onenet_config config;

#endif

????全部工程代码,博哥放在个人QQ群里或者 代码下载地址

注意点

  • 这里用到了JSON,请参考博哥上线博文 玩转ArduinoJson库 V5版本
  • 我们这里使用到了ESP8266 HttpClient来封装Http请求;

????将工程分别烧进多个NodeMcu(博哥这里烧录了两个),然后可以看到串口打印内容,如下:

????同时,也可以在OneNet平台看到设备情况,如下:

????接下来就可以通过App进行远程控制led了。

3.配套android App

3.1 下载App

  • 博主把App放在了个人交流群上以及Github
  • App源码暂不开源,博主也上传到了个人交流群

3.2 配置App

  • 手机App作为一个特殊的设备,需要自行注册一个新的设备,然后填入deviceId,至于如何注册设备,请参考 之前的博文。

3.3 操作App

  • 主页面可以看到当前所有的设备列表(也就是你自注册的所有智能灯),并且标明了设备状态,然后我们就可以远程控制开关灯。

3.4 实验效果



4.总结

需要注意几点:

  • 创建自己的OneNet产品,不要用博哥创建的,不然很容易发生MQTT重连的现象
  • 理论上设备接入数是无限制的,基本上能满足普通需求。

原文地址:https://www.cnblogs.com/danpianjicainiao/p/11751729.html

时间: 2024-11-07 11:11:25

玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(设备自注册)+ Android App控制的相关文章

HelloX操作系统与中国移动OneNET物联网平台成功完成对接

HelloX成功与中国移动物联网平台对接 经过HelloX项目组同仁的努力,尤其是Tywin(@飓风)的努力下,HelloX最新版本V1.78已成功与中国移动OneNET(open.iot.10086.cn)物联网平台完成对接.这标志着HelloX操作系统又向物联网领域的应用迈出了一大步. OneNET平台是中国移动物联网公司推出的专门针对物联网设备提供服务的云平台,只要遵循OneNET的接入协议,任何终端都可以与OneNET通过Internet进行对接.目前,OneNET平台支持RestFul

ESA2GJK1DH1K基础篇: 阿里云物联网平台: 测试MQTT连接阿里云物联网平台

前言 这节看一下在阿里云上实现MQTT通信是个怎样的流程 其实我很长时间都没有出怎么连接现成的物联网平台的教程, 一直写的是教给大家自己搭建服务器,主要原因是因为我感觉连接现有的学不到东西. 现在出这种教程,是因为发现确实很多人喜欢用. 但是大家看看吧!连接现有的十分的简单 其实我不明白的是:网上到处都是这种的教程!!!!而且价格定的高,就好像多么的高大上一样...... 搜索物联网平台(如果没有开通自行开通) 创建产品 注意:看看自己的这里是那个区域的,后面会用到 现在我就需要知道设备怎么连接

ESA2GJK1DH1K基础篇: 测试MQTT连接OneNet物联网平台

前言 多协议接入 添加产品 原文地址:https://www.cnblogs.com/yangfengwu/p/11842577.html

ESA2GJK1DH1K基础篇: 阿里云物联网平台: 测试MQTT客户端接收云平台的数据

前言 有时候想想可能直接连接现成的感觉比较方便吧! 但是实际上如果你做多了会发现,限制住了很多. 当然,适合个人玩家. 所以很多人去连接现成的.不愿意自己去搭建, 测这节会感觉:这是啥呀...下一节更精彩,但是必须看这节 测这节会感觉:这是啥呀...下一节更精彩,但是必须看这节 测这节会感觉:这是啥呀...下一节更精彩,但是必须看这节 测试1 1.选择设备 ---- 查看 2.Topic ---- 查看 下面是说咱可以订阅那几个主题 咱先看订阅:  /a1m7er1nJbQ/Mqtt/user/

QT采用MQTT协议远程控制LED灯

测试环境: mqtt_client(Publish) QT 5.6.0 win10 mqtt_client(Subscribe) ubuntu 12.04 mqtt_broker mosquitto ubuntu 12.0.4 开发QT程序使用了QMQTT library 下载地址 效果: QT Client代码: mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include &qu

【华为云技术分享】基于小熊派STM32芯片的通过MQTT上报JSON数据到华为物联网平台的自动售货机Demo解析

[摘要] STM32的工程在文章末尾,可自行下载. 一.工程配置 1.MCU类型选择STM32L431RC 2.烧录器选择OpenOCD,参数 -f interface/stlink-v2-1.cfg -f target/stm32l4x.cfg 3.输出目录选择 LiteOS_Lab_STM32\targets\STM32L431_BearPi\GCC\appbuild 4.编译器Makefile选择 targets\STM32L431_BearPi\GCC\Makefile 5.平台参数配置

物联网全景动态图谱2.0|PaaS物联网平台汇总(上篇)

物联网智库 原创 物联网智库 整理发布 转载请注明来源和出处 ------   [导读]   ------ 毫无疑问,2018年物联网对行业的深度变革才刚刚开启. 物联网产业链企业的质与量将进入全面爆发期.物联网智库作为业内的全周期观察者和信息服务聚焦者,被产业推动,亦将反哺于产业升级.自2016年起,物联网智库每年一度推出<全国物联网产业全景图谱>,为从业者提供物联网全视角跟踪和分析,切实践行物联网业内的信息对称化. 然而,随着物联网产业狂奔式升级,一年一度的全景图谱发布,已远远满足不了高歌

10.1 阿里云物联网平台介绍

阿里云物联网平台是阿里巴巴公司推出的专业物联网服务平台,其提供的详尽的文档和清晰的管理界面非常适合刚刚接触物联网平台的初学者,对物联网系统架构.管理等有一个整体上的把握. 阿里云物联网平台文档 阿里云物联网管理平台可视化界面 (需要注册阿里云账户后才能使用) 基于阿里云物联网平台的物联网系统架构 基于阿里云物联网平台的物联网系统架构图如上图所示,整个系统可大致分为4层架构: 边缘设备:物联网系统中的数据生产者,通常为传感器,一般认为没有计算能力. 边缘节点:边缘节点对下收集边缘设备产生的数据,对

国内物联网平台初探(八):中移物联网开放平台OneNet

平台定位 OneNET是中移物联网有限公司搭建的开放.共赢设备云平台,为各种跨平台物联网应用.行业解决方案,提供简便的云端接入.存储.计算和展现,快速打造物联网产品应用,降低开发成本. IoT PaaS基础能力:提供智能设备自助开发工具.后台技术支持服务.物联网专网.短彩信.位置定位.设备管理.消息分发.远程升级等基础服务 SaaS业务服务:提供第三方应用开发平台,快速实现不同业务需求,借助轻应用孵化器快速搭建Web和APP应用 IoT数据云:提供高扩展的数据库.实时数据处理.智能预测离线数据分