android+app+wifi+控制+协议,玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(数量无限制)+ Android App控制...
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。但愿你们分享给你周边须要的朋友或者同窗,说不定大神成长之路有博哥的奠定石。。。android
若是以为有用,麻烦点赞收藏,您的支持是博主创做的动力。github
1.理论基础
参考博主线上博文:web
在前面的博文中,博主主要经过手动方式去建立设备。这种方式的缺点明显:json
人为手动控制,对于开发者来讲极度不友好;
若是设备数量不少,岂不是要手动操做很是屡次;
那么,如何实现设备自注册呢?所谓自注册就是设备连入网络后自动往OneNet云平台注册设备信息并获取设备Id。api
为了区分惟一性,咱们采用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协议)
注意点:app
务必选择MQTT协议
建立完毕后,咱们点击查看具体的产品信息:svg
注意点:
须要记录产品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
#include
#include
#include
#include
#include
#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,请参考博哥上线博文
咱们这里使用到了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重连的现象
android+app+wifi+控制+协议,玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(数量无限制)+ Android App控制...相关推荐
- 玩转OneNET物联网平台之简介
❤️博主介绍❤️
- OneNET物联网平台08 MQTT产品设备发送消息到消息队列MQ
一.消息生产 设备终端接入OneNET平台不同的产品套件,上传设备消息至OneNET平台: 开通消息队列MQ服务,创建消息队列MQ实例,添加topic和sub: 选择不同的 数据源 配置规则引擎和消息 ...
- java实现mqtt服务端_基于Swoole使用MQTT协议连接阿里云物联网平台设备实现消息订阅
阿里云物联网平台为设备提供安全可靠的连接通信能力,支撑设备数据采集上云,我们这里认为阿里云物联网平台是 MQTT 服务端,那么我们自己的设备作为客户端,应该如何实现消息订阅? 阿里云没有提供 PHP ...
- esp8266 esp12 AT指令连接wifi热点联网,HTTP获取OneNET物联网平台消息,控制四路远程开关
esp8266 esp12 使用AT指令联网非常方便,很适合应对已经开发好的成品需要增加联网功能的需求. 使用AT指令进行开发,大多数是产品已经开发好,只需要增加小数据量的联网功能,而且不想对既有成品 ...
- 基于iOS快捷指令和Siri控制连接OneNET物联网平台的STM32的智能安防家居系统
摘要 之前做了一个智能安防系统,用STM32单片机作为主控芯片,ESP8266-01s模块作为Wi-Fi模块,成功利用MQTT协议实现了连接阿里云物联网平台或中国移动OneNET平台,并支持实时上报环 ...
- 树莓派mqtt协议连接阿里云物联网平台,手机端获取数据并控制
树莓派mqtt协议连接阿里云物联网平台(三) 前面树莓派的数据已经上传到云端,可是我的android手机该如何获取树莓派上传的这些数据呢,,困惑了我好几天的疑问,解开的那一刻,真的时拨开云雾见青天啊. ...
- mqtt 域名连接_中国移动OneNet物联网平台,如何使用MQTT协议,进行连接
大家好,超子又和大家见面了,超子我能力有限,技术不高,有什么错误的地方,欢迎板砖.今天我们一起构建MQTT协议中的CONNECT报文,连接OneNet物联网平台,然后进行通信.前面的文章中,超子介绍阿 ...
- Esp8266 进阶之路29【高级篇】百万条消息免费之乐鑫esp8266使用TCP直连模式MQTT协议接入阿里云物联网平台,支持私家服务器对接,支持阿里云规则引擎。(附带Demo)
本系列博客学习由非官方人员 半颗心脏 潜心所力所写,不做开发板.仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 序号 SDK版本 内容 链接 1 nonos2.0 搭建 ...
- 米思奇(Mixly)连接OneNet物联网平台(一)
米思奇(Mixly)连接OneNet物联网平台初体验(一) 中国移动物联网开放平台是中移物联网有限公司基于物联网技术和产业特点打造的开放平台和生态环境,适配各种网络环境和协议类型,支持各类传感器和智能 ...
最新文章
- 微软网站下载XPerf没有成功
- linux勒索病毒名称,Linux 也有加密勒索病毒了,也有人真的中了
- 数据库复杂查询,多表多联
- ubuntu中获取文件名称并生成txt文件
- MTCNN-tensorflow源码解析之训练PNet网络-train_PNet.py
- matlab tf-idf,java 兑现tfidf
- Mac osx 技巧
- Q88:全局光照(Global Illumination)——Path Tracing
- IDA for Linux/Mac/Windows
- matlab min函数_数学建模与MATLAB非线性规划
- MyBatis解析<if>动态sql时,Integer类型值为0,返回false
- dynamips常用命令
- 2022.02.17学习总结(最小生成树)
- 虚拟化技术的优点和缺点
- CVPR2021投稿要求
- 辰星人才 | 旷视实习生鲁盼:UCLA朱松纯准博士,两年七篇顶会论文
- QT读写Sqlite数据库的三种方式
- 真实感受一下县比省大不包邮,省市区乡镇多级数据重装上阵
- 网管教程:如何使用HTTP压缩优化服务器(图)
- 了解一下高速动态称重产品
热门文章
- VS.NET中的一些拖放操作
- TCP/IP 校验和算法简介
- CSP认证201312-3最大的矩形[C++题解]:枚举
- PAT甲级1132 Cut Integer:[C++题解]
- spring boot第二讲
- java删除页面数据不刷新_Ajax请求数据与删除数据后刷新页面
- leetcode最大矩形_LeetCode——最大矩形
- mac mysql 安装日志_Mac 安装 MySQL
- linux 系统时间是在哪里记录的,Linux系统如何记录时间
- mysql自动异地备份脚本_MYSQL数据库自动本地/异地双备份/MYSQL增量备份