CODE¶
Component Structure¶
Danger
Note that there is a built-in MQTT module in esp-idf, so to avoid conflicts, we name this module esp32_mqtt.
driver/esp32_mqtt/CMakeLists.txt¶
set(src_dirs
.
)
set(include_dirs
include
)
set(requires
mqtt
)
idf_component_register(SRC_DIRS ${src_dirs} INCLUDE_DIRS ${include_dirs} REQUIRES ${requires})
Note
You can see that the dependency relationship here is very simple, only mqtt.
mqtt.h¶
/**
* @file mqtt.h
* @author SHUAIWEN CUI (SHUAIWEN001@e.ntu.edu.sg)
* @brief This file contains the function prototypes for mqtt connection.
* @version 1.0
* @date 2025-03-17
*
* @copyright Copyright (c) 2025
*
*/
#ifndef __MQTT_H__
#define __MQTT_H__
/* Dependencies */
#include <stdio.h>
#include "esp_log.h"
#include "mqtt_client.h"
/* Macros */
#define MQTT_ADDRESS "mqtt://8.222.194.160" // MQTT Broker URL
#define MQTT_PORT 1883 // MQTT Broker Port
#define MQTT_CLIENT "ESP32-S3-Node-001" // Client ID (Unique for devices)
#define MQTT_USERNAME "cshwstem" // MQTT Username
#define MQTT_PASSWORD "Cshw0918#" // MQTT Password
#define MQTT_PUBLIC_TOPIC "/mqtt/node" // publish topic
#define MQTT_SUBSCRIBE_TOPIC "/mqtt/server" // subscribe topic
/* Variables */
extern const char *TAG_MQTT; // tag for logging
extern esp_mqtt_client_handle_t s_mqtt_client;
extern bool s_is_mqtt_connected;
/* Function Prototypes */
/**
* @brief MQTT client initialization and connection
*/
void mqtt_app_start(void);
#endif /* __MQTT_H__ */
mqtt.c¶
/**
* @file mqtt.c
* @author SHUAIWEN CUI (SHUAIWEN001@e.ntu.edu.sg)
* @brief This file contains the function prototypes for mqtt connection.
* @version 1.0
* @date 2025-03-17
*
* @copyright Copyright (c) 2025
*
*/
/* Dependencies */
#include "mqtt.h"
/* Macros */
/* Variables */
const char *TAG_MQTT = "NODE-MQTT"; // tag for logging
esp_mqtt_client_handle_t s_mqtt_client = NULL; // MQTT client handle
bool s_is_mqtt_connected = false; // MQTT connection status flag
/* Function Prototypes */
/**
* @brief MQTT event handler
*
* @param event_handler_arg Argument passed to the event handler
* @param event_base Event base identifier
* @param event_id Event identifier
* @param event_data Event-specific data
*/
void aliot_mqtt_event_handler(void *event_handler_arg,
esp_event_base_t event_base,
int32_t event_id,
void *event_data)
{
esp_mqtt_event_handle_t event = event_data;
esp_mqtt_client_handle_t client = event->client;
switch ((esp_mqtt_event_id_t)event_id)
{
case MQTT_EVENT_CONNECTED: // Connection established
ESP_LOGI(TAG_MQTT, "MQTT connected");
// Subscribe to the test topic upon successful connection
esp_mqtt_client_subscribe_single(client, MQTT_SUBSCRIBE_TOPIC, 1);
break;
case MQTT_EVENT_DISCONNECTED: // Connection disconnected
ESP_LOGI(TAG_MQTT, "MQTT disconnected");
break;
case MQTT_EVENT_SUBSCRIBED: // Subscription successful
ESP_LOGI(TAG_MQTT, "MQTT subscribed, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_UNSUBSCRIBED: // Unsubscription successful
ESP_LOGI(TAG_MQTT, "MQTT unsubscribed, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_PUBLISHED: // Publish acknowledgment received
ESP_LOGI(TAG_MQTT, "MQTT published ack, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA: // Data received
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: // Error event
ESP_LOGI(TAG_MQTT, "MQTT event error");
break;
default:
ESP_LOGI(TAG_MQTT, "Unhandled MQTT event id: %ld", event_id);
break;
}
}
/**
* @brief MQTT client initialization and connection
*/
void mqtt_app_start(void)
{
esp_err_t ret;
esp_mqtt_client_config_t mqtt_cfg = {0};
mqtt_cfg.broker.address.uri = MQTT_ADDRESS;
mqtt_cfg.broker.address.port = MQTT_PORT;
// Client ID
mqtt_cfg.credentials.client_id = MQTT_CLIENT;
// Username
mqtt_cfg.credentials.username = MQTT_USERNAME;
// Password
mqtt_cfg.credentials.authentication.password = MQTT_PASSWORD;
ESP_LOGI(TAG_MQTT, "Connecting to MQTT broker...");
// Initialize MQTT client with provided configuration
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
// Register MQTT event handler
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, aliot_mqtt_event_handler, client);
// Start MQTT client
ret = esp_mqtt_client_start(client);
if(ret == ESP_OK)
{
ESP_LOGI(TAG_MQTT, "MQTT client started");
s_mqtt_client = client;
s_is_mqtt_connected = true;
}
else
{
ESP_LOGE(TAG_MQTT, "MQTT client start failed");
}
}
main.c¶
/**
* @file main.c
* @author SHUAIWEN CUI (SHUAIWEN001@e.ntu.edu.sg)
* @brief
* @version 1.0
* @date 2024-11-20
*
* @copyright Copyright (c) 2024
*
*/
/* DEPENDENCIES */
// ESP
#include "esp_system.h" // ESP32 System
#include "nvs_flash.h" // ESP32 NVS
#include "esp_chip_info.h" // ESP32 Chip Info
#include "esp_psram.h" // ESP32 PSRAM
#include "esp_flash.h" // ESP32 Flash
#include "esp_log.h" // ESP32 Logging
// BSP
#include "led.h"
#include "exit.h"
#include "spi.h"
#include "lcd.h"
#include "tim.h"
#include "esp_rtc.h"
#include "spi_sdcard.h"
#include "wifi_wpa2_enterprise.h"
#include "mqtt.h"
/* Variables */
const char *TAG = "NEXNODE";
/**
* @brief Entry point of the program
* @param None
* @retval None
*/
void app_main(void)
{
esp_err_t ret;
uint32_t flash_size;
esp_chip_info_t chip_info;
char mqtt_pub_buff[64];
int count = 0;
// Initialize NVS
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()); // Erase if needed
ret = nvs_flash_init();
}
// Get FLASH size
esp_flash_get_size(NULL, &flash_size);
esp_chip_info(&chip_info);
// Display CPU core count
printf("CPU Cores: %d\n", chip_info.cores);
// Display FLASH size
printf("Flash size: %ld MB flash\n", flash_size / (1024 * 1024));
// Display PSRAM size
printf("PSRAM size: %d bytes\n", esp_psram_get_size());
// BSP Initialization
led_init();
exit_init();
spi2_init();
lcd_init();
// spiffs_test(); /* Run SPIFFS test */
while (sd_card_init()) /* SD card not detected */
{
lcd_show_string(0, 0, 200, 16, 16, "SD Card Error!", RED);
vTaskDelay(500);
lcd_show_string(0, 20, 200, 16, 16, "Please Check!", RED);
vTaskDelay(500);
}
// clean the screen
lcd_clear(WHITE);
lcd_show_string(0, 0, 200, 16, 16, "SD Initialized!", RED);
sd_card_test_filesystem(); /* Run SD card test */
lcd_show_string(0, 0, 200, 16, 16, "SD Tested CSW! ", RED);
// sd_card_unmount();
vTaskDelay(3000);
lcd_show_string(0, 0, lcd_self.width, 16, 16, "WiFi STA Test ", RED);
ret = wifi_sta_wpa2_init();
if(ret == ESP_OK)
{
ESP_LOGI(TAG_WIFI, "WiFi STA Init OK");
lcd_show_string(0, 0, lcd_self.width, 16, 16, "WiFi STA Test OK", RED);
}
else
{
ESP_LOGE(TAG_WIFI, "WiFi STA Init Failed");
}
// only when the ip is obtained, start mqtt
EventBits_t ev = 0;
ev = xEventGroupWaitBits(wifi_event_group,CONNECTED_BIT,pdTRUE,pdFALSE,portMAX_DELAY);
if(ev & CONNECTED_BIT)
{
mqtt_app_start();
}
while (1)
{
if(s_is_mqtt_connected)
{
snprintf(mqtt_pub_buff,64,"{\"count\":\"%d\"}",count);
esp_mqtt_client_publish(s_mqtt_client, MQTT_PUBLIC_TOPIC,
mqtt_pub_buff, strlen(mqtt_pub_buff),1, 0);
count++;
}
led_toggle();
ESP_LOGI(TAG, "Hello World!");
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}