sinricpro / esp8266-esp32-sdk

Library for https://sinric.pro - simple way to connect your device to Alexa, Google Home, SmartThings and cloud
https://sinric.pro
Other
234 stars 124 forks source link

Soft WDT reset #218

Closed t0mmy66 closed 2 years ago

t0mmy66 commented 3 years ago

Hi,

spent a long time trying to figure it out but im past that now. just trying to activate a stepper motor using sinric pro with a wemos d1 mini clone. I can control the motor fine but im getting a wdt reset error which is causing the arduino to lose the position of the blind. hoping someone has a quick work around to fix my problem. I havent been able to find an example program using the stepper motors that actually worked so resulted to hacking this one together.

/*
 * Example for how to use SinricPro Switch device:
 * - setup a switch device
 * - handle request using callback (turn on/off builtin led indicating device power state)
 * - send event to sinricPro server (flash button is used to turn on/off device manually)
 * 
 * If you encounter any issues:
 * - check the readme.md at https://github.com/sinricpro/esp8266-esp32-sdk/blob/master/README.md
 * - ensure all dependent libraries are installed
 *   - see https://github.com/sinricpro/esp8266-esp32-sdk/blob/master/README.md#arduinoide
 *   - see https://github.com/sinricpro/esp8266-esp32-sdk/blob/master/README.md#dependencies
 * - open serial monitor and check whats happening
 * - check full user documentation at https://sinricpro.github.io/esp8266-esp32-sdk
 * - visit https://github.com/sinricpro/esp8266-esp32-sdk/issues and check for existing issues or open a new one
 */

// Uncomment the following line to enable serial debug output
//#define ENABLE_DEBUG

#ifdef ENABLE_DEBUG
       #define DEBUG_ESP_PORT Serial
       #define NODEBUG_WEBSOCKETS
       #define NDEBUG
#endif 

#include <Arduino.h>
#ifdef ESP8266 
       #include <ESP8266WiFi.h>
#endif 
#ifdef ESP32   
       #include <WiFi.h>
#endif

#include "SinricPro.h"
#include "SinricProSwitch.h"
#include <Stepper.h>

#define STEPS  32   // Number of steps per revolution of Internal shaft
int  Steps2Take;  // 2048 = 1 Revolution
Stepper small_stepper(STEPS, 14, 12, 13, 15);

#define WIFI_SSID         "xx"    
#define WIFI_PASS         "xx"
#define APP_KEY           "xx"      // Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx"
#define APP_SECRET        "xx"   // Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx"
#define SWITCH_ID         "xx"    // Should look like "5dc1564130xxxxxxxxxxxxxx"
#define BAUD_RATE         9600                // Change baudrate to your need

#define BUTTON_PIN 0   // GPIO for BUTTON (inverted: LOW = pressed, HIGH = released)
#define LED_PIN   2   // GPIO for LED (inverted)

bool myPowerState = false;
unsigned long lastBtnPress = 0;
bool blindsup = true;

/* bool onPowerState(String deviceId, bool &state) 
 *
 * Callback for setPowerState request
 * parameters
 *  String deviceId (r)
 *    contains deviceId (useful if this callback used by multiple devices)
 *  bool &state (r/w)
 *    contains the requested state (true:on / false:off)
 *    must return the new state
 * 
 * return
 *  true if request should be marked as handled correctly / false if not
 */

bool onPowerState(const String &deviceId, bool &state) {
  Serial.printf("Device %s turned %s (via SinricPro) \r\n", deviceId.c_str(), state?"on":"off");
  myPowerState = state;
  digitalWrite(LED_PIN, myPowerState?LOW:HIGH);
  return true; // request handled properly
}

// setup function for WiFi connection
void setupWiFi() {
  Serial.printf("\r\n[Wifi]: Connecting");
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.printf(".");
    delay(250);
  }
  Serial.printf("connected!\r\n[WiFi]: IP-Address is %s\r\n", WiFi.localIP().toString().c_str());
}

// setup function for SinricPro
void setupSinricPro() {
  // add device to SinricPro
  SinricProSwitch& mySwitch = SinricPro[SWITCH_ID];

  // set callback function to device
  mySwitch.onPowerState(onPowerState);

  // setup SinricPro
  SinricPro.onConnected([](){ Serial.printf("Connected to SinricPro\r\n"); }); 
  SinricPro.onDisconnected([](){ Serial.printf("Disconnected from SinricPro\r\n"); });
  SinricPro.begin(APP_KEY, APP_SECRET);
}

