Сработал сторожевой таймер задач. / Abort () был вызван в P C 0x400de07b на ядре 0 - PullRequest
0 голосов
/ 13 марта 2020

Я работаю над проектом автономного робота GPS. Когда я запускаю приведенный ниже код через некоторое время, esp32 (devkit v1) перезагружается, и это повторяется.

Pause for Startup... 3
Pause for Startup... 2
Pause for Startup... 1
Searching for Satellites 
Searching for Satellites 
GPS Waypoint 1 Set Waypoint #1: 0.000000 , 0.000000
Waypoint #2: 0.000000 , 0.000000
5 Satellites Acquired10.190620
76.424872
25.190620
47.424872
YOYYYYO
Go to Waypoint
E (98333) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (98333) task_wdt:  - async_tcp (CPU 0/1)
E (98333) task_wdt: Tasks currently running:
E (98333) task_wdt: CPU 0: IDLE0
E (98333) task_wdt: CPU 1: async_tcp
E (98333) task_wdt: Aborting.
abort() was called at PC 0x400de07b on core 0

Backtrace: 0x4008cbf8:0x3ffbe170 0x4008ce29:0x3ffbe190 0x400de07b:0x3ffbe1b0 0x40084f01:0x3ffbe1d0 0x40148e07:0x3ffbc0d0 0x400df42b:0x3ffbc0f0 0x4008ab01:0x3ffbc110 0x4008930d:0x3ffbc130

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:8896
load:0x40080400,len:5816
entry 0x400806ac
Welcome
Autonmous Mode Initiated...

IP Address: 192.168.1.18
Compass setting done
 iam here1
Pause for Startup... 
Pause for Startup... 10
Pause for Startup... 9
Pause for Startup... 8
YOYYYYO
Go to Waypoint
Pause for Startup... 7
Pause for Startup... 6
Pause for Startup... 5
Pause for Startup... 4
Pause for Startup... 3
E (10128) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (10128) task_wdt:  - async_tcp (CPU 0)
E (10128) task_wdt: Tasks currently running:
E (10128) task_wdt: CPU 0: Tmr Svc
E (10128) task_wdt: CPU 1: IDLE1
E (10128) task_wdt: Aborting.
abort() was called at PC 0x400de07b on core 0

Backtrace: 0x4008cbf8:0x3ffbe170 0x4008ce29:0x3ffbe190 0x400de07b:0x3ffbe1b0 0x40084f01:0x3ffbe1d0 0x4000bfed:0x3ffbd060 0x4008a489:0x3ffbd070 0x400827d1:0x3ffbd090 0x40082843:0x3ffbd0b0 0x4008b825:0x3ffbd0d0 0x4008b924:0x3ffbd100 0x4008930d:0x3ffbd130

Rebooting...
ets Jun  8 2016 00:22:57

Это сообщение, которое отображается на последовательном мониторе. Я попытался отладить, но не могу понять, почему это происходит.

Код действительно большой, поэтому я загрузил только его часть.

// CompaSerial Variables & Setup

HMC5883L compass;
int16_t mx, my, mz;                                                // variables to store x,y,z axis from compass (HMC5883L)
int desired_heading;                                               // initialize variable - stores value for the new desired heading
int compass_heading;                                               // initialize variable - stores value calculated from compass readings
int compass_dev = 5;                                               // the amount of deviation that is allowed in the compass heading - Adjust as Needed
                                                                   // setting this variable too low will cause the robot to continuously pivot left and right
                                                                   // setting this variable too high will cause the robot to veer off course

int Heading_A;                                                     // variable to store compass heading
int Heading_B;                                                     // variable to store compass heading in Opposite direction
int pass = 0;                                                      // variable to store which paSerial the robot is on


//*****************************************************************************************************
// GPS Locations

unsigned long Distance_To_Home;                                    // variable for storing the distance to destination

int ac =0;                                                         // GPS array counter
int wpCount = 0;                                                   // GPS waypoint counter
double Home_LATarray[2];                                          // variable for storing the destination Latitude - Only Programmed for 5 waypoint
double Home_LONarray[2];                                          // variable for storing the destination Longitude - up to 50 waypoints

int increment = 0;

//*****************************************************************************************************
// HTML Page
AsyncWebServer server(80);
const char* ssid = "******";
const char* password = "******";

