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,18 +71,96 @@ 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; // Флаг для определения режима подключения
switch (connectStatus)
{
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;
}
break;
case CONNECT_FAIL:
Serial.print("Failed to connect to server in ");
Serial.println(isNonBlocking ? "non-blocking mode" : "blocking mode");
connectStatus = CONNECT_STOP_START;
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++)
{
client.write((uint8_t *)&packetCounter, sizeof(packetCounter));
// Печать отправленного пакета
Serial.print("Sending packet: ");
for (size_t j = 0; j < sizeof(packetCounter); j++)
{
Serial.print(((uint8_t *)&packetCounter)[j], HEX);
Serial.print(" ");
}
Serial.println();
packetCounter++;
lastActivityTime = millis(); // Обновляем время последней активности для каждого пакета
}
//! Передача завершена
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;
}
break;
default:
break;
}
switch (connectStatus)
{
case CONNECT_START:
case CONNECT_CONNECTING:
if (isNonBlocking) if (isNonBlocking)
{ {
connectStatus = client.connectNonBlock(serverIP, SERVER_PORT); connectStatus = client.connectNonBlock(serverIP, SERVER_PORT);
@ -88,40 +169,13 @@ void loop()
{ {
connectStatus = (ConnectionStatusSimple)client.connect(serverIP, SERVER_PORT); connectStatus = (ConnectionStatusSimple)client.connect(serverIP, SERVER_PORT);
} }
break;
if (connectStatus == CONNECT_SUCCESS) default:
{ break;
Serial.print("Connection established in "); }
Serial.println(isNonBlocking ? "non-blocking mode" : "blocking mode");
//! Соединение установлено
lastActivityTime = millis(); // Обновляем время последней активности
for (size_t i = 0; i < 3; i++)
{
client.write((uint8_t *)&packetCounter, sizeof(packetCounter));
// Печать отправленного пакета //? Проверка наличия доступных данных от сервера
Serial.print("Sending packet: ");
for (size_t j = 0; j < sizeof(packetCounter); j++)
{
Serial.print(((uint8_t *)&packetCounter)[j], HEX);
Serial.print(" ");
}
Serial.println();
packetCounter++;
lastActivityTime = millis(); // Обновляем время последней активности
}
dataReady = false;
connectStatus = CONNECT_IDLE;
}
else
{
Serial.print("Failed to connect to server in ");
Serial.println(isNonBlocking ? "non-blocking mode" : "blocking mode");
connectStatus = CONNECT_IDLE;
client.stop();
}
// Проверка наличия доступных данных от сервера
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

@ -45,4 +45,42 @@ 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__