// main setup function
void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP); // GPIO 0 as input, pulled high
  pinMode(LED_PIN, OUTPUT); // define LED GPIO as output
  digitalWrite(LED_PIN, HIGH); // turn off LED on bootup

  Serial.begin(BAUD_RATE); Serial.printf("\r\n\r\n");
  setupWiFi();
  setupSinricPro();
  small_stepper.setSpeed(400);
}

void blindDown(){
  small_stepper.step(2048);
}
void blindUp(){
  small_stepper.step(-2048);
}
void loop() {
  SinricPro.handle();
  Serial.printf("1");
  if(myPowerState == true && blindsup == false) {
      Serial.printf("1");
  blindUp();
    Serial.printf("2");
  delay(200);
    Serial.printf("3");
  }
  else {
    if(myPowerState == false && blindsup == true) {
        Serial.printf("4");
    blindDown();
      Serial.printf("5");
    delay(200);
      Serial.printf("6");
    }
  }
}

Error:

Wifi]: Connecting.............connected!
[WiFi]: IP-Address is 192.168.0.143
14
--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Soft WDT reset

>>>stack>>>

ctx: cont
sp: 3ffffdd0 end: 3fffffc0 offset: 01a0
3fffff70:  00000000 00000625 3ffeee54 4020c9ed  
3fffff80:  3fffdad0 3ffe8a35 3ffef100 4020339c  
3fffff90:  3fffdad0 3ffe8a35 3ffef100 402070c3  
3fffffa0:  feefeffe 00000000 3ffef244 4020e884  
3fffffb0:  feefeffe feefeffe 3ffe85e0 40100cf1  
<<<stack<<<

--------------- CUT HERE FOR EXCEPTION DECODER ---------------
⸮t

[Wifi]: Connecting.............connected!
[WiFi]: IP-Address is 192.168.0.143
14
--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Soft WDT reset

>>>stack>>>

ctx: cont
sp: 3ffffdc0 end: 3fffffc0 offset: 01a0
3fffff60:  3fffff01 00000003 3ffeee54 4020c848  
3fffff70:  00000000 00000615 3ffeee54 4020c9ed  
3fffff80:  3fffdad0 3ffe8a35 3ffef100 4020339c  
3fffff90:  3fffdad0 3ffe8a35 3ffef100 402070c3  
3fffffa0:  feefeffe 00000000 3ffef244 4020e884  
3fffffb0:  feefeffe feefeffe 3ffe85e0 40100cf1  
<<<stack<<<

--------------- CUT HERE FOR EXCEPTION DECODER ---------------
⸮⸮

[Wifi]: Connecting.............connected!
[WiFi]: IP-Address is 192.168.0.143
14
--------------- CUT HERE FOR EXCEPTION DECODER ---------------

any help much appreticiated 💯

sivar2311 commented 3 years ago

Hm, i don't have expirience with stepper motors. But it seems that the sketch is crashing at small_stepper.setSpeed(400); in setup. The main loop function never gets executed, otherwise the first Serial.printf("1"); would be visibile on the serial monitor.

sivar2311 commented 3 years ago

It looks that the stepper motor library does not feed the watchdog. This is necessary every 2 seconds - otherwise software watchdog (soft wdt) gets triggered. You need to make less steps at once and call yield() in between like so:

This should fix your soft-wdt issues:

  for (int i=0; i<2048; i++) {
    stepper.step(1);
    yield();
  }

I think you will ran into other problems because the logic in the main loop seems incorrect to me.

t0mmy66 commented 3 years ago

It looks that the stepper motor library does not feed the watchdog. This is necessary every 2 seconds - otherwise software watchdog (soft wdt) gets triggered. You need to make less steps at once and call yield() in between like so:

This should fix your soft-wdt issues:

  for (int i=0; i<2048; i++) {
    stepper.step(1);
    yield();
  }

I think you will ran into other problems because the logic in the main loop seems incorrect to me.

Thanks, it seems to be ish working


void blindDown(){
  for (int i=0; i<60; i++) {
    small_stepper.step(i);
    yield();
  }
}
void blindUp(){
  for (int i=0; i<-60; i--) {
    small_stepper.step(i);
    yield();
  }
}

cant get the negative number to work in order to reverse the motor direction, any ideas?. other then that it seems to work okay. only needs to work for a quick college presentation next week as a proof of concept. Thanks for the help

sivar2311 commented 3 years ago

