Assert failed: xQueueGenericSend queue.c:821 (!( ( pvItemToQueue == ((void *)0) ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ))

I'm trying to find the IP address of a server using multiple tasks and deleting all the tasks after I find the server IP. Along with this I have two other tasks running called button and serverFunc which basically do the respective: wait for a physical button to be pressed, if pressed send the states of the pins to the server and on the other hand, wait for the server to ping the esp. When i had only the two tasks "button" and "serverFunc" running, there were no errors and everything was running perfectly fine. It's only after I added the multiple tasks of finding server IP, I'm getting the mentioned error along with guru meditation error (LoadProhibited) sometimes.

#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiManager.h>
#include <WebServer.h>
#include <Preferences.h>

String serverip;
String pass; //user password input by user from the web page
String st; //states of pins received from server
IPAddress ip; //stores ip address of esp32 after connection to wifi
//pinx_state stores states of pins
int pin1_state = 0;
int pin2_state = 0;
int pin3_state = 0;
int pin4_state = 0;
String pinStates;
String postData;
int control_var = 1;
//WiFi creds
String ssid;
String password;
//server links
String get_website = "http://192.168.0.105:5000/ONOFF/getstate/switch";
String post_website = "http://192.168.0.105:5000/ONOFF/setstate/switch";
String setup_website = "http://192.168.0.105:5000/ONOFF/setup";

String SBID;
TaskHandle_t serverFind1;
TaskHandle_t serverFind2;
TaskHandle_t serverFind3;
TaskHandle_t serverFind4;
TaskHandle_t serverFind5;
TaskHandle_t setupESPFunc;

#define PIN1 13
#define PIN2 27
#define PIN3 25
#define PIN4 32
#define BUTTON1 4
#define BUTTON2 18
#define BUTTON3 21
#define BUTTON4 23

WiFiServer ESPServer(80);
Preferences prf;

/*Function button runs continuously and 
  paralelly to the server function "serverFunc"
  Waits for button to be pressed, if any,
  change corresponding LED state and 
  post data to server in the format - 
  {"id":"switchboxid", "state":"pinState"}*/
void button(void* param){
  while(1){
    vTaskDelay(100);
    if(Serial.available()){
      String serialData = Serial.readStringUntil('\n');

      if(serialData == "1"){
        pin1_state = !pin1_state;
        digitalWrite(PIN1, pin1_state);
        Serial.print("Button ");
        Serial.print(serialData);
        Serial.print(" pressed, sending data to: ");
        Serial.println(post_website);
        pinStates = String(pin1_state) + String(pin2_state) + String(pin3_state) + String(pin4_state);
        postData = "{\"id\":\"" + SBID + "\", \"state\":\"" + pinStates + "\"}";
        POST_data(postData);
      }
      if(serialData == "2"){
        pin2_state = !pin2_state;
        digitalWrite(PIN2, pin2_state);
        Serial.print("Button ");
        Serial.print(serialData);
        Serial.print(" pressed, sending data to: ");
        Serial.println(post_website);
        pinStates = String(pin1_state) + String(pin2_state) + String(pin3_state) + String(pin4_state);
        postData = "{\"id\":\"" + SBID + "\", \"state\":\"" + pinStates + "\"}";
        POST_data(postData);
      }
      if(serialData == "3"){
        pin3_state = !pin3_state;
        digitalWrite(PIN3, pin3_state);
        Serial.print("Button ");
        Serial.print(serialData);
        Serial.print(" pressed, sending data to: ");
        Serial.println(post_website);
        pinStates = String(pin1_state) + String(pin2_state) + String(pin3_state) + String(pin4_state);
        postData = "{\"id\":\"" + SBID + "\", \"state\":\"" + pinStates + "\"}";
        POST_data(postData);
      }
      if(serialData == "4"){
        pin4_state = !pin4_state;
        digitalWrite(PIN4, pin4_state);
        Serial.print("Button ");
        Serial.print(serialData);
        Serial.print(" pressed, sending data to: ");
        Serial.println(post_website);
        pinStates = String(pin1_state) + String(pin2_state) + String(pin3_state) + String(pin4_state);
        postData = "{\"id\":\"" + SBID + "\", \"state\":\"" + pinStates + "\"}";
        POST_data(postData);
      }
    }
  }
}

//Function for setting states of appliances in server
void POST_data(String data_to_post){
  if(WiFi.status() == WL_CONNECTED){
    HTTPClient http;

    http.begin(post_website);
    http.addHeader("Content-Type", "application/json");
    int httpResponseCode = http.POST(data_to_post);

    if (httpResponseCode > 0) {
      String response = http.getString();
      Serial.println(response);
    }
    else {
      Serial.print("Error sending request: ");
      Serial.println(httpResponseCode);
    }
    http.end();
  }
}

/*Function that runs paralelly to button
  Waits for a 'ping' from the server, 
  if received, calls the GET_data function
  to receives states of pins and update*/
void serverFunc(void* param){
  while(1){
    vTaskDelay(500);
    
    WiFiClient client = ESPServer.available();

    if(client){
      if(client.connected()){
        GET_data();
      }
    }
    client.stop();
  }
}

void GET_data(){
  if(WiFi.status() == WL_CONNECTED){
    st = httpGETRequest();

    Serial.print("States from server: ");
    Serial.println(st);
  }
}

String httpGETRequest(){
  HTTPClient http;

  http.begin(get_website);

  http.addHeader("Content-Type", "text/plain");
  int httpResponseCode = http.POST(SBID);

  String payload = "-";

  if (httpResponseCode > 0) {
    payload = http.getString();
  }
  http.end();
  return payload;
}

void wifiSetup(){
  WiFiManager wm;

  wm.setDarkMode(true);

  WiFiManagerParameter userPwd("userPWD", "User Password", "", 40);
  wm.addParameter(&userPwd);

  if (!wm.autoConnect("ESPWiFi")) {
    Serial.println("Failed to connect");
  } else {
    Serial.println("Connected Succesfully");
  }
  pass = userPwd.getValue();
  Serial.println();
  Serial.println();
  if(pass != ""){
    prf.begin("SBDetails", false);
    prf.putString("pwd", pass);
    prf.end();
  }
  Serial.println();
  Serial.println();

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnected to WiFi");
  ssid = wm.getWiFiSSID(true);
  Serial.print("SSID: ");
  Serial.println(ssid);
  password = wm.getWiFiPass(true);
  Serial.print("Password: ");
  Serial.println(password);
  Serial.print("ESP32 IP: ");
  ip = WiFi.localIP();
  Serial.println(ip);
  Serial.print("User Password: ");
  Serial.println(pass);
}

void calcTime(){
  configTime(16200, 3600, "pool.ntp.org");
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return;
  }
  char id[23];
  strftime(id, 23, "4LLLF%d%m%Y%H%M%S", &timeinfo);
  SBID = id;
  prf.begin("SBDetails", false);
  prf.putString("sbid", SBID);
  prf.end();
}