const char* PARAM_INPUT_1 = "input1";
const char* PARAM_INPUT_2 = "input2";
const char* PARAM_INPUT_3 = "input3";
const char* PARAM_INPUT_4 = "input4";
const char* PARAM_COMMIT = "commit";
double lati1;
double logi1;
double lati2;
double logi2;

// HTML web page to handle 4 input fields 
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
   <head>
      <h2>Autonomus GPS Robot Car<h2>
      <h3> Submit your Destination coordinates</h3>
      <meta name="viewport" content="width=device-width, initial-scale=1">
   </head>
   <body>
   <style>

   a {
  border: 10px solid powderblue;
  padding: 10px;
  color: red;
  font-family: verdana;
  font-size: 150%;
}
</style>
</head>
<body>
<form action="/get" >
 <br> 
    Waypoint 1 Latitude : <input type="text" name="input1">
     <br>
   <br>
    Waypoint 1 Longitude: <input type="text" name="input2">
  <br><br>
    <br> 
    Waypoint 2 Latitude : <input type="text" name="input3">
     <br>
   <br>
    Waypoint 2 Longitude: <input type="text" name="input4">
  <br><br>
   <input type="submit" value="Submit">

        <br>
    <br><br>
    <br><br>


    <a href="/go" >Go to Destination</a>
    <br><br>    <br><br>
    <br><br>

    <a href="/clear" > Clear waypoints</a>
</form>
</body>
</html>)rawliteral";

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

//*****************************************************************************************************
// Extras

#define autopilot 18
 void  gesturecontroll();
 void getGPS();    
 void getCompass();  
 void Forward();
void Forward_Meter();
void Reverse();
void LeftTurn();
void RightTurn();
void SlowLeftTurn();
void SlowRightTurn();
void StopCar();
void setWaypoint();
 void move();
 void Startup();
 void goWaypoint();
 void clearWaypoints();

 int blueToothVal;  
 int flag=0;
 int button;


void setup() 
{    Serial.begin(115200);                                            // Serial 0 is for communication with the computer
     Serial.println("Welcome");

pinMode(autopilot, INPUT);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 button = digitalRead(autopilot);
 if (button == HIGH)
 {   flag=15;
     Serial.println("Manual Control initated");
     Serial.println("ESPNow/Basic/Slave Example");
     //Set device in AP mode to begin with
     WiFi.mode(WIFI_AP);
     // configure device AP mode
     // This is the mac address of the Slave in AP Mode
     esp_wifi_set_mac(ESP_IF_WIFI_STA, &mac[0]);


     Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress());
     // Init ESPNow with a fallback logic
     if (esp_now_init()!=0)
      {
          Serial.println("*** ESP_Now init failed");
          while(true) {};
       }

       // Once ESPNow is successfully Init, we will register for recv CB to
      // get recv packer info.
       esp_now_register_recv_cb(OnDataRecv);
      Serial.print("Aheloiioi");                  // the remaining code for above part is not uploaded since when switch is pulled this part of code works perfectly
 }

 else{   
        S2.begin(9600, SERIAL_8N1, RXPin, TXPin);                                             // Serial 2 is for GPS communication at 9600 baud - DO NOT MODIFY - Ublox Neo 6m 
         flag=0;
        // pinMode(LED_BUILTIN, OUTPUT);                                   // An LED indicator - Not Used
         Serial.println("Autonmous Mode Initiated...");
    WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("WiFi Failed!");
    return;
  }
  Serial.println();
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
      CompaSerial////////////////////////////////////////////////////////////////////////////////////
         Wire.begin();                                                    // Join I2C bus used for the HMC5883L compass
        //compass.init();
         compass.begin();                                                 // initialize the compass (HMC5883L)
         compass.setRange(HMC5883L_RANGE_1_3GA);                          // Set measurement range  
         compass.setMeasurementMode(HMC5883L_CONTINOUS);                  // Set measurement mode  
         compass.setDataRate(HMC5883L_DATARATE_30HZ);                     // Set data rate  
         compass.setSamples(HMC5883L_SAMPLES_8);                          // Set number of samples averaged  
         compass.setOffset(0,0);
         Serial.println("Compass setting done");
               Startup(); // Run the Startup procedure on power-up one time
     }              
}  

