GSM SIM800L на Arduino: урок с AT-командами до SMS
SIM800L это GSM-модем от Simcom, который умеет звонить, принимать и отправлять SMS, а ещё поднимать GPRS-интернет. Управляется он AT-командами по UART, и весь этот урок построен вокруг одного простого правила: команда, потом пауза, потом чтение ответа.
Этот урок проведёт от подключения до отправки SMS. В симуляторе GSM можно отработать все AT-команды в браузере: модем виртуальный и отвечает типовыми ответами, а отправленное SMS появляется в списке.
Если вам нужна только связь с телефоном по кабелю, посмотрите HC-05 Bluetooth: это проще и не требует сим-карты. GSM нужен там, где важна связь на больших расстояниях или нужен интернет.
Подключение через SoftwareSerial
SIM800L подключается через UART, то есть двумя проводами данных плюс питание. На Arduino Uno аппаратный UART один, и он же занят USB, поэтому используем программный порт: SoftwareSerial gsm(2, 3), где D2 это RX платы, а D3 это TX. Сигнал идёт крест-накрест: TX модуля в D2, RX модуля в D3.
Питание. Модуль рассчитан на диапазон примерно от 3.4 до 4.4 В, и литиевый аккумулятор 3.7 В подходит идеально. Вывод 5 V Arduino даст около 500 мА, а модем в момент передачи GSM берёт до 2 А, поэтому с вывода 5 V он будет молчать или перезагружаться. Нужен отдельный источник 4 В 2 А и общий провод GND с Arduino. Конденсатор 1000 мкФ на питании модуля сглаживает просадки в момент передачи.
Уровни сигнала. Логика SIM800L около 2.8 В, а Arduino выдаёт 5 В, и RX-пин модема такое напряжение не любит. Между TX Arduino и RX модема поставьте делитель: резистор 10 кОм от TX к узлу и резистор 20 кОм от узла к земле. На узле получится 5 × 20 / 30, то есть примерно 3.3 В, этого достаточно, потому что порог логической единицы у модема равен 0.7 от напряжения питания, около 2.8 В при VDD 4 В. Вариант попроще: диод 1N4148 последовательно с TX Arduino срежет около 0.7 В и даст 4.3 В, но это впритык к пределу, поэтому делитель предпочтительнее. В обратную сторону проблемы нет: TX модема выдаёт 2.8 В, и Arduino это понимает.
AT-команды и отправка SMS
#include <SoftwareSerial.h>SoftwareSerial gsm(2, 3); // RX=2, TX=3void setup() { Serial.begin(9600); gsm.begin(9600); delay(3000); // ждать регистрацию в сети gsm.println("AT"); delay(100); gsm.println("AT+CSQ"); // сигнал сети delay(100); gsm.println("AT+CMGF=1"); // текстовый режим SMS delay(100); gsm.println("AT+CMGS=+79123456789"); // номер получателя delay(100); gsm.print("Hello from Arduino!"); delay(100); gsm.write(26); // Ctrl+Z — отправить SMS delay(5000); Serial.println("Ответ модема:"); while (gsm.available()) Serial.write((char)gsm.read());}void loop() {}Разберём по шагам. AT проверяет связь с модемом и отвечает OK. AT+CSQ показывает уровень сигнала сети по шкале от 0 до 31, где 99 означает «неизвестно», а значения выше 15 говорят о хорошем сигнале. AT+CREG? сообщает, зарегистрирован ли модем в сети: значение 1 это домашняя сеть, 5 это роуминг. AT+CMGF=1 переключает модем в текстовый режим SMS, в котором номер и текст пишутся обычными символами вместо двоичного PDU-формата.
Дальше начинается собственно отправка. AT+CMGS с номером в кавычках говорит модему, что сейчас будет SMS, и модем отвечает символом >. После этого нужно передать текст и завершить его символом Ctrl+Z, то есть кодом 26. Без Ctrl+Z модем будет ждать текст бесконечно, и это самая частая причина «SMS не отправляется».
Про задержки. Настоящий модем отвечает не мгновенно, а через десятки миллисекунд, поэтому после каждой команды нужна пауза, и только потом можно читать буфер. Первый delay на 3 секунды в setup нужен для регистрации в сети: модем включается и ищет оператора, и на это уходит от 10 секунд до пары минут в зависимости от покрытия.
Звонки. ATD с номером начинает вызов, ATA отвечает на входящий, ATH сбрасывает соединение, а AT+CLCC показывает состояние текущего вызова. Чтобы принять звонок, скетч должен периодически проверять входящие: в реальном проекте это делают через прерывание или опрос статуса звонка.
Подробнее про SoftwareSerial — в уроке про Serial. HC-05 Bluetooth — похожий модуль через AT.
| AT-команда | Ответ | Назначение |
|---|---|---|
| AT | OK | Проверка связи |
| AT+CSQ | +CSQ: 15,0 | Сигнал сети (0-31) |
| AT+CREG? | +CREG: 0,1 | Регистрация (1=домашняя сеть) |
| AT+CMGF=1 | OK | Текстовый режим SMS |
| AT+CMGS=номер | > | Ожидание текста |
| AT+CMGL | Список SMS | Прочитать входящие |
| ATD+номер | OK | Позвонить |
| write(26) | OK | Ctrl+Z — отправить SMS |
Что сначала не получилось
Первый модем я запитал от 5 V, потому что так проще всего. Он включался, на AT отвечал OK, а при попытке отправить SMS перезагружался. Замер тока мультиметром показал картину: в покое ток был нормальным, а в момент передачи уходил в сотни миллиампер и вызывал просадку, от которой модем перезагружался. Вынес питание на отдельный источник 4 В 2 А с общей землёй, и проблема ушла.
Второй затык был в скорости. Я выставил 115200 бод, потому что модем вроде бы умеет, и SMS отправлялись через раз. Оказалось, что на 115200 нужно перенастроить модем командой AT+UART, а по умолчанию он работает на 9600. SoftwareSerial на 115200 всё равно теряет байты, поэтому я вернулся к 9600 и оставил модем в заводской настройке.
Третий случай показал, что порядок команд важен. Если сначала отправить текст, а потом AT+CMGS, модем воспримет текст как неизвестную команду и ответит ERROR. Правильный порядок всегда такой: сначала номер, потом символ >, потом текст, потом Ctrl+Z.
Личный опыт: система оповещения
Первое устройство с SIM800L у меня было системой оповещения: Arduino забирает показание датчика температуры, и если оно вышло за порог, модем отправляет SMS владельцу. Схема обмена простая: сначала AT, потом AT+CMGF=1, потом номер, потом текст с текущей температурой, и в конце Ctrl+Z.
Проверял я это в симуляторе и по счётчику. В симуляторе команда отправки давала ответ OK, а в списке отправленных появлялась запись с текстом сообщения, в котором было видно подставленное значение температуры. Отдельно я добавил в скетч счётчик попыток и ограничил частоту отправки одним SMS в десять минут: при плохом сигнале модем иногда не отвечает, и без ограничения он бы завалил владельца десятками одинаковых сообщений. На настоящем железе я отдельно проверил, что модем успевает зарегистрироваться в сети: первая команда уходила сразу после старта и не сработала, поэтому в setup теперь стоит пауза и проверка AT+CREG.
Авторская позиция: что взять новичку
Берите модуль с готовой платой и стабилизатором, а не голый чип, и сразу выбирайте вариант с выведенными выводами питания и UART. Питание стройте от отдельного источника с общей землёй, это снимает половину всех проблем. И начинайте с команды AT, а не с отправки SMS: если модем не отвечает даже на AT, дело в питании или в проводах, и никакие более сложные команды тут не помогут. Для проектов, где нужна только связь на небольшом расстоянии, GSM избыточен, и HC-05 справится лучше.