问题描述
我在一个自治GPS机器人项目中。一段时间后,当我运行以下代码时,esp32(devkit v1)重新启动,并且此过程不断重复。
I am on an Autonomous GPS robot project. When I am running the below code after some time the esp32(devkit v1) reboots and this goes on repeating.
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
这是出现在串行监视器上的味精。我尝试调试,但找不到原因。
This is the msg that appears on the serial monitor. I tried debugging but can't find why this is happening.
该代码确实很大,所以我只上传了一部分。
The Code is really big, so I have uploaded only a part of it.
// 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
}
推荐答案
欢迎来到String堆压裂俱乐部:
Welcome to the String heap fracturing club:
String latitude1;
String latitude1Param;
String longitude1;
String longitude1Param;
String latitude2;
String latitude2Param;
String longitude2;
String longitude2Param;
String commitType;;
与异步网络服务器结合使用是一个巨大的问题。我重写了〜15.000行的应用程序以摆脱字符串(也在使用的库中),从那时起不再进行任何重置和重新引导。希望这对您的项目有所帮助。
使用预定义的固定char数组,它们将进入堆栈并保持较低的堆损坏。使用诸如strcpy,strcat,itua / atoi之类的函数来构建消息或检索值。 br>
编辑:用固定的char数组示例替换String类
in combination with async webserver is a huge problem. I rewrote a ~15.000 lines application to get rid of strings (also in the used libraries) and since then no resets and reboots anymore. Hope this helps you in your project.
Use predifined fixed char arrays they will go to the stack and keep heap corruption low.Use functions like strcpy, strcat, itoa / atoi to build messages or retrieve values.
replace String class with fixed char arrays example
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类。一些库在静态环境中运行良好,在Web上下文中使用它们会使ESP崩溃。我不得不放弃一些库,或者至少在没有String类的情况下重写它们。
进一步阅读:
最后提示:尝试注释掉String类的所有外观并将其替换为虚拟字符,然后重试代码。
One more thing if you use memset, make sure you do proper memory management, also check the used libraries for heavy use of String class. Some libs work in a static environment quite well, using them in a web context crashes the ESP. I had to ditch some libs or at least rewrite them without String class.
Further reading: https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/
Final Tip: Try to commenting out / replacing with dummy chars all appearancies of the String class and try the code again.
这篇关于任务看门狗被触发./abort()在核心0的PC 0x400de07b被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!