Отправка и приём SMS и звонков с GSM-модулем A6 и Arduino
Хотите слышать, что происходит в вашем доме, находясь далеко, или включить систему полива в саду простым звонком? Тогда GSM/GPRS-модуль A6 — отличная отправная точка для знакомства с IoT!
GSM/GPRS-модуль A6 — это миниатюрный GSM-модем, который можно интегрировать в множество IoT-проектов. Вы можете использовать этот модуль для выполнения практически всего, что может обычный мобильный телефон: SMS-сообщения, совершение или приём телефонных звонков, подключение к интернету через GPRS, TCP/IP и многое другое! Вдобавок модуль поддерживает четырёхдиапазонную сеть GSM/GPRS, что означает его работу практически в любой точке мира.
Обзор оборудования GSM/GPRS-модуля A6
Сердцем модуля является GSM-чип A6 от Ai-Thinker (производителя WiFi-модулей ESP8266). Он обменивается данными с микроконтроллером по UART и поддерживает скорость передачи данных от 1200 бит/с до 115200 бит/с с автоопределением скорости. Все необходимые выводы данных GSM-чипа A6 выведены на штыревые разъёмы с шагом 2,54 мм.
Модуль нуждается во внешней антенне для любого вида голосовой или передачи данных, а также для некоторых команд SIM-карты. Поэтому он обычно поставляется с небольшой штыревой антенной с усилением 2 дБи и импедансом 50 Ом, которая обеспечивает хорошее покрытие, даже если ваш проект находится в помещении.
Имеется кнопка питания для ручного включения/выключения модуля, хотя это можно сделать и программно. Состояние модуля индицируется светодиодом в правом верхнем углу модуля.
Хотя модуль может работать от 5 В, рабочее напряжение чипа составляет от 3,3 В до 4,2 В. Для поддержания безопасного напряжения питания на уровне 4,1 В модуль оснащён высокочастотным понижающим импульсным стабилизатором MP1584 от Monolithic Power Systems — способным обеспечивать ток нагрузки до 3 А.
Модуль также можно запитать через разъём micro USB. Вы можете просто взять зарядное устройство от мобильного телефона (рассчитанное на 5 В 2 А) и запитать модуль.
На обратной стороне находится разъём для SIM-карты! Подойдёт любая активированная micro SIM-карта 2G. К работе с разъёмом SIM-карты нужно привыкнуть. Чтобы разблокировать защёлку, сдвиньте верхнюю часть конструкции к разъёму micro USB, а затем поднимите её. Поместите SIM-карту в нижнюю часть разъёма так, чтобы выемка SIM-карты была направлена от разъёма micro USB. Затем опустите рычаг обратно в корпус разъёма и аккуратно сдвиньте его к положению «LOCK».
GSM-чип A6 имеет размер меньше почтовой марки, но содержит удивительное количество функций. Некоторые из них перечислены ниже:
Поддержка четырёх диапазонов: GSM850, EGSM900, DCS1800 и PCS1900
Подключение к любой глобальной сети GSM с любой 2G SIM-картой
Совершение и приём голосовых звонков с использованием внешнего динамика 8 Ом и электретного микрофона
Возможность подключения 4-контактного TRRS микрофона и гарнитуры
Отправка и приём голосовых звонков и SMS-сообщений
GPRS класса 10 со скоростью загрузки 85,6 Кбит/с и скоростью отдачи 42,8 Кбит/с
Потребление менее 3 мА в режиме ожидания
Уровень порта UART 8 В — совместимость с Arduino, Raspberry-Pi
Мощность передачи: Класс 4 (2 Вт) для GSM850/EGSM900
Класс 1 (1 Вт) для DCS1800/PCS1900
Распиновка GSM-модуля A6
GSM-модуль A6 имеет в общей сложности 24 вывода для связи с внешним миром. Подключения следующие:
VCC обеспечивает питание модуля. Подключите к внешнему источнику питания 5 В 2 А.
GND — это вывод заземления, его необходимо подключить к выводу GND на Arduino.
MIC± — дифференциальный вход микрофона. Два провода микрофона можно подключить непосредственно к этим выводам.
MIC2_P — вывод для подключения 4-контактного TRRS микрофона.
REC± — дифференциальный интерфейс динамика. Два вывода динамика 8 Ом можно подключить непосредственно к этим выводам.
U_TxD (передатчик) — вывод для последовательной связи.
U_RxD (приёмник) — вывод для последовательной связи.
GPIO1 используется для управления переходом модуля в режим пониженного энергопотребления.
U_RTS (запрос на передачу) — вывод управления потоком UART, позволяющий приёмнику и передатчику уведомлять друг друга о своём состоянии.
U_CTS (готовность к передаче) — вывод управления потоком UART, позволяющий приёмнику и передатчику уведомлять друг друга о своём состоянии.
EAR_R используется для подключения 4-контактной TRRS гарнитуры.
EAR_L используется для подключения 4-контактной TRRS гарнитуры.
HST_RXD HOST UART — это отладочный UART, который используется для загрузки, калибровки, трассировки и т.д. Он не поддерживает AT-команды. Этот интерфейс используется только при отладке.
HST_TXD UART — это отладочный UART, который используется для загрузки, калибровки, трассировки и т.д. Он не поддерживает AT-команды. Этот интерфейс используется только при отладке.
RST (сброс) — вывод аппаратного сброса. Если модуль совсем перестал отвечать, подтяните этот вывод к LOW на 100 мс для выполнения аппаратного сброса. .. raw:: html
<p><span class=»pinout pinout-orange»>PWR</span> — вывод для программного включения/выключения модуля. Для этого нужно подтянуть его к HIGH на короткое время (менее 500 мс).</p>
<p><span class=»pinout pinout-red»>NC</span> — не подключён.</p>
PWR — вывод для программного включения/выключения модуля. Для этого нужно подтянуть его к HIGH на короткое время (менее 500 мс).
Схема подключения GSM-модуля A6 к Arduino UNO
Теперь, когда мы знаем всё о модуле, можно приступить к его подключению к Arduino!
Для начала подключите выводы U_TxD и U_RxD модуля к цифровым выводам #3 и #2 на Arduino, поскольку мы будем использовать программный последовательный порт для связи с модулем.
Подключите вывод VCC модуля к внешнему источнику питания 5 В 2 А. Не поддавайтесь соблазну подключить этот вывод к выходу 5 В на Arduino, так как модуль не будет работать из-за недостаточного тока. Теперь соедините все земли в схеме.
Наконец, подключите антенну, вставьте полностью активированную micro SIM-карту в разъём.
Схема подключения GSM GPRS-модуля A6 к Arduino UNO с внешним источником питания
Вы также можете запитать модуль через сетевой адаптер 5 В 2 А, но убедитесь, что вывод GND на Arduino подключён к выводу GND на модуле.
Схема подключения GSM GPRS-модуля A6 к Arduino UNO через USB-питание
После того как всё подключено, просто нажмите кнопку питания примерно на 2 секунды — и вы готовы к работе!
Предупреждение:
Будьте очень внимательны: не отключайте GND раньше VCC и всегда подключайте GND раньше VCC. Иначе модуль может использовать низковольтные выводы последовательного порта как землю и мгновенно выйти из строя.
Код Arduino — тестирование AT-команд
Для отправки AT-команд и взаимодействия с модулем A6 мы будем использовать монитор последовательного порта. Приведённый ниже скетч позволит Arduino обмениваться данными с модулем A6 через монитор последовательного порта. Прежде чем переходить к подробному разбору кода, подключите Arduino к ПК, скомпилируйте код ниже и загрузите его на Arduino.
После открытия монитора последовательного порта убедитесь, что выбрана опция „Both NL & CR“!
#include <SoftwareSerial.h>
//Create software serial object to communicate with A6
SoftwareSerial mySerial(3, 2); //A6 Tx & Rx is connected to Arduino #3 & #2
void setup()
{
//Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
Serial.begin(9600);
//Begin serial communication with Arduino and A6
mySerial.begin(9600);
Serial.println("Initializing...");
delay(1000);
mySerial.println("AT"); //Once the handshake test is successful, it will back to OK
updateSerial();
mySerial.println("AT+CSQ"); //Signal quality test, value range is 0-31 , 31 is the best
updateSerial();
mySerial.println("AT+CCID"); //Read SIM information to confirm whether the SIM is plugged
updateSerial();
mySerial.println("AT+CREG?"); //Check whether it has registered in the network
updateSerial();
}
void loop()
{
updateSerial();
}
void updateSerial()
{
delay(500);
while (Serial.available())
{
mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
}
while(mySerial.available())
{
Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
}
}
Скетч начинается с подключения библиотеки SoftwareSerial.h и инициализации её с выводами Arduino, к которым подключены Tx и Rx модуля A6.
#include <SoftwareSerial.h>
//Create software serial object to communicate with A6
SoftwareSerial mySerial(3, 2); //A6 Tx & Rx is connected to Arduino #3 & #2
В функции setup: мы инициализируем канал последовательной связи между Arduino, Arduino IDE и модулем A6 на скорости 9600 бод.
//Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
Serial.begin(9600);
//Begin serial communication with Arduino and A6
mySerial.begin(9600);
Теперь, когда мы установили базовое соединение, мы попробуем взаимодействовать с модулем A6, отправляя AT-команды.
AT — самая базовая AT-команда. Она также инициализирует автоопределение скорости. Если всё работает, вы должны увидеть эхо символов AT и затем OK, сообщающее, что всё в порядке и модуль вас правильно понимает! Затем можно отправить команды для запроса информации о модуле, например:
AT+CSQ — проверка «уровня сигнала» — первое число показывает силу в дБ, оно должно быть выше примерно 5. Чем выше, тем лучше. Конечно, это зависит от антенны и местоположения!
AT+CCID — получение номера SIM-карты — проверяет, что SIM-карта найдена, и вы можете сверить номер, написанный на карте.
AT+CREG? — проверка регистрации в сети. Второе число должно быть 1 или 5. 1 означает регистрацию в домашней сети, 5 — в роуминге. Любые другие числа означают отсутствие регистрации в сети.
mySerial.println("AT"); //Once the handshake test is successful, it will back to OK
updateSerial();
mySerial.println("AT+CSQ"); //Signal quality test, value range is 0-31 , 31 is the best
updateSerial();
mySerial.println("AT+CCID"); //Read SIM information to confirm whether the SIM is plugged
updateSerial();
mySerial.println("AT+CREG?"); //Check whether it has registered in the network
updateSerial();
В циклической части кода мы вызываем пользовательскую функцию updateSerial(), которая непрерывно ожидает ввод из монитора последовательного порта и отправляет его модулю A6 через вывод D2 (Rx модуля). Она также непрерывно считывает вывод D3 (Tx модуля) на случай, если модуль A6 имеет ответы.
void updateSerial()
{
delay(500);
while (Serial.available())
{
mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
}
while(mySerial.available())
{
Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
}
}
Вы должны увидеть следующий вывод в мониторе последовательного порта.
Теперь вы можете свободно отправлять любые команды через монитор последовательного порта, например, следующие, которые дают больше информации о сетевом подключении:
ATI — получение имени модуля и ревизии
AT+COPS? — проверка, к какой сети вы подключены, в данном случае 40466 (BSNL)
AT+COPS=? — возвращает список операторов, присутствующих в сети.
Код Arduino — отправка SMS
Перейдём к самому интересному. Давайте запрограммируем Arduino для отправки SMS на любой номер телефона. Перед запуском скетча вам нужно ввести номер телефона. Найдите строку ZZxxxxxxxxxx и замените ZZ на код страны, а xxxxxxxxxx — на 10-значный номер телефона.
#include <SoftwareSerial.h>
//Create software serial object to communicate with A6
SoftwareSerial mySerial(3, 2); //A6 Tx & Rx is connected to Arduino #3 & #2
void setup()
{
//Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
Serial.begin(9600);
//Begin serial communication with Arduino and A6
mySerial.begin(9600);
Serial.println("Initializing...");
delay(1000);
mySerial.println("AT"); //Once the handshake test is successful, it will back to OK
updateSerial();
mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
updateSerial();
mySerial.println("AT+CMGS=\"+ZZxxxxxxxxxx\"");//change ZZ with country code and xxxxxxxxxxx with phone number to sms
updateSerial();
mySerial.print("Last Minute Engineers | lastminuteengineers.com"); //text content
updateSerial();
mySerial.write(26);
}
void loop()
{
}
void updateSerial()
{
delay(500);
while (Serial.available())
{
mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
}
while(mySerial.available())
{
Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
}
}
Скетч почти такой же, как предыдущий, за исключением следующего фрагмента кода. После установления соединения мы отправляем следующие AT-команды:
AT+CMGF=1 — выбирает формат SMS-сообщений как текстовый. Формат по умолчанию — **P**rotocol **D**ata **U**nit (PDU)
AT+CMGS=+ZZxxxxxxxxxx — отправляет SMS на указанный номер телефона. Введённое текстовое сообщение, за которым следует символ „Ctrl+z“, обрабатывается как SMS. „Ctrl+z“ — это 26-й непечатаемый символ, описанный как „substitute“ в таблице ASCII. Поэтому нам нужно отправить 26 в десятичной системе (1A в шестнадцатеричной) после отправки сообщения.
mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
updateSerial();
mySerial.println("AT+CMGS=\"+ZZxxxxxxxxxx\"");//change ZZ with country code and xxxxxxxxxxx with phone number to sms
updateSerial();
mySerial.print("Last Minute Engineers | lastminuteengineers.com"); //text content
updateSerial();
mySerial.write(26);
Цикл loop оставлен пустым, поскольку мы хотим отправить SMS только один раз. Если вы хотите отправить SMS ещё раз, просто нажмите кнопку RESET на Arduino. На скриншоте ниже показано SMS, отправленное GSM-модулем A6.
Код Arduino — чтение SMS
Теперь давайте запрограммируем Arduino для чтения входящих сообщений. Этот скетч очень полезен, когда нужно выполнить действие при получении определённого SMS. Например, когда Arduino получает SMS, вы можете дать команду включить или выключить реле. Идея понятна!
#include <SoftwareSerial.h>
//Create software serial object to communicate with A6
SoftwareSerial mySerial(3, 2); //A6 Tx & Rx is connected to Arduino #3 & #2
void setup()
{
//Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
Serial.begin(9600);
//Begin serial communication with Arduino and A6
mySerial.begin(9600);
Serial.println("Initializing...");
delay(1000);
mySerial.println("AT"); //Once the handshake test is successful, it will back to OK
updateSerial();
mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
updateSerial();
mySerial.println("AT+CNMI=1,2,0,0,0"); // Decides how newly arrived SMS messages should be handled
updateSerial();
}
void loop()
{
updateSerial();
}
void updateSerial()
{
delay(500);
while (Serial.available())
{
mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
}
while(mySerial.available())
{
Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
}
}
Скетч аналогичен предыдущему, за исключением следующего фрагмента кода. После установления соединения мы отправляем следующие AT-команды:
AT+CMGF=1 — выбирает формат SMS-сообщений как текстовый. Формат по умолчанию — **P**rotocol **D**ata **U**nit (PDU)
AT+CNMI=1,2,0,0,0 — определяет, как обрабатывать новые входящие SMS-сообщения. Таким образом вы можете указать модулю A6 либо пересылать новые SMS непосредственно на ПК, либо сохранять их в хранилище сообщений и затем уведомлять ПК об их расположении.
Ответ начинается с +CMT: Все поля в ответе разделены запятыми: первое поле — номер телефона, второе — имя отправителя SMS, третье — временная метка, а четвёртое — само сообщение.
mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
updateSerial();
mySerial.println("AT+CNMI=1,2,0,0,0"); // Decides how newly arrived SMS messages should be handled
updateSerial();
Обратите внимание, что на этот раз мы НЕ оставили функцию loop пустой, так как мы опрашиваем новые входящие SMS-сообщения. После отправки SMS на GSM-модуль A6 вы увидите следующий вывод в мониторе последовательного порта.
Увеличение буфера SoftwareSerial в Arduino
Если ваше сообщение достаточно длинное, как наше, вы, вероятно, получите его с некоторыми пропущенными символами. Это не из-за ошибки в коде. Буфер приёма SoftwareSerial заполняется и отбрасывает символы. Вы недостаточно быстро считываете данные из буфера.
Простейшее решение — увеличить размер буфера SoftwareSerial с 64 байт по умолчанию до 512 байт (или меньше, в зависимости от того, что подходит вам).
На ПК с Windows перейдите в C:Program Files (x86) -> Arduino -> hardware -> Arduino -> avr -> libraries -> SoftwareSerial (-> src для новых версий Arduino IDE). Откройте SoftwareSerial.h и измените строку:
// RX buffer size
#define _SS_MAX_RX_BUFF 64
// RX buffer size
#define _SS_MAX_RX_BUFF 512
Сохраните файл и попробуйте скетч снова.
Увеличение буфера SoftwareSerial в Arduino
Код Arduino — совершение звонка
Теперь давайте запрограммируем Arduino для совершения звонка. Этот скетч очень полезен, когда вы хотите, чтобы Arduino совершал SOS/экстренный звонок в случае чрезвычайной ситуации, например, при превышении температуры или проникновении в дом. Идея понятна!
Перед запуском скетча вам нужно ввести номер телефона. Найдите строку ZZxxxxxxxxxx и замените ZZ на код страны, а xxxxxxxxxx — на 10-значный номер телефона.
#include <SoftwareSerial.h>
//Create software serial object to communicate with A6
SoftwareSerial mySerial(3, 2); //A6 Tx & Rx is connected to Arduino #3 & #2
void setup()
{
//Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
Serial.begin(9600);
//Begin serial communication with Arduino and A6
mySerial.begin(9600);
Serial.println("Initializing...");
delay(1000);
mySerial.println("AT"); //Once the handshake test is successful, i t will back to OK
updateSerial();
mySerial.println("ATD+ZZxxxxxxxxxx"); // change ZZ with country code and xxxxxxxxxxx with phone number to dial
updateSerial();
delay(20000); // wait for 20 seconds...
mySerial.println("ATH"); //hang up
updateSerial();
}
void loop()
{
}
void updateSerial()
{
delay(500);
while (Serial.available())
{
mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
}
while(mySerial.available())
{
Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
}
}
Для совершения звонка используются следующие AT-команды:
ATD+ZZxxxxxxxxxx; — набирает указанный номер.
ATH — завершает звонок.
mySerial.println("ATD+ZZxxxxxxxxxx"); // change ZZ with country code and xxxxxxxxxxx with phone number to dial
updateSerial();
delay(20000); // wait for 20 seconds...
mySerial.println("ATH"); //hang up
updateSerial();
На скриншоте ниже показан звонок, совершённый GSM-модулем A6.
Код Arduino — приём звонка
Для приёма звонка не требуется специального кода; достаточно просто прослушивать модуль A6. Тем не менее, этот скетч может быть очень полезен, когда нужно выполнить действие при получении звонка с определённого номера телефона.
#include <SoftwareSerial.h>
//Create software serial object to communicate with A6
SoftwareSerial mySerial(3, 2); //A6 Tx & Rx is connected to Arduino #3 & #2
void setup()
{
//Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
Serial.begin(9600);
//Begin serial communication with Arduino and A6
mySerial.begin(9600);
Serial.println("Initializing...");
}
void loop()
{
updateSerial();
}
void updateSerial()
{
delay(500);
while (Serial.available())
{
mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
}
while(mySerial.available())
{
Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
}
}
Входящий звонок обычно индицируется словом „RING“ в мониторе последовательного порта, за которым следуют номер телефона и идентификатор звонящего. Для принятия/завершения звонка используются следующие AT-команды:
ATA — принимает входящий звонок.
ATH — завершает звонок. При завершении звонка модуль отправляет NO CARRIER в монитор последовательного порта, указывая, что соединение не состоялось.
Ниже показан вывод в мониторе последовательного порта при приёме звонка GSM-модулем A6.