Перезапуск скетча ардуино в рандомные моменты

Есть прошивка, которая работает на 2 интерфейса: отправка/прием данных по usb и по wifi (само устройство является точкой доступа). По usb всё работает хорошо, скетч не перезапускается. При использовании интерфейса wifi в рандомные промежутки времени скетч перезапускается без каких-либо оповещениях об ошибках и т.д. Множество событий было прописано, чтобы отследить, что происходит, но никаких событий перед вылетом не происходило. Может есть какие-то особенности передачи и приемке данных по wifi, отличающееся от usb, которые я не учла.
Интерфейс wifi:

#include "ISerialInterface.h"
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiAP.h>
#include <WiFiType.h>
#include "EEPROM.h"

#define EEPROM_SSID_LEN_OFFSET 0x400
#define EEPROM_SSID_OFFSET 0x300
#define EEPROM_PASS_LEN_OFFSET 0x200
#define EEPROM_PASS_OFFSET 0x100
EEPROMClass  SAVED_SSID_LEN("eeprom0");
EEPROMClass  SAVED_SSID("eeprom1");
EEPROMClass  SAVED_PASS_LEN("eeprom2");
EEPROMClass  SAVED_PASS("eeprom3");

#define DEFAULT_AP_SSID "MyWiFi1_0000"
#define DEFAULT_AP_PASS "12345678"

class TWiFiTCPSerial : public ISerialInterface {
public:
  //Конструктор
  //TWiFiTCPSerial();
  //Деструктор
  //..~TWiFiTCPSerial();

  String AP_SSID = String(DEFAULT_AP_SSID);
  String AP_PASS = String(DEFAULT_AP_PASS);

//------------------------------------------------------------------------------------------------
  bool begin(unsigned long baud)
  {
    AP_SSID = String(DEFAULT_AP_SSID);
    AP_PASS = String(DEFAULT_AP_PASS);
    isCreatedAP = false;
    isClientConnected = false;

    //Проверяем, есть ли конфигурация для подключения к существуюшей точке доступа
    bool needToCreateAP = false;
    String config_ssid = "";
    String config_pass = "";
    if (readNetworkConfig(&config_ssid, &config_pass))
    {
      AP_SSID = config_ssid; //TEST DEBUG
      AP_PASS = config_pass;
      Serial.print("AP3=");
      Serial.println(AP_SSID);
      needToCreateAP = false;
    }
    else
    {
      needToCreateAP = true;
    }

ToForceCreateAP:;
    if (needToCreateAP)
    {
      //Сбрасываем настройки сети на по-умолчанию
      AP_SSID = String(DEFAULT_AP_SSID);
      AP_PASS = String(DEFAULT_AP_PASS);

      String mac = WiFi.macAddress();
      AP_SSID = "MyWiFi1_0000";
      AP_SSID[5] = mac[12];
      AP_SSID[6] = mac[13];
      AP_SSID[7] = mac[15];
      AP_SSID[8] = mac[16];

      Serial.print("Creating Wi-Fi AP ");
      Serial.println(AP_SSID);

      //Создаём точку доступа с сгенерированным из mac SSID и фиксированным паролем
      createAP(AP_SSID, AP_PASS);

      if (!isCreatedAP)
      {
        //Необрабатываемая ошибка создания сети
        ESP.restart();
        return false;
      }
    }

    if (isCreatedAP)
    {
      //Мы уже внутри собственной сети
    }
    else
    {
      //Подключаемся к точке доступа
      Serial.println();
      Serial.println("******************************************************");
      Serial.print("Connecting to ");
      Serial.println(AP_SSID);

      WiFi.mode(WIFI_AP);
      WiFi.begin(AP_SSID, AP_PASS);
      WiFi.setSleep(false);

      unsigned long start = millis();

      while (WiFi.status() != WL_CONNECTED)
      {
        if (millis() - start > 10000)
        {
          //не удалось подключиться к существующей сети. Создаём свою сеть
          needToCreateAP = true;
          goto ToForceCreateAP;
        }
        Serial.print(".");
        delay(100);
      }
      Serial.println();

      WiFi.setAutoReconnect(true);
      WiFi.persistent(true);
      

      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
    }

    //Создаём TCP сервер
    tcpServer = WiFiServer(port);
    tcpServer.begin();
    tcpServer.setNoDelay(true);

    Serial.print("Created TCP server at port ");
    Serial.println(port);

    tcpClient.stop();
    return true;
  }
//------------------------------------------------------------------------------------------------
  inline void end()
  {
    tcpServer.end();
    isClientConnected = false;
    isCreatedAP = false;
    WiFi.softAPdisconnect();
  }

  inline void update()
  {
    {
      if (!isClientConnected && tcpServer.hasClient())
      {
        Serial.println("New client connected!");
        tcpClient = tcpServer.accept();
        tcpClient.setNoDelay(true);
        tcpClient.setTimeout(100);
        
        isClientConnected = true;
      }
      if (isClientConnected && !tcpClient)
      {
        Serial.println("Client disconnected.");
        isClientConnected = false;
        tcpClient.stop();
      }
    }
  }
//------------------------------------------------------------------------------------------------
  inline size_t print(const char* value) {
    return write((const uint8_t *)value, strlen(value));
  }

  inline size_t print(const String &value) {
    return write((const uint8_t *)value.c_str(), value.length());
  }

