当前位置:网站首页>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
边栏推荐
猜你喜欢
STM32 how to locate the code segment that causes hard fault
uCOS-III 的特点、任务状态、启动
优先级反转与死锁
基於Redis的分布式ID生成器
Générateur d'identification distribué basé sur redis
荣耀Magic 3Pro 充电架构分析
几个关于指针的声明【C语言】
Basic operations of databases and tables ----- classification of data
Basic knowledge of lithium battery
MySQL takes up too much memory solution
随机推荐
Esp8266 connects to bafayun (TCP maker cloud) through Arduino IED
RuntimeError: cuDNN error: CUDNN_ STATUS_ NOT_ INITIALIZED
Kaggle competition two Sigma connect: rental listing inquiries (xgboost)
JS Title: input array, exchange the largest with the first element, exchange the smallest with the last element, and output array.
MySQL占用内存过大解决方案
Variable parameter principle of C language function: VA_ start、va_ Arg and VA_ end
JS正则表达式基础知识学习
[Red Treasure Book Notes simplified version] Chapter 12 BOM
记一次云服务器被密码爆破的经历——关小黑屋、改密码、改端口
ESP8266通过Arduino IDE连接Onenet云平台(MQTT)
VSCode基础配置
【ESP32学习-1】Arduino ESP32开发环境搭建
PyTorch四种常用优化器测试
JS 函数提升和var变量的声明提升
冒泡排序【C语言】
GNN的第一个简单案例:Cora分类
JS object and event learning notes
Oppo vooc fast charging circuit and protocol
map文件粗略分析
优先级反转与死锁