Сработал сторожевой таймер задач. / Abort () был вызван на ПК 0x400de07b на ядре 0

Я работаю над проектом автономного 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


}   

person Jose Ben    schedule 13.03.2020    source источник
comment
это может быть полезно. github.com/espressif/arduino-esp32/issues/   -  person Nijeesh Joshy    schedule 13.03.2020
comment
@NijeeshJoshy Я пробовал, но теперь он не работает, новая ошибка Guru Meditation Error: Core 1 panic'ed (IntegerDivideByZero). Exception was unhandled. Core 1 register dump:, за которой следует перезагрузка, затем повторяется старая ошибка   -  person Jose Ben    schedule 13.03.2020
comment
система дает сбой после того, как я нажимаю go to destination ссылку в Интернете, и веб-страницы продолжают загружаться   -  person Jose Ben    schedule 13.03.2020
comment
происходит какое-то деление на ноль. вы можете опубликовать полный код?   -  person Nijeesh Joshy    schedule 13.03.2020
comment
Я могу отправить вам ссылку на Google Диск, хорошо? так как я сделал код в разных вкладках, копировать их немного сложно   -  person Jose Ben    schedule 13.03.2020


Ответы (2)


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

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

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

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

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

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

 while (true)  
  {
  delay(1);

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

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

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

person romkey    schedule 13.03.2020
comment
добавление delay(1) не помогло, я наконец добавил его в getCompass() и get GPS(), но это не работает - person Jose Ben; 13.03.2020

Добро пожаловать в клуб по разрыву кучи струн:

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

в сочетании с асинхронным веб-сервером - огромная проблема. Я переписал приложение с ~ 15 000 строками, чтобы избавиться от строк (также в используемых библиотеках), и с тех пор больше никаких сбросов и перезагрузок. Надеюсь, это поможет вам в вашем проекте.
Используйте заранее определенные массивы фиксированных символов, которые они отправят в стек и сохранят низкий уровень повреждения кучи. Используйте такие функции, как 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. Некоторые библиотеки довольно хорошо работают в статической среде, их использование в веб-контексте приводит к сбою ESP. Мне пришлось отказаться от некоторых библиотек или, по крайней мере, переписать их без класса String.
Дальнейшее чтение: https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/
Последний совет: попробуйте комментировать / заменяя фиктивными символами все проявления класса String и попробуйте код еще раз.

person Codebreaker007    schedule 13.03.2020
comment
Я не понял вашего решения? Можете привести пример? - person Jose Ben; 13.03.2020
comment
Класс String в Arduino - это дерьмо, проще говоря - он резервирует и освобождает память, тем самым прокалывая и фрагментируя вашу кучу памяти. Поскольку микроконтроллеры не имеют так называемого механизма сбора мусора для восстановления памяти, это приводит к сбою платы (с различными часто вводящими в заблуждение сообщениями об ошибках). Асинхронная коммуникация только ускоряет этот процесс, потому что память проникает быстрее. Я усвоил это на собственном горьком опыте. Для примера я отредактирую свой ответ. - person Codebreaker007; 13.03.2020
comment
@JoseBen hackingmajenkoblog.wordpress.com/2016/02 / 04 / - person Nijeesh Joshy; 13.03.2020
comment
@Nijeesh Спасибо за ссылку, почти забыл ;-) Добавлю то же самое к своему ответу - person Codebreaker007; 13.03.2020
comment
@ Codebreaker007, честно говоря, я плохо разбирался в примере, я новичок в этом виде кода, я не понимал, зачем вы использовали strcat, itoa и numBuffer, это все необходимо? - person Jose Ben; 13.03.2020
comment
Пожалуйста, прочтите информацию, на которую ссылается Nijeesh, и в моем EDIT и учитесь. Нет простого решения сложных вопросов. Посмотрите эти функции в документации, например, arduino.cc или здесь, в stackoverflow, и узнайте, как и зачем их использовать. Я только покажу, как ловить рыбу, ловить надо самому. String и float - это разные типы - пожалуйста, также посмотрите разные типы var - float на микроконтроллерах следует избегать насколько это возможно - person Codebreaker007; 13.03.2020
comment
@ Codebreaker007, я знаю эту функцию и прошел по ссылке, которую предоставил Nijeesh. Я не понимаю, что это пример, вы определили два символьных массива, затем вы дали широту значение, а затем преобразовали некоторые int-данные в строку и добавил его до конца широты. Единственная причина, по которой я использую строку, заключается в том, что request->getParam(PARAM_INPUT_1)->value() является строковым значением, поэтому для его сохранения мне нужна строка, позже в коде я конвертирую эту строку в float double. У меня нет другого использования для строки там. - person Jose Ben; 13.03.2020
comment
Поэтому сначала я не понял, зачем вы использовали strcat и все такое. А что такое ошеломитель? просто переменная? - person Jose Ben; 13.03.2020
comment
Хотя фрагментация кучи может быть проблемой для длительного кода, проблема здесь не в этом. Посмотрите на сообщения отладки - код не запускается достаточно долго, чтобы фрагментировать кучу. И это ESP32, который имеет намного больше памяти, чем Arduino или ESP8266, и менее подвержен фрагментации кучи. - person romkey; 13.03.2020
comment
Извините за возражение, дело не в длительной работе, а в том, какие области кучи затронуты. Я сделал подпрограмму (с конструктором String + =), при вызове которой через GET немедленно вылетел esp32, независимо от того, работает он 1 секунду или 1 час. Просто мой опыт работы с async и дерьмовым классом Arduino String. Если вы пишете в неправильный раздел памяти, возможно, большая свободная куча не имеет значения. Прочтите связанный блог - person Codebreaker007; 13.03.2020
comment
@jose bem Вам нужна строка (String class = или строка в стиле c, это две разные вещи. Если вам нужна строка c для вашего ответа, вы просто помещаете на нее указатель. Async веб-сервер работает с строками c , поэтому использование класса String устарело. В зависимости от формата приема вы можете поместить любой формат в c-строку. numBuffer - вспомогательный массив, если вы используете itoa и добавляете данные, вам нужен буфер, потому что itoa, как strcpy, очищает char массив, который может быть проблемой при создании c-строк для отображения. - person Codebreaker007; 13.03.2020