Привет фанатам GSM автоматики! Подпишитесь, чтобы ничего не пропустить, и начнем очередной выпуск по работе SIM800L и Arduino. На этот раз рассмотрим тему Arduino SIM800 входящий звонок. Проработаем автоматический подъем трубки по входящему звонку, а так же будем автоматически включать реле по звонку с определенного номера.
Мы здесь будем использовать код из предыдущего видео, модифицируем его и наведем марафет. Схема устройства тоже будет такая как в прошлом видео, но добавится реле на дискретном выходе контроллера.
В общем виде схема будет выглядеть так. Здесь все как в предыдущих видео, но добавляется реле, подключенное к дискретному выходу D7 контроллера Arduino Nano.
Для практической работы с минимальным монтажом, я возьму одну из наших плат, на которую устанавливается SIM800 и Arduino Nano, и на которой предусмотрены два реле со светодиодной индикацией их включения. Здесь на плате подписано, что одно реле управляется от пина D7, а второе от пина D8. Реле управляется от контроллера не напрямую, а через транзистор. Вы также можете собрать свою схему и без нашей платы, но реле подключайте или через транзистор, или возьмите готовый модуль реле с логикой 5В.
Моя плата питается от внешнего источника питания 5В ибо от USB-порта будет маловато мощности для питания SIM800.
Включаю питание устройства.
Соединяю Arduino с ноутбуком USB-кабелем и открываю программу Arduino IDE.
Здесь открыт скетч из прошлого видео. И мне в глаза бросается, что функции для работы с SIM800 занимают на первой вкладке много места и мешают читать или воспринимать визуально основную программу.
#include <SoftwareSerial.h>
SoftwareSerial SIM800serial (2, 3);
#define OK 1
#define NOTOK 2
#define TIMEOUT 3
void setup() {
Serial.begin(9600);
SIM800serial.begin(9600);
delay(10000);
SIM800command("AT", "OK", "ERROR", 500, 5);
delay(1000);
SIM800command("AT+CCLK?", "OK", "ERROR", 500, 1); //date time of SIM800
delay(1000);
SIM800command("AT+CCLK=\"21/12/12,16:25:33+02\"", "OK", "ERROR", 500, 1); //yy/mm/dd,hh:mm:ss+zz
}
void loop() {
SIM800command("AT+CCLK?", "OK", "ERROR", 500, 1); //date time of SIM800
delay(1000);
}
byte SIM800command(String command, String response1, String response2, uint16_t timeOut, uint16_t repetitions) {
byte returnValue = NOTOK;
byte countt = 0;
while (countt < repetitions && returnValue != OK) {
SIM800serial.println(command);
if (SIM800waitFor(response1, response2, timeOut) == OK) {
returnValue = OK;
} else {returnValue = NOTOK;}
countt++;
}
return returnValue;
}
byte SIM800waitFor(String response1, String response2, uint16_t timeOut) {
uint16_t entry = 0;
uint16_t count = 0;
String reply = SIM800read();
byte retVal = 99;
do {
reply = SIM800read();
delay(1);
entry ++;
} while ((reply.indexOf(response1) + reply.indexOf(response2) == -2) && entry < timeOut );
if (entry >= timeOut) {
retVal = TIMEOUT;
} else {
if (reply.indexOf(response1) + reply.indexOf(response2) > -2) retVal = OK;
else retVal = NOTOK;
}
return retVal;
}
String SIM800read() {
String reply = "";
if (SIM800serial.available()) {
reply = SIM800serial.readString();
}
if (reply!=""){
Serial.print("Reply: ");
Serial.println(reply);
}
return reply;
}
Поэтому создадим новую вкладку, клацнув на кнопку со стрелочкой. Дальше New Tab и вводим название вкладки, которое первым придет в голову. Клацаем OK – вкладка появилась.
Теперь вырежу функции, которые в первой вкладке будут лишними, и вставлю в новую вкладку.
Ну вот, теперь основная вкладка будет посвободнее.
А теперь просто возьмем и загрузим этот старый скетч в контроллер чисто для практического эксперимента.
Запускаю монитор порта и жду поступления команды из секции loop().
А теперь позвоню с мобильного на номер симки, вставленной в GSM-модуль.
И вот, загруженный скетч побочным эффектом показывает нам, какие сообщения пишет SIM800 при входящем вызове. То есть RING, потом CLIP – это команда определителя номера, потом номер звонящего. 145 - это формат номера. И, пока идет вызов, такие сообщения модуль будет писать периодически в порт UART.
А, когда звонящий вешает трубку, приходит сообщение NO CARRIER.
Узнав эту информацию, теперь набросаем программку, которая будет автоматически включать реле при входящем звонке и вешать трубку. При чем, реле будет включаться на одну секунду, и срабатывать оно будет только на звонок от хозяина. Звонки от других номеров телефона будут игнорироваться.
Для начала сконфигурируем дискретный пин D7 как выход. Остальную начинку секции Setup() трогать не будем.
Дальше заменим содержимое секции loop() парой новых строк.
#include <SoftwareSerial.h>
SoftwareSerial SIM800serial (2, 3);
#define OK 1
#define NOTOK 2
#define TIMEOUT 3
void setup() {
pinMode(7, OUTPUT); //relay1
Serial.begin(9600);
SIM800serial.begin(9600);
delay(10000);
SIM800command("AT", "OK", "ERROR", 500, 5);
delay(1000);
SIM800command("AT+CCLK?", "OK", "ERROR", 500, 1); //date time of SIM800
delay(1000);
SIM800command("AT+CCLK=\"21/12/12,16:25:33+02\"", "OK", "ERROR", 500, 1); //yy/mm/dd,hh:mm:ss+zz
}
void loop() {
String txt;
txt = SIM800read();
if ((txt.indexOf("+CLIP: \"+380934158245") > -1)&&(txt.indexOf("NO CARRIER") == -1)){
digitalWrite(7, HIGH);
SIM800command("ATA", "NO CARRIER", "ERROR", 30000, 1);
// SIM800command("ATH", "OK", "ERROR", 500, 5);
}
SIM800command("AT", "OK", "ERROR", 500, 1);
delay(1000);
digitalWrite(7, LOW);
}
Переменная txt будет хранить текст принятого сообщения от GSM-модуля.
Во второй строчке задействуется функция SIM800read(), которую мы создали в предыдущем видео. Она проверяет буфер UART порта и возвращает текст сообщения, если такое поступило.
В операторе if содержатся два условия. Первое – это, что есть входящий звонок, и номер телефона такой, как у хозяина. Второе условие нужно объяснить чуть дольше.
Мы видели в мониторе порта сообщения SIM800 при входящем звонке, а так же при сбросе вызова. Так вот в нашем случае сбрасывать вызов будет принимающая звонок сторона, и то же последнее сообщение NO CARRIER, а перед ним и RING и номер телефона звонящего по какой-то причине приходит от оператора секунд через 20-30. И если не проверять сообщение с номером телефона на присутствие строки NO CARRIER, то по каждому звонку хозяина, реле будет срабатывать два раза. Один раз во время звонка, а второй раз через случайное количество секунд. А нам такое естественно не нужно. Ведь у нас задача – четко клацнуть релешкой на одну секунду по звонку.
Кстати сюда можно добавить ещё номера телефонов, добавляя похожие условия через знак или. Например, можете добавить номер вашей жены, чтобы её звонки тоже срабатывали.
Если условия выполняются, пин D7 взводим в единицу и реле срабатывает.
Следующая функция отправляет команду ATH для сброса вызова на SIM800.
Дальше идут строки без условия, которые активируются раз в секунду. Команда AT здесь просто, чтобы GSM-модуль не переходил в режим сна, а также чтобы мы видели в мониторе порта, что контроллер живой.
После паузы в одну секунду, выключаем реле, подавая ноль на выход D7 Arduino Nano.
Загружаю скетч в контроллер.
И запускаю монитор порта.
Через 10 секунд ожидания наблюдаем за обменом сообщениями.
Пробую звонить на номер симки в GSM-модуле. Вот есть сообщение о звонке, реле срабатывает и сообщение ATH означает успешный сброс звонка. Примерно через секунду реле выключается.
Теперь для прикола попробую позвонить с другого номера телефона.
В мониторе порта видим дозвоны, но реле молчит и звонок не сбрасывается. То есть условия не выполняются. Как и было задумано.
Сейчас снова наберу с заданного телефона. С первого раза не получилось потому, что случайно пришло сообщение о положенной трубке, про которое я долго рассказывал.
А теперь с повторного звонка реле срабатывает и вызов сбрасывается. Кстати по первому гудку реле не сработало так как я попал на отправку команды AT, но по второму гудку всё прошло и это не критично по-моему. Программу считаем полностью рабочей и ставим лайк.
Так вот мы уже познакомились с командой ATH, которая ложит трубку, если нужно разорвать входящий вызов, а теперь протестируем команду подъема трубки. Сценарий такой: все та же релешка будет включаться по входящему звонку, но выключаться она будет только, когда звонящий хозяин повесит трубку.
Закомментируем команду ATH и напишем в пределах оператора if отправку команды поднятия трубки ATA. Функция SIM800command будет крутиться 30 секунд ожидая сообщения, что звонящий повесил трубку. И все это время реле будет замкнуто.
Загружаю скетч в Arduino Nano.
Запускаю монитор порта.
После поступления команд AT, набираю номер устройства.
После второго гудка контроллер подымает трубку и включает реле.
Сбрасываю вызов на мобилке, после чего видно сообщение NO CARRIER, через секунду выключается реле и программа продолжает свои циклы.
Звоню ещё раз. Контроллер по первому гудку включает реле и принимает вызов командой ATA. В принципе в это время, если вы подключите к SIM800 микрофон и динамик, то сможете послушать, что происходит возле устройства и даже поговорить с присутствующими.
Когда разрываю вызов, реле выключается, как по сценарию и было задумано.
В итоге мы разобрали две основные AT-команды для работы с входящими звонками, а так же попробовали их на практике. Немного закрепили использование функций для управления GSM-модулем, которые мы создали в предыдущем видео. А в следующем ролике проработаем исходящие звонки и так же как и сейчас отладим пример практического применения.
Всем спасибо за внимание! Буду благодарен за подписку и обратную связь!
Набор перемычек (мама-мама) 40шт 10см
Набор соединительных проводов для соединения плат контроллера с периферией без пайки. Подходят под с..
48.08грн.
LED драйвер 330/660мА с ШИМ управлением
Драйвер для мощных светодиодов и светодиодных светильников на основе микросхемы AL8805. Позволя..
116.28грн.
Генератор импульсов на NE555
Генератор прямоугольных импульсов на микросхеме NE555 с плавной подстройкой частоты и заполненияНапр..
40.60грн.
Модуль MP3-плеера GW
Полностью автономный mp3-плеер с питанием 5 В. Миниатюрный, имеет на борту кнопки управления. Читает..
85.66грн.