当前位置:网站首页>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
边栏推荐
- imgcat使用心得
- Rough analysis of map file
- Basic operations of databases and tables ----- view data tables
- Page performance optimization of video scene
- AMBA、AHB、APB、AXI的理解
- Postman 中级使用教程【环境变量、测试脚本、断言、接口文档等】
- STM32 如何定位导致发生 hard fault 的代码段
- RuntimeError: cuDNN error: CUDNN_STATUS_NOT_INITIALIZED
- E-commerce data analysis -- salary prediction (linear regression)
- inline详细讲解【C语言】
猜你喜欢
ESP learning problem record
History object
The dolphin scheduler remotely executes shell scripts through the expect command
Custom view puzzle getcolor r.color The color obtained by colorprimary is incorrect
Pat 1097 duplication on a linked list (25 points)
Understanding of AMBA, AHB, APB and Axi
STM32 how to locate the code segment that causes hard fault
Reno7 60W super flash charging architecture
基于Redis的分布式ID生成器
Types de variables JS et transformations de type communes
随机推荐
Redis 缓存更新策略,缓存穿透、雪崩、击穿问题
JS数组常用方法的分类、理解和运用
MP3mini播放模块arduino<DFRobotDFPlayerMini.h>函数详解
2022.2.12 resumption
GNN的第一个简单案例:Cora分类
RT thread API reference manual
Mysqldump error1066 error solution
【ESP32学习-2】esp32地址映射
C语言,log打印文件名、函数名、行号、日期时间
基于Redis的分布式ID生成器
MySQL takes up too much memory solution
RT-Thread API参考手册
ES6 grammar summary -- Part I (basic)
The dolphin scheduler remotely executes shell scripts through the expect command
Fashion Gen: the general fashion dataset and challenge paper interpretation & dataset introduction
Arduino JSON data information parsing
MySQL时间、时区、自动填充0的问题
1081 rational sum (20 points) points add up to total points
map文件粗略分析
Inline detailed explanation [C language]