espressif / esp-mqtt

ESP32 mqtt component
Apache License 2.0
603 stars 255 forks source link

Error write data or timeout, written len = 0 (IDFGH-4042) #170

Closed Shaopus closed 4 years ago

Shaopus commented 4 years ago

Environment

static EventGroupHandle_t wifi_event_group; const static int CONNECTED_BIT = BIT0; esp_mqtt_client_handle_t client;

static esp_err_t mqtt_event_handler(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;
}
return ESP_OK;

}

static esp_err_t wifi_event_handler(void ctx, system_event_t event) { / For accessing reason codes in case of disconnection / system_event_info_t *info = &event->event_info;

switch (event->event_id) {
    case SYSTEM_EVENT_STA_START:
        esp_wifi_connect();
        break;
    case SYSTEM_EVENT_STA_GOT_IP:
        xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);

        break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
        ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
        if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
            /*Switch to 802.11 bgn mode */
            esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N);
        }
        esp_wifi_connect();
        xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
        break;
    default:
        break;
}
return ESP_OK;

}

static void wifi_init(void) { tcpip_adapter_init(); wifi_event_group = xEventGroupCreate(); ESP_ERROR_CHECK(esp_event_loop_init(wifi_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)); wifi_config_t wifi_config = { .sta = { .ssid = CONFIG_WIFI_SSID, .password = CONFIG_WIFI_PASSWORD, }, }; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); ESP_LOGI(TAG, "start the WIFI SSID:[%s]", CONFIG_WIFI_SSID); ESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG, "Waiting for wifi"); xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); }

static void mqtt_app_start(void) { esp_mqtt_client_config_t mqtt_cfg = { .uri = CONFIG_BROKER_URL, .event_handle = mqtt_event_handler, // .user_context = (void *)your_context };

if CONFIG_BROKER_URL_FROM_STDIN

char line[128];

if (strcmp(mqtt_cfg.uri, "FROM_STDIN") == 0) {
    int count = 0;
    printf("Please enter url of mqtt broker\n");
    while (count < 128) {
        int c = fgetc(stdin);
        if (c == '\n') {
            line[count] = '\0';
            break;
        } else if (c > 0 && c < 127) {
            line[count] = c;
            ++count;
        }
        vTaskDelay(10 / portTICK_PERIOD_MS);
    }
    mqtt_cfg.uri = line;
    printf("Broker url: %s\n", line);
} else {
    ESP_LOGE(TAG, "Configuration mismatch: wrong broker url");
    abort();
}

endif / CONFIG_BROKER_URL_FROM_STDIN /

client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_start(client);

}

static void th2mqtt_timer_cb(TimerHandle_t xTimer) { int msg_id; msg_id = esp_mqtt_client_publish(client, "/topic/th", "{\"temperature\":25.5,\"humidity\":67.7}", 0, 0, 0); ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id); }

void app_main() { TimerHandle_t th_timer;

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("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);

nvs_flash_init();
wifi_init();
mqtt_app_start();

th_timer = xTimerCreate("th2mqtt", pdMS_TO_TICKS(5 * 1000), pdTRUE,
    NULL, th2mqtt_timer_cb);
xTimerStart(th_timer, 0);

}

### Debug Logs
After flashing, sometimes to publish is OK, with this bellow messages:

I (2144235) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2149236) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2154241) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2159242) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2164246) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2169247) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2174251) MQTT_EXAMPLE: sent publish successful, msg_id=0 E (2189254) MQTT_CLIENT: Error write data or timeout, written len = 0 E (2189257) MQTT_CLIENT: Error to public data to topic=/topic/th, qos=0 I (2189260) MQTT_EXAMPLE: sent publish successful, msg_id=-1 E (2199269) MQTT_CLIENT: Error write data or timeout, written len = 0 E (2199272) MQTT_CLIENT: Error to public data to topic=/topic/th, qos=0 I (2199275) MQTT_EXAMPLE: sent publish successful, msg_id=-1 E (2209282) MQTT_CLIENT: Error write data or timeout, written len = 0 E (2209285) MQTT_CLIENT: Error to public data to topic=/topic/th, qos=0 I (2209288) MQTT_EXAMPLE: sent publish successful, msg_id=-1 E (2219297) MQTT_CLIENT: Error write data or timeout, written len = 0 E (2219300) MQTT_CLIENT: Error to public data to topic=/topic/th, qos=0 I (2219303) MQTT_EXAMPLE: sent publish successful, msg_id=-1 I (2220568) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2220581) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2220592) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2220604) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2220616) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2224272) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2229273) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2234276) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2239279) MQTT_EXAMPLE: sent publish successful, msg_id=0 I (2244282) MQTT_EXAMPLE: sent publish successful, msg_id=0


please, help me ☺️
david-cermak commented 4 years ago

Hi @Shaopus

I assume that you meant ESP8266_RTOS_SDK in release/v3.3, not the ESP-IDF in v3.3, so this version of esp-mqtt: https://github.com/espressif/ESP8266_RTOS_SDK/tree/release/v3.3/components/mqtt/esp-mqtt

This version is based on an older revision of esp-mqtt, specifically this commit of esp-mqtt: 8b45c25fdca6e4bfe693321c368080db86b9c8ae and the errors you're getting are very likely concurrency issues, since the API locks were added a bit later to support publishing from a separate task in 752953dc3be007cca4255b66a35d3087e61f6a54.

As a workaround I might suggest replacing the content of components/mqtt/esp-mqtt in ESP8266_RTOS_SDK with the latest version this library.

Shaopus commented 4 years ago

Hi @david-cermak

Thanks! It is OK when I use the latest version.