2024-10-29 15:14:23 +03:00

216 lines
6.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "EthernetMaket.h" // Предполагается, что этот файл подключает Ethernet3.h
// Настройки для W5500
#define W5500_CS_PIN PA2 // Пин для CS
#define SOCKET_NUMBER 0 // Используем сокет 0
#define SERVER_PORT 1337 // Порт на сервере
#define CLIENT_PORT 1337 // Порт клиента
#define ServerMac {0xDA, 0x7A, 0xFF, 0x00, 0x00, 0x00}
#define ServerIP {192, 168, 254, 254}
#define IniMac {0xDA, 0x7A, 0xF0, 0x00, 0x00, 0x00}
#define IniIP {192, 168, 254, 253}
uint8_t gateway[] = {192, 168, 0, 1}; // Шлюз
uint8_t subnet[] = {255, 255, 0, 0}; // Маска подсети
uint8_t mac[] = IniMac; // MAC-адрес
uint8_t localIP[] = IniIP; // Локальный IP-адрес
uint8_t serverMac[] = ServerMac; // MAC-адрес сервера
uint8_t serverIP[] = ServerIP; // IP-адрес сервера
uint8_t buf[512]; // Буфер для передачи данных
uint32_t previousMillis = 0; // Для хранения времени последней отправки
const long interval = 3750; // Интервал отправки данных (1.75 секунды)
uint32_t ttt;
EthernetServer server(SERVER_PORT);
EthernetMaketClient client;
// EthernetMaketClient c;
uint32_t packetCounter = 0;
uint32_t lastActivityTime = 0; // Время последней активности
const uint16_t timeout = 300; // Таймаут неактивности в миллисекундах
uint32_t startConnection = 0;
const uint16_t connectionTimeout = 350;
uint32_t stopStartTime = 0; // Время начала состояния CONNECT_IDLE
const uint32_t stopTimeout = 300; // Таймаут для закрытия сокета в состоянии CONNECT_IDLE
void setup()
{
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
Ethernet.setCsPin(W5500_CS_PIN);
Ethernet.init();
// Настройка Ethernet с указанием статических параметров
Ethernet.begin(mac, localIP, subnet, gateway, gateway);
// Ethernet.setRtTimeOut(1000 * 10);
// Ethernet.setRtCount(3);
// client.setNoDelayedACK(true); // Не ждать ответа от сервера
}
ConnectionStatusSimple connectStatus = CONNECT_IDLE;
void loop()
{
uint32_t currentMillis = millis();
if (currentMillis - ttt > 75)
{
digitalToggle(PC13);
ttt = currentMillis; // Обновляем время
}
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
// client.stop(); // Завершаем предыдущее соединение
connectStatus = CONNECT_START;
}
// Подключаемся к серверу
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)
{
connectStatus = client.connectNonBlock(serverIP, SERVER_PORT);
}
else
{
connectStatus = (ConnectionStatusSimple)client.connect(serverIP, SERVER_PORT);
}
break;
default:
break;
}
//? Проверка наличия доступных данных от сервера
if (client.available() > 0)
{
byte response[16];
int len = client.read(response, sizeof(response));
if (len == 16)
{
// Проверка контрольной суммы
uint8_t checksum = 0;
for (int i = 0; i < 15; i++)
{
checksum += response[i];
}
Serial.print("RX: ");
for (int i = 0; i < 16; i++)
{
Serial.print(response[i], HEX);
Serial.print(" ");
}
if (response[15] == checksum)
{
Serial.println("Checksum is OK");
}
else
{
Serial.println("Checksum is ERROR");
}
lastActivityTime = millis(); // Обновляем время последней активности
}
else
{
Serial.println("Received an incomplete response");
}
}
//? -------------------------------------------------
}