1

I'm working on Python and nodeMCU with websocket connection.

So, I send a string from Python to nodeMCU and nodeMCU collects the string and decodes to set values to a stepper motor. Initial code worked fine before updating with stepper motor code. Now it triggers watchdog resets.

Here's my full code:-

#include <ESP8266WiFi.h>
#include <ESPAsyncWebServer.h>
#include <AccelStepper.h>

// Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver:
#define dirPin 8  // clk+
#define stepPin 9  // cw+
#define motorInterfaceType 1

 
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

const char ssid[] PROGMEM ="PencoNetwork2";    //change it to your wifi SSID
const char password[] PROGMEM ="Penco1234567890";    //change it to your 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); //To the end of the string
          
          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(){


  }


It would be a great help pointing out my mistakes.

1
  • Does stepper.runToPosition(); block the code from continuing until the stepper has moved into position? wdt reset cause:4 is a hardware watchdog crash type, and occurs because your ESP8266 has been busy for too long without giving control back to the underlying RTOS. IIRC, it fires for perceived 'lockups' of approx 8 seconds. You can try scattering a few yield(); in your onWsEvent function and see if that helps. Commented Aug 10, 2020 at 5:13

1 Answer 1

2

You're calling delay() in the onWsEvent() callback. The ESPAsyncWebServer documentation specifically says not to do that in the 'Important things to remember' section:

You can not use yield or delay or any function that uses them inside the callbacks

When you call delay() or loop inside an async web server callback, you block its event task from doing any other processing. This can interfere with a variety of housekeeping functions that HTTP, TCP and the Arduino Core need to perform. In general you should do as little as possible during a callback and return as quickly as possible.

The correct way to structure this code is to set a flag in the callback and inspection the flag and do the work in loop().

For instance,

AsyncWebServer server(80);
AsyncWebSocket ws("/test");

boolean flag_move_stepper = false;

void setup(){

and

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;

    // you'll need to rewrite this code to share variables with `loop()` and do the work there

and

void loop(){
  if(flag_move_stepper) {
    flag_move_stepper = false;

    // do the work formerly in onWsEvent() here
  }

}

You'll need to make the variables you stored data in in the event handler available to loop() and move the stepper code there for this to work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.