// Main Loop

void loop()
{  button = digitalRead(autopilot);
    if (button == HIGH && flag==15)
    {      
      } 
     else
    {  Coordinates();
    getGPS();                                                        // Update the GPS location
    getCompass();                                                    // Update the CompaSerial Heading
    //Ping();                                                          // Use at your own discretion, this is not fully tested

    }    

}


void Coordinates()
{    Serial.println("i am here1");


  // Send web page with input fields to client
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });

  // Send a GET request to <ESP_IP>/get?input1=<inputMessage>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String latitude1;
    String latitude1Param;
    String longitude1;
    String longitude1Param;
    String latitude2;
    String latitude2Param;
    String longitude2;
    String longitude2Param;
   String commitType;;


    if (request->hasParam(PARAM_INPUT_2)||request->hasParam(PARAM_INPUT_1) ) {
    // GET input1 value on <ESP_IP>/get?input1=<latitude>

      latitude1 = request->getParam(PARAM_INPUT_1)->value();
      latitude1Param = PARAM_INPUT_1;

    // GET input2 value on <ESP_IP>/get?input2=<longitude>

       longitude1 = request->getParam(PARAM_INPUT_2)->value();
       longitude1Param = PARAM_INPUT_2;

// GET input3 value on <ESP_IP>/get?input3=<latitude>

      latitude2 = request->getParam(PARAM_INPUT_3)->value();
      latitude2Param = PARAM_INPUT_3;

    // GET input4 value on <ESP_IP>/get?input4=<longitude>

       longitude2 = request->getParam(PARAM_INPUT_4)->value();
       longitude2Param = PARAM_INPUT_4;
  }


    else {
      latitude1 = "No message sent";
      latitude1Param = "none";
      longitude1 = "No message sent";
      longitude1Param = "none";
      latitude2 = "No message sent";
      latitude2Param = "none";
      longitude2 = "No message sent";
      longitude2Param = "none";

    }


    Serial.println(latitude1);
    Serial.println(longitude1);
    Serial.println(latitude2);
    Serial.println(longitude2);
    lati1=(latitude1.toFloat());
    logi1=(longitude1.toFloat());
    lati2=(latitude2.toFloat());
    logi2=(longitude2.toFloat());
    //Serial.println(lati,6);
    //Serial.println(logi,6);
    request->send(200, "text/html", "Command succesfuly sent""<br><a href=\"/\">Return to Home Page</a>");
  });

  server.on("/go", HTTP_GET, [] (AsyncWebServerRequest *request) {
//logic for go here
Serial.println("YOYYYYO");
        goWaypoint();

request->redirect("/");
});

server.on("/clear", HTTP_GET, [] (AsyncWebServerRequest *request) {
//logic for clear here
  Serial.println("fdfghgh");
   clearWaypoints();
request->redirect("/");
});
  server.onNotFound(notFound);
  server.begin();
}

void getGPS()                                                 // Get Latest GPS coordinates
{  Serial.println("i am here2");
    while (S2.available() > 0)
    gps.encode(S2.read());
} 

// *************************************************************************************************************************************************

void setWaypoint()                                            // Set up to 5 GPS waypoints
{

//if ((wpCount >= 0) && (wpCount < 50))
if (wpCount >= 0)
  {
    Serial.print("GPS Waypoint ");
    Serial.print(wpCount + 1);
    Serial.print(" Set ");

    Home_LATarray[ac] = lati1 ;                   // store waypoint in an array   
    Home_LONarray[ac] = logi1 ;             // store waypoint in an array   
    Home_LATarray[ac] = lati2 ;               // store waypoint in an array   
    Home_LONarray[ac] = logi2 ;                  // store waypoint in an array   

    Serial.print("Waypoint #1: ");
    Serial.print(Home_LATarray[0],6);
    Serial.print(" , ");
    Serial.println(Home_LONarray[0],6);
    Serial.print("Waypoint #2: ");
    Serial.print(Home_LATarray[1],6);
    Serial.print(" , ");
    Serial.println(Home_LONarray[1],6);
    wpCount++;                                                  // increment waypoint counter
    ac++;                                                       // increment array counter

  }         
  else {Serial.print("Waypoints Full");}
}