// void serverFinder1(void* param){
//   while(1){
//     vTaskDelay(100);
//     for(int i = 0; i < 51; i++){
//       IPAddress servip1(192, 168, 0, i);
//       HTTPClient checkhttp1;
//       String check_website1 = "http://"+servip1.toString()+":5000/check";
//       checkhttp1.begin(check_website1);
//       if(checkhttp1.GET() > 0){
//         if(checkhttp1.getString() == "abcdefg"){
//           Serial.print("Server IP found: ");
//           Serial.println(servip1);
//           serverip = servip1.toString();
//           control_var = 0;
//           checkhttp1.end();
//           vTaskDelete(serverFind2);
//           vTaskDelete(serverFind3);
//           vTaskDelete(serverFind4);
//           vTaskDelete(serverFind5);
//           vTaskDelete(serverFind1);
//         }
//       }
//       checkhttp1.end();
//     }
//   }
// }

// void serverFinder2(void* param){
//   while(1){
//     vTaskDelay(100);
//     for(int i = 51; i < 102; i++){
//       IPAddress servip2(192, 168, 0, i);
//       HTTPClient checkhttp2;
//       String check_website2 = "http://"+servip2.toString()+":5000/check";
//       checkhttp2.begin(check_website2);
//       if(checkhttp2.GET() > 0){
//         if(checkhttp2.getString() == "abcdefg"){
//           Serial.print("Server IP found: ");
//           Serial.println(servip2);
//           serverip = servip2.toString();
//           control_var = 0;
//           checkhttp2.end();
//           vTaskDelete(serverFind1);
//           vTaskDelete(serverFind3);
//           vTaskDelete(serverFind4);
//           vTaskDelete(serverFind5);
//           vTaskDelete(serverFind2);
//         }
//       }
//       checkhttp2.end();
//     }
//   }
// }

// void serverFinder3(void* param){
//   while(1){
//     vTaskDelay(100);
//     for(int i = 102; i < 153; i++){
//       IPAddress servip3(192, 168, 0, i);
//       HTTPClient checkhttp3;
//       String check_website3 = "http://"+servip3.toString()+":5000/check";
//       checkhttp3.begin(check_website3);
//       if(checkhttp3.GET() > 0){
//         if(checkhttp3.getString() == "abcdefg"){
//           Serial.print("Server IP found: ");
//           Serial.println(servip3);
//           serverip = servip3.toString();
//           control_var = 0;
//           checkhttp3.end();
//           vTaskDelete(serverFind1);
//           vTaskDelete(serverFind2);
//           vTaskDelete(serverFind4);
//           vTaskDelete(serverFind5);
//           vTaskDelete(serverFind3);
//         }
//       }
//       checkhttp3.end();
//     }
//   }
// }

// void serverFinder4(void* param){
//   while(1){
//     vTaskDelay(100);
//     for(int i = 153; i < 204; i++){
//       IPAddress servip4(192, 168, 0, i);
//       HTTPClient checkhttp4;
//       String check_website4 = "http://"+servip4.toString()+":5000/check";
//       checkhttp4.begin(check_website4);
//       if(checkhttp4.GET() > 0){
//         if(checkhttp4.getString() == "abcdefg"){
//           Serial.print("Server IP found: ");
//           Serial.println(servip4);
//           serverip = servip4.toString();
//           control_var = 0;
//           checkhttp4.end();
//           vTaskDelete(serverFind1);
//           vTaskDelete(serverFind2);
//           vTaskDelete(serverFind3);
//           vTaskDelete(serverFind5);
//           vTaskDelete(serverFind4);
//         }
//       }
//       checkhttp4.end();
//     }
//   }
// }

// void serverFinder5(void* param){
//   while(1){
//     vTaskDelay(100);
//     for(int i = 204; i < 255; i++){
//       IPAddress servip5(192, 168, 0, i);
//       HTTPClient checkhttp5;
//       String check_website5 = "http://"+servip5.toString()+":5000/check";
//       checkhttp5.begin(check_website5);
//       if(checkhttp5.GET() > 0){
//         if(checkhttp5.getString() == "abcdefg"){
//           Serial.print("Server IP found: ");
//           Serial.println(servip5);
//           serverip = servip5.toString();
//           control_var = 0;
//           checkhttp5.end();
//           vTaskDelete(serverFind1);
//           vTaskDelete(serverFind2);
//           vTaskDelete(serverFind3);
//           vTaskDelete(serverFind4);
//           vTaskDelete(serverFind5);
//         }
//       }
//       checkhttp5.end();
//     }
//   }
// }

// void setupESP(void* param){
//   while(1){
//     vTaskDelay(200);
//     if(control_var != 1){
//       Serial.print("Inside setupESP function, ");
//       Serial.print("value of control var: ");
//       Serial.println(control_var);
//       WiFiManager wm;
//       wm.autoConnect("ESPWiFi");
//       get_website = "http://"+serverip+":5000/ONOFF/getstate/switch";
//       post_website = "http://"+serverip+":5000/ONOFF/setstate/switch";
//       setup_website = "http://"+serverip+":5000/ONOFF/setup";
//       HTTPClient setuphttp;
//       setuphttp.begin(setup_website);
//       setuphttp.addHeader("Content-Type", "application/json");
//       String data = "{\"id\": \"" + SBID + "\", \"state\": \"0000\", \"ip\": \"" + WiFi.localIP().toString() + "\"}";
//       if(setuphttp.POST(data) > 0){
//         Serial.println("Setup Successful");
//       }
//       else{
//         Serial.println("Setup Failed");
//       }
//       Serial.println("End of the setupESP function");
//       vTaskDelete(setupESPFunc);
//     }
//   }
// }

