· 7 months ago · Mar 11, 2025, 03:20 PM
1#include <WiFi.h>
2#include <WebServer.h>
3#include <HTTPClient.h>
4#include <ArduinoJson.h>
5#include <EEPROM.h>
6
7const char* ssidAP = "F_T";
8const char* passwordAP = "1234512345";
9
10WebServer server(80);
11
12String wifiSSID;
13String wifiPassword;
14String firebaseURL;
15String firebaseAPIKey;
16String firebaseNode;
17
18const int EEPROM_SIZE = 512;
19
20const int ledPin = 2; // פין הלד המובנה ב-ESP32
21unsigned long startTime = 0; // משתנה לשמירת זמן ההתחלה
22bool ledOn = false; // משתנה למעקב אחרי מצב ה-LED
23int duration = 0; // משתנה לאחסון זמן ההדלקה
24
25String globalSerialData = "";
26
27int preValue1 = -1;
28int preValue2 = -1;
29int preValue3 = -1;
30
31// פונקציה שמחלצת ערכים מספריים מ-JSON ושולחת אותם כערכים עשרוניים ל-Serial2
32void processJsonAndSendSerial2(const String &jsonString) {//מעבד מחרוזת ג'יסון ושולח נתונים דרך Serial2.
33 // יצירת אובייקט JSON
34 StaticJsonDocument<200> jsonDoc;
35
36 // ניסיון לפענח את ה-JSON
37 DeserializationError error = deserializeJson(jsonDoc, jsonString);
38
39 if (error) {
40 Serial.print("deserializeJson() failed: ");
41 Serial.println(error.f_str());
42 return;
43 }
44 Serial.print("json send to serial ============> ");
45 Serial.println(jsonString);
46 // חילוץ 4 הערכים מתוך ה-JSON (בהנחה שהם מספרים שלמים)
47 int value1 = jsonDoc["A"];//47-53 לא פעיל
48 int value2 = jsonDoc["B"];
49 int value3 = jsonDoc["C"];
50
51 preValue1 = value1;
52 preValue2 = value2;
53 preValue3 = value3;
54
55 Serial2.write(jsonString.toInt());//שולח למוניטור את המידע מהפיירבייס
56
57}
58
59
60
61void turnOnLED() {//מדליק את הלד ומשתמש במשתנה זמן כדי לקבוע מתי לכבות אותו.
62 pinMode(ledPin, OUTPUT); // הגדרת פין ה-LED כיציאה
63
64 if (!ledOn || duration == 0) { // אם ה-LED כבוי, להדליק אותו ולשמור את זמן ההתחלה
65 digitalWrite(ledPin, HIGH); // הדלקת ה-LED
66 startTime = millis(); // שמירת זמן ההתחלה
67 ledOn = true; // עדכון מצב ה-LED
68 }
69
70
71 // בדיקה אם ה-LED דולק ואם עבר הזמן שנקבע
72 if (ledOn && (millis() - startTime >= duration) && duration > 0) {
73 digitalWrite(ledPin, LOW); // כיבוי ה-LED
74 ledOn = false; // עדכון מצב ה-LED
75 }
76}
77
78bool connectToWiFi() {//מנסה להתחבר לרשת הויפי עם האישורים השמורים.
79 if (wifiSSID.length() > 0 ) {
80 WiFi.softAPdisconnect();
81 WiFi.begin(wifiSSID.c_str(), wifiPassword.c_str());
82 Serial.print("Connecting to WiFi");
83 int attempts = 0;
84 while (WiFi.status() != WL_CONNECTED && attempts < 20) {
85 delay(500);
86 Serial.print(".");
87 attempts++;
88
89 }
90 Serial.println();
91
92 if (WiFi.status() == WL_CONNECTED) {
93 Serial.println("Connected to WiFi");
94 Serial.print("IP address: ");
95 Serial.println(WiFi.localIP());
96 Serial.println(WiFi.getHostname());
97 duration = 0;
98
99 return true;
100 } else {
101 Serial.println("Failed to connect to WiFi, setting up Access Point...");
102 duration = 1000;
103 return false;
104
105 }
106 } else {
107 Serial.println("No WiFi credentials stored, setting up Access Point...");
108
109 duration = 500;
110 return false;
111 }
112}
113int x=0;
114bool setupAccessPoint() {//מגדיר נקודת גישה במידה ואין חיבור לרשת ויפי.
115 //IPAddress IP = WiFi.softAPIP();
116 if(x==0){
117 IPAddress local_ip(192, 168, 4, 1); // הגדרת כתובת IP קבועה ל-AP
118 IPAddress gateway(192, 168, 4, 1);
119 IPAddress subnet(255, 255, 255, 0);
120 WiFi.softAPConfig(local_ip, gateway, subnet); // הגדרת כתובת IP קבועה
121 WiFi.softAP(ssidAP, passwordAP);
122 IPAddress IP = WiFi.softAPIP();
123
124 server.on("/", handleRoot);//כניסה לענף
125 server.on("/submit", handleFormSubmission);
126 server.begin();
127 Serial.println("Web server started.");
128 x=1;//אם הצלחנו להיכנס אז מקבל ערך אחד כדי שלא ינסא להתחבר שוב
129 return true;
130 }else{
131 duration = 10;
132 Serial.print("AP IP address: ");
133 Serial.println(WiFi.softAPIP());//מדפיס את הכתובת של של האתר להכנסת המידע של הוייפי והפיירבייס
134 duration = 1000;
135
136 delay(500);
137 return true;
138 }
139
140
141
142
143 return false;
144
145}
146void saveToEEPROM() {//מקצה מקום בזיכרון לנתונים של הויפי והפיירבייס
147 EEPROM.writeString(0, wifiSSID);
148 EEPROM.writeString(100, wifiPassword);
149 EEPROM.writeString(200, firebaseURL);
150 EEPROM.writeString(300, firebaseAPIKey);
151 EEPROM.writeString(400, firebaseNode);
152 EEPROM.commit();
153}
154void handleRoot() {
155 String html = "<!DOCTYPE html><html lang='en'><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width, initial-scale=1.0'>";
156 html += "<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css'>";
157 html += "<title>ESP32 Configuration</title></head><body>";
158 html += "<div class='container'><h2>ESP32 Configuration</h2>";
159 html += "<form action='/submit' method='post'>";
160 html += "<div class='form-group'><label for='ssid'>WiFi SSID:</label><input type='text' class='form-control' id='ssid' name='ssid' value='" + wifiSSID + "' required></div>";
161 html += "<div class='form-group'><label for='password'>WiFi Password:</label><input type='password' class='form-control' id='password' name='password' value='" + wifiPassword + "' required></div>";
162 html += "<div class='form-group'><label for='firebaseURL'>Firebase URL:</label><input type='text' class='form-control' id='firebaseURL' name='firebaseURL' value='" + firebaseURL + "' required></div>";
163 html += "<div class='form-group'><label for='firebaseAPIKey'>Firebase API Key:</label><input type='text' class='form-control' id='firebaseAPIKey' name='firebaseAPIKey' value='" + firebaseAPIKey + "' required></div>";
164 html += "<div class='form-group'><label for='firebaseNode'>Firebase Node:</label><input type='text' class='form-control' id='firebaseNode' name='firebaseNode' value='" + firebaseNode + "' required></div>";
165 html += "<button type='submit' class='btn btn-primary'>Submit</button></form></div>";
166 html += "</body></html>";
167
168 server.send(200, "text/html", html);
169}
170
171void handleFormSubmission() {//מעבד את הנתונים שהוזנו בתופס ושומר אותם בזיכרון
172 if (server.method() == HTTP_POST) {
173 wifiSSID = server.arg("ssid");
174 if(server.hasArg("password")){
175 wifiPassword = server.arg("password");
176 }else{
177 wifiPassword = "";
178 }
179
180 firebaseURL = server.arg("firebaseURL");
181 firebaseAPIKey = server.arg("firebaseAPIKey");
182 firebaseNode = server.arg("firebaseNode");
183 Serial.print("Connected to WiFi => ");
184 Serial.println(wifiPassword);
185 saveToEEPROM();
186
187 if (connectToWiFi()) {
188 Serial.println("Connected to WiFi");
189 Serial.print("IP address: ");
190 Serial.println(WiFi.localIP());
191 server.on("/", handleRoot);
192 server.on("/submit", handleFormSubmission);
193
194 server.begin();
195 Serial.println("Web server started.");
196
197 String ip = WiFi.localIP().toString();
198 String response = "<html><body><h2>Data saved successfully!</h2>";
199 response += "<p>WiFi SSID: " + wifiSSID + "</p>";
200 response += "<p>WiFi Password: " + wifiPassword + "</p>";
201 response += "<p>Firebase URL: " + firebaseURL + "</p>";
202 response += "<p>Firebase API Key: " + firebaseAPIKey + "</p>";
203 response += "<p>Firebase Node: " + firebaseNode + "</p>";
204 response += "<p>Web server IP: " + ip + "</p>";
205 response += "</body></html>";
206
207 server.send(200, "text/html", response);
208 } else {
209 Serial.println("Failed to connect to WiFi");
210 setupAccessPoint();
211 }
212 } else {
213 server.send(405, "text/plain", "Method Not Allowed");
214 }
215}
216
217
218
219void readFromEEPROM() {//קורא את נתוני הויפיי ונתוני הפיירבייס מהזיכרון באת אתחול המכשיר
220 wifiSSID = EEPROM.readString(0);
221 wifiPassword = EEPROM.readString(100);
222 firebaseURL = EEPROM.readString(200);
223 firebaseAPIKey = EEPROM.readString(300);
224 firebaseNode = EEPROM.readString(400);
225}
226
227byte incomingByte[13];//כי זה מה שאייל קבע TM
228int cnt = 0;
229char str;
230//int incomingByte =0;
231String readFromSerial2() {//קורא את הנתנוים מהסייראל וממיר אותם למחרוזת
232
233 if (Serial2.available()>=13) {
234 uint8_t receivedData[13];
235 String serialData = "";
236 // Read the 13 bytes from Serial2
237 for (int i = 0; i < 13; i++) {
238 receivedData[i] = Serial2.read();
239 }
240
241 for (int i = 0; i < 13; i++) {
242 if (i==3 || i==7 || i==11){
243 serialData += String(receivedData[i]);
244 Serial.println(serialData);
245
246 }else{
247 serialData += char(receivedData[i]);
248 }
249
250 }
251 //Serial2.flush();
252 return serialData;
253 }
254 return globalSerialData;
255}
256
257String convertToJsonString(const String &input) {//מקבל את הסטרינג של המידע ומעביר אותו למידע ג'יסון על מנת שנוכל לשלוח אותה לפיירבייס
258 // לבדוק אם המחרוזת מתחילה ב- '{' ומסתיימת ב- '}'
259 if (input.charAt(0) != '{' || input.charAt(input.length() - 1) != '}') {
260 return ""; // פורמט לא חוקי
261 }
262
263 String jsonString = "{";
264 int startPos = 1; // התחל אחרי '{'
265 int endPos = 0;
266
267 while (startPos < input.length() - 1) {
268 endPos = input.indexOf(':', startPos);
269 if (endPos == -1) {
270 return ""; // לא נמצא הסימן ':'
271 }
272 String name = input.substring(startPos, endPos);
273
274 startPos = endPos + 1;
275 endPos = input.indexOf(',', startPos);
276 if (endPos == -1) {
277 endPos = input.length() - 1; // הסימן האחרון הוא '}'
278 }
279 String value = input.substring(startPos, endPos);
280
281 jsonString += "\"" + name + "\":\"" + value + "\"";
282 startPos = endPos + 1;
283 if (startPos < input.length() - 1) {
284 jsonString += ",";
285 }
286 }
287
288 jsonString += "}";
289 return jsonString;
290}
291
292
293
294
295String parseInputToJsonString(const String &input) {//מפרק קלט עם פורמט מותאם אישית למחרוזת ג'יסון
296 String jsonString = "{";
297 int startPos = 0;
298 int endPos = 0;
299
300 while (startPos < input.length()) {
301 endPos = input.indexOf(':', startPos);
302 if (endPos == -1) {
303 return ""; // לא נמצא הסימן ":"
304 }
305 String name = input.substring(startPos, endPos);
306
307 startPos = endPos + 1;
308 endPos = input.indexOf('/', startPos);
309 if (endPos == -1) {
310 return ""; // לא נמצא הסימן "/"
311 }
312 String value = input.substring(startPos, endPos);
313
314 jsonString += "\"" + name + "\":\"" + value + "\"";
315 startPos = endPos + 1;
316 if (startPos < input.length()) {
317 jsonString += ",";
318 }
319 }
320
321 jsonString += "}";
322 Serial.print("jsonString =>");
323 Serial.println();
324 return jsonString;
325}
326
327void processAndSendSerialData(String data) {//מעבד נתנונים ושולח אותם לפיירבייס אם יש חיבור וייפיי
328 StaticJsonDocument<200> jsonDoc;
329 DeserializationError error = deserializeJson(jsonDoc, data);
330
331 if (error) {
332 Serial.print("deserializeJson() failed: ");
333 Serial.println(error.f_str());
334 return;
335 }
336
337 if (WiFi.status() == WL_CONNECTED) {//שולח את המידע בצורת הג'ייסון לפיירביייס
338 HTTPClient http;
339 String url = firebaseURL + "/" + firebaseNode+"/TX" + ".json?auth=" + firebaseAPIKey;
340 duration = 3000;
341 String jsonData;
342 serializeJson(jsonDoc, jsonData);
343
344 http.begin(url);
345 http.addHeader("Content-Type", "application/json");
346 int httpResponseCode = http.PUT(jsonData);
347
348 if (httpResponseCode > 0) {
349 String response = http.getString();
350 // Serial.println("HTTP PUT Response : " + String(httpResponseCode));
351 Serial.println("HTTP PUT Response : " + response);
352 } else {
353 Serial.println("Error in sending PUT: " + String(httpResponseCode));
354 }
355
356 http.end();
357 } else {
358 Serial.println("Wi-Fi not connected");
359 duration = 1000;
360 }
361}
362
363String getFirebaseData() {
364 String jsonData = "";
365 if (WiFi.status() == WL_CONNECTED) {
366 HTTPClient http;
367 String url = firebaseURL + "/" + firebaseNode+"/RX" + ".json?auth=" + firebaseAPIKey;
368 duration = 3000;
369 http.begin(url);
370 int httpResponseCode = http.GET();
371
372 if (httpResponseCode > 0) {
373 jsonData = http.getString();
374 // Serial.println("HTTP Response code: GET " + String(httpResponseCode));
375 Serial.println("HTTP Response: GET" + jsonData);
376 http.end();
377 return jsonData;
378 }
379 http.end();
380
381 } else {
382 Serial.println("Wi-Fi not connected");
383 duration = 1000;
384 return "Wi-Fi not connected";
385 }
386
387
388}
389
390void getSerialDataTask(void *pvParameters);
391void setup() {
392 Serial.begin(115200);
393 Serial2.begin(9600, SERIAL_8N1, 16, 17); // הגדרת Serial2 עם פינים RX ו-TX
394
395 EEPROM.begin(EEPROM_SIZE);
396
397 readFromEEPROM();
398
399 if(!connectToWiFi()){
400 setupAccessPoint();
401 }else{
402 server.on("/", handleRoot);
403 server.on("/submit", handleFormSubmission);
404
405 server.begin();
406 Serial.println("Web server started.");
407
408
409
410 StaticJsonDocument<200> jsonDoc;//זה הגודל של הג'יסון
411 jsonDoc["IP"] = WiFi.localIP().toString();
412 HTTPClient http;
413 String url = firebaseURL + "/" + firebaseNode+"/espServerIP" + ".json?auth=" + firebaseAPIKey;
414 String jsonData;
415 serializeJson(jsonDoc, jsonData);
416 Serial.println("firebaseNode: " + url);
417
418 http.begin(url);
419 http.addHeader("Content-Type", "application/json");
420 int httpResponseCode = http.PUT(jsonData);
421 if (httpResponseCode > 0) {
422 String response = http.getString();
423 Serial.println("HTTP PUT Response code: " + String(httpResponseCode));
424 Serial.println("Response: " + response);
425 } else {
426 Serial.println("Error in sending POST: " + String(httpResponseCode));
427 }
428//פונקציאה אשר קוראת מהסייראל
429 xTaskCreatePinnedToCore(
430 getSerialDataTask, // פונקציית המשימה
431 "get FB data", // שם המשימה
432 4096, // גודל מחסנית
433 NULL, // פרמטרים
434 1, // עדיפות
435 NULL, // מזהה משימה
436 1 // ליבה
437 );
438
439
440 }
441}
442
443void getSerialDataTask(void *pvParameters) {
444 while (true) {
445 globalSerialData =readFromSerial2();//שמירת המידע המתקבל במשתנה גלובלי
446 //vTaskDelay(500 / portTICK_PERIOD_MS);
447 delay(200);
448 Serial.println("serialData 2 Received =>"+globalSerialData);//מדפיס את המידע המתקבל במוניטור
449
450
451 }
452}
453
454unsigned long start = millis();
455String prevJsonString = "";
456void loop(){
457 server.handleClient();
458
459 if(WiFi.status() == WL_CONNECTED){
460
461 //Serial.println("serialData 2 Received =>"+serialData);
462
463 // if (serialData.length() >= 13) {
464 String tempJsonString = convertToJsonString(globalSerialData);
465 //Serial.println("tempJsonString =>"+globalSerialData);
466 //Serial.println("tempJsonString =>"+tempJsonString);
467
468 //if( prevJsonString == "" && tempJsonString.length()>1){
469
470 Serial.println("prevJsonString =>"+prevJsonString);
471 Serial.println("tempJsonString =>"+tempJsonString);
472 prevJsonString = tempJsonString;
473 processAndSendSerialData(tempJsonString);
474 //delay(500);
475 // }
476
477 //Serial2.flush();
478 String jsonData = getFirebaseData();
479 Serial.println("Received from FirebaseData = "+jsonData);
480 processJsonAndSendSerial2(jsonData);
481 delay(500);
482
483 }else{
484 setupAccessPoint();
485 }
486}