Базовый рабочий скетч для управления нагрузкой связкой esp8266 + sim800l
Скетч для ESP8266 с GSM-модулем SIM800L, предназначенный для удалённого управления устройством с помощью телефонного звонка с авторизованного номера и последующей передачи команды на HTTP-сервер.
При запуске ESP8266 подключается к заданной Wi-Fi-сети, после чего инициализирует SIM800L и выполняет основные проверки GSM-модуля: связь с модулем, включение определения номера входящего звонка (CLIP), настройку расширенных сообщений об ошибках, регистрацию в мобильной сети и проверку уровня сигнала.
В основном цикле контроллер отслеживает сообщения от SIM800L. При поступлении входящего звонка определяется номер вызывающего абонента. Если номер совпадает с заранее заданным разрешённым номером, контроллер принимает вызов, формирует HTTP GET-запрос с идентификатором устройства и отправляет его на сервер.
После выполнения запроса звонок принудительно завершается командой ATH независимо от результата передачи. Таким образом, сам звонок используется как сигнал-команда, а продолжительное соединение с абонентом не требуется.
Основная последовательность работы:
- ESP8266 подключается к Wi-Fi.
- Инициализируется SIM800L.
- SIM800L ожидает входящий звонок.
- Получается номер вызывающего абонента.
- Номер сравнивается с разрешённым.
- При совпадении принимается звонок командой
ATA. - На сервер отправляется HTTP-запрос с
deviceId. - После обработки запроса звонок завершается командой
ATH. - Контроллер возвращается в режим ожидания.
Дополнительно предусмотрена проверка Wi-Fi перед отправкой запроса и подробный вывод состояния работы SIM800L и HTTP-соединения в Serial Monitor.
Таким образом, скетч представляет собой GSM/Wi-Fi шлюз для управления устройством по звонку: авторизованный телефонный звонок от пользователя преобразуется ESP8266 в HTTP-команду для серверной системы автоматизации.
#include
#include
#include
#include
// Настройки подключения
SoftwareSerial sim800l(5, 4); // RX=D1(5), TX=D2(4)
const char* ssid = "TP-LINK_3A9E";
const char* password = "********";
const char* serverUrl = "http://192.168.1.207/handler.php";
const char* deviceId = "pap1";
const char* allowedNumber = "+7910978****";
void setup() {
Serial.begin(115200);
sim800l.begin(9600);
Serial.println("\nInitializing system...");
// Подключение WiFi с таймаутом 15 секунд
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
unsigned long wifiStart = millis();
while (WiFi.status() != WL_CONNECTED && millis() - wifiStart < 15000) {
delay(500);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi connected! IP: " + WiFi.localIP().toString());
} else {
Serial.println("\nWiFi connection failed!");
}
// Инициализация SIM800L
initSIM800L();
Serial.println("System ready. Waiting for calls...");
}
void loop() {
static String buffer;
// Чтение данных от SIM800L
while (sim800l.available()) {
char c = sim800l.read();
buffer += c;
if (c == '\n') {
buffer.trim();
processBuffer(buffer);
buffer = "";
}
}
delay(10);
}
void processBuffer(String &response) {
Serial.println("SIM800L: " + response);
if (response == "RING") {
Serial.println("Incoming call detected");
// Ждем информацию о номере
delay(1000); // Увеличена задержка для получения CLIP
}
if (response.startsWith("+CLIP:")) {
int start = response.indexOf("\"") + 1;
int end = response.indexOf("\"", start);
String callerNumber = response.substring(start, end);
Serial.println("Call from: " + callerNumber);
if (callerNumber == allowedNumber) {
Serial.println("Processing authorized call");
// 1. Поднимаем трубку
sim800l.println("ATA");
delay(1000); // Даем время на установку соединения
// 2. Формируем URL
String url = String(serverUrl) + "?id=" + deviceId;
Serial.println("Sending to: " + url);
// 3. Отправляем запрос
if (sendGetRequest(url)) {
Serial.println("GET request successful");
} else {
Serial.println("GET request failed");
}
// 4. Сбрасываем вызов в любом случае
sim800l.println("ATH");
Serial.println("Call ended");
}
}
}
bool sendGetRequest(String url) {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi not connected!");
return false;
}
WiFiClient client;
HTTPClient http;
Serial.println("Starting HTTP request...");
if (http.begin(client, url)) {
int httpCode = http.GET();
if (httpCode > 0) {
Serial.printf("HTTP code: %d\n", httpCode);
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
Serial.println("Response: " + payload);
http.end();
return true;
}
}
Serial.printf("HTTP error: %s\n", http.errorToString(httpCode).c_str());
http.end();
} else {
Serial.println("HTTP connection failed");
}
return false;
}
void initSIM800L() {
Serial.println("Initializing SIM800L...");
// Сброс буфера
while (sim800l.available()) sim800l.read();
// Основные настройки
sendATCommand("AT", "OK", 2000);
sendATCommand("ATE0", "OK", 1000);
sendATCommand("AT+CLIP=1", "OK", 1000); // Включение АОН
sendATCommand("AT+CMEE=1", "OK", 1000); // Подробные ошибки
// Проверка регистрации в сети
if (!sendATCommand("AT+CREG?", "+CREG: 0,1", 2000) &&
!sendATCommand("AT+CREG?", "+CREG: 0,5", 2000)) {
Serial.println("Not registered in network!");
}
// Проверка уровня сигнала
sendATCommand("AT+CSQ", "+CSQ:", 1000);
}
bool sendATCommand(String cmd, String expected, uint16_t timeout) {
Serial.println("AT CMD: " + cmd);
sim800l.println(cmd);
unsigned long start = millis();
String response;
while (millis() - start < timeout) {
while (sim800l.available()) {
char c = sim800l.read();
response += c;
if (response.indexOf(expected) != -1) {
Serial.println("AT RESP: " + response);
return true;
}
}
}
Serial.println("AT timeout");
return false;
}