日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android+app+wifi+控制+协议,玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(数量无限制)+ Android App控制...

發(fā)布時間:2025/4/5 Android 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android+app+wifi+控制+协议,玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(数量无限制)+ Android App控制... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

授人以魚不如授人以漁,目的不是為了教會你具體項目開發(fā),而是學會學習的能力。但愿你們分享給你周邊須要的朋友或者同窗,說不定大神成長之路有博哥的奠定石。。。android

若是以為有用,麻煩點贊收藏,您的支持是博主創(chuàng)做的動力。github

1.理論基礎(chǔ)

參考博主線上博文:web

在前面的博文中,博主主要經(jīng)過手動方式去建立設備。這種方式的缺點明顯:json

人為手動控制,對于開發(fā)者來講極度不友好;

若是設備數(shù)量不少,豈不是要手動操做很是屢次;

那么,如何實現(xiàn)設備自注冊呢?所謂自注冊就是設備連入網(wǎng)絡后自動往OneNet云平臺注冊設備信息并獲取設備Id。api

為了區(qū)分惟一性,咱們采用ESP-Mac地址的組合形式

同時為了操做方便,博主花了個周末的時間作了一個對應的app,理論上不限制ESP8266接入點的數(shù)量

本篇博文的目的就在于教會你們?nèi)绾魏蚢pp通訊,完成MQTT協(xié)議下的App遠程控制LED燈,而且LED燈的數(shù)量能夠隨意接入,用戶能夠在app端修改設備名字以便方便操做。服務器

博主極度建議你們從第一篇看起,有個大概了解,由于本系列教程都是有相聯(lián)系的

先上個概念圖:

網(wǎng)絡

2.遠程控制LED,實現(xiàn)設備自注冊

2.1 實驗材料

ESP8266 NodeMcu

Android手機

OneNet平臺

2.2 實驗步驟

2.2.1 建立 ESP8266智能燈系統(tǒng) 產(chǎn)品(MQTT協(xié)議)

注意點:app

務必選擇MQTT協(xié)議

建立完畢后,咱們點擊查看具體的產(chǎn)品信息:svg

注意點:

須要記錄產(chǎn)品ID,其用來區(qū)分產(chǎn)品惟一標識符,這個ID待會須要填入App

Master-APIkey,網(wǎng)絡請求鑒權(quán)信息,接口調(diào)用須要帶入,這個ID待會須要填入App

2.2.2 NodeMcu燒錄代碼 —— MQTT設備端

為了明確區(qū)分代碼功能,博哥命名工程名為P_OneNet_Exam05:

P_OneNet_Exam05.ino文件:

/**

* 功能:ESP8266 Mqtt客戶端自注冊功能,經(jīng)過配套App控制Led消息,理論上能夠接入無數(shù)個esp8266

* 做者:單片機菜鳥

* 時間:2019-10-27

* 描述:

* 1.初始化工做:初始化網(wǎng)絡配置,Mqtt客戶端自注冊,鏈接鑒權(quán),訂閱主題

* 2.訂閱消息:獲取發(fā)送過來的消息(json格式),解析消息,實現(xiàn)控制亮滅燈

*/

#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);//關(guān)閉自動鏈接

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;

//重啟系統(tǒng)

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;

//重啟系統(tǒng)

delayRestart(1);

}

}

if(!parseRegisterResponse()){

//重啟系統(tǒng)

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

}

/*

* 保存參數(shù)到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加載參數(shù)

*/

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數(shù)據(jù)

*/

void parseOneNetMqttResponse(char* payload){

Serial.println("start parseOneNetMqttResponse");

StaticJsonBuffer<100> jsonBuffer;

// StaticJsonBuffer 在棧區(qū)分配內(nèi)存 它也能夠被 DynamicJsonBuffer(內(nèi)存在堆區(qū)分配) 代替

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

}

}

}

/**

* 解析注冊返回結(jié)果

*/

bool parseRegisterResponse(){

Serial.println("start parseRegisterResponse");

StaticJsonBuffer<200> jsonBuffer;

// StaticJsonBuffer 在棧區(qū)分配內(nèi)存 它也能夠被 DynamicJsonBuffer(內(nèi)存在堆區(qū)分配) 代替

// 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相關(guān)操做 **************************/

void delayRestart(float t);

void delayNs(uint8_t m);

/*********************************************************/

/*************** OneNet MQTT相關(guān)操做 ****************************/

void initOneNet(uint8_t *productId,uint8_t *apiKey,uint8_t *deviceId);

int connectToOneNetMqtt();

/*********************************************************/

/**************** OneNet Http相關(guān)操做 ***************************/

HTTPClient http;

String response;

const char* host = "api.heclouds.com";

bool registerDeviceToOneNet();

/****************************************************************/

#define ONENET_DISCONNECTED 1//已經(jīng)斷開

#define ONENET_CONNECTED 2//已經(jīng)鏈接上

#define ONENET_RECONNECT 3//重連成功

//常量

#define VER "MQTT_LED_V1.0"

const char* ssid = "xxxxxxxx";//wifi帳號

const char* password = "xxxxxxx";//wifi秘密

//OneNet相關(guān)

PubSubClient mqttClient;

const char* mqttServer = "183.230.40.39";//mqtt服務器

const uint16_t mqttPort = 6002;

#define PRODUCT_ID "253190"//此為博哥本身的產(chǎn)品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(博哥這里燒錄了兩個),而后能夠看到串口打印內(nèi)容,以下:

同時,也能夠在OneNet平臺看到設備狀況,以下:

接下來就能夠經(jīng)過App進行遠程控制led了。

3.配套android App

3.1 下載App

博主把App放在了我的交流群上以及Github

App源碼暫不開源,博主也上傳到了我的交流群

3.2 配置App

手機App做為一個特殊的設備,須要自行注冊一個新的設備,而后填入deviceId,至于如何注冊設備,請參考 以前的博文。

3.3 操做App

主頁面能夠看到當前全部的設備列表(也就是你自注冊的全部智能燈),而且標明了設備狀態(tài),而后咱們就能夠遠程控制開關(guān)燈。

3.4 實驗效果

4.總結(jié)

須要注意幾點:

建立本身的OneNet產(chǎn)品,不要用博哥建立的,否則很容易發(fā)生MQTT重連的現(xiàn)象

總結(jié)

以上是生活随笔為你收集整理的android+app+wifi+控制+协议,玩转OneNET物联网平台之MQTT服务④ —— 远程控制LED(数量无限制)+ Android App控制...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。