Last active
December 17, 2024 17:30
-
-
Save khusamov/4c0b945a9f5156c8539276ee29d1205f to your computer and use it in GitHub Desktop.
GSM-модуль SIM800L: самый полный мануал (на примерах с Arduino Uno) https://bit.ly/2PEIB3H
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SoftwareSerial.h> | |
SoftwareSerial SIM800(8, 9); // 8 - RX Arduino (TX SIM800L), 9 - TX Arduino (RX SIM800L) | |
void setup() { | |
Serial.begin(9600); // Скорость обмена данными с компьютером | |
Serial.println("Start!"); | |
SIM800.begin(9600); // Скорость обмена данными с модемом | |
SIM800.println("AT"); | |
} | |
void loop() { | |
if (SIM800.available()) // Ожидаем прихода данных (ответа) от модема... | |
Serial.write(SIM800.read()); // ...и выводим их в Serial | |
if (Serial.available()) // Ожидаем команды по Serial... | |
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SoftwareSerial.h> // Библиотека програмной реализации обмена по UART-протоколу | |
SoftwareSerial SIM800(8, 9); // RX, TX | |
String _response = ""; // Переменная для хранения ответа модуля | |
void setup() { | |
Serial.begin(9600); // Скорость обмена данными с компьютером | |
SIM800.begin(9600); // Скорость обмена данными с модемом | |
Serial.println("Start!"); | |
sendATCommand("AT", true); // Автонастройка скорости | |
// sendATCommand("AT+CLVL?", true); // Запрашиваем громкость динамика | |
// sendATCommand("AT+CMGF=1", true); // Включить TextMode для SMS | |
// sendATCommand("AT+DDET=1,0,0", true); // Включить DTMF | |
} | |
String sendATCommand(String cmd, bool waiting) { | |
String _resp = ""; // Переменная для хранения результата | |
Serial.println(cmd); // Дублируем команду в монитор порта | |
SIM800.println(cmd); // Отправляем команду модулю | |
if (waiting) { // Если необходимо дождаться ответа... | |
_resp = waitResponse(); // ... ждем, когда будет передан ответ | |
// Если Echo Mode выключен (ATE0), то эти 3 строки можно закомментировать | |
if (_resp.startsWith(cmd)) { // Убираем из ответа дублирующуюся команду | |
_resp = _resp.substring(_resp.indexOf("\r", cmd.length()) + 2); | |
} | |
Serial.println(_resp); // Дублируем ответ в монитор порта | |
} | |
return _resp; // Возвращаем результат. Пусто, если проблема | |
} | |
String waitResponse() { // Функция ожидания ответа и возврата полученного результата | |
String _resp = ""; // Переменная для хранения результата | |
long _timeout = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд) | |
while (!SIM800.available() && millis() < _timeout) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то... | |
if (SIM800.available()) { // Если есть, что считывать... | |
_resp = SIM800.readString(); // ... считываем и запоминаем | |
} | |
else { // Если пришел таймаут, то... | |
Serial.println("Timeout..."); // ... оповещаем об этом и... | |
} | |
return _resp; // ... возвращаем результат. Пусто, если проблема | |
} | |
void loop() { | |
if (SIM800.available()) { // Если модем, что-то отправил... | |
_response = waitResponse(); // Получаем ответ от модема для анализа | |
Serial.println(_response); // Если нужно выводим в монитор порта | |
// ... здесь можно анализировать данные полученные от GSM-модуля | |
} | |
if (Serial.available()) { // Ожидаем команды по Serial... | |
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SoftwareSerial.h> // Библиотека програмной реализации обмена по UART-протоколу | |
SoftwareSerial SIM800(8, 9); // RX, TX | |
String _response = ""; // Переменная для хранения ответа модуля | |
void setup() { | |
Serial.begin(9600); // Скорость обмена данными с компьютером | |
SIM800.begin(9600); // Скорость обмена данными с модемом | |
Serial.println("Start!"); | |
sendATCommand("AT", true); // Отправили AT для настройки скорости обмена данными | |
// Команды настройки модема при каждом запуске | |
//_response = sendATCommand("AT+CLIP=1", true); // Включаем АОН | |
//_response = sendATCommand("AT+DDET=1", true); // Включаем DTMF | |
} | |
String sendATCommand(String cmd, bool waiting) { | |
String _resp = ""; // Переменная для хранения результата | |
Serial.println(cmd); // Дублируем команду в монитор порта | |
SIM800.println(cmd); // Отправляем команду модулю | |
if (waiting) { // Если необходимо дождаться ответа... | |
_resp = waitResponse(); // ... ждем, когда будет передан ответ | |
// Если Echo Mode выключен (ATE0), то эти 3 строки можно закомментировать | |
if (_resp.startsWith(cmd)) { // Убираем из ответа дублирующуюся команду | |
_resp = _resp.substring(_resp.indexOf("\r", cmd.length()) + 2); | |
} | |
Serial.println(_resp); // Дублируем ответ в монитор порта | |
} | |
return _resp; // Возвращаем результат. Пусто, если проблема | |
} | |
String waitResponse() { // Функция ожидания ответа и возврата полученного результата | |
String _resp = ""; // Переменная для хранения результата | |
long _timeout = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд) | |
while (!SIM800.available() && millis() < _timeout) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то... | |
if (SIM800.available()) { // Если есть, что считывать... | |
_resp = SIM800.readString(); // ... считываем и запоминаем | |
} | |
else { // Если пришел таймаут, то... | |
Serial.println("Timeout..."); // ... оповещаем об этом и... | |
} | |
return _resp; // ... возвращаем результат. Пусто, если проблема | |
} | |
void loop() { | |
if (SIM800.available()) { // Если модем, что-то отправил... | |
_response = waitResponse(); // Получаем ответ от модема для анализа | |
_response.trim(); // Убираем лишние пробелы в начале и конце | |
Serial.println(_response); // Если нужно выводим в монитор порта | |
if (_response.startsWith("RING")) { // Есть входящий вызов | |
sendATCommand("ATA", true); // Отвечаем на вызов | |
// или | |
sendATCommand("ATH", true); // Отклоняем вызов | |
} | |
} | |
if (Serial.available()) { // Ожидаем команды по Serial... | |
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SoftwareSerial.h> // Библиотека програмной реализации обмена по UART-протоколу | |
SoftwareSerial SIM800(8, 9); // RX, TX | |
String _response = ""; // Переменная для хранения ответа модуля | |
void setup() { | |
Serial.begin(9600); // Скорость обмена данными с компьютером | |
SIM800.begin(9600); // Скорость обмена данными с модемом | |
Serial.println("Start!"); | |
sendATCommand("AT", true); // Отправили AT для настройки скорости обмена данными | |
// Команды настройки модема при каждом запуске | |
_response = sendATCommand("AT+CLIP=1", true); // Включаем АОН | |
//_response = sendATCommand("AT+DDET=1", true); // Включаем DTMF | |
} | |
String sendATCommand(String cmd, bool waiting) { | |
String _resp = ""; // Переменная для хранения результата | |
Serial.println(cmd); // Дублируем команду в монитор порта | |
SIM800.println(cmd); // Отправляем команду модулю | |
if (waiting) { // Если необходимо дождаться ответа... | |
_resp = waitResponse(); // ... ждем, когда будет передан ответ | |
// Если Echo Mode выключен (ATE0), то эти 3 строки можно закомментировать | |
if (_resp.startsWith(cmd)) { // Убираем из ответа дублирующуюся команду | |
_resp = _resp.substring(_resp.indexOf("\r", cmd.length()) + 2); | |
} | |
Serial.println(_resp); // Дублируем ответ в монитор порта | |
} | |
return _resp; // Возвращаем результат. Пусто, если проблема | |
} | |
String waitResponse() { // Функция ожидания ответа и возврата полученного результата | |
String _resp = ""; // Переменная для хранения результата | |
long _timeout = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд) | |
while (!SIM800.available() && millis() < _timeout) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то... | |
if (SIM800.available()) { // Если есть, что считывать... | |
_resp = SIM800.readString(); // ... считываем и запоминаем | |
} | |
else { // Если пришел таймаут, то... | |
Serial.println("Timeout..."); // ... оповещаем об этом и... | |
} | |
return _resp; // ... возвращаем результат. Пусто, если проблема | |
} | |
void loop() { | |
if (SIM800.available()) { // Если модем, что-то отправил... | |
_response = waitResponse(); // Получаем ответ от модема для анализа | |
_response.trim(); // Убираем лишние пробелы в начале и конце | |
Serial.println(_response); // Если нужно выводим в монитор порта | |
String whiteListPhones = "+7928xxxxxxx, +7928xxxxxxx, +7928xxxxxxx"; // Белый список телефонов | |
if (_response.startsWith("RING")) { // Есть входящий вызов | |
int phoneindex = _response.indexOf("+CLIP: \"");// Есть ли информация об определении номера, если да, то phoneindex>-1 | |
String innerPhone = ""; // Переменная для хранения определенного номера | |
if (phoneindex >= 0) { // Если информация была найдена | |
phoneindex += 8; // Парсим строку и ... | |
innerPhone = _response.substring(phoneindex, _response.indexOf("\"", phoneindex)); // ...получаем номер | |
Serial.println("Number: " + innerPhone); // Выводим номер в монитор порта | |
} | |
// Проверяем, чтобы длина номера была больше 6 цифр, и номер должен быть в списке | |
if (innerPhone.length() >= 7 && whiteListPhones.indexOf(innerPhone) >= 0) { | |
sendATCommand("ATA", true); // Если да, то отвечаем на вызов | |
} | |
else { | |
sendATCommand("ATH", true); // Если нет, то отклоняем вызов | |
} | |
} | |
} | |
if (Serial.available()) { // Ожидаем команды по Serial... | |
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SoftwareSerial.h> // Библиотека програмной реализации обмена по UART-протоколу | |
SoftwareSerial SIM800(8, 9); // RX, TX | |
String _response = ""; // Переменная для хранения ответа модуля | |
void setup() { | |
Serial.begin(9600); // Скорость обмена данными с компьютером | |
SIM800.begin(9600); // Скорость обмена данными с модемом | |
Serial.println("Start!"); | |
sendATCommand("AT", true); // Отправили AT для настройки скорости обмена данными | |
// Команды настройки модема при каждом запуске | |
//_response = sendATCommand("AT+CLIP=1", true); // Включаем АОН | |
//_response = sendATCommand("AT+DDET=1", true); // Включаем DTMF | |
_response = sendATCommand("AT+CMGF=1;&W", true); // Включаем текстовый режима SMS (Text mode) и сразу сохраняем значение (AT&W)! | |
sendSMS("+7928xxxxxxx", "test message"); | |
} | |
String sendATCommand(String cmd, bool waiting) { | |
String _resp = ""; // Переменная для хранения результата | |
Serial.println(cmd); // Дублируем команду в монитор порта | |
SIM800.println(cmd); // Отправляем команду модулю | |
if (waiting) { // Если необходимо дождаться ответа... | |
_resp = waitResponse(); // ... ждем, когда будет передан ответ | |
// Если Echo Mode выключен (ATE0), то эти 3 строки можно закомментировать | |
if (_resp.startsWith(cmd)) { // Убираем из ответа дублирующуюся команду | |
_resp = _resp.substring(_resp.indexOf("\r", cmd.length()) + 2); | |
} | |
Serial.println(_resp); // Дублируем ответ в монитор порта | |
} | |
return _resp; // Возвращаем результат. Пусто, если проблема | |
} | |
String waitResponse() { // Функция ожидания ответа и возврата полученного результата | |
String _resp = ""; // Переменная для хранения результата | |
long _timeout = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд) | |
while (!SIM800.available() && millis() < _timeout) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то... | |
if (SIM800.available()) { // Если есть, что считывать... | |
_resp = SIM800.readString(); // ... считываем и запоминаем | |
} | |
else { // Если пришел таймаут, то... | |
Serial.println("Timeout..."); // ... оповещаем об этом и... | |
} | |
return _resp; // ... возвращаем результат. Пусто, если проблема | |
} | |
void loop() { | |
if (SIM800.available()) { // Если модем, что-то отправил... | |
_response = waitResponse(); // Получаем ответ от модема для анализа | |
_response.trim(); // Убираем лишние пробелы в начале и конце | |
Serial.println(_response); // Если нужно выводим в монитор порта | |
//.... | |
if (_response.startsWith("+CMGS:")) { // Пришло сообщение об отправке SMS | |
int index = _response.lastIndexOf("\r\n");// Находим последний перенос строки, перед статусом | |
String result = _response.substring(index + 2, _response.length()); // Получаем статус | |
result.trim(); // Убираем пробельные символы в начале/конце | |
if (result == "OK") { // Если результат ОК - все нормально | |
Serial.println ("Message was sent. OK"); | |
} | |
else { // Если нет, нужно повторить отправку | |
Serial.println ("Message was not sent. Error"); | |
} | |
} | |
} | |
if (Serial.available()) { // Ожидаем команды по Serial... | |
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему | |
}; | |
} | |
void sendSMS(String phone, String message) | |
{ | |
sendATCommand("AT+CMGS=\"" + phone + "\"", true); // Переходим в режим ввода текстового сообщения | |
sendATCommand(message + "\r\n" + (String)((char)26), true); // После текста отправляем перенос строки и Ctrl+Z | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SoftwareSerial.h> // Библиотека програмной реализации обмена по UART-протоколу | |
SoftwareSerial SIM800(8, 9); // RX, TX | |
String _response = ""; // Переменная для хранения ответа модуля | |
void setup() { | |
Serial.begin(9600); // Скорость обмена данными с компьютером | |
SIM800.begin(9600); // Скорость обмена данными с модемом | |
Serial.println("Start!"); | |
sendATCommand("AT", true); // Отправили AT для настройки скорости обмена данными | |
// Команды настройки модема при каждом запуске | |
//_response = sendATCommand("AT+CLIP=1", true); // Включаем АОН | |
//_response = sendATCommand("AT+DDET=1", true); // Включаем DTMF | |
_response = sendATCommand("AT+CMGF=1;&W", true); // Включаем текстовый режима SMS (Text mode) и сразу сохраняем значение (AT&W)! | |
} | |
String sendATCommand(String cmd, bool waiting) { | |
String _resp = ""; // Переменная для хранения результата | |
Serial.println(cmd); // Дублируем команду в монитор порта | |
SIM800.println(cmd); // Отправляем команду модулю | |
if (waiting) { // Если необходимо дождаться ответа... | |
_resp = waitResponse(); // ... ждем, когда будет передан ответ | |
// Если Echo Mode выключен (ATE0), то эти 3 строки можно закомментировать | |
if (_resp.startsWith(cmd)) { // Убираем из ответа дублирующуюся команду | |
_resp = _resp.substring(_resp.indexOf("\r", cmd.length()) + 2); | |
} | |
Serial.println(_resp); // Дублируем ответ в монитор порта | |
} | |
return _resp; // Возвращаем результат. Пусто, если проблема | |
} | |
String waitResponse() { // Функция ожидания ответа и возврата полученного результата | |
String _resp = ""; // Переменная для хранения результата | |
long _timeout = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд) | |
while (!SIM800.available() && millis() < _timeout) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то... | |
if (SIM800.available()) { // Если есть, что считывать... | |
_resp = SIM800.readString(); // ... считываем и запоминаем | |
} | |
else { // Если пришел таймаут, то... | |
Serial.println("Timeout..."); // ... оповещаем об этом и... | |
} | |
return _resp; // ... возвращаем результат. Пусто, если проблема | |
} | |
void loop() { | |
if (SIM800.available()) { // Если модем, что-то отправил... | |
_response = waitResponse(); // Получаем ответ от модема для анализа | |
_response.trim(); // Убираем лишние пробелы в начале и конце | |
Serial.println(_response); // Если нужно выводим в монитор порта | |
//.... | |
if (_response.startsWith("+CMTI:")) { // Пришло сообщение об отправке SMS | |
int index = _response.lastIndexOf(","); // Находим последнюю запятую, перед индексом | |
String result = _response.substring(index + 1, _response.length()); // Получаем индекс | |
result.trim(); // Убираем пробельные символы в начале/конце | |
_response=sendATCommand("AT+CMGR="+result, true); // Получить содержимое SMS | |
parseSMS(_response); // Распарсить SMS на элементы | |
sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удалить все сообщения, чтобы не забивали память модуля | |
} | |
} | |
if (Serial.available()) { // Ожидаем команды по Serial... | |
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему | |
}; | |
} | |
void parseSMS(String msg) { | |
String msgheader = ""; | |
String msgbody = ""; | |
String msgphone = ""; | |
msg = msg.substring(msg.indexOf("+CMGR: ")); | |
msgheader = msg.substring(0, msg.indexOf("\r")); | |
msgbody = msg.substring(msgheader.length() + 2); | |
msgbody = msgbody.substring(0, msgbody.lastIndexOf("OK")); | |
msgbody.trim(); | |
int firstIndex = msgheader.indexOf("\",\"") + 3; | |
int secondIndex = msgheader.indexOf("\",\"", firstIndex); | |
msgphone = msgheader.substring(firstIndex, secondIndex); | |
Serial.println("Phone: "+msgphone); | |
Serial.println("Message: "+msgbody); | |
// Далее пишем логику обработки SMS-команд. | |
// Здесь также можно реализовывать проверку по номеру телефона | |
// И если номер некорректный, то просто удалить сообщение. | |
} | |
void sendSMS(String phone, String message) | |
{ | |
sendATCommand("AT+CMGS=\"" + phone + "\"", true); // Переходим в режим ввода текстового сообщения | |
sendATCommand(message + "\r\n" + (String)((char)26), true); // После текста отправляем перенос строки и Ctrl+Z | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SoftwareSerial.h> // Библиотека програмной реализации обмена по UART-протоколу | |
SoftwareSerial SIM800(8, 9); // RX, TX | |
int pins[3] = {5, 6, 7}; // Пины с подключенными светодиодами | |
String _response = ""; // Переменная для хранения ответа модуля | |
long lastUpdate = millis(); // Время последнего обновления | |
long updatePeriod = 60000; // Проверять каждую минуту | |
String phones = "+7928xxxxxxx, +7920xxxxxxx, +7918xxxxxxx"; // Белый список телефонов | |
void setup() { | |
for (int i = 0; i < 3; i++) { | |
pinMode(pins[i], OUTPUT); // Настраиваем пины в OUTPUT | |
} | |
Serial.begin(9600); // Скорость обмена данными с компьютером | |
SIM800.begin(9600); // Скорость обмена данными с модемом | |
Serial.println("Start!"); | |
sendATCommand("AT", true); // Отправили AT для настройки скорости обмена данными | |
//sendATCommand("AT+CMGDA=\"DEL ALL\"", true); // Удаляем все SMS, чтобы не забивать память | |
// Команды настройки модема при каждом запуске | |
//_response = sendATCommand("AT+CLIP=1", true); // Включаем АОН | |
//_response = sendATCommand("AT+DDET=1", true); // Включаем DTMF | |
sendATCommand("AT+CMGF=1;&W", true); // Включаем текстовый режима SMS (Text mode) и сразу сохраняем значение (AT&W)! | |
lastUpdate = millis(); // Обнуляем таймер | |
} | |
String sendATCommand(String cmd, bool waiting) { | |
String _resp = ""; // Переменная для хранения результата | |
Serial.println(cmd); // Дублируем команду в монитор порта | |
SIM800.println(cmd); // Отправляем команду модулю | |
if (waiting) { // Если необходимо дождаться ответа... | |
_resp = waitResponse(); // ... ждем, когда будет передан ответ | |
// Если Echo Mode выключен (ATE0), то эти 3 строки можно закомментировать | |
if (_resp.startsWith(cmd)) { // Убираем из ответа дублирующуюся команду | |
_resp = _resp.substring(_resp.indexOf("\r", cmd.length()) + 2); | |
} | |
Serial.println(_resp); // Дублируем ответ в монитор порта | |
} | |
return _resp; // Возвращаем результат. Пусто, если проблема | |
} | |
String waitResponse() { // Функция ожидания ответа и возврата полученного результата | |
String _resp = ""; // Переменная для хранения результата | |
long _timeout = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд) | |
while (!SIM800.available() && millis() < _timeout) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то... | |
if (SIM800.available()) { // Если есть, что считывать... | |
_resp = SIM800.readString(); // ... считываем и запоминаем | |
} | |
else { // Если пришел таймаут, то... | |
Serial.println("Timeout..."); // ... оповещаем об этом и... | |
} | |
return _resp; // ... возвращаем результат. Пусто, если проблема | |
} | |
bool hasmsg = false; // Флаг наличия сообщений к удалению | |
void loop() { | |
if (lastUpdate + updatePeriod < millis() ) { // Пора проверить наличие новых сообщений | |
do { | |
_response = sendATCommand("AT+CMGL=\"REC UNREAD\",1", true);// Отправляем запрос чтения непрочитанных сообщений | |
if (_response.indexOf("+CMGL: ") > -1) { // Если есть хоть одно, получаем его индекс | |
int msgIndex = _response.substring(_response.indexOf("+CMGL: ") + 7, _response.indexOf("\"REC UNREAD\"", _response.indexOf("+CMGL: ")) - 1).toInt(); | |
char i = 0; // Объявляем счетчик попыток | |
do { | |
i++; // Увеличиваем счетчик | |
_response = sendATCommand("AT+CMGR=" + (String)msgIndex + ",1", true); // Пробуем получить текст SMS по индексу | |
_response.trim(); // Убираем пробелы в начале/конце | |
if (_response.endsWith("OK")) { // Если ответ заканчивается на "ОК" | |
if (!hasmsg) hasmsg = true; // Ставим флаг наличия сообщений для удаления | |
sendATCommand("AT+CMGR=" + (String)msgIndex, true); // Делаем сообщение прочитанным | |
sendATCommand("\n", true); // Перестраховка - вывод новой строки | |
parseSMS(_response); // Отправляем текст сообщения на обработку | |
break; // Выход из do{} | |
} | |
else { // Если сообщение не заканчивается на OK | |
Serial.println ("Error answer"); // Какая-то ошибка | |
sendATCommand("\n", true); // Отправляем новую строку и повторяем попытку | |
} | |
} while (i < 10); | |
break; | |
} | |
else { | |
lastUpdate = millis(); // Обнуляем таймер | |
if (hasmsg) { | |
sendATCommand("AT+CMGDA=\"DEL READ\"", true); // Удаляем все прочитанные сообщения | |
hasmsg = false; | |
} | |
break; | |
} | |
} while (1); | |
} | |
if (SIM800.available()) { // Если модем, что-то отправил... | |
_response = waitResponse(); // Получаем ответ от модема для анализа | |
_response.trim(); // Убираем лишние пробелы в начале и конце | |
Serial.println(_response); // Если нужно выводим в монитор порта | |
if (_response.indexOf("+CMTI:")>-1) { // Пришло сообщение об отправке SMS | |
lastUpdate = millis() - updatePeriod; // Теперь нет необходимости обрабатываеть SMS здесь, достаточно просто | |
// сбросить счетчик автопроверки и в следующем цикле все будет обработано | |
} | |
} | |
if (Serial.available()) { // Ожидаем команды по Serial... | |
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему | |
}; | |
} | |
void parseSMS(String msg) { // Парсим SMS | |
String msgheader = ""; | |
String msgbody = ""; | |
String msgphone = ""; | |
msg = msg.substring(msg.indexOf("+CMGR: ")); | |
msgheader = msg.substring(0, msg.indexOf("\r")); // Выдергиваем телефон | |
msgbody = msg.substring(msgheader.length() + 2); | |
msgbody = msgbody.substring(0, msgbody.lastIndexOf("OK")); // Выдергиваем текст SMS | |
msgbody.trim(); | |
int firstIndex = msgheader.indexOf("\",\"") + 3; | |
int secondIndex = msgheader.indexOf("\",\"", firstIndex); | |
msgphone = msgheader.substring(firstIndex, secondIndex); | |
Serial.println("Phone: " + msgphone); // Выводим номер телефона | |
Serial.println("Message: " + msgbody); // Выводим текст SMS | |
if (msgphone.length() > 6 && phones.indexOf(msgphone) > -1) { // Если телефон в белом списке, то... | |
setLedState(msgbody, msgphone); // ...выполняем команду | |
} | |
else { | |
Serial.println("Unknown phonenumber"); | |
} | |
} | |
void setLedState (String result, String phone) { | |
bool correct = false; // Для оптимизации кода, переменная корректности команды | |
String msgToSend = ""; | |
if (result.length() == 2) { | |
int ledIndex = ((String)result[0]).toInt(); // Получаем первую цифру команды - адрес устройства (1-3) | |
int ledState = ((String)result[1]).toInt(); // Получаем вторую цифру команды - состояние (0 - выкл, 1 - вкл) | |
if (ledIndex >= 1 && ledIndex <= 3 && (ledState == 0 or ledState == 1)) { // Если все нормально, исполняем команду | |
msgToSend = "LED:" + (String)ledIndex + " set to " + (ledState == 0 ? "OFF" : "ON"); // Статус исполнения | |
digitalWrite(pins[ledIndex - 1], ledState); // Исполняем команду | |
correct = true; // Флаг корректности команды | |
} | |
} | |
if (!correct) { | |
msgToSend = "Incorrect command: " + result; // Статус исполнения | |
} | |
Serial.println(msgToSend); // Выводим результат в терминал | |
} | |
void sendSMS(String phone, String message) | |
{ | |
sendATCommand("AT+CMGS=\"" + phone + "\"", true); // Переходим в режим ввода текстового сообщения | |
sendATCommand(message + "\r\n" + (String)((char)26), true); // После текста отправляем перенос строки и Ctrl+Z | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SoftwareSerial.h> | |
SoftwareSerial SIM800(8, 9); // 8 - RX Arduino (TX SIM800L), 9 - TX Arduino (RX SIM800L) | |
void setup() { | |
Serial.begin(9600); // Скорость обмена данными с компьютером | |
Serial.println("Start!"); | |
SIM800.begin(9600); // Скорость обмена данными с модемом | |
SIM800.println("AT"); | |
} | |
long lastcmd = millis(); | |
void loop() { | |
if (SIM800.available()) // Ожидаем прихода данных (ответа) от модема... | |
Serial.write(SIM800.read()); // ...и выводим их в Serial | |
if (Serial.available()) // Ожидаем команды по Serial... | |
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему | |
if (millis() - lastcmd > 5000) { // Прошло ли 5 секунд | |
lastcmd = millis(); // Фиксируем время | |
SIM800.println("AT+CSQ"); // Запрашиваем информацию о качестве сигнала | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SoftwareSerial.h> | |
SoftwareSerial SIM800(8, 9); // 8 - RX Arduino (TX SIM800L), 9 - TX Arduino (RX SIM800L) | |
void setup() { | |
Serial.begin(9600); // Скорость обмена данными с компьютером | |
Serial.println("Start!"); | |
SIM800.begin(9600); // Скорость обмена данными с модемом | |
SIM800.println("AT"); // Автонастройка скорости | |
SIM800.println("AT+CLVL?"); // Запрашиваем громкость динамика | |
SIM800.println("AT+CMGF=1"); // Включить TextMode для SMS | |
SIM800.println("AT+DDET=1,0,1"); // Включить DTMF | |
SIM800.println("AT+CLIP=1"); // Включить АОН | |
} | |
void loop() { | |
if (SIM800.available()) // Ожидаем прихода данных (ответа) от модема... | |
Serial.write(SIM800.read()); // ...и выводим их в Serial | |
if (Serial.available()) // Ожидаем команды по Serial... | |
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SoftwareSerial.h> | |
SoftwareSerial SIM800(8, 9); // 8 - RX Arduino (TX SIM800L), 9 - TX Arduino (RX SIM800L) | |
void setup() { | |
Serial.begin(9600); // Скорость обмена данными с компьютером | |
Serial.println("Start!"); | |
SIM800.begin(9600); // Скорость обмена данными с модемом | |
SIM800.println("AT"); // Автонастройка скорости | |
SIM800.println("AT+CLVL?"); // Запрашиваем громкость динамика | |
SIM800.println("AT+CMGF=1"); // Включить TextMode для SMS | |
SIM800.println("AT+DDET=1,0,3"); // Включить DTMF - в этой строке умышленно допущена ошибка - недопустимый параметр | |
SIM800.println("AT+CLIP=1"); // Включить АОН | |
} | |
void loop() { | |
if (SIM800.available()) // Ожидаем прихода данных (ответа) от модема... | |
Serial.write(SIM800.read()); // ...и выводим их в Serial | |
if (Serial.available()) // Ожидаем команды по Serial... | |
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SoftwareSerial.h> | |
SoftwareSerial SIM800(8, 9); // 8 - RX Arduino (TX SIM800L), 9 - TX Arduino (RX SIM800L) | |
void setup() { | |
Serial.begin(9600); // Скорость обмена данными с компьютером | |
Serial.println("Start!"); | |
SIM800.begin(9600); // Скорость обмена данными с модемом | |
SIM800.println("AT"); // Автонастройка скорости | |
delay(500); | |
SIM800.println("AT+CLVL?"); // Запрашиваем громкость динамика | |
delay(500); | |
SIM800.println("AT+CMGF=1"); // Включить TextMode для SMS | |
delay(500); | |
SIM800.println("AT+DDET=1,0,3"); // Включить DTMF - в этой строке умышленно допущена ошибка - недопустимый параметр | |
delay(500); | |
SIM800.println("AT+CLIP=1"); // Включить АОН | |
delay(500); | |
} | |
void loop() { | |
if (SIM800.available()) // Ожидаем прихода данных (ответа) от модема... | |
Serial.write(SIM800.read()); // ...и выводим их в Serial | |
if (Serial.available()) // Ожидаем команды по Serial... | |
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void sendSMS(String phone, String message) // Некорректный пример | |
{ | |
SIM800.print("AT+CMGF=1\r"); // Устанавливаем текстовый (не PDU) формат сообщений | |
delay(100); // Даем модулю отработать команду | |
SIM800.println("AT+CMGS=\"" + phone + "\""); // Задаем номер телефона адресата | |
delay(100); | |
SIM800.println(message); // Вводим сообщение | |
delay(100); | |
SIM800.println((char)26); // Уведомляем GSM-модуль об окончании ввода | |
delay(100); | |
SIM800.println(); | |
delay(4000); // Ожидаем отправки | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
String sendATCommand(String cmd, bool waiting) { | |
String _resp = ""; // Переменная для хранения результата | |
Serial.println(cmd); // Дублируем команду в монитор порта | |
SIM800.println(cmd); // Отправляем команду модулю | |
if (waiting) { // Если необходимо дождаться ответа... | |
_resp = waitResponse(); // ... ждем, когда будет передан ответ | |
// Если Echo Mode выключен (ATE0), то эти 3 строки можно закомментировать | |
if (_resp.startsWith(cmd)) { // Убираем из ответа дублирующуюся команду | |
_resp = _resp.substring(_resp.indexOf("\r", cmd.length()) + 2); | |
} | |
Serial.println(_resp); // Дублируем ответ в монитор порта | |
} | |
return _resp; // Возвращаем результат. Пусто, если проблема | |
} | |
String waitResponse() { // Функция ожидания ответа и возврата полученного результата | |
String _resp = ""; // Переменная для хранения результата | |
long _timeout = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд) | |
while (!SIM800.available() && millis() < _timeout) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то... | |
if (SIM800.available()) { // Если есть, что считывать... | |
_resp = SIM800.readString(); // ... считываем и запоминаем | |
} | |
else { // Если пришел таймаут, то... | |
Serial.println("Timeout..."); // ... оповещаем об этом и... | |
} | |
return _resp; // ... возвращаем результат. Пусто, если проблема | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SoftwareSerial.h> // Библиотека програмной реализации обмена по UART-протоколу | |
SoftwareSerial SIM800(8, 9); // RX, TX | |
String _response = ""; // Переменная для хранения ответа модуля | |
void setup() { | |
Serial.begin(9600); // Скорость обмена данными с компьютером | |
SIM800.begin(9600); // Скорость обмена данными с модемом | |
Serial.println("Start!"); | |
sendATCommand("AT", true); // Автонастройка скорости | |
sendATCommand("AT+CLVL?", true); // Запрашиваем громкость динамика | |
sendATCommand("AT+CMGF=1", true); // Включить TextMode для SMS | |
sendATCommand("AT+DDET=1,0,3", true); // Включить DTMF - в этой строке умышленно допущена ошибка - недопустимый параметр | |
do { | |
_response = sendATCommand("AT+CLIP=1", true); // Включаем АОН | |
_response.trim(); // Убираем пробельные символы в начале и конце | |
} while (_response != "OK"); // Не пускать дальше, пока модем не вернет ОК | |
Serial.println("CLI enabled"); // Информируем, что АОН включен | |
// Проверка пройдена, модем сообщил о готовности, можно запускать основной цикл... | |
// ... | |
} | |
String sendATCommand(String cmd, bool waiting) { | |
String _resp = ""; // Переменная для хранения результата | |
Serial.println(cmd); // Дублируем команду в монитор порта | |
SIM800.println(cmd); // Отправляем команду модулю | |
if (waiting) { // Если необходимо дождаться ответа... | |
_resp = waitResponse(); // ... ждем, когда будет передан ответ | |
// Если Echo Mode выключен (ATE0), то эти 3 строки можно закомментировать | |
if (_resp.startsWith(cmd)) { // Убираем из ответа дублирующуюся команду | |
_resp = _resp.substring(_resp.indexOf("\r", cmd.length()) + 2); | |
} | |
Serial.println(_resp); // Дублируем ответ в монитор порта | |
} | |
return _resp; // Возвращаем результат. Пусто, если проблема | |
} | |
String waitResponse() { // Функция ожидания ответа и возврата полученного результата | |
String _resp = ""; // Переменная для хранения результата | |
long _timeout = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд) | |
while (!SIM800.available() && millis() < _timeout) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то... | |
if (SIM800.available()) { // Если есть, что считывать... | |
_resp = SIM800.readString(); // ... считываем и запоминаем | |
} | |
else { // Если пришел таймаут, то... | |
Serial.println("Timeout..."); // ... оповещаем об этом и... | |
} | |
return _resp; // ... возвращаем результат. Пусто, если проблема | |
} | |
void loop() { | |
if (SIM800.available()) // Ожидаем прихода данных (ответа) от модема... | |
Serial.write(SIM800.read()); // ...и выводим их в Serial | |
if (Serial.available()) // Ожидаем команды по Serial... | |
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void loop() { | |
if (SIM800.available()) { // Если модем, что-то отправил... | |
_response = waitResponse(); // Получаем ответ от модема для анализа | |
Serial.println(_response); // Если нужно выводим в монитор порта | |
// ... здесь можно анализировать данные полученные от GSM-модуля | |
} | |
if (Serial.available()) { // Ожидаем команды по Serial... | |
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment