You can chat about native SDK questions and issues here.

User avatar
By MaroMet
#85571 Hello, I'm new to ESP8266, and I'm having some trouble with frequently calling GET Requests.
I'm using RTOS SDK 3.0.
I have looked around here and in google, and could find an answer.
I'm using http_client API based on http_client_example.

What happens:
    -The GET Request is in a task performed every now and then (issue persists regardless of delay),
    -After around 20-50 repetitions the message can't be written(ERROR 28675), even so it's a short constant string,
    -Wiresharked TCP connection looks pretty normal when it happens, but omits the PSH signal,
    -Sometimes it resolves itself after a while
    -Sometimes it drops connection and leaves (ERROR 28674 couldn't connect sock < 0).

Things I've done to try to resolve the issue
    -I've set the tasks' priorities to lower than 12,
    -I'm using the GET request on one client instance, which is immediately cleaned up.
    -Looked around in SDK modules to find errors' implementations. The Error write requests come from esp_http_client_request_send function, which is indirectly called from esp_http_client_perform,
    -Disabled router's DoS protection,
Maybe it's a memory issue? The client is not cleanedup properly?
NOTE: Deleting any of my personal code (Json Parsing, the array or struct operation), except for the HTTP GET request in a task doesn't solve the issue, neither is changing the Delay


HTTP Task
Code: Select allstatic void http_test_task(void *pvParameters)
{
   
    while(1){
        const char *id = "id=1";
        char buff[MAX_HTTP_RECV_BUFFER];
        esp_http_client_config_t config = {
        .url = "http://192.168.1.2/api/light/get",
        .event_handler = _http_event_handler,
        .timeout_ms = 1000,
        };
       
        esp_http_client_handle_t client;
        client = esp_http_client_init(&config);
        esp_http_client_set_url(client, "http://192.168.1.2/api/light/get");
        esp_http_client_set_header(client, "Content_Type", "application/x-www-form-urlencoded");
        esp_http_client_set_post_field(client, id, strlen(id));
        esp_http_client_set_method(client, HTTP_METHOD_GET);

        esp_err_t err;
       
        err = esp_http_client_perform(client);

        if (err == ESP_OK) {
           
            ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %d",       
            esp_http_client_get_status_code(client),
            esp_http_client_get_content_length(client));
            esp_http_client_read(client, buff, MAX_HTTP_RECV_BUFFER);
            esp_http_client_cleanup(client);
           
            json = cJSON_Parse(buff);
   
            r = cJSON_GetObjectItem(json, "red");
            char *out = cJSON_Print(r);
            mylight.red = strtod(out, NULL);
            printf("red: %f", mylight_p->red);
            duties[0] = (uint32_t)(mylight_p->red*1000);
                       
            g = cJSON_GetObjectItem(json, "green");
            out = cJSON_Print(g);
            mylight.green = strtod(out, NULL);
            printf("green: %f", mylight_p->green);
            duties[1] = (uint32_t)(mylight_p->green*1000);
                       
            b = cJSON_GetObjectItem(json, "blue");
            out = cJSON_Print(b);
            mylight.blue = strtod(out, NULL);
            printf("blue: %f", mylight_p->blue);
            duties[2] = (uint32_t)(mylight_p->blue*1000);
                       
            i = cJSON_GetObjectItem(json, "intensity");
            out = cJSON_Print(i);
            mylight.intensity = strtod(out, NULL);
            printf("intensity: %f", mylight_p->intensity);
            if  (mylight_p->intensity == 0) {
                duties[0] = 0;
                duties[1] = 0;
                duties[2] = 0;
            }


        } else {
            ESP_LOGE(TAG, "HTTP GET request failed: %d", err);
            esp_http_client_cleanup(client);

        }
   
        vTaskDelay(2000/portTICK_PERIOD_MS);
    }
    vTaskDelete(NULL);
}


FULL Code
Code: Select all
#include <string.h>
#include <stdlib.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"

#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"

#include "app_wifi.h"
#include "esp_http_client.h"
#include "cJSON.h"

#include "driver/pwm.h"
#include "esp8266/gpio_register.h"
#include "esp8266/pin_mux_register.h"


#define MAX_HTTP_RECV_BUFFER 512

#define PWM_0_OUT_IO_NUM   12
#define PWM_1_OUT_IO_NUM   13
#define PWM_2_OUT_IO_NUM   14

#define PWM_PERIOD  (1000)

static const char *TAG = "HTTP_CLIENT";
char buff[MAX_HTTP_RECV_BUFFER];

/* pwm configuration */
const uint32_t pin_num[3] = {
    PWM_0_OUT_IO_NUM,
    PWM_1_OUT_IO_NUM,
    PWM_2_OUT_IO_NUM,
};

uint32_t duties[3] = {
    0, 0, 0,
};

int16_t phase[3] = {
    0, 0, 0,
};

cJSON *json;
cJSON *r;
cJSON *g;
cJSON *b;
cJSON *i;

