Причина сброса 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(){


  }


Это было бы большим подспорьем, указывая на мои ошибки.

, 👍1

Обсуждение

Блокирует ли "stepper.runToPosition();" код от продолжения работы до тех пор, пока степпер не переместится в нужное положение? "wdt reset cause: 4" - это тип сбоя аппаратного сторожевого пса, который возникает из-за того, что ваш ESP8266 был занят слишком долго, не возвращая контроль базовым ОСРВ. IIRC, он срабатывает при воспринимаемых "блокировках" примерно на 8 секунд. Вы можете попробовать рассеять несколько yield(); в своей функции onWsEvent и посмотреть, поможет ли это., @Peter Feerick


1 ответ


2

Вы вызываете функцию 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() и переместить туда шаговый код, чтобы это сработало.

,