MQTT②创建客户端发送温度数据

此篇教程的内容是跟随【零知ESP32教程】MQTT①服务器搭建

我们在MQTT①中已经搭建好了服务器,接下来就可以使用这个服务器发送和接收消息了。 需要注意的是,要记住服务器的IP地址,才能进行连接。

下面是整个通信流程的示意图:

ESP32#1 已订阅esp32/led主题,并且在主题esp32/temperature下发布温度读数。

按下ESP32#2 按钮时,它会在esp32/led主题下发布消息,以控制连接到ESP32#1的LED。

ESP32#2 已订阅esp32/temperature主题,以接收温度读数并将其显示在LCD上。

一、软件和硬件

sht3x的引脚说明:

EPS32#1 连线:

打开零知开源工具安装MQTT所依赖的库:

AsyncMqttClient.zip(点击下载)
AsyncTCP.zip(点击下载)

安装完成后如图:

SHT3X驱动文件,解压后放在项目目录下即可。

sht3x-lingzhilab.zip(点击下载)

注意:在导入代码之后,要在第10,11行替换自己的WiFi名称和密码。 在第15行替换自己的MQTT服务器IP地址。


							
	#include <WiFi.h>
	extern "C" {
	        #include "freertos/FreeRTOS.h"
	        #include "freertos/timers.h"
	}
	#include <AsyncMqttClient.h>
	#include "HTU3X.h"
	 
	// Change the credentials below, so your ESP32 connects to your router
	#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
	#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"
	 
	// Change the MQTT_HOST variable to your IP address,
	// so it connects to your Mosquitto MQTT broker
	#define MQTT_HOST IPAddress(192, 168, X, XXX)
	#define MQTT_PORT 1883
	 
	// Create objects to handle MQTT client
	AsyncMqttClient mqttClient;
	TimerHandle_t mqttReconnectTimer;
	TimerHandle_t wifiReconnectTimer;
	 
	HTU3X myHumidity;//SDA = 21,SCL = 22
	 
	String temperatureString = "";      // Variable to hold the temperature reading
	unsigned long previousMillis = 0;   // Stores last time temperature was published
	const long interval = 5000;         // interval at which to publish sensor readings
	 
	const int ledPin = 25;              // GPIO where the LED is connected to
	int ledState = LOW;                 // the current state of the output pin
	 
	void connectToWifi() {
	        Serial.println("Connecting to Wi-Fi...");
	        WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
	}
	 
	void connectToMqtt() {
	        Serial.println("Connecting to MQTT...");
	        mqttClient.connect();
	}
	 
	void WiFiEvent(WiFiEvent_t event) {
	        Serial.printf("[WiFi-event] event: %d\n", event);
	        switch(event) {
	                case SYSTEM_EVENT_STA_GOT_IP:
	                Serial.println("WiFi connected");
	                Serial.println("IP address: ");
	                Serial.println(WiFi.localIP());
	                connectToMqtt();
	                break;
	                case SYSTEM_EVENT_STA_DISCONNECTED:
	                Serial.println("WiFi lost connection");
	                xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
	                xTimerStart(wifiReconnectTimer, 0);
	                break;
	        }
	}
	 
	// Add more topics that want your ESP32 to be subscribed to
	void onMqttConnect(bool sessionPresent) {
	        Serial.println("Connected to MQTT.");
	        Serial.print("Session present: ");
	        Serial.println(sessionPresent);
	        // ESP32 subscribed to esp32/led topic
	        uint16_t packetIdSub = mqttClient.subscribe("esp32/led", 0);
	        Serial.print("Subscribing at QoS 0, packetId: ");
	        Serial.println(packetIdSub);
	}
	 
	void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
	        Serial.println("Disconnected from MQTT.");
	        if (WiFi.isConnected()) {
	                xTimerStart(mqttReconnectTimer, 0);
	        }
	}
	 
	void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
	        Serial.println("Subscribe acknowledged.");
	        Serial.print("  packetId: ");
	        Serial.println(packetId);
	        Serial.print("  qos: ");
	        Serial.println(qos);
	}
	 
	void onMqttUnsubscribe(uint16_t packetId) {
	        Serial.println("Unsubscribe acknowledged.");
	        Serial.print("  packetId: ");
	        Serial.println(packetId);
	}
	 
	void onMqttPublish(uint16_t packetId) {
	        Serial.println("Publish acknowledged.");
	        Serial.print("  packetId: ");
	        Serial.println(packetId);
	}
	 
	// You can modify this function to handle what happens when you receive a certain message in a specific topic
	void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
	        String messageTemp;
	        for (int i = 0; i < len; i++) {
	                //Serial.print((char)payload[i]);
	                messageTemp += (char)payload[i];
	        }
	        // Check if the MQTT message was received on topic esp32/led
	        if (strcmp(topic, "esp32/led") == 0) {
	                // If the LED is off turn it on (and vice-versa)
	                if (ledState == LOW) {
	                        ledState = HIGH;
	                } else {
	                        ledState = LOW;
	                }
	                // Set the LED with the ledState of the variable
	                digitalWrite(ledPin, ledState);
	        }
	         
	        Serial.println("Publish received.");
	        Serial.print("  message: ");
	        Serial.println(messageTemp);
	        Serial.print("  topic: ");
	        Serial.println(topic);
	        Serial.print("  qos: ");
	        Serial.println(properties.qos);
	        Serial.print("  dup: ");
	        Serial.println(properties.dup);
	        Serial.print("  retain: ");
	        Serial.println(properties.retain);
	        Serial.print("  len: ");
	        Serial.println(len);
	        Serial.print("  index: ");
	        Serial.println(index);
	        Serial.print("  total: ");
	        Serial.println(total);
	}
	 
	 
	 
	void setup() {
	         
	        // Define LED as an OUTPUT and set it LOW
	        pinMode(ledPin, OUTPUT);
	        digitalWrite(ledPin, LOW);
	         
	        Serial.begin(115200);
	         
	        mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
	        wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));
	         
	        WiFi.onEvent(WiFiEvent);
	         
	        myHumidity.begin();
	         
	        mqttClient.onConnect(onMqttConnect);
	        mqttClient.onDisconnect(onMqttDisconnect);
	        mqttClient.onSubscribe(onMqttSubscribe);
	        mqttClient.onUnsubscribe(onMqttUnsubscribe);
	        mqttClient.onMessage(onMqttMessage);
	        mqttClient.onPublish(onMqttPublish);
	        mqttClient.setServer(MQTT_HOST, MQTT_PORT);
	         
	        connectToWifi();
	}
	 
	void loop() {
	        unsigned long currentMillis = millis();
	        // Every X number of seconds (interval = 5 seconds)
	        // it publishes a new MQTT message on topic esp32/temperature
	        if (currentMillis - previousMillis >= interval) {
	                // Save the last time a new reading was published
	                previousMillis = currentMillis;
	                // New temperature readings
	                float humd, temp;
	                myHumidity.readTempAndHumi(&temp, &humd);
	                 
	                temperatureString = " " + String(temp) + "C " + String(32 + temp * 1.8) +
	                "F";
	                Serial.println(temperatureString);
	                // Publish an MQTT message on topic esp32/temperature with Celsius and Fahrenheit temperature readings
	                uint16_t packetIdPub2 = mqttClient.publish("esp32/temperature", 2, true, temperatureString.c_str());
	                Serial.print("Publishing on topic esp32/temperature at QoS 2, packetId: ");
	                Serial.println(packetIdPub2);
	        }
	}						
							
						

验证程序后并上传到ESP32,打开调试窗口,可以看到已经成功连入MQTT服务器,并且发送主题为 esp32/temperature 的消息: