当前位置:网站首页>ESP8266连接onenet(旧版MQTT方式)
ESP8266连接onenet(旧版MQTT方式)
2022-07-06 09:17:00 【XlinliY.Zhang】
一、为什么使用旧版MQTT
1、简单
使用ESP8266 + Arduino开发的方式,只需要极简的代码,就可以实现上云。
MQTT在ESP8266上拥有现成的库,我们只需要在平台创建设备,在程序里面输入参数即可。
2、双向
对比于HTTP的单向连接,MQTT是双向的,不需要设备去请求服务器下发数据,大大简化了程序流程。
二、如何实现MQTT接入
1、注册设备
直接上图
第一步当然是登陆账号(没有的直接注册+实名认证即可,免费哒)
然后进入控制台

然后开始添加产品设备
使用的是旧版控制台

先添加产品才能添加设备



添加完产品,然后点击刚刚添加的产品进入产品管理,再然后开始添加设备


设备ID为CLIENTID 鉴权信息为USERPASSWORD 产品ID为USERNAME
到这一步,设备已经添加完成了,数据流什么的可以不用理,设备上传数据后系统会自动添加数据节点。
2、烧录ESP8266代码
关于Arduino IDE如何烧录ESP8266,网上有许多的教程,这一步不再赘叙,直接上代码
const char *Device_ID = "*******"; //设备ID
const char *Product_ID = "*******"; //产品ID
const char *Api_KEY = "*******"; //鉴权信息
const char *WiFi_SSID = "*******"; //WiFi名称
const char *WiFi_Password = "***********"; //WiFi密码
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
float Current = 0;
uint8_t Upload_Package[100];
uint32_t Last_Updata_Time = 0;
WiFiClient espClient;
PubSubClient client(espClient);
void WiFi_Init(void);
void MQTT_Init(void);
void MQTT_Reconnection(void);
void MQTT_Callback(char *MQTT_Topic, uint8_t *MQTT_Payload, uint16_t MQTT_Payload_Len);
void setup()
{
Serial.begin(115200);
WiFi_Init();
MQTT_Init();
}
void loop()
{
if (!client.connected())
MQTT_Reconnection();
if (millis() - Last_Updata_Time >= 3000)
{
Last_Updata_Time = millis();
float ADC_Value = analogRead(A0);
Current = (ADC_Value - 512) * 0.033783784;
Serial.print("Current: ");
Serial.print(Current);
Serial.println(" A\r\n");
memset(Upload_Package, 0, 100);
String Json_Buffer = ",;Current,";
Json_Buffer += String(Current);
Json_Buffer += ";";
Upload_Package[0] = 5;
Upload_Package[1] = highByte(Json_Buffer.length());
Upload_Package[2] = lowByte(Json_Buffer.length());
for (int i = 0; i < Json_Buffer.length(); i++)
Upload_Package[i + 3] = Json_Buffer.c_str()[i];
client.publish("$dp", Upload_Package, Json_Buffer.length() + 3);
}
client.loop();
}
void WiFi_Init(void)
{
Serial.print("\r\n\r\nConnecting to ");
Serial.print(WiFi_SSID);
WiFi.mode(WIFI_STA);
WiFi.begin(WiFi_SSID, WiFi_Password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.print("\r\nWiFi Connected.\r\nIP address: ");
Serial.println(WiFi.localIP());
}
void MQTT_Init(void)
{
client.setServer("183.230.40.39", 6002);
client.setCallback(MQTT_Callback);
}
void MQTT_Callback(char *MQTT_Topic, uint8_t *MQTT_Payload, uint16_t MQTT_Payload_Len)
{
Serial.printf("Topic: %s[%d]:\r\n", MQTT_Topic, MQTT_Payload_Len);
for (uint16_t i = 0; i < MQTT_Payload_Len; i++)
{
Serial.print(MQTT_Payload[i] < 0x10 ? " 0x0" : " 0x");
Serial.print(MQTT_Payload[i]);
}
Serial.println();
}
void MQTT_Reconnection(void)
{
while (!client.connected())
{
Serial.println("MQTT Reconnection.");
if (client.connect(Device_ID, Product_ID, Api_KEY))
Serial.println("MQTT Connected");
else
{
Serial.print("Connect Failed, Error Code = ");
Serial.print(client.state());
Serial.println(", Try again in 5 seconds.");
delay(5000);
}
}
}
本示例将A0口读取的模拟值上传到onenet,并在接收到onenet下发信息时在串口打印
三、程序讲解
1、联网相关
//首先要有WiFi参数
const char *WiFi_SSID = "*******"; //WiFi名称
const char *WiFi_Password = "***********"; //WiFi密码
//其次要有WiFi驱动库
#include <ESP8266WiFi.h>
//声明下函数
void WiFi_Init(void);
void setup()//setup只执行一次,联网放这里面就行
{
//串口要初始化下,方便查看过程
Serial.begin(115200);
//开始WiFi初始化
WiFi_Init();
}
void loop()
{
}
void WiFi_Init(void)
{
//打印下提示语
Serial.print("\r\n\r\nConnecting to ");
Serial.print(WiFi_SSID);
//STA模式,传入wifi参数
WiFi.mode(WIFI_STA);
WiFi.begin(WiFi_SSID, WiFi_Password);
//循环到WiFi连接
while (WiFi.status() != WL_CONNECTED)
{
//定时打印............告诉你老子没死机
delay(500);
Serial.print(".");
}
//打印提示语和本机IP地址
Serial.print("\r\nWiFi Connected.\r\nIP address: ");
Serial.println(WiFi.localIP());
}2、上云相关
//首先要有参数
const char *Device_ID = "711583270"; //设备ID
const char *Product_ID = "421451"; //产品ID
const char *Api_KEY = "20210425"; //鉴权信息
//提供socket协议(MQTT基于TCP)
#include <ESP8266WiFi.h>
//提供MQTT协议
#include <PubSubClient.h>
//创建对象
WiFiClient espClient;
PubSubClient client(espClient);
//声明下函数
void MQTT_Init(void);
void MQTT_Reconnection(void);
void setup()
{
Serial.begin(115200);
MQTT_Init();//初始化MQTT
}
void loop()//loop相当于其他单片机的while(1)
{
//判断MQTT连接了没,没的话重新连接
if (!client.connected())
MQTT_Reconnection();
//MQTT运行
client.loop();
}
void MQTT_Init(void)
{
client.setServer("183.230.40.39", 6002);//设置服务器IP地址和端口
client.setCallback(MQTT_Callback); //设置接收到信息的回调函数
}
//MQTT重连函数
void MQTT_Reconnection(void)
{
while (!client.connected())//循环到MQTT已连接
{
Serial.println("MQTT Reconnection.");
if (client.connect(Device_ID, Product_ID, Api_KEY))//调用MQTT连接,传入对应的参数,返回1则连接成功
Serial.println("MQTT Connected");
else//否则就打印错误消息
{
Serial.print("Connect Failed, Error Code = ");
Serial.print(client.state());
Serial.println(", Try again in 5 seconds.");
delay(5000);
}
}
}
3、收发数据相关
//在初始化MQTT时候,我们已经设置了回调函数
client.setCallback(MQTT_Callback);
//所以,当收到信息时,会调用这个函数,传入参数含义如下
//MQTT_Topic 收到的消息的主题
//MQTT_Payload 收到的消息的内容
//MQTT_Payload_Len 收到的消息的内容的长度
void MQTT_Callback(char *MQTT_Topic, uint8_t *MQTT_Payload, uint16_t MQTT_Payload_Len)
{
//此处只进行了打印,没有其余处理操作
Serial.printf("Topic: %s[%d]:\r\n", MQTT_Topic, MQTT_Payload_Len);
for (uint16_t i = 0; i < MQTT_Payload_Len; i++)
{
Serial.print(MQTT_Payload[i] < 0x10 ? " 0x0" : " 0x");
Serial.print(MQTT_Payload[i]);
}
Serial.println();
}
//若要上传数据,则使用发布函数发布
//$dp ONENT上传数据固定主题
//Upload_Package 上传的数据数组
//Json_Buffer.length() + 3 上传的数据长度,因为包含0,使用不能使用strlen计算长度
client.publish("$dp", Upload_Package, Json_Buffer.length() + 3);4、上传协议
Upload_Package[0]为上传格式,详见ONENET文档,此处用的是5
数据示例:,;数据名称,数据值;
Upload_Package[1] * 256 + Upload_Package[2] 为 3~数据结束的长度
四、总结
1、几个需要注意的点
ONENET的上传数据格式有点特殊,前3字节为固定格式,其后才是真正数据
ONENET的端口号是6002不是传统的1883
格式5即使是字符也不需要双引号(不同于JSON)
2、缺点
ONENET下发数据和更新数据时间不一样,导致有时候下发了数据,控件还没刷新
故障描述如下:
按下按钮,他变ON,过一会又变OFF,直到设备上传ON的数据才会变成ON
边栏推荐
- [Red Treasure Book Notes simplified version] Chapter 12 BOM
- Pytorch: tensor operation (I) contiguous
- Inline detailed explanation [C language]
- 小天才电话手表 Z3工作原理
- Esp8266 connects to bafayun (TCP maker cloud) through Arduino IED
- 2022.2.12 resumption
- ESP学习问题记录
- Fashion-Gen: The Generative Fashion Dataset and Challenge 论文解读&数据集介绍
- .elf .map .list .hex文件
- ES6 grammar summary -- Part 2 (advanced part es6~es11)
猜你喜欢

小天才电话手表 Z3工作原理

open-mmlab labelImg mmdetection

Redis cache update strategy, cache penetration, avalanche, breakdown problems

(五)R语言入门生物信息学——ORF和序列分析

JS正则表达式基础知识学习

Symbolic representation of functions in deep learning papers

记一次云服务器被密码爆破的经历——关小黑屋、改密码、改端口

锂电池基础知识

Custom view puzzle getcolor r.color The color obtained by colorprimary is incorrect

JS object and event learning notes
随机推荐
Imgcat usage experience
level16
Comparison of solutions of Qualcomm & MTK & Kirin mobile platform USB3.0
Selective sorting and bubble sorting [C language]
嵌入式启动流程
[esp32 learning-1] construction of Arduino esp32 development environment
Esp8266 connects to bafayun (TCP maker cloud) through Arduino IED
(一)R语言入门指南——数据分析的第一步
MP3mini播放模块arduino<DFRobotDFPlayerMini.h>函数详解
高通&MTK&麒麟 手机平台USB3.0方案对比
VIM command line notes
Raspberry pie tap switch button to use
RT-Thread 线程的时间片轮询调度
基于Redis的分布式锁 以及 超详细的改进思路
map文件粗略分析
Kaggle competition two Sigma connect: rental listing inquiries (xgboost)
列表的使用
Pytoch implements simple linear regression demo
Redis based distributed locks and ultra detailed improvement ideas
RT-Thread API参考手册