How to use ESP-MQTT in a correct way (event loop)?

brixxx
Posts: 4
Joined: Fri Jun 28, 2019 9:02 am

How to use ESP-MQTT in a correct way (event loop)?

Postby brixxx » Fri Jun 28, 2019 9:20 am

Hi,

I would like to use ESP-MQTT.
The TCP SSL example included in the idf examples works fine, but to be honest I have not understood the concept how to use it right.

Here is the relevant code:

Code: Select all

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_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;
        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);
}

static void mqtt_app_start(void)
{
    const esp_mqtt_client_config_t mqtt_cfg = {
        .uri = CONFIG_BROKER_URI,
        .cert_pem = (const char *)iot_eclipse_org_pem_start,
    };

    ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
    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_mqtt_client_start(client);
}
The function "mqtt_app_start()" is called once in the example and then the event loop runs once.

If I would like to publish measurement values e.g. every 10 seconds which function would I call?
Stays the connection if "keep alive" is configured, so that I would just call the function "esp_mqtt_client_publish() every 10 seconds"?
Or would this be wrong?
I do not really get the concept of the event loop.

Thank you very much.

brixxx
Posts: 4
Joined: Fri Jun 28, 2019 9:02 am

Re: How to use ESP-MQTT in a correct way (event loop)?

Postby brixxx » Tue Jul 16, 2019 9:43 am

No one?
It would be really nice if you could help me!

I now found out that I maybe should use "esp_event_post_to()" to use the mqtt lib.
But for this I do not now where to get the event base from.

Thanks!

ESP_cermak
Posts: 69
Joined: Thu Nov 01, 2018 8:32 am

Re: How to use ESP-MQTT in a correct way (event loop)?

Postby ESP_cermak » Tue Jul 16, 2019 2:25 pm

Hi,

No need to use event_loop to publish messages. You can just call mqtt-publish from a separate task every 10 s. I would also recommend event flags to be set on connection event and cleared on disconnect. Then you can simply run the needed API whenever you're connected.

brixxx
Posts: 4
Joined: Fri Jun 28, 2019 9:02 am

Re: How to use ESP-MQTT in a correct way (event loop)?

Postby brixxx » Wed Jul 17, 2019 10:52 am

Thank you very much!
This was a good idea and works fine :)

mohasrj
Posts: 33
Joined: Mon Jan 20, 2020 9:38 am

Re: How to use ESP-MQTT in a correct way (event loop)?

Postby mohasrj » Mon Jun 29, 2020 10:52 am

hi, please u can share ur code, i dont understand how it work well , and how i can add a new context ..

and when i try to use esp_mqtt_client_publish in BMP280 sensor task, it not work :roll: :roll:

maybe u use espmqtt library ?


what's difference between the liberary used here :

https://github.com/kyberpunk/esp-temperature-control
https://github.com/hoon/esp32-env-mqtt/ ... ain/main.c
https://github.com/lucadentella/esp32-t ... er/21_mqtt
Attachments
bg.PNG
bg.PNG (27.46 KiB) Viewed 15258 times

GirishHolla
Posts: 15
Joined: Tue Jun 01, 2021 10:21 am

Re: How to use ESP-MQTT in a correct way (event loop)?

Postby GirishHolla » Tue Jun 01, 2021 10:25 am

As you mentioned as "publish call" in freertos task but how client is defined within it (with reference to screenshot).kindly let me know,
thank you in advance,

markirwin
Posts: 10
Joined: Sun Nov 22, 2020 10:42 am

Re: How to use ESP-MQTT in a correct way (event loop)?

Postby markirwin » Tue Jun 22, 2021 10:38 am

I would like to follow up on this post and see if there was a resolution?

I have been attempting to get the MQTT-TCP examples working where i would publish a message every 5s in a while (1) loop within the app_main like below. Running the vanilla example.

Code: Select all

while (1) {
       
        esp_mqtt_client_publish (client, "test", "data", 4, 0, false);
        vTaskDelay(5000 / portTICK_PERIOD_MS);

    }
This fails with the error that client does not exist because it is not global.

Code: Select all

./main/app_main.c:553:34: error: 'client' undeclared (first use in this function); did you mean 'creat'?
         esp_mqtt_client_publish (client, "test/bye", "data", 4, 0, false);
                                  ^~~~~~
I tried moving the contents of the mqtt_app_start function to global so that client would be accessible from anywhere but this again failed with this error.

Code: Select all

main/app_main.c:130:42: error: initializer element is not constant
 static esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
                                          ^~~~~~~~~~~~~~~~~~~~

What i would like to do is every 10s send a MQTT message or when a button is pressed publish a message. I know this must be a common request but the examples are too generic to help.

Best

Mark

ESP_Sprite
Posts: 9709
Joined: Thu Nov 26, 2015 4:08 am

Re: How to use ESP-MQTT in a correct way (event loop)?

Postby ESP_Sprite » Wed Jun 23, 2021 2:27 am

You declare the client globally, but initialize it in e.g. your main function. Something like this:

Code: Select all

 static esp_mqtt_client_handle_t client;
 
 void app_main() {
 	client = esp_mqtt_client_init(&mqtt_cfg);
}


Who is online

Users browsing this forum: MicroController and 256 guests