【物联网】ESP32使用MQTT协议上传数据到onenet物联网平台

“为什么使用MQTT协议?MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。(来自百度百科)”

但是作为小白初学者来说,写MQTT的Arduino代码是真的不懂,反正我感觉一点儿都不简单,相较于http协议的post请求,代码多了好多!

废话不多说,上代码:

#include <Arduino.h>
#include "PubSubClient.h"
#include "WiFi.h"
#include "Ticker.h"
#include "ArduinoJson.h"


const char* ssid = "XXXXXXXX";              //wifi名
const char* password = "XXXXXXXX";      //wifi密码
const char* mqtt_server = "mqtts.heclouds.com"; //onenet 的 IP地址 mqtts.heclouds.com 183.230.40.96
const int port = 1883;                    //端口号
const int potPin = 34; // 读取模拟引脚值,设置为34号引脚

#define mqtt_pubid "XXXXXXXX"    //产品ID
#define mqtt_devid "XXXXXXXX"       //设备名称

#define mqtt_password "version=2018-10-31&res=products%产品ID%2Fdevices%2F设备名称&et=2557387130&method=md5&sign=sIYDOQXHTbooFOlU5XZIVA%3D%3D"       //鉴权信息

WiFiClient espClient;           //创建一个WIFI连接客户端
PubSubClient client(espClient); // 创建一个PubSub客户端, 传入创建的WIFI客户端
Ticker tim1;                    //定时器,用来循环上传数据
Ticker tim2;                    //定时器,用来循环上传数据
float temp;
float humi;
float dis;

int postMsgId = 0; //记录已经post了多少条
//----------------------------------------------------------------------------
//设备上传数据的post主题
#define ONENET_TOPIC_PROP_POST "$sys/" mqtt_pubid "/" mqtt_devid "/dp/post/json" //"$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/post"
//接收下发属性设置主题
#define ONENET_TOPIC_PROP_SET  "$sys/" mqtt_pubid "/" mqtt_devid "/dp/post/json/+" //"$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/set"
//接收下发属性设置成功的回复主题
#define ONENET_TOPIC_PROP_SET_REPLY "$sys/" mqtt_pubid "/" mqtt_devid "/dp/post/accepted" //"$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/set_reply"
 
//接收设备属性获取命令主题
#define ONENET_TOPIC_PROP_GET "$sys/" mqtt_pubid "/" mqtt_devid "/cmd/request/+" //"$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/get"
//接收设备属性获取命令成功的回复主题
#define ONENET_TOPIC_PROP_GET_REPLY "$sys/" mqtt_pubid "/" mqtt_devid "/cmd/response/+/+" //"$sys/" mqtt_pubid "/" mqtt_devid "/thing/property/get_reply"
 
//这是post上传数据使用的模板
#define ONENET_POST_BODY_FORMAT "{\"id\":%d,\"dp\":%s}"
//----------------------------------------------------------------------------



//连接WIFI相关函数
void setupWifi()
{
  delay(10);
  Serial.println("connect WIFI");
  WiFi.begin(ssid, password);
  while (!WiFi.isConnected())
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println("OK");
  Serial.println("Wifi connected!");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

}

void sendTempAndHumi()
{
  if (client.connected())
  {
    //先拼接出json字符串
    char param[82];
    char jsonBuf[178];
    //sprintf(param, "{ \"temp\":[{\"v\":%.2f}],\"humi\":[{\"v\":%.2f}] }", temp, humi); //我们把要上传的数据写在param里
    sprintf(param, "{ \"light\":[{\"v\":%.2f}] }", dis); //我们把要上传的数据写在param里
    postMsgId += 1;
    sprintf(jsonBuf, ONENET_POST_BODY_FORMAT, postMsgId, param);
    //再从mqtt客户端中发布post消息
    if (client.publish(ONENET_TOPIC_PROP_POST, jsonBuf))
    {
      Serial.print("Post message to cloud: ");
      Serial.println(jsonBuf);
    }
    else
    {
      Serial.println("Publish message to cloud failed!");
    }
  }

}


