Причина сброса wdt: 4, режим загрузки: (3,6)
Я работаю над Python и NodeMCU с подключением websocket.
Итак, я отправляю строку из Python в NodeMCU, а NodeMCU собирает строку и декодирует ее, чтобы установить значения для шагового двигателя. Первоначальный код работал нормально перед обновлением с помощью кода шагового двигателя. Теперь он запускает сброс сторожевого пса.
Вот мой полный код:
#include <ESP8266WiFi.h>
#include <ESPAsyncWebServer.h>
#include <AccelStepper.h>
// Определите соединения шагового двигателя и тип интерфейса двигателя. При использовании драйвера тип интерфейса двигателя должен быть установлен в 1:
#define dirPin 8 // clk+
#define stepPin 9 // cw+
#define motorInterfaceType 1
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
const char ssid[] PROGMEM ="PencoNetwork2"; // измените его на ваш wifi SSID
const char password[] PROGMEM ="Penco1234567890"; // измените его на ваш wifi password
AsyncWebServer server(80);
AsyncWebSocket ws("/test");
void setup(){
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println(WiFi.localIP());
ws.onEvent(onWsEvent);
server.addHandler(&ws);
server.begin();
}
void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){
if(type == WS_EVT_CONNECT){
Serial.println("Websocket client connection received");
} else if(type == WS_EVT_DISCONNECT){
Serial.println("Client disconnected");
} else if(type == WS_EVT_DATA){
Serial.println("Data received: ");
for(int i=0; i < len; i++) {
// Serial.print((char) data[i]);
String data_String = (String) data[i];
int commaIndex = data_String.indexOf(',');
int secondCommaIndex = data_String.indexOf(',', commaIndex+1);
String firstValue = data_String.substring(0, commaIndex);
String secondValue = data_String.substring(commaIndex+1, secondCommaIndex);
String thirdValue = data_String.substring(secondCommaIndex+1); //До конца строки
int mDist = firstValue.toInt();
int mspeed = secondValue.toInt();
int mAccel = thirdValue.toInt();
stepper.setMaxSpeed(mspeed);
stepper.setAcceleration(mAccel);
stepper.moveTo(mDist);
stepper.runToPosition();
delay(1000);
stepper.moveTo(0);
stepper.runToPosition();
delay(1000);
}
// Serial.println();
}
}
void loop(){
}
Это было бы большим подспорьем, указывая на мои ошибки.
@Ihsan, 👍1
Обсуждение1 ответ
Вы вызываете функцию delay()
в
обратном вызове onWsEvent(). В документации ESPAsyncWebServer конкретно говорится, что этого не следует делать в разделе "Важные вещи, которые нужно помнить":
Вы не можете использовать yield или delay или любую функцию, которая использует их внутри обратных вызовов
Когда вы вызываете delay()
или цикл внутри асинхронного обратного вызова веб-сервера, вы блокируете его задачу события от выполнения любой другой обработки. Это может помешать различным функциям домашнего хозяйства, которые должны выполнять HTTP, TCP и ядро Arduino. В общем, вы должны делать как можно меньше во время обратного вызова и возвращаться как можно быстрее.
Правильный способ структурировать этот код - установить флаг в обратном вызове, проверить флаг и выполнить работу в loop()
.
Например,
AsyncWebServer server(80);
AsyncWebSocket ws("/test");
boolean flag_move_stepper = false;
void setup(){
и
void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){
if(type == WS_EVT_CONNECT){
Serial.println("Websocket client connection received");
} else if(type == WS_EVT_DISCONNECT){
Serial.println("Client disconnected");
} else if(type == WS_EVT_DATA){
flag_move_stepper = true;
// вам нужно будет переписать этот код, чтобы совместно использовать переменные с `loop()` и выполнять там работу
и
void loop(){
if(flag_move_stepper) {
flag_move_stepper = false;
// выполните работу, ранее выполнявшуюся в onWsEvent() здесь
}
}
Вам нужно будет сделать переменные, в которых вы хранили данные в обработчике событий, доступными для loop()
и переместить туда шаговый код, чтобы это сработало.
- Получение сброса wdt + перезагрузка каждые 5 секунд с помощью простого кода кнопки/реле
- Как заставить 5-вольтовое реле работать с NodeMCU
- ESP8266 не подключается к Wi-Fi
- Разница между этими двумя платами NodeMCU?
- NodeMCU - использовать кнопку flash в качестве входного сигнала в loop()
- Как определить размер Flash?
- Как изменить имя модуля ESP8266-12E по умолчанию
- Простой запрос GET с ESP8266HTTPClient
Блокирует ли "stepper.runToPosition();" код от продолжения работы до тех пор, пока степпер не переместится в нужное положение? "wdt reset cause: 4" - это тип сбоя аппаратного сторожевого пса, который возникает из-за того, что ваш ESP8266 был занят слишком долго, не возвращая контроль базовым ОСРВ. IIRC, он срабатывает при воспринимаемых "блокировках" примерно на 8 секунд. Вы можете попробовать рассеять несколько
yield();
в своей функции onWsEvent и посмотреть, поможет ли это., @Peter Feerick