-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIoTCode.ino
More file actions
118 lines (95 loc) · 3.5 KB
/
Copy pathIoTCode.ino
File metadata and controls
118 lines (95 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <WiFi.h>
#include <WebSocketsServer.h>
const char* SSID = "YOUR_WIFI_SSID";
const char* PASSWORD = "YOUR_WIFI_PASS";
// Static IP — so Flutter app always knows where to connect
IPAddress local_IP(192, 168, 1, 100);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet (255, 255, 255, 0);
const int RELAY_PINS[8] = {13, 32, 14, 27, 19, 21, 22, 23};
bool relayState[8] = {false};
WebSocketsServer ws(81);
unsigned long lastReconnectAttempt = 0;
// ── State helpers ─────────────────────────────────────────
String buildStateMsg() {
String msg = "";
for (int i = 0; i < 8; i++) {
msg += relayState[i] ? "1" : "0";
if (i < 7) msg += ",";
}
return msg;
}
void sendStates(uint8_t clientNum) {
ws.sendTXT(clientNum, buildStateMsg());
}
void broadcastStates() {
ws.broadcastTXT(buildStateMsg());
}
// ── WebSocket event handler ───────────────────────────────
void onWsEvent(uint8_t clientNum, WStype_t type, uint8_t* payload, size_t length) {
switch (type) {
case WStype_CONNECTED:
Serial.printf("[WS] Client %d connected\n", clientNum);
sendStates(clientNum); // sync state to newly connected client
break;
case WStype_DISCONNECTED:
Serial.printf("[WS] Client %d disconnected\n", clientNum);
break;
case WStype_TEXT: {
String msg = String((char*)payload, length); // length-safe construction
Serial.printf("[WS] Received: %s\n", msg.c_str());
// Validate format: must be "Rn:ON" or "Rn:OFF"
if (msg.length() < 5) break;
if (msg.charAt(0) != 'R') break;
int idx = msg.charAt(1) - '0';
if (idx < 0 || idx > 7) break;
String cmd = msg.substring(3);
if (cmd != "ON" && cmd != "OFF") break;
bool on = (cmd == "ON");
relayState[idx] = on;
digitalWrite(RELAY_PINS[idx], on ? HIGH : LOW);
broadcastStates(); // keep all connected clients in sync
break;
}
default:
break;
}
}
// ── Setup ─────────────────────────────────────────────────
void setup() {
Serial.begin(115200);
// Relays first — all OFF before WiFi starts
for (int i = 0; i < 8; i++) {
pinMode(RELAY_PINS[i], OUTPUT);
digitalWrite(RELAY_PINS[i], LOW);
}
// WiFi
WiFi.mode(WIFI_STA);
WiFi.config(local_IP, gateway, subnet);
WiFi.setAutoReconnect(true);
WiFi.persistent(false);
WiFi.begin(SSID, PASSWORD);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected: " + WiFi.localIP().toString());
// WebSocket
ws.begin();
ws.onEvent(onWsEvent);
Serial.println("WebSocket server on port 81");
}
// ── Loop ──────────────────────────────────────────────────
void loop() {
ws.loop();
// Non-blocking WiFi reconnect — won't freeze WebSocket processing
if (WiFi.status() != WL_CONNECTED) {
unsigned long now = millis();
if (now - lastReconnectAttempt > 5000) {
lastReconnectAttempt = now;
Serial.println("WiFi lost — reconnecting...");
WiFi.reconnect();
}
}
}