void setup() {
  WiFi.disconnect();

  Serial.begin(9600);

  pinMode(PIN1, OUTPUT);
  pinMode(PIN2, OUTPUT);
  pinMode(PIN3, OUTPUT);
  pinMode(PIN4, OUTPUT);
  pinMode(BUTTON1, INPUT);
  pinMode(BUTTON2, INPUT);
  pinMode(BUTTON3, INPUT);
  pinMode(BUTTON4, INPUT);
  digitalWrite(PIN1, LOW);
  digitalWrite(PIN2, LOW);
  digitalWrite(PIN3, LOW);
  digitalWrite(PIN4, LOW);

  Serial.println();
  Serial.println();
  prf.begin("SBDetails", true);
  pass = prf.getString("pwd", "");
  prf.end();
  if(pass == ""){
    wifiSetup();
  }
  Serial.println();
  Serial.println();
  prf.begin("SBDetails", true);
  SBID = prf.getString("sbid", "");
  prf.end();
  if(SBID == ""){
    calcTime();
  }
  Serial.println();
  Serial.println();

  WiFiManager wm;
  wm.autoConnect("ESPWiFi");

  ESPServer.begin();
  Serial.println("ESPServer begun");

  // xTaskCreate(serverFinder1, "Find Server", 8192, NULL, 1, &serverFind1);
  // xTaskCreate(serverFinder2, "Find Server", 8192, NULL, 1, &serverFind2);
  // xTaskCreate(serverFinder3, "Find Server", 8192, NULL, 1, &serverFind3);
  // xTaskCreate(serverFinder4, "Find Server", 8192, NULL, 1, &serverFind4);
  // xTaskCreate(serverFinder5, "Find Server", 8192, NULL, 1, &serverFind5);
  // xTaskCreate(setupESP, "Find Server", 8192, NULL, 1, &setupESPFunc);
  xTaskCreate(button, "Button Function", 4096, NULL, 2, NULL);
  xTaskCreate(serverFunc, "Server Function", 4096, NULL, 2, NULL);
}

void loop() {}

Please show the error message in full

Why do you need multiple tasks to do that?

Hello, I managed to fix the error by suspending the tasks instead of deleting them but of course I would prefer if I could delete the tasks.

I'm doing a POST request to the IP addresses and in the server side, i have a function that specifically returns a particular value. So when I get a response, I can check if it is the value the server is returning. Because I'm doing a POST request, going through 1 IP address takes about 1-2 seconds and I need to scan through 255 addresses, which brings the worst case scenario time to about 12 minutes. By splitting the load between multiple tasks, I'm able to scan 5 addresses at once which reduces my time to about 2.5min. I couldn't really find another work around so please let me know if there's a better way to do it.

Have you explored how the standard HTTPClient library behaves with multiple open clients? I'd think you'd need the AsyncClient library to properly handle that.

I'd look into doing it all with one task using an array of AsyncClient objects.

I remember seeing a library "AsyncTCP" somewhere while looking for solution, but don't remember the code using the functions from the library. Do you think this might be the solution? Also would love to find out how to properly delete the tasks because I'm currently only suspending them. I'd want to know that for some time in the future I'm sure.

Perhaps, that's why I suggested looking in to it.

You won't need to worry about that if you use a single task handling an array of AsyncClient objects. Once one of them locates the IP address you're looking for, you just need to stop and clean up the remaining clients. Then the task can cleanly delete itself.

so having something like this should be good to go?

void findServer(void* param){
    //logic for finding ip using asynctcp
   vTaskDelete(findServerHandle);
}

void setup(){
    xTaskCreate(findServer, ....);
}

A task can delete itself with:

vTaskDelete(NULL);

Alright I'll try this out. Thanks!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.