Постоянная перрезагрузка nodemcu

Тема в разделе "ESP8266, ESP32", создана пользователем Grzeg, 2 ноя 2020.

  1. Grzeg

    Grzeg Нуб

    Использую NodeMcu v3 для проекта, но выскакивает ошибка.
    Код (C++):
     ets Jan  8 2013,rst cause:4, boot mode:(3,6)

    wdt reset
    load 0x4010f000, len 3664, room 16
    tail 0
    chksum 0xee
    csum 0xee
    v39c79d9b
    ~ld
    С помощью кода внизу проверил ошибку в ESP Exception Decoder и он дал такой ответ:
    Код (C++):
    Soft WDT reset

    >>>stack>>>

    ctx: cont
    sp: 3ffffdf0 end: 3fffffc0 offset: 01a0
    3fffff90:  3fffdad0 00000000 3ffee314 40201048
    3fffffa0:  feefeffe feefeffe 3ffee33c 402018b4
    3fffffb0:  feefeffe feefeffe 3ffe84e0 40100b85
    <<<stack<<<


    Ответ:
    Decoding stack results
    0x40201048: setup() at C:\Users\stoma\OneDrive\Документи\Arduino\sketches\_______/_______.ino line 5
    0x402018b4: loop_wrapper() at C:\Users\stoma\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\core_esp8266_main.cpp line 194
    Проверочная программа:
    Код (C++):
    void setup()
    {
      Serial.begin(115200);
      Serial.println();
      Serial.println("Let's provoke the s/w wdt firing...");

      while(true);

      Serial.println("This line will not ever print out");

    }

    void loop(){}
    Сама программа:
    Код (C++):

    #include <ESP8266WiFi.h>
    #include <ArduinoJson.h>
    //оглашаем константи
    const char* ssid = "Lvov"; //ім'я wifi точки
    const char* password = "Lvov1"; //пароль wifi точки
    const char* host = "herokuapp.com";

    #define IN1 3
    #define IN2 4
    #define IN3 5
    #define IN4 6

    bool up = 0;
    bool down = 0;
    bool left = 0;
    bool right = 0;

    String line;

    void setup()
    {
     
      Serial.begin(115200);
      delay(10);
     
      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);
     
      WiFi.begin(ssid, password);
     
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());

                                       
      pinMode(IN1, OUTPUT);
      pinMode(IN2, OUTPUT);
      pinMode(IN3, OUTPUT);
      pinMode(IN4, OUTPUT);

        jsonGet();
    }

    void loop()
    {
      StaticJsonBuffer<2000> jsonBuffer; /// буфер на 2000 символов
      const char* json = "{\"left\":false,\"right\":false,\"down\":false,\"up\":false}";
      JsonObject& root = jsonBuffer.parseObject(line);    
      if (!root.success())
      {
        Serial.println("parseObject() failed");            
        jsonGet();                                        
        return;                                          
      }
     
      Serial.println();
      String name = root["name"];                          
      Serial.print("name:");
      Serial.println(name);
     
      bool left = root["left"];                  
      Serial.print("left: ");
      Serial.print(left);                                

      bool right = root["right"];          
      Serial.print("right: ");
      Serial.print(right);

      bool down = root["down"];
      Serial.print("down: ");
      Serial.print(down);
     
      bool up = root["up"];
      Serial.print("up: ");
      Serial.print(up);

      Serial.println();
      Serial.println();
      delay(50000);
       
      while(up == true && down == false && left == false && right == false){
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, HIGH);
        digitalWrite(IN3, LOW);
        digitalWrite(IN4, HIGH);
        }
       
      while(up == false && down == true && left == false && right == false){
        digitalWrite(IN1, HIGH);
        digitalWrite(IN2, LOW);
        digitalWrite(IN3, HIGH);
        digitalWrite(IN4, LOW);
        }
       
      while(up == false && down == false && left == false && right == true){
        digitalWrite(IN1, HIGH);
        digitalWrite(IN2, HIGH);
        digitalWrite(IN3, HIGH);
        digitalWrite(IN4, HIGH);
        }
       
      while(up == false && down == false && left == true && right == false){
        digitalWrite(IN1, HIGH);
        digitalWrite(IN2, HIGH);
        digitalWrite(IN3, HIGH);
        digitalWrite(IN4, HIGH);
        }

    }

    void jsonGet()
    {
     
      WiFiClient client;
      const int httpPort = 80;
      if (!client.connect(host, httpPort))
      {
        Serial.println("connection failed");
        return;
      }
     
      client.println("GET secure-plains-50034.herokuapp.com HTTP/1.1");
      client.println("Host: herokuapp.com");
      client.println("Connection: close");
      client.println();
      delay(1500);
     
     
      while(client.available()){
        line = client.readStringUntil('\r');
      }
      Serial.print(line);
      Serial.println();
      Serial.println("closing connection");
    }
    Кто знает, что можно сделать, чтобы это прекратить?
     
  2. 1. Глухие циклы, код за ними не выполняется, нет какого либо выхода, переменные в стеке, если проверка условий выполнена, то в теле цикла эти переменные не меняются и следующая проверка опять даст истину.
    2. Вам сторожевой таймер и без декодеров ошибок кричит, что он причина перезагрузки, ожидаете дрыганье пинами будет сбрасывать его?
     
    Grzeg и NikitOS нравится это.
  3. SergeiL

    SergeiL Оракул Модератор

    Другими словами нельзя зависать в циклах надолго. Надолго - это более 15мс.
    То есть нужно проверить то, что нужно и вывалиться из loop.
    Иначе будет отваливаться WiFi, а если дольше не выходить из loop - будет рестарт по вотчдогу.
     
    Grzeg, ИгорьК и NikitOS нравится это.
  4. Grzeg

    Grzeg Нуб

    Спасибо вам за замечание, но не подскажете, как устранить проблему со сторожевым таймером?
     
  5. ИгорьК

    ИгорьК Гуру

    ... через 0.5 - 1.5 сек в зависимости от нагрузки.

    Проблема вашего кода в логике этих строк:
    Код (C++):
    while(up == true && down == false && left == false && right == false){
    они "держат" процессор за хобот пока выполняется их условие. У вас четыре таких строки в лупе, значит процессор в какой-то момент будет крутить одну из них более 0.5 сек и произойдет укус собаки.

    Лечить? Полностью переписывать код, чтобы луп безостановочно проверял необходимые условия без while опираясь только на if или switch.
     
  6. b707

    b707 Гуру

    Вы не поняли, это было не "замечание" - сообщения #2, 3 и #5 - это и были подсказки, как устранить проблему со сторожевым таймером.
     
  7. Grzeg

    Grzeg Нуб

    Спасибо Вам, за замечания, я почистил код, убрал почти все while и ненужные задержки, но проблема все равно осталась, вот что выдает декодер:
    Код (C++):
    Soft WDT reset

    >>>stack>>>

    ctx: cont
    sp: 3ffffd40 end: 3fffffc0 offset: 01a0
    3ffffee0:  402051e5 feefeffe feefeffe feefeffe
    3ffffef0:  3ffe8788 00000000 0a0d0304 4020514d
    3fffff00:  0031d227 4bc6a7f0 0031d227 00000000
    3fffff10:  0031d227 00000000 4bc6a7f0 00000000
    3fffff20:  40203668 3ffee4c0 401001d0 4bc6a7f0
    3fffff30:  00000000 3ffee4c0 3ffee488 00000003
    3fffff40:  402313d7 3ffee4c0 3ffe8714 40203941
    3fffff50:  3ffeec3c 40202770 3ffee4c0 000001f4
    3fffff60:  3ffee474 3ffee488 3ffee4c0 40201d22
    3fffff70:  feefeffe feefeffe feefeffe feefeffe
    3fffff80:  feefeffe feefeffe feefeffe feefeffe
    3fffff90:  feefeffe feefeffe feefeffe 3ffee538
    3fffffa0:  3fffdad0 00000000 3ffee4f8 40204398
    3fffffb0:  feefeffe feefeffe 3ffe8538 40100bed
    <<<stack<<<
    Decoding stack results
    0x402051e5: uart_flush(uart_t*) at C:\Users\stoma\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\uart.cpp line 544
    0x4020514d: uart_write(uart_t*, char const*, size_t) at C:\Users\stoma\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\uart.cpp line 509
    0x40203668: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\stoma\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266/HardwareSerial.h line 164
    0x401001d0: millis() at C:\Users\stoma\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\core_esp8266_wiring.cpp line 185
    0x40203941: Print::write(char const*) at C:\Users\stoma\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266/Print.h line 62
    0x40202770: ESP8266WiFiSTAClass::status() at C:\Users\stoma\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\libraries\ESP8266WiFi\src\ESP8266WiFiSTA.cpp line 634
    0x40201d22: setup() at C:\Users\stoma\OneDrive\Робочий стіл\amperka/amperka.ino line 41
    0x40204398: loop_wrapper() at C:\Users\stoma\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.2\cores\esp8266\core_esp8266_main.cpp line 194
     
    В чем проблема? Подскажите пожалуйста.
    Вот сам код.
    Код (C++):

    #include <ESP8266WiFi.h>
    #include <ArduinoJson.h>

    const char* ssid = ""; // wifi
    const char* password = ""; //пароль wifi
    const char* host = "herokuapp.com";

    unsigned long time_1;
    unsigned long time_2;


    #define IN1 3
    #define IN2 4
    #define IN3 5
    #define IN4 6

    bool up = 0;
    bool down = 0;
    bool left = 0;
    bool right = 0;

    String line;

    void setup()
    {

      Serial.begin(115200);
      delay(10);


      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED)
      {
      if (millis() - time_1 > 500)
      {
      time_1 = millis();
      Serial.print(".");
      }
      }

      Serial.println("");
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
                                 
      pinMode(IN1, OUTPUT);
      pinMode(IN2, OUTPUT);
      pinMode(IN3, OUTPUT);
      pinMode(IN4, OUTPUT);

        jsonGet();
    }

    void loop()
    {
      StaticJsonBuffer<2000> jsonBuffer; /// буфер на 2000 символов
      JsonObject& root = jsonBuffer.parseObject(line);  
      if (!root.success())
      {
        Serial.println("parseObject() failed");          
        jsonGet();                                      
        return;                                        
      }

      Serial.println();
      String name = root["name"];                        
      Serial.print("name:");
      Serial.println(name);

      bool left = root["left"];                
      Serial.print("left: ");
      Serial.print(left);                              

      bool right = root["right"];        
      Serial.print("right: ");
      Serial.print(right);

      bool down = root["down"];
      Serial.print("down: ");
      Serial.print(down);

      bool up = root["up"];
      Serial.print("up: ");
      Serial.print(up);

     
      if(up == true)
        {
          digitalWrite(IN1, LOW);
          digitalWrite(IN2, HIGH);
          digitalWrite(IN3, LOW);
          digitalWrite(IN4, HIGH);
        }
     
      else if(down == true)
        {
          digitalWrite(IN1, HIGH);
          digitalWrite(IN2, LOW);
          digitalWrite(IN3, HIGH);
          digitalWrite(IN4, LOW);
        }
     
      else if(right == true)
        {
          digitalWrite(IN1, HIGH);
          digitalWrite(IN2, HIGH);
          digitalWrite(IN3, HIGH);
          digitalWrite(IN4, HIGH);
        }
     
      else if(left == true)
        {
          digitalWrite(IN1, HIGH);
          digitalWrite(IN2, HIGH);
          digitalWrite(IN3, HIGH);
          digitalWrite(IN4, HIGH);
        }
      else
        {
          digitalWrite(IN1, HIGH);
          digitalWrite(IN2, HIGH);
          digitalWrite(IN3, HIGH);
          digitalWrite(IN4, HIGH);
        }

    }

    void jsonGet()
    {

      WiFiClient client;
      const int httpPort = 80;
      if (!client.connect(host, httpPort))
        {
          Serial.println("connection failed");
          return;
        }

      client.println("GET secure-plains-50034.herokuapp.com HTTP/1.1");
      client.println("Host: herokuapp.com");
      client.println("Connection: close");
      client.println();

      if(client.available())
        {
          line = client.readStringUntil('\r');
        }
      Serial.print(line);
      Serial.println();
      Serial.println("closing connection");
    }
     
    Последнее редактирование: 4 ноя 2020
  8. Grzeg

    Grzeg Нуб

    Закоментировал void loop(), но в Serial'е опять выдает ошибку
     
  9. ИгорьК

    ИгорьК Гуру

    Я не большой спец в управлении esp на Си, но в сетапе есть еще один while. Закомментируйте весь его блок, посмотрите что будет.

    Вообще, в случае такой ошибки надо комментировать куски кода и выявлять его проблемные части.
     
    SergeiL нравится это.
  10. SergeiL

    SergeiL Оракул Модератор

    От delay() нужно избавляться в loop(),так как пока мы сидим в delay(), больше ничего не работает из loop().
    В setup(), в таком виде, как в коде выше, нет смыла убирать delay().
    Все равно управление никому не отдается пока мы сидим в while. Заходим мы в if или нет - разницы нет.
    Наоборот, вызывая delay() в setup(), пользовательский код останавливается, отдавая управление.
    В выводе выше не увидел "WiFi connected", либо его нет, либо вывод не полный, начал бы с этого.
     
  11. Grzeg

    Grzeg Нуб

    Код (C++):
    Connecting to g23
    ..............................
    WiFi connected
    IP address:
    мой ip адрес

    ets Jan  8 2013,rst cause:4, boot mode:(3,7)

    wdt reset
    load 0x4010f000, len 3584, room 16
    tail 0
    chksum 0xb0
    csum 0xb0
    v5d3af165
    ~ld

     
     
  12. parovoZZ

    parovoZZ Гуру

    а nodemcu разве не на RTOS сделан?
     
  13. b707

    b707 Гуру

    что значит "сделан" ? прошивку пишет программист. если он использует RTOS() - он будет, а нет - так нет
    Я пишу для ЕСП без RTOS(). правда у меня задачки обычно скромные
     
  14. SergeiL

    SergeiL Оракул Модератор

    Так нужно попробовать закомментировать Jason, как предлагал ИгорьК.
     
  15. ZAZ-965

    ZAZ-965 Гуру

    Для ESP8266 на NON-OS SDK, для ESP32 на ESP-IDF (китайская FreeRTOS v8)
     
  16. Grzeg

    Grzeg Нуб

    Всем спасибо, забыл , что нужно использовать gpio