野路子学习esp32(十二) MQTT 学习记录@a.宏万

官方的最新文档地址,

https://docs.espressif.com/projects/esp-idf/zh_CN/latest/index.html

持续更新,新的文档推出了很多新的案例。

 

现在记录下我学习MQTT的过程,希望可以帮助到一些朋友和自己。

官方的案例写的很好,我直接把官方的案例做一个说明。加上链接WiFi的代码

本文默认您已经知道mqtt的相关知识,我前面有一篇写的emq。

emq官方有升级,请安装时注意。

EMQ 安装与部署 @a.宏万

 

首先看官方的说明

https://docs.espressif.com/projects/esp-idf/zh_CN/latest/api-reference/protocols/mqtt.html#

 

本文选择 TCP协议

链接wifi

    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
    wifi_config_t sta_config = {
        .sta = {
            .ssid = "",//wifi名称
            .password = "",//密码
            .bssid_set = false
        }
    };
    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) );
    ESP_ERROR_CHECK( esp_wifi_start() );
    ESP_ERROR_CHECK( esp_wifi_connect() );

 

注册mqtt

    const esp_mqtt_client_config_t mqtt_cfg = {
    .host = "*.*.*.*",//服务器IP地址 默认端口 1883 
    };
    esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client);
    ESP_ERROR_CHECK(esp_mqtt_client_start(client));

以上两端代码就可以链接到mqtt服务器了。

事件监控代码  

mqtt_event_handler
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);
    mqtt_event_handler_cb(event_data);
}
事件实现代码
mqtt_event_handler_cb


static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
{
    esp_mqtt_client_handle_t client = event->client;
    int msg_id;
    // your_context_t *context = event->context;
    switch (event->event_id) {
        case MQTT_EVENT_CONNECTED://连接事件 
            ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
            msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0);//发布
            ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);

            msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);//订阅
            ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

            msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);//订阅
            ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

            msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");//取消订阅
            ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
            break;
        case MQTT_EVENT_DISCONNECTED://断开事件
            ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
            break;

        case MQTT_EVENT_SUBSCRIBED://订阅事件 
            ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
            msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);//发布
            ESP_LOGI(TAG, "sent publish successful, msg_id=%d", 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;
        case MQTT_EVENT_BEFORE_CONNECT: //事件在连接之前发生

            break;
        default:
            ESP_LOGI(TAG, "Other event id:%d", event->event_id);
            break;
    }
    return ESP_OK;
}

 

 

esp-idf mqtt 提供了很多事件

 

 代码中默认订阅的主题是 :/topic/qos0

现在我们使用mqtt程序给这个主题发布消息

 

使用串口链接软件 链接到esp32 查看打印内容

 

测试成功!

这里多说几句,如果你的设备可以链接mqtt了基本上就啥都可以干了。比如开灯。关灯。
远程开关电脑,向日葵的开机棒基本上也就是这个原理。

远程开关,温度传感器。火焰探测。这些都是可以的。

mqtt最大支持的传输可以达到100多兆,你都可以用设备传输图像了。

可以更新本地wifi链接,设备重启。

凡是可以通过消息对话搞定的都可以试试。

 

下面是完整代码。

 

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
 
#include "esp_wifi.h" 
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "driver/gpio.h"

#include "esp_log.h"
#include "mqtt_client.h"

static const char *TAG = "MQTT_EXAMPLE";

esp_err_t event_handler(void *ctx, system_event_t *event)
{
    return ESP_OK;
}

static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
{
    esp_mqtt_client_handle_t client = event->client;
    int msg_id;
    // your_context_t *context = event->context;
    switch (event->event_id) {
        case MQTT_EVENT_CONNECTED://连接事件 
            ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
            msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0);//发布
            ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);

            msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);//订阅
            ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

            msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);//订阅
            ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

            msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");//取消订阅
            ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
            break;
        case MQTT_EVENT_DISCONNECTED://断开事件
            ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
            break;

        case MQTT_EVENT_SUBSCRIBED://订阅事件 
            ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
            msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);//发布
            ESP_LOGI(TAG, "sent publish successful, msg_id=%d", 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;
        case MQTT_EVENT_BEFORE_CONNECT: //事件在连接之前发生

            break;
        default:
            ESP_LOGI(TAG, "Other event id:%d", event->event_id);
            break;
    }
    return ESP_OK;
}

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);
    mqtt_event_handler_cb(event_data);
}


