state mashine upd

This commit is contained in:
2024-10-29 15:14:23 +03:00
parent f3e1dd6ee8
commit 94ea050345
4 changed files with 149 additions and 74 deletions

View File

@ -23,7 +23,7 @@ uint8_t serverIP[] = ServerIP; // IP-адрес сервера
uint8_t buf[512]; // Буфер для передачи данных uint8_t buf[512]; // Буфер для передачи данных
unsigned long previousMillis = 0; // Для хранения времени последней отправки uint32_t previousMillis = 0; // Для хранения времени последней отправки
const long interval = 3750; // Интервал отправки данных (1.75 секунды) const long interval = 3750; // Интервал отправки данных (1.75 секунды)
uint32_t ttt; uint32_t ttt;
@ -34,11 +34,13 @@ EthernetMaketClient client;
uint32_t packetCounter = 0; uint32_t packetCounter = 0;
unsigned long lastActivityTime = 0; // Время последней активности uint32_t lastActivityTime = 0; // Время последней активности
const long timeout = 300; // Таймаут неактивности в миллисекундах const uint16_t timeout = 300; // Таймаут неактивности в миллисекундах
uint32_t startConnection = 0;
const uint16_t connectionTimeout = 350;
bool wasConnected = false; uint32_t stopStartTime = 0; // Время начала состояния CONNECT_IDLE
bool dataReady = false; const uint32_t stopTimeout = 300; // Таймаут для закрытия сокета в состоянии CONNECT_IDLE
void setup() void setup()
{ {
@ -48,7 +50,7 @@ void setup()
Ethernet.init(); Ethernet.init();
// Настройка Ethernet с указанием статических параметров // Настройка Ethernet с указанием статических параметров
Ethernet.begin(mac, localIP, gateway, gateway, subnet); Ethernet.begin(mac, localIP, subnet, gateway, gateway);
// Ethernet.setRtTimeOut(1000 * 10); // Ethernet.setRtTimeOut(1000 * 10);
// Ethernet.setRtCount(3); // Ethernet.setRtCount(3);
@ -56,6 +58,7 @@ void setup()
// client.setNoDelayedACK(true); // Не ждать ответа от сервера // client.setNoDelayedACK(true); // Не ждать ответа от сервера
} }
ConnectionStatusSimple connectStatus = CONNECT_IDLE;
void loop() void loop()
{ {
uint32_t currentMillis = millis(); uint32_t currentMillis = millis();
@ -68,33 +71,41 @@ void loop()
if (currentMillis - previousMillis >= interval) if (currentMillis - previousMillis >= interval)
{ {
previousMillis = currentMillis; previousMillis = currentMillis;
// client.stop(); // Завершаем предыдущее соединение
Serial.println("\n\nConnecting..."); connectStatus = CONNECT_START;
client.stop(); // Завершаем предыдущее соединение
dataReady = true;
} }
// Подключаемся к серверу // Подключаемся к серверу
ConnectionStatusSimple connectStatus;
bool isNonBlocking = true; // Флаг для определения режима подключения bool isNonBlocking = true; // Флаг для определения режима подключения
if (isNonBlocking) switch (connectStatus)
{ {
connectStatus = client.connectNonBlock(serverIP, SERVER_PORT); case CONNECT_START:
startConnection = millis();
connectStatus = CONNECT_CONNECTING;
client.close();
Serial.println("\n\nConnecting...");
break;
case CONNECT_CONNECTING:
if (millis() - startConnection >= connectionTimeout)
{
connectStatus = CONNECT_FAIL;
break;
} }
else break;
{ case CONNECT_FAIL:
connectStatus = (ConnectionStatusSimple)client.connect(serverIP, SERVER_PORT); Serial.print("Failed to connect to server in ");
}
if (connectStatus == CONNECT_SUCCESS)
{
Serial.print("Connection established in ");
Serial.println(isNonBlocking ? "non-blocking mode" : "blocking mode"); Serial.println(isNonBlocking ? "non-blocking mode" : "blocking mode");
//! Соединение установлено connectStatus = CONNECT_STOP_START;
lastActivityTime = millis(); // Обновляем время последней активности break;
case CONNECT_SUCCESS:
Serial.print("Connected to server in ");
Serial.println(isNonBlocking ? "non-blocking mode" : "blocking mode");
lastActivityTime = millis();
connectStatus = CONNECT_CONNECTED;
//! Передача пакетов
for (size_t i = 0; i < 3; i++) for (size_t i = 0; i < 3; i++)
{ {
client.write((uint8_t *)&packetCounter, sizeof(packetCounter)); client.write((uint8_t *)&packetCounter, sizeof(packetCounter));
@ -108,20 +119,63 @@ void loop()
} }
Serial.println(); Serial.println();
packetCounter++; packetCounter++;
lastActivityTime = millis(); // Обновляем время последней активности lastActivityTime = millis(); // Обновляем время последней активности для каждого пакета
} }
dataReady = false; //! Передача завершена
break;
case CONNECT_CONNECTED:
if (!client.connected())
{
Serial.println("Client disconnected");
connectStatus = CONNECT_STOP_START;
}
// Закрытие соединения по таймеру неактивности
if (client.connected() && (millis() - lastActivityTime > timeout))
{
Serial.println("Connection closed due to inactivity");
connectStatus = CONNECT_STOP_START;
}
break;
case CONNECT_STOP_START:
client.disconnect();
stopStartTime = millis();
connectStatus = CONNECT_STOP_WAITING;
break;
case CONNECT_STOP_WAITING:
if (millis() - stopStartTime >= stopTimeout)
{
client.close(); // Закрываем сокет после таймаута
connectStatus = CONNECT_IDLE; connectStatus = CONNECT_IDLE;
} }
break;
default:
break;
}
switch (connectStatus)
{
case CONNECT_START:
case CONNECT_CONNECTING:
if (isNonBlocking)
{
connectStatus = client.connectNonBlock(serverIP, SERVER_PORT);
}
else else
{ {
Serial.print("Failed to connect to server in "); connectStatus = (ConnectionStatusSimple)client.connect(serverIP, SERVER_PORT);
Serial.println(isNonBlocking ? "non-blocking mode" : "blocking mode"); }
connectStatus = CONNECT_IDLE; break;
client.stop();
default:
break;
} }
// Проверка наличия доступных данных от сервера //? Проверка наличия доступных данных от сервера
if (client.available() > 0) if (client.available() > 0)
{ {
byte response[16]; byte response[16];
@ -158,27 +212,5 @@ void loop()
Serial.println("Received an incomplete response"); Serial.println("Received an incomplete response");
} }
} }
//? -------------------------------------------------
// Обновление состояния подключения
if (!wasConnected && client.connected())
{
wasConnected = true;
} }
if (wasConnected && !client.connected())
{
wasConnected = false;
client.stop();
Serial.println("Client disconnected");
}
// Закрытие соединения по таймеру неактивности
if (client.connected() && (millis() - lastActivityTime > timeout))
{
wasConnected = false;
Serial.println("Connection closed due to inactivity");
client.stop();
}
}

