MQTT Hello World
This is a simple example of using the MQTT protocol to send data to a remote broker on the Internet.
We set everything up, wait for the GOT_IP event, and then start MQTT and send the string “Hello World” followed by the MAC address of the respective node every 5 seconds.
1#include <esp_err.h>
2#include <esp_event.h>
3#include <esp_log.h>
4#include <esp_mac.h>
5#include <esp_wifi.h>
6#include <freertos/FreeRTOS.h>
7#include <freertos/task.h>
8#include <meshnow.h>
9#include <mqtt_client.h>
10#include <nvs_flash.h>
11
12// The Wi-Fi credentials are configured via sdkconfig
13#define ROUTER_SSID CONFIG_EXAMPLE_ROUTER_SSID
14#define ROUTER_PASS CONFIG_EXAMPLE_ROUTER_PASSWORD
15
16// MQTT broker URI is configured via sdkconfig
17#define MQTT_BROKER_URI CONFIG_EXAMPLE_MQTT_BROKER_URI
18
19// Waitbits
20#define GOT_IP_BIT BIT0
21#define MQTT_CONNECTED_BIT BIT1
22
23static const char *TAG = "hello-world";
24
25// Fixed MAC address of the root node
26static const uint8_t root_mac[MESHNOW_ADDRESS_LENGTH] = {0x24, 0x6f, 0x28, 0x4a, 0x63, 0x3c};
27
28// MAC address of the current node
29static uint8_t node_mac[MESHNOW_ADDRESS_LENGTH];
30
31// Whether this node is the root
32static bool is_root = false;
33
34// Event group for various waiting processes
35static EventGroupHandle_t my_event_group;
36
37// Event handler for IP_EVENT
38static void ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
39 assert(event_base == IP_EVENT);
40 assert(event_id == IP_EVENT_STA_GOT_IP);
41
42 // set the bit for getting IP
43 xEventGroupSetBits(my_event_group, GOT_IP_BIT);
44}
45
46// Event handler for MQTT_EVENT
47static void mqtt_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
48 assert(event_id == MQTT_EVENT_CONNECTED);
49
50 xEventGroupSetBits(my_event_group, MQTT_CONNECTED_BIT);
51}
52
53// Sends messages via MQTT
54static void perform_mqtt() {
55 // initialize
56 esp_mqtt_client_config_t config = {
57 .broker.address.uri = MQTT_BROKER_URI,
58 };
59 esp_mqtt_client_handle_t client = esp_mqtt_client_init();
60
61 // register event handler
62 ESP_ERROR_CHECK(esp_mqtt_client_register_event(client, MQTT_EVENT_CONNECTED, &mqtt_event_handler, NULL));
63
64 char *msg;
65 asprintf(&msg, "Hello World from " MACSTR "(%s)", MAC2STR(node_mac), is_root ? "root" : "node");
66 size_t len = strlen(msg);
67
68 // start
69 ESP_ERROR_CHECK(esp_mqtt_client_start(client, &config));
70
71 // wait for connection
72 EventBits_t bits = xEventGroupWaitBits(my_event_group, MQTT_CONNECTED_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
73 assert((bits & MQTT_CONNECTED_BIT) != 0);
74
75 while (true) {
76 ESP_ERROR_CHECK(esp_mqtt_client_publish(client, "/helloworld", msg, len, 0, 0));
77 vTaskDelay(pMS_TO_TICKS(5000));
78 }
79}
80
81// Initializes NVS, Event Loop, Wi-Fi, and Netif
82static void pre_init(void) {
83 // nvs
84 esp_err_t ret = nvs_flash_init();
85 if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
86 ESP_ERROR_CHECK(nvs_flash_erase());
87 ret = nvs_flash_init();
88 }
89 ESP_ERROR_CHECK(ret);
90
91 // event loop
92 ESP_ERROR_CHECK(esp_event_loop_create_default());
93
94 // wifi
95 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
96 ESP_ERROR_CHECK(esp_wifi_init(&cfg));
97
98 // netif
99 ESP_ERROR_CHECK(esp_netif_init());
100}
101
102void app_main(void) {
103 pre_init();
104
105 // get MAC address
106 ESP_ERROR_CHECK(esp_read_mac(node_mac, ESP_MAC_WIFI_STA));
107
108 // check if root
109 is_root = memcmp(node_mac, root_mac, MESHNOW_ADDRESS_LENGTH) == 0;
110
111 // create event group
112 my_event_group = xEventGroupCreate();
113 assert(my_event_group != NULL);
114
115 // initialize meshnow
116 wifi_sta_config_t sta_config = {
117 .ssid = ROUTER_SSID,
118 .password = ROUTER_PASS,
119 };
120 meshnow_config_t config = {
121 .root = is_root,
122 .router_config =
123 {
124 .should_connect = true, // MQTT requires internet access
125 .sta_config = sta_config,
126 },
127 };
128 ESP_ERROR_CHECK(meshnow_init(&config));
129
130 // register event handler for IP_EVENT
131 ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL, NULL));
132
133 // start meshnow
134 ESP_ERROR_CHECK(meshnow_start());
135
136 // wait for IP
137 // when we get an IP address, the node has to have connected to a parent/router
138 // in a real application, you would want to handle disconnects/lost IP as well and restart MQTT
139 EventBits_t bits = xEventGroupWaitBits(my_event_group, GOT_IP_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
140 assert((bits & GOT_IP_BIT) != 0);
141
142 perform_mqtt();
143}