void app_main()
{ 
    ESP_LOGI(TAG, "[APP] Startup..");
    ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
    ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());

    esp_log_level_set("*", ESP_LOG_INFO);
    esp_log_level_set("MQTT_CLIENT", ESP_LOG_VERBOSE);
    esp_log_level_set("MQTT_EXAMPLE", ESP_LOG_VERBOSE);
    esp_log_level_set("TRANSPORT_TCP", ESP_LOG_VERBOSE);
    esp_log_level_set("TRANSPORT_SSL", ESP_LOG_VERBOSE);
    esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE);
    esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE);

    ESP_ERROR_CHECK(nvs_flash_init());
    tcpip_adapter_init();
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
    wifi_config_t sta_config = {
        .sta = {
            .ssid = "xz220",
            .password = "www",
            .bssid_set = false
        }
    };
    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) );
    ESP_ERROR_CHECK( esp_wifi_start() );
    ESP_ERROR_CHECK( esp_wifi_connect() );
  
    const esp_mqtt_client_config_t mqtt_cfg = {
    .host = "*.*.*.*", 
    };
    esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client);
    ESP_ERROR_CHECK(esp_mqtt_client_start(client));
 
    gpio_set_direction(GPIO_NUM_2, GPIO_MODE_OUTPUT);
    int level = 0;
    while (true) {
        gpio_set_level(GPIO_NUM_2, level);
        level = !level;
        vTaskDelay(300 / portTICK_PERIOD_MS);
    }
}
 

 

转载于:https://www.cnblogs.com/hongwans/p/11217785.html

ESP32 Arduino MQTT is a way to connect an ESP32 microcontroller to an MQTT broker using the Arduino programming language. MQTT stands for Message Queuing Telemetry Transport, which is a lightweight messaging protocol designed for IoT devices. This protocol allows devices to publish and subscribe to topics, enabling communication between them. To use ESP32 Arduino MQTT, you need to first set up your ESP32 microcontroller with the Arduino IDE. Once you have done that, you can install the MQTT library for Arduino and start coding. Here are the basic steps: 1. Install the PubSubClient library in the Arduino IDE. 2. Connect your ESP32 to a Wi-Fi network using the Wi-Fi library. 3. Connect to an MQTT broker using the MQTT library and the PubSubClient library. 4. Publish messages to a topic using the MQTT library and the PubSubClient library. 5. Subscribe to topics and receive messages using the MQTT library and the PubSubClient library. Here is an example code for setting up an ESP32 Arduino MQTT connection: ``` #include <WiFi.h> #include <PubSubClient.h> // Wi-Fi credentials const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; // MQTT broker details const char* mqtt_server = "your_MQTT_broker_IP_address"; const int mqtt_port = 1883; const char* mqtt_username = "your_MQTT_username"; const char* mqtt_password = "your_MQTT_password"; // MQTT client WiFiClient espClient; PubSubClient client(espClient); void setup() { // Connect to Wi-Fi network WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); } // Connect to MQTT broker client.setServer(mqtt_server, mqtt_port); client.setCallback(callback); while (!client.connected()) { if (client.connect("ESP32_client", mqtt_username, mqtt_password)) { client.subscribe("test/topic"); } else { delay(1000); } } } void loop() { // Publish message to MQTT broker client.publish("test/topic", "Hello, world!"); // Check for incoming messages client.loop(); } void callback(char* topic, byte* payload, unsigned int length) { // Handle incoming messages Serial.print("Message received on topic: "); Serial.println(topic); Serial.print("Message: "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); } ``` This code connects to a Wi-Fi network and an MQTT broker, subscribes to a topic, publishes a message to that topic, and receives incoming messages. You can modify the code to fit your specific use case.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值