290 lines
8.8 KiB
C++
290 lines
8.8 KiB
C++
#include <WiFi.h>
|
||
#include "logs.h"
|
||
#include <Adafruit_NeoPixel.h>
|
||
|
||
// -------------------- НАСТРОЙКИ --------------------
|
||
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
|
||
}
|