// ************************************************************************************************************************************************* 

void clearWaypoints()
{
   memset(Home_LATarray, 0, sizeof(Home_LATarray));             // clear the array
   memset(Home_LONarray, 0, sizeof(Home_LONarray));             // clear the array
   wpCount = 0;                                                 // reset increment counter to 0
   ac = 0;

   Serial.print("GPS Waypoints Cleared");                      // display waypoints cleared

}

 // *************************************************************************************************************************************************

void getCompass()                                               // get latest compass value
 {  

  Vector norm = compass.readNormalize();

  // Calculate heading
  float heading = atan2(norm.YAxis, norm.XAxis);

  if(heading < 0)
     heading += 2 * M_PI;      
  compass_heading = (int)(heading * 180/M_PI);                   // aSerialign compass calculation to variable (compass_heading) and convert to integer to remove decimal places                                                              

 }

void Startup()
{ 
     Serial.println("Pause for Startup... ");

     for (int i=10; i >= 1; i--)                       // Count down for X seconds
      {         
        Serial.print("Pause for Startup... "); 
        Serial.println(i);
        delay(1000);                                   // Delay for X seconds
      }    


  Serial.println("Searching for Satellites "); 
  Serial.println("Searching for Satellites "); 

  while (Number_of_SATS <= 4)                         // Wait until x number of satellites are acquired before starting main loop
  {                                  
    getGPS();                                         // Update gps data
    Number_of_SATS = (int)(gps.satellites.value());   // Query Tiny GPS for the number of Satellites Acquired       
  }    
  setWaypoint();                                      // set intial waypoint to current location
  wpCount = 0;                                        // zero waypoint counter
  ac = 0;                                             // zero array counter

  Serial.print(Number_of_SATS);
  Serial.print(" Satellites Acquired");    
}   

void goWaypoint()
{   
 Serial.println("Go to Waypoint");
//Serial.print("Home_Latarray ");
//Serial.print(Home_LATarray[ac],6);
//Serial.print(" ");
//Serial.println(Home_LONarray[ac],6);   

//Serial1.print("Distance to Home");   
//Serial1.print(Distance_To_Home);

//Serial1.print("ac= ");
//Serial1.print(ac);

 while (true)  
  {                                                                // Start of Go_Home procedure 
 // bluetooth();                                                     // Run the Bluetooth procedure to see if there is any data being sent via BT
  if (blueToothVal == 5){break;}                                   // If a 'Stop' Bluetooth command is received then break from the Loop
  getCompass();                                                    // Update Compass heading                                          
  getGPS();                                                        // Tiny GPS function that retrieves GPS data - update GPS location// delay time changed from 100 to 10

  if (millis() > 5000 && gps.charsProcessed() < 10)                // If no Data from GPS within 5 seconds then send error
    Serial.println(F("No GPS data: check wiring"));     

  Distance_To_Home = TinyGPSPlus::distanceBetween(gps.location.lat(),gps.location.lng(),Home_LATarray[ac], Home_LONarray[ac]);  //Query Tiny GPS for Distance to Destination
  GPS_Course = TinyGPSPlus::courseTo(gps.location.lat(),gps.location.lng(),Home_LATarray[ac],Home_LONarray[ac]);                               //Query Tiny GPS for Course to Destination   

   /*
    if (Home_LATarray[ac] == 0) {
      Serial1.print("End of Waypoints");
      StopCar();      
      break;
      }      
   */ 
    if (Distance_To_Home == 0)                                   // If the Vehicle has reached it's Destination, then Stop
        {
        StopCar();                                               // Stop the robot after each waypoint is reached
        Serial.println("You have arrived!");                    // Print to Bluetooth device - "You have arrived"          
        ac++;                                                    // increment counter for next waypoint
        break;                                                   // Break from Go_Home procedure and send control back to the Void Loop 
                                                                 // go to next waypoint

        }   


   if ( abs(GPS_Course - compass_heading) <= 15)                  // If GPS Course and the Compass Heading are within x degrees of each other then go Forward                                                                  
                                                                  // otherwise find the shortest turn radius and turn left or right  
       {
         Forward();                                               // Go Forward
       } else 
         {                                                       
            int x = (GPS_Course - 360);                           // x = the GPS desired heading - 360
            int y = (compass_heading - (x));                      // y = the Compass heading - x
            int z = (y - 360);                                    // z = y - 360

            if ((z <= 180) && (z >= 0))                           // if z is less than 180 and not a negative value then turn left otherwise turn right
                  { SlowLeftTurn();  }
             else { SlowRightTurn(); }               
        } 


  }                                                              // End of While Loop


}   

