#include #include "logs.h" #include // -------------------- НАСТРОЙКИ -------------------- char ssid[32] = ""; char password[32] = ""; char serverIP[32] = "198.168.0.1"; #define NEOPIXEL_PIN 48 #define NUMPIXELS 1 #define BRIGHTNESS 40 #define SERVER // раскомментировать для сервера // -------------------- ФУНКЦИИ -------------------- Adafruit_NeoPixel pixels(NUMPIXELS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800); uint8_t brightness = 0; // 0 = выкл, 255 = макс bool greenOn = false; LogModule logger; void toggleGreen() { greenOn = !greenOn; // меняем состояние if (greenOn) { pixels.setPixelColor(0, pixels.Color(0, BRIGHTNESS, 0)); // включаем зелёный } else { pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // выключаем } pixels.show(); } void setRed() { pixels.setPixelColor(0, pixels.Color(BRIGHTNESS, 0, 0)); pixels.show(); } void setYellow() { pixels.setPixelColor(0, pixels.Color(BRIGHTNESS, BRIGHTNESS, 0)); pixels.show(); } void clearLED() { pixels.setPixelColor(0, pixels.Color(0, 0, 0)); pixels.show(); } // -------------------- РЕЖИМЫ -------------------- #ifdef SERVER WiFiServer server(1234); #else WiFiClient client; #endif // -------------------- Wi-Fi -------------------- bool wifiConnecting = false; void startWiFi() { WiFi.disconnect(true); WiFi.begin(ssid, password); wifiConnecting = true; Serial.print("Connecting to WiFi"); } void handleWiFi() { static uint32_t lastCheck = 0; const uint32_t interval = 500; // проверять каждые 500 мс if (millis() - lastCheck < interval) return; lastCheck = millis(); if (WiFi.status() == WL_CONNECTED) { if (wifiConnecting) { wifiConnecting = false; clearLED(); Serial.println("\nWiFi connected"); Serial.print("IP: "); Serial.println(WiFi.localIP()); #ifdef SERVER server.begin(); } #else else { if (!client.connected()) { if (WiFi.status() != WL_CONNECTED) return; setYellow(); if (client.connect(serverIP, 1234)) { clearLED(); Serial.println("Connected to server"); } } } #endif } else { setRed(); if (!wifiConnecting) { Serial.println("\nWiFi disconnected. Reconnecting..."); startWiFi(); } else { Serial.print("."); } } } // -------------------- UART ДЛЯ НАСТРОЕК -------------------- void handleUARTNetwork() { static String buffer; while (Serial.available()) { char c = Serial.read(); if (c == '\n' || c == '\r') { buffer.trim(); if (buffer.length() > 0) { int sep = buffer.indexOf(' '); if (sep > 0) { String cmd = buffer.substring(0, sep); String val = buffer.substring(sep + 1); if (cmd == "SSID") { val.toCharArray((char*)ssid, 32); Serial.print("\nSSID set to: "); Serial.println(ssid); startWiFi(); } else if (cmd == "PASS") { val.toCharArray((char*)password, 32); Serial.print("\nPassword set to: "); Serial.println(password); startWiFi(); } else if (cmd == "IP") { val.toCharArray((char*)serverIP, 16); Serial.print("\nServer IP set to: "); Serial.println(serverIP); } else { logger.handleUART(buffer[0]); // передаем неизвестные команды в логгер } } else { logger.handleUART(buffer[0]); // нет пробела — считаем команду неизвестной } } buffer = ""; } else { buffer += c; } } } void setup() { Serial.begin(115200); delay(1000); logger.begin(); pixels.begin(); pixels.show(); #ifdef SERVER Serial.println("SERVER MODE: Enter SSID and PASS via UART, e.g.:\nSSID MyWiFi\nPASS 12345678"); #else Serial.println("CLIENT MODE: Enter server IP via UART, e.g.:\nIP 192.168.1.100"); #endif } void loop() { handleUARTNetwork(); // UART-функция для настройки сети и получения логов handleWiFi(); // проверка состояния Wi-Fi if (WiFi.status() != WL_CONNECTED) return; #ifdef SERVER WiFiClient clientConn = server.available(); if (!clientConn) return; Serial.println("Client connected"); while (clientConn.connected()) { if (clientConn.available()) { String msg = clientConn.readStringUntil('\n'); msg.trim(); if (msg.length() == 0) continue; // Разбор входящего сообщения LogEntry entry; entry.seq = 0; entry.ts = 0; entry.event_type = 0; // RECEIVE memset(entry.payload, 0, sizeof(entry.payload)); int seqIndex = msg.indexOf("SEQ:"); int tsIndex = msg.indexOf("TS:"); int payloadIndex = msg.indexOf("PAYLOAD:"); if (seqIndex >= 0 && tsIndex > seqIndex && payloadIndex > tsIndex) { String seqStr = msg.substring(seqIndex + 4, tsIndex); seqStr.trim(); String tsStr = msg.substring(tsIndex + 3, payloadIndex); tsStr.trim(); String payloadStr = msg.substring(payloadIndex + 8); payloadStr.trim(); entry.seq = seqStr.toInt(); entry.ts = strtoull(tsStr.c_str(), nullptr, 10); int len = min((int)payloadStr.length(), 16); payloadStr.toCharArray(entry.payload, len + 1); } // Сохраняем лог logger.writeLog(entry); Serial.print("Received: "); Serial.println(msg); toggleGreen(); // Создаем SEND-запись LogEntry sendEntry = entry; sendEntry.ts = millis(); sendEntry.event_type = 1; // SEND logger.writeLog(sendEntry); // Echo для клиента String echo = "SEQ:" + String(sendEntry.seq) + " TS:" + String(sendEntry.ts) + " EVT:SEND PAYLOAD:" + String(sendEntry.payload) + "\n"; if (clientConn.print(echo)) { Serial.print("Sent: "); Serial.println(echo); } else { Serial.println("Error sending to client"); setRed(); } } } clientConn.stop(); Serial.println("Client disconnected"); #else // CLIENT static uint32_t lastSendMillis = 0; // время последней отправки const uint32_t sendInterval = 500; // 500 мс между отправками static uint16_t seqNum = 1; if (!client.connected()) return; // проверяем, пора ли отправлять сообщение if (millis() - lastSendMillis >= sendInterval) { lastSendMillis = millis(); // фиксируем время отправки String msg = "SEQ:" + String(seqNum) + " TS:" + String(millis()) + " PAYLOAD:Hard!Text^?123\n"; if (client.print(msg)) { Serial.print("Sent: "); Serial.println(msg); toggleGreen(); // Сохраняем SEND-запись LogEntry entry; entry.seq = seqNum; entry.ts = millis(); entry.event_type = 1; // SEND msg.substring(msg.indexOf("PAYLOAD:") + 8).toCharArray(entry.payload, 16); logger.writeLog(entry); seqNum++; } else { Serial.println("Error sending"); setRed(); } } // Чтение ответа без блокировки while (client.available()) { String resp = client.readStringUntil('\n'); resp.trim(); if (resp.length() == 0) continue; Serial.print("Received: "); Serial.println(resp); // Сохраняем RECEIVE-запись LogEntry entry; entry.seq = resp.indexOf("SEQ:"); entry.ts = resp.indexOf("TS:"); entry.event_type = 0; // RECEIVE int payloadIndex = resp.indexOf("PAYLOAD:"); if (payloadIndex >= 0) { String payloadStr = resp.substring(payloadIndex + 8); payloadStr.toCharArray(entry.payload, 16); } logger.writeLog(entry); toggleGreen(); } #endif }