//重连函数, 如果客户端断线,可以通过此函数重连
void clientReconnect()
{
  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);
    }
  }
}


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[i]);
  }
  Serial.println();
 
  if (strstr(topic, ONENET_TOPIC_PROP_SET))
  {
    DynamicJsonDocument doc(100);
    DeserializationError error = deserializeJson(doc, payload);
    if (error)
    {
      Serial.println("parse json failed");
      return;
    }
    JsonObject setAlinkMsgObj = doc.as<JsonObject>();
    serializeJsonPretty(setAlinkMsgObj, Serial);
    String str = setAlinkMsgObj["id"];
    Serial.println(str);
    char sendbuf[100];
    sprintf(sendbuf, "{\"id\": \"%s\",\"code\":200,\"msg\":\"success\"}", str.c_str());
    Serial.println(sendbuf);
    client.publish(ONENET_TOPIC_PROP_SET_REPLY, sendbuf);
  }
  if (strstr(topic, ONENET_TOPIC_PROP_GET))
  {
    DynamicJsonDocument doc(100);
    DeserializationError error = deserializeJson(doc, payload);
    if (error)
    {
      Serial.println("parse json failed");
      return;
    }
    JsonObject setAlinkMsgObj = doc.as<JsonObject>();
    serializeJsonPretty(setAlinkMsgObj, Serial);
    String str = setAlinkMsgObj["id"];
    Serial.println(str);
    char sendbuf[100];
    //sprintf(sendbuf, "{\"id\": \"%s\",\"code\":200,\"msg\":\"success\",\"data\":{\"temp\":%.2f,\"humi\":%.2f}}", str.c_str(), temp, humi);
    sprintf(sendbuf, "{\"id\": \"%s\",\"code\":200,\"msg\":\"success\",\"data\":{\"dis\":%.2f }}", str.c_str(), temp);
    Serial.println(sendbuf);
    client.publish(ONENET_TOPIC_PROP_GET_REPLY, sendbuf);
  }
}


void update_date(void)
{
  
  dis = analogRead(potPin); // 读取模拟引脚的值,连接的是光敏传感器

  }



void setup() {
 // put your setup code here, to run once:


  Serial.begin(115200); //初始化串口
  //Wire.begin();
  //sht20.begin();
  delay(3000);
  setupWifi();                                           //调用函数连接WIFI
  client.setServer(mqtt_server, port);                   //设置客户端连接的服务器,连接Onenet服务器, 使用1883端口
  delay(2000);
  Serial.println("setServer Init!"); 
  //client.setCallback(callback);
  client.connect(mqtt_devid, mqtt_pubid, mqtt_password); //客户端连接到指定的产品的指定设备.同时输入鉴权信息
  delay(2000);
  Serial.println("connect Init!"); 
  
  if (client.connected())
  {
    Serial.println("OneNet is connected!"); //判断以下是不是连好了.
  }
  client.subscribe(ONENET_TOPIC_PROP_SET);
  client.subscribe(ONENET_TOPIC_PROP_GET);
  client.setCallback(callback);
  tim1.attach(2, sendTempAndHumi); //定时每20秒调用一次发送数据函数sendTempAndHumi
  tim2.attach(1, update_date);
  temp =10;
  humi =20;
  dis = 100;

}
int count = 0;

void loop() {

  // put your main code here, to run repeatedly:

  if (!WiFi.isConnected()) //先看WIFI是否还在连接
  {
    setupWifi();
  }
  if (!client.connected()) //如果客户端没连接ONENET, 重新连接
  {
    clientReconnect();
    delay(100);
  }
  client.loop(); //客户端循环检测

}

代码实现的是从“34”GPIO口读取模拟信号值,并上传到onenet平台。

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值