typedef struct light {
    double red;
    double green;
    double blue;
    double intensity;
}light;

/* Root cert for howsmyssl.com, taken from howsmyssl_com_root_cert.pem

   The PEM file was extracted from the output of this command:
   openssl s_client -showcerts -connect www.howsmyssl.com:443 </dev/null

   The CA root cert is the last cert given in the chain of certs.

   To embed it in the app binary, the PEM file is named
   in the component.mk COMPONENT_EMBED_TXTFILES variable.
*/
extern const char howsmyssl_com_root_cert_pem_start[] asm("_binary_howsmyssl_com_root_cert_pem_start");
extern const char howsmyssl_com_root_cert_pem_end[]   asm("_binary_howsmyssl_com_root_cert_pem_end");

light mylight = {};
light *mylight_p = &mylight;

static const char *id = "id=69";

esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
    switch(evt->event_id) {
        case HTTP_EVENT_ERROR:
            ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
            break;
        case HTTP_EVENT_ON_CONNECTED:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
            break;
        case HTTP_EVENT_HEADER_SENT:
            ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
            break;
        case HTTP_EVENT_ON_HEADER:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
            break;
        case HTTP_EVENT_ON_DATA:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
            if (!esp_http_client_is_chunked_response(evt->client)) {
                // Write out data
                // printf("%.*s", evt->data_len, (char*)evt->data);
            }

            break;
        case HTTP_EVENT_ON_FINISH:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
            break;
        case HTTP_EVENT_DISCONNECTED:
            ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED");
            break;
    }
    return ESP_OK;
}

   


static void http_test_task(void *pvParameters)
{
   
    while(1){
        const char *id = "id=1";
        char buff[MAX_HTTP_RECV_BUFFER];
        esp_http_client_config_t config = {
        .url = "http://192.168.1.2/api/light/get",
        .event_handler = _http_event_handler,
        .timeout_ms = 1000,
        };
       
        esp_http_client_handle_t client;
        client = esp_http_client_init(&config);
        esp_http_client_set_url(client, "http://192.168.1.2/api/light/get");
        esp_http_client_set_header(client, "Content_Type", "application/x-www-form-urlencoded");
        esp_http_client_set_post_field(client, id, strlen(id));
        esp_http_client_set_method(client, HTTP_METHOD_GET);

        esp_err_t err;
       
        err = esp_http_client_perform(client);

        if (err == ESP_OK) {
           
            ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %d",       
            esp_http_client_get_status_code(client),
            esp_http_client_get_content_length(client));
            esp_http_client_read(client, buff, MAX_HTTP_RECV_BUFFER);
            esp_http_client_cleanup(client);
           
            json = cJSON_Parse(buff);
   
            r = cJSON_GetObjectItem(json, "red");
            char *out = cJSON_Print(r);
            mylight.red = strtod(out, NULL);
            printf("red: %f", mylight_p->red);
            duties[0] = (uint32_t)(mylight_p->red*1000);
                       
            g = cJSON_GetObjectItem(json, "green");
            out = cJSON_Print(g);
            mylight.green = strtod(out, NULL);
            printf("green: %f", mylight_p->green);
            duties[1] = (uint32_t)(mylight_p->green*1000);
                       
            b = cJSON_GetObjectItem(json, "blue");
            out = cJSON_Print(b);
            mylight.blue = strtod(out, NULL);
            printf("blue: %f", mylight_p->blue);
            duties[2] = (uint32_t)(mylight_p->blue*1000);
                       
            i = cJSON_GetObjectItem(json, "intensity");
            out = cJSON_Print(i);
            mylight.intensity = strtod(out, NULL);
            printf("intensity: %f", mylight_p->intensity);
            if  (mylight_p->intensity == 0) {
                duties[0] = 0;
                duties[1] = 0;
                duties[2] = 0;
            }


        } else {
            ESP_LOGE(TAG, "HTTP GET request failed: %d", err);
            esp_http_client_cleanup(client);

        }
   
        vTaskDelay(2000/portTICK_PERIOD_MS);
    }
    vTaskDelete(NULL);
}

static void pwm_task(void *pvParameters)
{
    while(1){
        pwm_set_duties(duties);
        pwm_start();
        vTaskDelay(50/portTICK_RATE_MS);
    }
    vTaskDelete(NULL);
}
static void set_light_task(void *pvParameters){


}

void app_main()
{
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
      ESP_ERROR_CHECK(nvs_flash_erase());
      ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);
   
    app_wifi_initialise();
    app_wifi_wait_connected();
    pwm_init(PWM_PERIOD, duties, 3, pin_num);
    pwm_set_phases(phase);
    pwm_start();
   
    xTaskCreate(&http_test_task, "http_test_task", 32768, NULL, 15, NULL);
    xTaskCreate(&pwm_task, "pwm_task", 8192, NULL, 16, NULL);
   
}


Here are the errors, and wireshark output - the screen with HTTP packets is when the requests are working.
Image
Image
Image

Thanks for your response :)