ESP32 是由 Espressif 开发的一系列低成本低功耗系统级芯片(SoC)微控制器,包括 Wi-Fi 和蓝牙无线功能以及双核处理器。如果你熟悉 ESP8266,那么 ESP32 就是它的继任者,拥有许多新功能。
在物联网领域,基于ESP32开发是一个非常不错的选择,广泛用于智能家居、智能农业及工业物联网等行业。
而MQTT作为物联网通信技术的首选,两者结合,简直完美!我们这期讨论如何在ESP32中应用MQTT?
为什么要使用ESP32,以下是它的主要优点:
ESP32如何应用MQTT?
我们在应用之前,首先要了解MQTT的几个核心概念:
通过整理我们这期介绍两种平台来如何使用 ESP32 通过 MQTT 协议向 MQTT 代理发送和接收数据:
Arduino IDE
首先,我们需要安装Arduino开发环境:
基本的步骤:
我们这里不做详细说明,有开发经验的朋友欢迎补充,具体的可以参考文末的链接【1】。
当然,我们把内部的代码贴在下方:
/*
* This ESP32 code is created by esp32io.com
*
* This ESP32 code is released in the public domain
*
* For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-mqtt
*/
#include <WiFi.h>
#include <MQTTClient.h>
#include <ArduinoJson.h>
#define CLIENT_ID "ESP32-001" // CHANGE IT AS YOU DESIRE
const char WIFI_SSID[] = "YOUR_WIFI_SSID"; // CHANGE TO YOUR WIFI SSID
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // CHANGE TO YOUR WIFI PASSWORD
const char MQTT_BROKER_ADRRESS[] = "192.168.0.26"; // CHANGE TO MQTT BROKER'S IP ADDRESS
const int MQTT_PORT = 1883;
const char MQTT_USERNAME[] = ""; // CHANGE IT IF REQUIRED
const char MQTT_PASSWORD[] = ""; // CHANGE IT IF REQUIRED
// The MQTT topics that this device should publish/subscribe
#define PUBLISH_TOPIC "esp32-001/send"
#define SUBSCRIBE_TOPIC "esp32-001/receive"
#define PUBLISH_INTERVAL 5000 // 4 seconds
WiFiClient network;
MQTTClient mqtt = MQTTClient(256);
unsigned long lastPublishTime = 0;
void setup() {
Serial.begin(9600);
// set the ADC attenuation to 11 dB (up to ~3.3V input)
analogSetAttenuation(ADC_11db);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.println("ESP32 - Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
connectToMQTT();
}
void loop() {
mqtt.loop();
if (millis() - lastPublishTime > PUBLISH_INTERVAL) {
sendToMQTT();
lastPublishTime = millis();
}
}
void connectToMQTT() {
// Connect to the MQTT broker
mqtt.begin(MQTT_BROKER_ADRRESS, MQTT_PORT, network);
// Create a handler for incoming messages
mqtt.onMessage(messageHandler);
Serial.print("ESP32 - Connecting to MQTT broker");
while (!mqtt.connect(CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {
Serial.print(".");
delay(100);
}
Serial.println();
if (!mqtt.connected()) {
Serial.println("ESP32 - MQTT broker Timeout!");
return;
}
// Subscribe to a topic, the incoming messages are processed by messageHandler() function
if (mqtt.subscribe(SUBSCRIBE_TOPIC))
Serial.print("ESP32 - Subscribed to the topic: ");
else
Serial.print("ESP32 - Failed to subscribe to the topic: ");
Serial.println(SUBSCRIBE_TOPIC);
Serial.println("ESP32 - MQTT broker Connected!");
}
void sendToMQTT() {
StaticJsonDocument<200> message;
message["timestamp"] = millis();
message["data"] = analogRead(0); // Or you can read data from other sensors
char messageBuffer[512];
serializeJson(message, messageBuffer);
mqtt.publish(PUBLISH_TOPIC, messageBuffer);
Serial.println("ESP32 - sent to MQTT:");
Serial.print("- topic: ");
Serial.println(PUBLISH_TOPIC);
Serial.print("- payload:");
Serial.println(messageBuffer);
}
void messageHandler(String &topic, String &payload) {
Serial.println("ESP32 - received from MQTT:");
Serial.println("- topic: " + topic);
Serial.println("- payload:");
Serial.println(payload);
// You can process the incoming data as json object, then control something
/*
StaticJsonDocument<200> doc;
deserializeJson(doc, payload);
const char* message = doc["message"];
*/
}
上述ESP32 代码的作用是:
VS CODE+ESP-IDF
下面我们将介绍如何使用 ESP32 作为 ESP-IDF mqtt_client 库的 MQTT 客户端。
主要的步骤:
我们将在 Raspberry Pi 上安装 Mosquitto MQTT 代理,但你也可以在你的 Windows 和 Linux 机器上安装它。当然,也可以选择其他的代理:
详细的步骤可参考文末的链接【2】,我们这里把主题代码贴在下方:
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "protocol_examples_common.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "esp_log.h"
#include "mqtt_client.h"
static const char *TAG = "MQTT_EXAMPLE";
#define EXAMPLE_ESP_WIFI_SSID "YOUR_SSID"
#define EXAMPLE_ESP_WIFI_PASS "YOUR_PASSWORD"
uint32_t MQTT_CONNEECTED = 0;
static void mqtt_app_start(void);
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch (event->event_id)
{
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
ESP_LOGI(TAG, "Trying to connect with Wi-Fi\n");
break;
case SYSTEM_EVENT_STA_CONNECTED:
ESP_LOGI(TAG, "Wi-Fi connected\n");
break;
case SYSTEM_EVENT_STA_GOT_IP:
ESP_LOGI(TAG, "got ip: startibg MQTT Client\n");
mqtt_app_start();
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGI(TAG, "disconnected: Retrying Wi-Fi\n");
esp_wifi_connect();
break;
default:
break;
}
return ESP_OK;
}
void wifi_init(void)
{
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_ESP_WIFI_SSID,
.password = EXAMPLE_ESP_WIFI_PASS,
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
ESP_ERROR_CHECK(esp_wifi_start());
}
/*
* @brief Event handler registered to receive MQTT events
*
* This function is called by the MQTT client event loop.
*
* @param handler_args user data registered to the event.
* @param base Event base for the handler(always MQTT Base in this example).
* @param event_id The id for the received event.
* @param event_data The data for the event, esp_mqtt_event_handle_t.
*/
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
esp_mqtt_event_handle_t event = event_data;
esp_mqtt_client_handle_t client = event->client;
int msg_id;
switch ((esp_mqtt_event_id_t)event_id)
{
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
MQTT_CONNEECTED=1;
msg_id = esp_mqtt_client_subscribe(client, "/topic/test1", 0);
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
msg_id = esp_mqtt_client_subscribe(client, "/topic/test2", 1);
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
MQTT_CONNEECTED=0;
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_UNSUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
break;
case MQTT_EVENT_ERROR:
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
break;
default:
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
break;
}
}
esp_mqtt_client_handle_t client = NULL;
static void mqtt_app_start(void)
{
ESP_LOGI(TAG, "STARTING MQTT");
esp_mqtt_client_config_t mqttConfig = {
.uri = "mqtt://192.168.1.4:1883"};
client = esp_mqtt_client_init(&mqttConfig);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client);
esp_mqtt_client_start(client);
}
void Publisher_Task(void *params)
{
while (true)
{
if(MQTT_CONNEECTED)
{
esp_mqtt_client_publish(client, "/topic/test3", "Helllo World", 0, 0, 0);
vTaskDelay(15000 / portTICK_PERIOD_MS);
}
}
}
void app_main(void)
{
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
wifi_init();
xTaskCreate(Publisher_Task, "Publisher_Task", 1024 * 5, NULL, 5, NULL);
}
详细代码:
https://github.com/ESP32Tutorials/esp32-mqtt-pub-sub-esp-idf
关于本期内容,重要是实践,要完全搞懂这些,可以参考下方详细的链接,包含上述没有细化的内容。
参考链接:
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有