314|2

170

帖子

0

资源

一粒金砂(高级)

【Beetle ESP32-C3】十、MQTT接入OneNET [复制链接]

       利用PubSubClient库(2.8.0版本),可以快速实现MQTT数据包封装,将ESP32-C3作为MQTT Client以连接MQTT Server。本篇连接的是OneNET的MQTT产品,选取平台的旧版MQTT接入。

 

image-20220919182806-1.png

图10-1 PubSubClient库

 

       案例在上篇基础之上完成,这里只展示添加的代码部分。

       为了验证MQTT的双向通信能力,启用Beetle ESP32-C3的板载LED(连接GPIO10),可以通过OneNET平台发送命令来控灯,这里设计“L0”熄灭,“L1”点亮。

OneNET MQTT旧版接入地址为:183.230.40.39,端口为6002,接入是需要配置“设备ID(即MQTT协议的Client ID)”、“产品ID(即MQTT协议的用户名)”和“鉴权信息(即MQTT协议的密码)”。

       另外,OneNET上传数据是统一向平台发布主题为“$dp”的消息,而消息载荷(PayLoad)有平台定义的格式,本例采用格式3——一种JSON对象格式,如:{"temp":29,"humi":26}。

 

//增加启用LED的相关宏定义
#define LED             10
#define LED_ON          digitalWrite(LED, HIGH)
#define LED_OFF         digitalWrite(LED, LOW)

//增加OneNET MQTT 信息
const char *mqtt_server = "183.230.40.39"; //onenet 的 IP地址
#define mqtt_devid "deviceid"    //设备ID需在OneNET注册
#define mqtt_pubid "productid"       //产品ID需在OneNET注册
#define mqtt_password "authorization" //鉴权信息建立产品时自定义
WiFiClient   espClient;           //tcp client实例用于连接OneNET服务器
PubSubClient client(espClient);   //pubsub client实例
char msg_buf[200];                                //发送信息的缓存
char dataTemplate[] = "{\"temp\":%d,\"humi\":%d}";//封装格式3的模板
char msgJson[75];                                 //存放封装好的JSON字串
unsigned short json_len = 0;                      //JSON字串长度
void sendTempAndHumi(void);
void clientReconnect(void);

//-----get OneNET order callback
void callback(char *topic, byte *payload, unsigned int length) {
  Serial.println("message rev:");
  Serial.println(topic);
  for(size_t i=0; i<length; i++) Serial.print((char)payload);
  Serial.println();

  if(payload[0] == 'L') {
    if(payload[1] == 0x30) //第二个接收字符是0,则接收“L0”,熄灯
      LED_OFF;
    else if(payload[1] == 0x31) //第二个接收字符是1,则接收“L1”,点灯
      LED_ON;
  }
}
//-----send data to OneNET
void sendTempAndHumi(void) {
  if(client.connected()) {
//为了省事,温湿度只取整数部分,这样可以保证snprintf()转字串成功
    int temperature = (int)aht_temp.temperature;
    int humidity = (int)aht_humi.relative_humidity;
//将湿度数据套入dataTemplate模板中, 生成的字符串传给msgJson
    snprintf(msgJson, 40, dataTemplate, temperature, humidity);
//msgJson的长度
    json_len = strlen(msgJson); 
//payload首字迹是OneNET格式编号,这里为格式3
    msg_buf[0] = char(0x03);    
//数据第二位是要发送的数据长度的高八位,数据第三位是要发送数据的长度的低八位
    msg_buf[1] = char(json_len >> 8);
    msg_buf[2] = char(json_len & 0xff);
//从msg_buf的第四位开始,放入要传的数据msgJson
    memcpy(msg_buf + 3, msgJson, strlen(msgJson)); 
//添加一个0作为最后一位, 这样要发送的msg_buf准备好了
    msg_buf[3 + strlen(msgJson)] = 0;
    Serial.print("public message:");
Serial.println(msgJson);
//发送数据到主题$dp
    client.publish("$dp", (uint8_t *)msg_buf, 3 + strlen(msgJson)); 
  }
}

//重连函数, 如果客户端断线,可以通过此函数重连
void clientReconnect(void) {
  while(!client.connected()) {
    Serial.println("reconnect MQTT...");
    if(client.connect(mqtt_devid, mqtt_pubid, mqtt_password)) {
      Serial.println("connected");
    } else {
      Serial.println("failed");
      Serial.println(client.state());
      Serial.println("try again in 5 sec");
      delay(5000);
    }
  }
}


//setup()中增加LED初始化和MQTT接入
void setup() {
//省略其它代码
  pinMode(LED, OUTPUT);
  LED_OFF;

//-----connect to OneNET
//设置客户端连接的服务器,连接Onenet服务器, 使用6002端口
  client.setServer(mqtt_server, 6002);
//客户端连接到指定的产品的指定设备.同时输入鉴权信息
  client.connect(mqtt_devid, mqtt_pubid, mqtt_password);
//注册回调函数
  client.setCallback(callback); 
}

//loop()中增加发送
void loop() {
//省略其它代码
//-----update weather info per 5 minutes
  if(t.tm_min%5==0 && t.tm_sec==0) {
    getAHT10();
    if(WiFi.status() == WL_CONNECTED) {
      getWeather();
    }
    sendTempAndHumi(); //此处增加发送温湿度调用
  }
//省略其它代码
}

 

       平台发送的命令后,串口可以看到解析,LED也会有变化。命令解析就是依靠接受回调callback(),PubSubClient库对接收数据包自动解析,得到了主题topic和载荷payload。OneNET发来命令的主题是“$crep”再加上一个uuid,而命令就是payload,因为解析的命令是byte数组,为了省事也没有做String类转换,自定义的命令就是“L0”和“L1”也比较简单,逐字节比对就好了。

 

image-20220919183533-2.png

图10-2 解析命令的串口输出

 

此帖出自RF/无线论坛

回复

6991

帖子

0

资源

五彩晶圆(中级)

看来MQTT接入OneNET不是很容易

点评

还可以吧,熟悉了也就是几个协议参数的配置。Arduino也有库。  详情 回复 发表于 2022-9-21 22:54

回复

170

帖子

0

资源

一粒金砂(高级)

Jacktang 发表于 2022-9-21 07:13 看来MQTT接入OneNET不是很容易

还可以吧,熟悉了也就是几个协议参数的配置。Arduino也有库。


回复
您需要登录后才可以回帖 登录 | 注册

相关帖子
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
    关闭
    站长推荐上一条 1/8 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表