Базовый рабочий скетч для управления нагрузкой связкой esp8266 + sim800l

Базовый рабочий скетч для управления нагрузкой связкой esp8266 + sim800l


Скетч для ESP8266 с GSM-модулем SIM800L, предназначенный для удалённого управления устройством с помощью телефонного звонка с авторизованного номера и последующей передачи команды на HTTP-сервер.

При запуске ESP8266 подключается к заданной Wi-Fi-сети, после чего инициализирует SIM800L и выполняет основные проверки GSM-модуля: связь с модулем, включение определения номера входящего звонка (CLIP), настройку расширенных сообщений об ошибках, регистрацию в мобильной сети и проверку уровня сигнала.

В основном цикле контроллер отслеживает сообщения от SIM800L. При поступлении входящего звонка определяется номер вызывающего абонента. Если номер совпадает с заранее заданным разрешённым номером, контроллер принимает вызов, формирует HTTP GET-запрос с идентификатором устройства и отправляет его на сервер.

После выполнения запроса звонок принудительно завершается командой ATH независимо от результата передачи. Таким образом, сам звонок используется как сигнал-команда, а продолжительное соединение с абонентом не требуется.

Основная последовательность работы:

  1. ESP8266 подключается к Wi-Fi.
  2. Инициализируется SIM800L.
  3. SIM800L ожидает входящий звонок.
  4. Получается номер вызывающего абонента.
  5. Номер сравнивается с разрешённым.
  6. При совпадении принимается звонок командой ATA.
  7. На сервер отправляется HTTP-запрос с deviceId.
  8. После обработки запроса звонок завершается командой ATH.
  9. Контроллер возвращается в режим ожидания.

Дополнительно предусмотрена проверка 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;
}
Комментариев пока нет.

Оставить комментарий