Page 1 of 1

Code Crashing when Requesting Data from OpenWeatherMap

Posted: Fri Jul 07, 2023 6:50 pm
by xpress_embedo
Hello Everyone,
I am new to ESP32 and wanted to write a simple application to get weather information from the OpenWeatherMap website.
It works fine for the first time, but when I try to request the data next time, my program crashes and restarts with the following message.
  1. Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.
The following is the piece of the code for reference, and it is crashing when "openweathermap_send_request" is called second time, and more specifically while calling the function "esp_err_t err = esp_http_client_perform(client);"
  1. // OpenWeatherMap Task
  2. static void openweathermap_task(void *pvParameters)
  3. {
  4.   // Initialize the City Names
  5.   strcpy(city_weather[0].city_name, "manali");
  6.   strcpy(city_weather[1].city_name, "kashmir");
  7.   strcpy(city_weather[2].city_name, "jaipur");
  8.   strcpy(city_weather[3].city_name, "delhi");
  9.  
  10.   for( ; ; )
  11.   {
  12.     openweathermap_send_request();
  13.     vTaskDelay(HTTP_REQ_EXEC_RATE / portTICK_PERIOD_MS);
  14.   }
  15.  
  16.   vTaskDelete(NULL);
  17. }
  18.  
  19. static void openweathermap_send_request(void)
  20. {
  21.   char openweathermap_url[200];
  22.   city_weather_index = 0;  // added for debugging
  23.   snprintf( openweathermap_url, sizeof(openweathermap_url), \
  24.             "%s%s%s", CLIENT_REQ_PRE, city_weather[city_weather_index].city_name, CLIENT_REQ_POST);
  25.  
  26.   esp_http_client_config_t config =
  27.   {
  28.     .url = openweathermap_url,
  29.     .method = HTTP_METHOD_GET,
  30.     .event_handler = openweathermap_event_handler,
  31.   };
  32.  
  33.   ESP_LOGI(TAG, "OpenWeatherMap Task Execution Started");
  34.  
  35.   esp_http_client_handle_t client = esp_http_client_init(&config);
  36.   esp_http_client_set_header(client, CLIENT_KEY, CLIENT_VALUE);
  37.   esp_err_t err = esp_http_client_perform(client);
  38.   if( err == ESP_OK )
  39.   {
  40.     int status = esp_http_client_get_status_code(client);
  41.     if(status == 200)
  42.     {
  43.       ESP_LOGI(TAG, "City=%s, Message Sent Successfully", city_weather[city_weather_index].city_name);
  44.       city_weather_index++;
  45.       // Reset back to Initial Position
  46.       if( city_weather_index >= NUM_OF_CITIES )
  47.       {
  48.         city_weather_index = 0;
  49.       }
  50.     }
  51.     else
  52.     {
  53.       ESP_LOGI(TAG, "City=%s, Message Sent Failed", city_weather[city_weather_index].city_name);
  54.     }
  55.   }
  56.   else
  57.   {
  58.     ESP_LOGI(TAG, "City=%s, Message Sent Failed", city_weather[city_weather_index].city_name);
  59.   }
  60.   esp_http_client_cleanup(client);
  61.   ESP_LOGI(TAG, "OpenWeatherMap Task Execution Complete");
  62. }
  63.  
  64. static esp_err_t openweathermap_event_handler(esp_http_client_event_t *event)
  65. {
  66.   switch(event->event_id)
  67.   {
  68.     case HTTP_EVENT_ON_DATA:
  69.       // Resize the Buffer to fit the new chunk of the data
  70.       response_data = realloc(response_data, response_len + event->data_len);
  71.       // Copy the Data
  72.       memcpy(response_data+response_len, event->data, event->data_len);
  73.       // Update the Length
  74.       response_len += event->data_len;
  75.       // Only used for debugging
  76.       // ESP_LOGI("OpenWeatherAPI", "Partial Received Data: %d", event->data_len);
  77.       break;
  78.     case HTTP_EVENT_ON_FINISH:
  79.       all_data_received = true;
  80.       // NOTE: TAG is different here (debugging purpose)
  81.       // ESP_LOGI("OpenWeatherAPI", "Received Data: %s", response_data);
  82.       // Decode/Parse the weather data from the response data
  83.       openweathermap_get_weather(response_data, &city_weather[0]);
  84.       // free up the space, and reset the response length
  85.       free(response_data);
  86.       response_len = 0;
  87.       ESP_LOGI("OpenWeatherAPI", "City=%s, Temp=%f, Pressure=%d, Humidity=%d", \
  88.                 city_weather[city_weather_index].city_name,   \
  89.                 city_weather[city_weather_index].temperature, \
  90.                 city_weather[city_weather_index].pressure,    \
  91.                 city_weather[city_weather_index].humidity);
  92.       ESP_LOGI("OpenWeatherAPI", "Exiting Event Handler");
  93.       break;
  94.     default:
  95.       break;
  96.   }
  97.   return ESP_OK;
  98. }
Logs on Terminal when code crashed.
  1. I (27940) WIFI: OpenWeatherMap Task Execution Complete
  2. I (30920) WIFI: Hello World from Main Task
  3. I (32940) WIFI: OpenWeatherMap Task Execution Started
  4. I (35920) WIFI: Hello World from Main Task
  5. I (35970) OpenWeatherAPI: City=manali, Temp=30.040001, Pressure=1007, Humidity=82
  6. I (35970) OpenWeatherAPI: Exiting Event Handler
  7. I (35970) WIFI: City=manali, Message Sent Successfully
  8. I (35980) WIFI: OpenWeatherMap Task Execution Complete
  9. I (40920) WIFI: Hello World from Main Task
  10. I (40980) WIFI: OpenWeatherMap Task Execution Started
  11. Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.
Any sort of help is appreciated.
Thanks, and Regards

Re: Code Crashing when Requesting Data from OpenWeatherMap

Posted: Sat Jul 08, 2023 7:17 am
by xpress_embedo
I found the reason, it was not due to the "_perform()" function, while it was due to the realloc function, still don't know why, instead of crashing it should have returned the NULL pointer.
Anyways I changed the approach to use a big buffer and track the data with indexes, and it works.
The problem is solved, in case someone wanted to comment on something, feel free.
Thanks, and Regards