当前位置:网站首页>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
边栏推荐
- 共用体(union)详解【C语言】
- GNN的第一个简单案例:Cora分类
- [golang] leetcode intermediate - fill in the next right node pointer of each node & the k-smallest element in the binary search tree
- AMBA、AHB、APB、AXI的理解
- uCOS-III 的特点、任务状态、启动
- Pytorch four commonly used optimizer tests
- I2C bus timing explanation
- @Autowired 和 @Resource 的区别
- Comparaison des solutions pour la plate - forme mobile Qualcomm & MTK & Kirin USB 3.0
- The first simple case of GNN: Cora classification
猜你喜欢

History object
![[golang] leetcode intermediate - fill in the next right node pointer of each node & the k-smallest element in the binary search tree](/img/6e/0802a92511ac50a652afa1678ad28c.jpg)
[golang] leetcode intermediate - fill in the next right node pointer of each node & the k-smallest element in the binary search tree

uCOS-III 的特点、任务状态、启动

ESP8266使用arduino连接阿里云物联网

锂电池基础知识

Basic knowledge of lithium battery

优先级反转与死锁

Pytorch: tensor operation (I) contiguous

JS Title: input array, exchange the largest with the first element, exchange the smallest with the last element, and output array.

Pat 1097 duplication on a linked list (25 points)
随机推荐
Walk into WPF's drawing Bing Dwen Dwen
Programmers can make mistakes. Basic pointers and arrays of C language
Common properties of location
OPPO VOOC快充电路和协议
小天才电话手表 Z3工作原理
map文件粗略分析
Pytorch: tensor operation (I) contiguous
FreeRTOS 任务函数里面的死循环
Postman 中级使用教程【环境变量、测试脚本、断言、接口文档等】
程序员老鸟都会搞错的问题 C语言基础 指针和数组
JS object and event learning notes
Who says that PT online schema change does not lock the table, or deadlock
arduino获取数组的长度
arduino获取随机数
js 变量作用域和函数的学习笔记
高通&MTK&麒麟 手机平台USB3.0方案对比
Minio文件下载问题——inputstream:closed
Pat 1097 duplication on a linked list (25 points)
The dolphin scheduler remotely executes shell scripts through the expect command
E-commerce data analysis -- salary prediction (linear regression)