Есть прошивка, которая работает на 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;
};