1. Tài liệu
2. Kit phát triển các bạn có thể mua tại link sau:
KIT PHÁT TRIỂN WIFI BLUETOOTH ESP32-C3U
KIT PHÁT TRIỂN WIFI BLUETOOTH ESP32-C3S
KIT PHÁT TRIỂN WIFI BLUETOOTH ESP32-S3-DEVKITC-1
KIT PHÁT TRIỂN WIFI BLUETOOTH ESP32 S NODEMCU
KIT PHÁT TRIỂN 3G 4G SIM7600CE ESP32
3. Giới thiệu về MQTT
MQTT (Message Queuing Telemetry Transport) là giao thức truyền thông điệp (message) theo mô hình publish/subscribe (cung cấp / thuê bao), được sử dụng cho các thiết bị IoT với băng thông thấp, độ tin cậy cao và khả năng được sử dụng trong mạng lưới không ổn định. Nó dựa trên một Broker (tạm dịch là “Máy chủ môi giới”) “nhẹ” (khá ít xử lý) và được thiết kế có tính mở (tức là không đặc trưng cho ứng dụng cụ thể nào), đơn giản và dễ cài đặt.
MQTT là lựa chọn lý tưởng trong các môi trường như:
4. Ví dụ Kết nối MQTT sử dụng Kit ESP32
ESP_IDF\examples\protocols\mqtt\tcp
ESP_IDF\examples\protocols\mqtt\tcp --> D:\mqtt_tcp
nếu ESP_IDF Cài đặt tại D:\esp-idf_master thì:
D:\esp-idf_master\examples\protocols\mqtt\tcp -> D:\mqtt_tcp
idf_cmd_init.bat
idf.py menuconfig
Đổi lại broker thành: mqtt://mqtt.eclipseprojects.io (mặc định)
-> Đổi wifi SSID
-> Đổi wifi Password
idf.py build
idf.py -p COM6 flash monitor
Trong đó có log kết quả kết nối Wi-Fi, MQTT và MQTT Message
Trong ví dụ này, MQTT sẽ tự động kết nối và reconnect khi kết nối Wi-Fi bị ngắt hoặc bị ngắt kết nối từ server
4. Ví dụ thực tế
#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"
#include "driver/gpio.h"
#define GPIO_OUTPUT_IO_0 18
#define GPIO_OUTPUT_IO_1 19
#define GPIO_OUTPUT_PIN_SEL ((1ULL<<GPIO_OUTPUT_IO_0) | (1ULL<<GPIO_OUTPUT_IO_1))
static const char *TAG = "MQTT_EXAMPLE";
static const char* topicControl = "test/control";
static const char* topicStatus = "test/status";
static esp_mqtt_client_handle_t client;
static bool mqttConnected;
static float temperature = 30.0F;
static char mqtt_tx_buf[64];
static uint32_t mqtt_tx_buf_len;
void mqtt_on_message(char *msg, uint32_t len);
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
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");
/* Set MQTT Connected */
mqttConnected = true;
/* Subcribe topic test/control */
msg_id = esp_mqtt_client_subscribe(client, topicControl, 0);
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_DISCONNECTED:
/* Set MQTT Disconnected */
mqttConnected = false;
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
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:
mqtt_on_message(event->data, event->data_len);
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
printf("\t\tTOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("\t\tDATA=%.*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;
}
}
static void mqtt_app_start(void)
{
esp_mqtt_client_config_t mqtt_cfg = { .uri = CONFIG_BROKER_URL};
client = esp_mqtt_client_init(&mqtt_cfg);
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
esp_mqtt_client_start(client);
}
static void app_gpio_init(void)
{
gpio_config_t io_conf;
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_INPUT_OUTPUT ;
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0;
gpio_config(&io_conf);
gpio_set_level(GPIO_OUTPUT_IO_0, 1);
gpio_set_level(GPIO_OUTPUT_IO_1, 1);
}
/*
* Receive message MQTT
*/
void mqtt_on_message(char *msg, uint32_t len){
if(strstr(msg, "on") != NULL){
ESP_LOGI(TAG, "ON LED");
gpio_set_level(GPIO_OUTPUT_IO_0, 0);
}
else if(strstr(msg, "off") != NULL){
ESP_LOGI(TAG, "OFF LED");
gpio_set_level(GPIO_OUTPUT_IO_0, 1);
}
else if(strstr(msg, "toggle") != NULL){
ESP_LOGI(TAG, "TOGGLE LED");
gpio_set_level(GPIO_OUTPUT_IO_0, gpio_get_level(GPIO_OUTPUT_IO_0) ^ 1);
}
}
/*
* Publish message to broker
* QoS: 1
* Retain: True
*/
bool mqtt_publish(char *msg, uint32_t len){
if(!mqttConnected) return false;
int msg_id = esp_mqtt_client_publish(client, topicStatus, msg, len, 1, 1);
ESP_LOGI(TAG, "Send status data");
return true;
}
void app_main(void)
{
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_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* Init GPIO */
app_gpio_init();
/* Connect Wi-Fi */
ESP_ERROR_CHECK(example_connect());
/* MQTT Init & Connect */
mqtt_app_start();
while(true)
{
temperature += 0.1F;
if(temperature > 50.0F) temperature = 30.0F;
mqtt_tx_buf_len = sprintf(mqtt_tx_buf, "{\"temp\": %f}", temperature);
/* Publish message to MQTT broker */
mqtt_publish(mqtt_tx_buf, mqtt_tx_buf_len);
/* Toggle Pin out */
// gpio_set_level(GPIO_OUTPUT_IO_0, gpio_get_level(GPIO_OUTPUT_IO_0) ^ 1);
/* Sleep 5000ms to let task to Suspended Mode */
/* Refer: https://www.freertos.org/RTOS-task-states.html */
vTaskDelay(1000 / portTICK_RATE_MS);
}
}
Kết quả
Bình luận