  inline size_t print(int value, int base = DEC) {
    return print((long)value, base);
  }

  inline size_t print(unsigned int value, int base = DEC) {
    return print((unsigned long)value, base);
  }

  size_t print(long value, int base = DEC) {
    char buf[11]; // достаточно для base 2
    ltoa(value, buf, base);
    return print(buf);
  }
  size_t print(unsigned long value, int base = DEC)
  {
    char buf[11];
    ultoa(value, buf, base);
    return print(buf);
  }
  size_t print(float value)
  {
    return 0;
  }
//------------------------------------------------------------------------------------------------
  inline void println(String text)
  {
    if (tcpClient)
    {
      tcpClient.print(text + "\r\n");
    }
    else
    {
      Serial.println("tcpClient in println = 0");
    }
  }
//------------------------------------------------------------------------------------------------
  int available()
  {
    if (!isClientConnected)
      return 0;
    return tcpClient.available();
  }
//------------------------------------------------------------------------------------------------
  inline int read()
  {
    return tcpClient.read();
  }
//------------------------------------------------------------------------------------------------
  inline void flush()
  {
    if (tcpClient)
    {
      tcpClient.flush();
    }
    else
    {
      Serial.println("tcpClient in flush = 0");
    }
  }
//------------------------------------------------------------------------------------------------
  inline size_t write(uint8_t value)
  {
    if (tcpClient)
    {
      return tcpClient.write(value);
    }
    else
    {
      Serial.println("tcpClient in write = 0");
      return 0;
    }
  }
//------------------------------------------------------------------------------------------------
  inline size_t write(const uint8_t* buffer, size_t size)
  {
    if (tcpClient)
    {
      return tcpClient.write(buffer, size);
    }
    else
    {
      Serial.println("tcpClient in write = 0");
      return 0;
    }
  }
//------------------------------------------------------------------------------------------------
  String readString()
  {
    if (tcpClient)
    {
        int len = tcpClient.available();

      if (len <= 0)
        return "";

      char* chr_arr = new char[len];
      for (uint32_t i = 0; i < len; i++)
      {
        int byte = tcpClient.read();
        if (byte == -1)
        {
          Serial.println("Error reading data");
        }
        chr_arr[i] = (char)byte;
      }

      String result(chr_arr, len);
      delete[] chr_arr;
      return result;
    }
    else
    {
      Serial.println("tcpClient in readString = 0");
      return "";
    }
  }

  inline bool isConnected()
  {
    return isClientConnected;
  }
//------------------------------------------------------------------------------------------------
  //Задать конфигурацию подключения к существующей wi-fi сети
  void setNetworkConfig(char* ssid, char* pass)
  {
    AP_SSID = String(ssid);
    AP_PASS = String(pass);
  }
//------------------------------------------------------------------------------------------------
  //Сохранить в EEPROM конфигурацию подключения к существующей wi-fi сети
  void saveNetworkConfig()
  {
    if (SAVED_SSID.begin(EEPROM_SSID_OFFSET))
      SAVED_SSID.writeString(0, AP_SSID);

    if (SAVED_PASS.begin(EEPROM_PASS_OFFSET))
      SAVED_PASS.writeString(0, AP_PASS);
  }
//------------------------------------------------------------------------------------------------
  //Очистить/удалить из EEPROM конфигурацию подключения к существующей wi-fi сети
  void clearNetworkConfig()
  {
    if (SAVED_SSID.begin(EEPROM_SSID_OFFSET))
      SAVED_SSID.writeString(0, "");

    if (SAVED_PASS.begin(EEPROM_PASS_OFFSET))
      SAVED_PASS.writeString(0, "");
  }
//------------------------------------------------------------------------------------------------
  //Попытаться считать из EEPROM конфигурацию подключения к существующей wi-fi сети
  bool readNetworkConfig(String* config_ssid, String* config_pass)
  {
    return false;
  }
//================================================================================================

private:

//------------------------------------------------------------------------------------------------
  bool createAP(String ssid, String password)
  {
    //Создаём точку доступа
    if (!WiFi.softAP(ssid, password))
    {
      Serial.println("Soft AP creation failed.");
      return false;
    }

    IPAddress myIP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(myIP);

    isCreatedAP = true;
    return true;
  }
//------------------------------------------------------------------------------------------------

  //Флаг - Создана Wi-Fi точка доступа
  bool isCreatedAP = false;
  //Флаг - к TCP серверу подключен клиент
  bool isClientConnected = false;
  //
  uint16_t port = 23;
  WiFiServer tcpServer;
  WiFiClient tcpClient;
  
};

есть - плохое питание.
а вообще, что за плата, как/от чего питается, ну и далее по списку…

Плата ESP32-S3-WROOM-1 Питание идет от компьютера и повербанка, если по вай фай передача, от телефона если по usb. Flash Size - 8MB, использую OPI PSRAM. Много информации не могу дать, так как плату делала не я, только прошивкой занимаюсь

вызови esp_reset_reason() в начале скетча, посмотри какая причина прошлой перезагрузки.

Если причина перезагрузки watchdog interrupt или еще какой watchdog, или, может, brownout, то СКОРЕЕ ВСЕГО проблема в слабом блоке питания. WiFi жрет много, и может вызывать перезагрузку, если питания недостаточно.

2 лайка

помогло понять причину!! спасибо большое!!

1 лайк