Ответы [ 2 ]

0 голосов
/ 13 марта 2020

wdt - сторожевой таймер. Это таймер, который используется для определения сбоя вашего кода. Если он не сбрасывается периодически, он выдаст ошибку и перезапустит ESP32. Таймер необходимо часто сбрасывать.

Обратите внимание, что ошибка говорит о том, что это была задача async_tcp, которая выполнялась при срабатывании сторожевого таймера. Вы используете сервер AsyncWeb, который использует async_tcp.

Когда веб-сервер asyn c получает запрос страницы, он вызывает ваш код. У вас есть обработчики для отдельных страниц. Эти обработчики должны обрабатывать вызовы к ним так же, как мы имеем дело с loop() - если вы тратите 3 секунды или более, не возвращаясь и не вызывая delay() или yield(). Это дает базовому программному обеспечению возможность сбросить сторожевой таймер.

Просмотрите обработчики веб-страниц. Ищите, где вы можете провести в них долгое время.

Вы обнаружите, что вы вызываете goWayPoint() в своем обработчике для '/ go'. В нем есть все 1034 *, которые могут блокироваться на 5 секунд. 5 секунд слишком долго - если этот l oop не вернется или не вызовет delay(), сработает сторожевой таймер, что и происходит.

Простое решение - добавить вызов к delay() в while(true) l oop.

 while (true)  
  {
  delay(1);

это позволит базовому коду сбросить сторожевой таймер.

Это не поможет, если другие части вашего кода (getCompass() , getGPS() или другие вещи) займет слишком много времени.

В конечном счете, вам следует провести рефакторинг своего кода. Вы делаете слишком много работы в обратных вызовах веб-сервера. Эта работа должна быть выполнена в независимых задачах - возможно, в loop(). Но это большой проект. Добавление вызова к delay(1) в любое место в обратном вызове веб-сервера, которое у вас есть некоторое время l oop или занимает некоторое время, чтобы выполнить некоторую обработку, является неуклюжим, но должно решить эту проблему.

0 голосов
/ 13 марта 2020

Добро пожаловать в клуб ГРП:

String latitude1;
String latitude1Param;
String longitude1;
String longitude1Param;
String latitude2;
String latitude2Param;
String longitude2;
String longitude2Param;
String commitType;;

в сочетании с веб-сервером asyn c - огромная проблема. Я переписал приложение на ~ 15.000 строк, чтобы избавиться от строк (также в используемых библиотеках), и с тех пор больше не перезагружается и не перезагружается. Надеюсь, что это поможет вам в вашем проекте.
Используйте заранее определенные фиксированные массивы символов, они будут go в стек и сохранят повреждение кучи низким. Используйте функции, такие как strcpy, strcat, itoa / atoi, для создания сообщений или получения значений.

РЕДАКТИРОВАТЬ: заменить класс String примером фиксированных массивов символов

 char numBuffer [16] ={'\0'}    // For 15 chars and the null terminator
 char latitude1 [32] ={'\0'}    // For 31 chars and the null terminator
  .... some code here ....
 strcpy (latitude1 , "No values here"); 
 //or
 strcpy (latitude1 , "Value 1: ");
 itoa (SomeIntDataNumber, numBuffer,10);
 strcat (latitude1, numBuffer)   // append the converted SomeIntDataNumber

Еще одна вещь, если вы используете memset, убедитесь, что вы правильно управляете памятью, также проверьте используемые библиотеки для интенсивного использования класса String. Некоторые библиотеки достаточно хорошо работают в среде c, их использование в веб-контексте приводит к сбою ESP. Мне пришлось отказаться от некоторых библиотек или, по крайней мере, переписать их без класса String.
Дальнейшее чтение: https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/
Последний совет: попробуйте закомментировать / заменить на фиктивные символы все появления строки Класс и попробуйте код снова.

...