[5]ESP32连接阿里云MQTT,并上报传感器数据

1.基础知识

sprintf()函数:将各种类型的数据构造成字符串类型。

int sprintf( char *buffer, const char *format [, argument] … );

除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数:格式化字符串上。

1.格式化数字字符串

sprintf(s, "%d", 123); // 产生"123"

2.控制浮点数打印格式

1

2

3

sprintf(s, "%10.3f", 3.1415626);    // 产生:"     3.142″

sprintf(s, "%-10.3f", 3.1415626);   // 产生:"3.142     "

sprintf(s, "%.3f", 3.1415626);      // 不指定总宽度,产生:"3.142"

3.连接字符串

1

2

3

char *who = "I";

char *whom = "52PHP";

sprintf(s, "%s love %s.", who, whom); // 产生:"I love 52PHP. "

4.打印地址信息

1

sprintf(s, "%p", &i);

5.返回值为字符串的长度

1

int len = sprintf(s, "%d", i);

strcpy()函数:将一个字符串复制到另一块空间地址中,‘\0’是停止拷贝的终止条件,同时也会将 '\0' 也复制到目标空间。

char* strcpy(char* destination,const char* source);

注意事项:源字符必须以‘\0’结束,目标空间必须足够大,以确保能放源字符串,目标空间必须可变。

2.ESP32通过MQTT上传温湿度数据至阿里云服务器

注意事项:上传的数据格式因为阿里云物模型上报规定需要加上params和method,还有上传的键值需要和设置的物模型的标识符一致

eg:{"params":

{"Temp": %d ,

"Hum": %d ,

"Light": %d,

"Led":%d,

"Beep":%d},

"method": "thing.event.property.post"}

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

#include <Adafruit_Sensor.h>
#include <DHT.h>

#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

// const char *ssid = "leisure";
// const char *password = "shadow27";
const char *ssid = "TP-LINK_9B47";
const char *password = "MengYun1006&";

const char *mqttServer = "iot-06z00formvsxwnm.mqtt.iothub.aliyuncs.com";
const char *mqttUserName = "device2&i3c6vjLss9C";
const char *mqttPwd = "27ae4ab21d99554afb9b02e224e1543eccdfa3400c378f01bdf43140ad5aae56";
const char *clientId = "i3c6vjLss9C.device2|securemode=2,signmethod=hmacsha256,timestamp=1672664951875|";
const char *subTopic = "/i3c6vjLss9C/device2/user/mytopic";

#define ALINK_BODY_FORMAT "{\"id\":\"device2\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}"
#define ALINK_TOPIC_PROP_POST "/sys/i3c6vjLss9C/device2/thing/event/property/post" // 发布主题

unsigned long lastMS = 0;

WiFiClient esp32Client;
PubSubClient mqttClient(esp32Client);

void connectwifi()
{
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    vTaskDelay(500);
    Serial.print(F("."));
  }
  Serial.println(F(""));
  Serial.println(F("WiFi Connected!"));
  Serial.println(F(""));
}

/*订阅主题*/
void subscribeTopic()
{
  if (mqttClient.subscribe(subTopic))
  {
    Serial.print("Subscribed Topic: ");
    Serial.println(subTopic);
  }
  else
  {
    Serial.print("Subscribe Fail...");
  }
}

void connectMQTTServer()
{
  while (!mqttClient.connected())
  {
    if (mqttClient.connect(clientId, mqttUserName, mqttPwd))
    {
      Serial.println(F("MQTT connected"));
      subscribeTopic(); // 订阅指定主题
    }
    else
    {
      Serial.print("failed, rc=");
      Serial.print(mqttClient.state());
      Serial.println(" try again in 5 seconds");
      vTaskDelay(5000);
    }
  }
}

/*subscribe call back*/
void receiveCallback(char *topic, byte *payload, unsigned int length)
{
  Serial.print(F("Message arrived in topic: "));
  Serial.println(topic);
  Serial.print("Message:");
  String data = "";
  for (int i = 0; i < length; i++)
  {
    Serial.print((char)payload[i]);
    data += (char)payload[i];
  }
  Serial.println("");
  Serial.print("Message Length(Bytes) ");
  Serial.println(length);
  Serial.println();
  Serial.println("-----------------------");
  Serial.println(data);
  /*JSON数据解析*/
  StaticJsonDocument<32> doc;
  DeserializationError error = deserializeJson(doc, data);
  if (error)
  {
    Serial.print("deserializeJson() failed: ");
    Serial.println(error.c_str());
    return;
  }
  int msg = doc["msg"]; // 1

  Serial.print("msg = ");
  Serial.println(msg);
  /*根据JSON信息执行相应的动作*/
  switch (msg)
  {
  case 1:
    Serial.println("LED_on");
    break;
  case 2:
    Serial.println("LED_off");
    break;
  default:
    break;
  }
}

void pubMQTTmsg()
{
  char param[32];
  char jsonBuf[128];
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  sprintf(param, "{\"humi\":%2f}", h); // 换成对应的标识符
  sprintf(jsonBuf, ALINK_BODY_FORMAT, param);
  Serial.println(jsonBuf);
  boolean b = mqttClient.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
  if (b)
  {
    Serial.println("publish Humidity success");
  }
  else
  {
    Serial.println("publish Humidity fail");
  }

  sprintf(param, "{\"temp\":%2f}", t); // 换成对应的标识符
  sprintf(jsonBuf, ALINK_BODY_FORMAT, param);
  Serial.println(jsonBuf);
  boolean c = mqttClient.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
  if (c)
  {
    Serial.println("publish Humidity success");
  }
  else
  {
    Serial.println("publish Humidity fail");
  }
}

void setup()
{
  Serial.begin(115200);
  connectwifi();
  dht.begin();
  mqttClient.setServer(mqttServer, 1883);
  // mqttClient.setCallback(receiveCallback);
  connectMQTTServer();
}

void loop()
{
  if (!mqttClient.connected())
  {
    connectMQTTServer();
  }
  mqttClient.setCallback(receiveCallback);

  if(millis()-lastMS>=1000){
     lastMS = millis();
     pubMQTTmsg();//上报信息
  }
  // 处理信息以及心跳
  mqttClient.loop();
}

猜你喜欢

转载自blog.csdn.net/qq_45355603/article/details/128496517