View File

@ -10,7 +10,10 @@ enum ConnectionStatusSimple{
CONNECT_SUCCESS = 1, CONNECT_SUCCESS = 1,
CONNECT_CONNECTING = 2, CONNECT_CONNECTING = 2,
CONNECT_START = 3, CONNECT_START = 3,
CONNECT_IDLE = 4 CONNECT_IDLE = 4,
CONNECT_CONNECTED = 5,
CONNECT_STOP_START = 6,
CONNECT_STOP_WAITING = 7,
}; };

View File

@ -46,3 +46,41 @@ ConnectionStatusSimple EthernetMaketClient::connectNonBlock(IPAddress ip, uint16
return CONNECT_CONNECTING; return CONNECT_CONNECTING;
} }
void EthernetMaketClient::disconnect(){
if (_sock == MAX_SOCK_NUM)
return;
::disconnect(_sock);
}
void EthernetMaketClient::close(){
if (_sock == MAX_SOCK_NUM)
return;
::close(_sock);
_sock = MAX_SOCK_NUM;
}
// void EthernetMaketClient::stop() {
// if (_sock == MAX_SOCK_NUM)
// return;
// // attempt to close the connection gracefully (send a FIN to other side)
// disconnect(_sock);
// unsigned long start = millis();
// // wait a second for the connection to close
// uint8_t s;
// do {
// s = status();
// if (s == SnSR::CLOSED)
// break; // exit the loop
// delay(1);
// } while (millis() - start < 1000);
// // if it hasn't closed, close it forcefully
// if (status() != SnSR::CLOSED)
// close(_sock);
// EthernetClass::_server_port[_sock] = 0;
// _sock = MAX_SOCK_NUM;
// }

View File

@ -9,7 +9,9 @@ public:
using EthernetClient::EthernetClient; using EthernetClient::EthernetClient;
ConnectionStatusSimple connectNonBlock(IPAddress ip, uint16_t port); ConnectionStatusSimple connectNonBlock(IPAddress ip, uint16_t port);
// void stop() override;
void disconnect();
void close();
}; };
#endif // __MAKET_TCP_H__ #endif // __MAKET_TCP_H__