149 lines
3.4 KiB
C++
149 lines
3.4 KiB
C++
#include <SoftwareSerial.h>
|
||
#define RX_PIN D3 // RX NodeMCU -> TX M66
|
||
#define TX_PIN D4 // TX NodeMCU -> RX M66
|
||
|
||
SoftwareSerial M66(RX_PIN, TX_PIN);
|
||
|
||
const String url = "http://amlakmodaberan.ir/1.html";
|
||
// =========================
|
||
// Timeout ها
|
||
// =========================
|
||
const unsigned long AT_TIMEOUT = 15000;
|
||
const unsigned long HTTP_TIMEOUT = 30000;
|
||
|
||
// =========================
|
||
// ارسال دستور AT با انتظار پاسخ
|
||
// =========================
|
||
bool sendAT(String cmd, String expected = "OK", unsigned long timeout = AT_TIMEOUT) {
|
||
Serial.print("[TX] "); Serial.println(cmd);
|
||
|
||
while (M66.available()) M66.read(); // پاکسازی بافر
|
||
|
||
M66.println(cmd);
|
||
|
||
unsigned long start = millis();
|
||
String response = "";
|
||
|
||
while (millis() - start < timeout) {
|
||
yield();
|
||
while (M66.available()) {
|
||
char c = M66.read();
|
||
response += c;
|
||
Serial.write(c);
|
||
|
||
if (response.indexOf(expected) != -1) return true;
|
||
if (response.indexOf("ERROR") != -1 || response.indexOf("+CME ERROR") != -1) {
|
||
Serial.println("❌ Command failed");
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
Serial.println("⏱ Timeout waiting for response");
|
||
return false;
|
||
}
|
||
|
||
// =========================
|
||
// راهاندازی GPRS و HTTP با QIREGAPP
|
||
// =========================
|
||
bool initGPRS() {
|
||
Serial.println("=== Initializing GPRS ===");
|
||
delay(2000);
|
||
|
||
sendAT("ATE0");
|
||
sendAT("AT+CMEE=2");
|
||
sendAT("AT+CFUN=1");
|
||
delay(2000);
|
||
|
||
if (!sendAT("AT+CPIN?", "READY")) return false;
|
||
|
||
// شبکه ثبت شده
|
||
for (int i = 0; i < 10; i++) {
|
||
if (sendAT("AT+CREG?", "+CREG: 0,1")) break;
|
||
delay(2000);
|
||
}
|
||
|
||
if (!sendAT("AT+CGATT=1")) return false;
|
||
delay(5000);
|
||
|
||
// reset context
|
||
sendAT("AT+QIFGCNT=0");
|
||
|
||
if (!sendAT("AT+QICSGP=1,\"mcinet\",\"\",\"\"")) return false;
|
||
|
||
// فعال کردن QIREGAPP به جای QIACT
|
||
if (!sendAT("AT+QIREGAPP", "OK", 30000)) return false;
|
||
|
||
// بررسی IP state
|
||
sendAT("AT+QISTAT", "STATE: IP GPRSACT");
|
||
|
||
// پیکربندی HTTP
|
||
sendAT("AT+QHTTPCFG=\"contextid\",1");
|
||
sendAT("AT+QHTTPCFG=\"responseheader\",1");
|
||
sendAT("AT+QHTTPCFG=\"timeout\",30000");
|
||
sendAT("AT+QHTTPCFG=\"requestheader\",1");
|
||
|
||
Serial.println("✅ GPRS ready!");
|
||
return true;
|
||
}
|
||
|
||
// =========================
|
||
// ارسال HTTP GET
|
||
// =========================
|
||
bool sendHTTPRequest() {
|
||
Serial.println("=== Sending HTTP Request ===");
|
||
|
||
int len = url.length();
|
||
|
||
if (!sendAT("AT+QHTTPURL=" + String(len) + ",60", "CONNECT", 15000)) {
|
||
Serial.println("❌ URL setup failed");
|
||
return false;
|
||
}
|
||
|
||
M66.print(url);
|
||
delay(200);
|
||
M66.write(0x1A); // Ctrl+Z
|
||
delay(1500);
|
||
|
||
if (!sendAT("AT+QHTTPGET=80", "OK", HTTP_TIMEOUT)) {
|
||
Serial.println("❌ HTTP GET failed");
|
||
return false;
|
||
}
|
||
|
||
if (!sendAT("AT+QHTTPREAD", "+QHTTPREAD:", HTTP_TIMEOUT)) {
|
||
Serial.println("⚠️ No HTTP response body");
|
||
return false;
|
||
}
|
||
|
||
Serial.println("✅ HTTP request done!");
|
||
return true;
|
||
}
|
||
|
||
// =========================
|
||
// setup
|
||
// =========================
|
||
void setup() {
|
||
Serial.begin(115200);
|
||
M66.begin(9600);
|
||
delay(2000);
|
||
|
||
int retry = 0;
|
||
while (retry < 3) {
|
||
if (initGPRS()) {
|
||
if (sendHTTPRequest()) break;
|
||
else Serial.println("⚠️ HTTP failed, retrying...");
|
||
} else {
|
||
Serial.println("❌ GPRS init failed, retrying...");
|
||
}
|
||
retry++;
|
||
delay(5000);
|
||
}
|
||
}
|
||
|
||
// =========================
|
||
// loop
|
||
// =========================
|
||
void loop() {
|
||
yield(); // جلوگیری از WDT
|
||
}
|