#include SoftwareSerial esp8266(4, 5); // RX, TX // صفحه پیش‌فرض HTML const char* HTML_PAGE = "

Hello from ESP8266

"; void setup() { Serial.begin(9600); esp8266.begin(9600); delay(2000); // آماده‌سازی ESP // تنظیمات اولیه ESP8266 sendCommand("AT", "OK", 2000); sendCommand("ATE0", "OK", 2000); sendCommand("AT+CWMODE=2", "OK", 2000); sendCommand("AT+CWSAP=\"ESP8266_AP\",\"12345678\",1,0", "OK", 5000); sendCommand("AT+CIPMUX=1", "OK", 3000); sendCommand("AT+CIPSERVER=1,80", "OK", 3000); Serial.println(F("ESP8266 Ready. Connect to SSID: ESP8266_AP, Pass: 12345678")); Serial.println(F("Then open http://192.168.4.1/ in your browser")); } void loop() { if (esp8266.available()) { String line = esp8266.readStringUntil('\n'); line.trim(); if (line.length() == 0) return; Serial.println("[ESP8266] " + line); if (line.startsWith("+IPD,")) { int len = 0; int linkId = parseIPDLine(line, len); if (linkId < 0) { Serial.println("Failed to parse IPD line."); return; } drainPayload(len); // فراخوانی تابع پردازش و ارسال پاسخ processAndSend(linkId, line); } } } // =================== توابع کمکی =================== // تابع پردازش داده و ارسال پاسخ به کلاینت void processAndSend(int linkId, const String &requestLine) { String html; // بررسی پارامتر صفحه در URL if (requestLine.indexOf("GET /?page=") != -1) { int start = requestLine.indexOf("GET /?page=") + 10; int end = requestLine.indexOf(" ", start); int pageNum = requestLine.substring(start, end).toInt(); switch (pageNum) { case 1: html = "

صفحه ۱

"; break; case 2: html = "

صفحه ۲

"; break; case 3: html = "

صفحه ۳

"; break; default: html = "

صفحه پیش‌فرض

"; break; } } else { html = HTML_PAGE; // صفحه پیش‌فرض } // ساخت پاسخ HTTP String response = "HTTP/1.1 200 OK\r\n"; response += "Content-Type: text/html\r\n"; response += "Content-Length: " + String(html.length()) + "\r\n"; response += "Connection: close\r\n\r\n"; response += html; // ارسال پاسخ String cmd = "AT+CIPSEND=" + String(linkId) + "," + String(response.length()); if (sendCommand(cmd, ">", 5000)) { esp8266.print(response); if (waitFor("SEND OK", 5000)) { Serial.println("Response sent to client."); } else { Serial.println("SEND OK not received (timeout)."); } } else { Serial.println("CIPSEND prompt not received (timeout)."); } // بستن کانکشن String closeCmd = "AT+CIPCLOSE=" + String(linkId); sendCommand(closeCmd, "OK", 2000); } // استخراج linkId و len از خط +IPD int parseIPDLine(const String& line, int &lenOut) { int ipdPos = line.indexOf("+IPD,"); if (ipdPos == -1) return -1; int firstComma = line.indexOf(',', ipdPos + 4); int secondComma = line.indexOf(',', firstComma + 1); if (firstComma == -1 || secondComma == -1) return -1; int colon = line.indexOf(':', secondComma + 1); if (colon == -1) { lenOut = line.substring(secondComma + 1).toInt(); return line.substring(ipdPos + 4, firstComma).toInt(); } else { lenOut = line.substring(firstComma + 1, secondComma).toInt(); return line.substring(ipdPos + 4, firstComma).toInt(); } } // پاک‌سازی payload بعد از +IPD void drainPayload(int len) { unsigned long t0 = millis(); int remaining = len; while (millis() - t0 < 1000 && remaining > 0) { if (esp8266.available()) { esp8266.read(); remaining--; } } } // ارسال فرمان AT و انتظار ACK bool sendCommand(const String& cmd, const char* ack, unsigned long timeout) { esp8266.println(cmd); return waitFor(ack, timeout); } // منتظر بودن برای وجود یک ACK/کلمه کلیدی تا مهلت معین bool waitFor(const char* target, unsigned long timeout) { unsigned long start = millis(); String buffer = ""; while (millis() - start < timeout) { while (esp8266.available()) { char c = esp8266.read(); buffer += c; if (buffer.indexOf(target) != -1) return true; } } Serial.print("Timeout waiting for: "); Serial.println(target); return false; }