Unfortunately, you have made a mistake there. The number of steps would increase with each loop pass and then looks like this:

  small_stepper.step(0); // i=0
  small_stepper.step(1); // i=1 
  small_stepper.step(2); // i=2 
  small_stepper.step(3); // i=3
  ...
  small_stepper.step(60); // i=60

In the end the total number of steps is 1830 instead of 60 (1+2+3...+60).

Have a look at this:

// Uncomment the following line to enable serial debug output
//#define ENABLE_DEBUG

#ifdef ENABLE_DEBUG
#define DEBUG_ESP_PORT Serial
#define NODEBUG_WEBSOCKETS
#define NDEBUG
#endif

#include <Arduino.h>
#ifdef ESP8266
#include <ESP8266WiFi.h>
#endif
#ifdef ESP32
#include <WiFi.h>
#endif

#include <SinricPro.h>
#include <SinricProSwitch.h>
#include <Stepper.h>

#define WIFI_SSID  "YOUR-WIFI-SSID"
#define WIFI_PASS  "YOUR-WIFI-PASS"
#define APP_KEY    "YOUR-APP-KEY"     
#define APP_SECRET "YOUR-APP-SECRET"  
#define SWITCH_ID  "YOUR-DEVICE-ID"   
#define BAUD_RATE  9600               

const int stepsPerRevolution = 200;

Stepper          myStepper(stepsPerRevolution, D1, D2);
SinricProSwitch &mySwitch         = SinricPro[SWITCH_ID];  // create new switch device
int              stepsToDo        = 0;
bool             motor_is_running = false;

bool onPowerState(const String &deviceId, bool &state) {
    if (motor_is_running) return true;  // if the motor is running, ignore the command

    if (state) {           // if device is turned on
        stepsToDo = 100;   // make 100 steps in positive direction
    } else {               // if device is turned off
        stepsToDo = -100;  // make 100 steps in negative direction
    }

    return true;  // request handled properly
}

void handleStepper() {
    if (stepsToDo == 0) return;  // return if nothing is to do...

    if (stepsToDo > 0) {     // if we have to do steps in positive direction
        myStepper.step(1);   // make a single step in positive direction
        stepsToDo--;         // reduce the remaining steps by one
    } else {                 // if we have to do steps in negative direction
        myStepper.step(-1);  // make a single step in negative direction
        stepsToDo++;         // reduce the remaining steps (to reduce a negative number we have to add)
    }

    if (stepsToDo == 0) motor_is_running = false;  // if motion is completed set motor_is_running to false;
}

void setupWiFi() {
    WiFi.begin(WIFI_SSID, WIFI_PASS);  // start wifi
    Serial.printf("Connecting to WiFi \"%s\"", WIFI_SSID);
    while (WiFi.status() != WL_CONNECTED) {
        Serial.printf(".");
        delay(100);
    }
    Serial.printf("connected\r\n");
}

void setupSinricPro() {
    mySwitch.onPowerState(onPowerState);   // apply onPowerState callback
    SinricPro.begin(APP_KEY, APP_SECRET);  // start SinricPro
}

void setupStepper() {
    // set the speed at 60 rpm:
    myStepper.setSpeed(60);
}

void setup() {
    Serial.begin(BAUD_RATE);
    setupWiFi();
    setupSinricPro();
    setupStepper();
}

void loop() {
    SinricPro.handle();  // handle SinricPro commands
    handleStepper();     // handle Stepper motor
}

Note: It looks like you want to implement a blinds control. SinricPro offers you the suitable device (SinricProBlinds) for this purpose. This allows you a correct voice control with commands like "Alexa, open the blinds" or "Alexa, set the blinds position to 40%". Please have a look at the blinds example.

The callback functions work with percent values between 0 to 100 (onRangeValue) or -100 to +100 (adjustRangeValue). You would then have to convert the percent values into the required number of steps (and implement some more logic controls).

stale[bot] commented 2 years ago

This issue has gone quiet. Spooky quiet. We currently close issues after 14 days of inactivity. It’s been at least 7 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. As a friendly reminder, the best way to fix this or any other problem is to provide a detailed error description including a serial log. Thanks for being a part of the SinricPro community!

stale[bot] commented 2 years ago

Hey again! It’s been 14 days since anything happened on this issue, so our friendly robot (that’s me!) is going to close it. Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m HUMAN_EMOTION_SORRY. Please feel free to comment on this issue or create a new one if you need anything else. As a friendly reminder, the best way to fix this or any other problem is to provide a detailed error description including a serial log. Thanks again for being a part of the SinricPro community!