Проблема с получением SMS - GSM-модуль Arduino Uno и SIM900A
Я намерен управлять светодиодом в соответствии с содержанием полученного SMS. Например, если SMS «ВКЛ», включите светодиод, а если «ВЫКЛ», выключите его. Я ссылался на многие сайты и получил приведенный ниже код. Цифровые контакты 9 и 10 используются вместо Rx и Tx, чтобы избежать проблем с загрузкой кода.
(Я сохранил в коде комментарии к различным версиям AT-команд, потому что не уверен, какая из них верна. С текущей версией я могу получить какой-то вывод, который я упомянул после код.)
#include <SoftwareSerial.h>
SoftwareSerial mySerial(9, 10);
char msg;
void setup()
{
Serial.begin(9600);
mySerial.begin(9600); // Установка скорости передачи GSM-модуля
delay(1000);
//mySerial.print("AT+CMGF=1r"); // установить режим SMS на текст
mySerial.print("AT+CMGF=1\r"); // установить режим SMS на текст
delay(100);
//mySerial.println("AT+CNMI=2,2,0,0,0"); // AT-команда для получения живого SMS
//mySerial.print("AT+CNMI=2,2,0,0,0r");
mySerial.print("AT+CNMI=1,2,0,0,0\r"); // AT-команда для получения живого SMS
delay(100);
Serial.println("Ready");
}
void loop()
{
if (mySerial.available()>0)
{
msg=mySerial.read();
Serial.print(msg);
}
}
Вот что я получаю..
Ready
AT+CMGF=1
AT+CNMI=1,2,0,0,0
OK
+CMTI: "SM",31
+CMTI: "SM",32
+CMTI: "SM",33
+CMTI: "SM",34
Проблема в том, что я не могу получить содержимое сообщения. Я получаю
"+CMTI: "SM",31"
"+CMTI: "SM",32"
и число продолжает увеличиваться. (33, 34 и так далее).
Я понимаю, что мне нужно разобрать сообщение, чтобы получить точное содержание, но здесь я вообще не получаю содержание. Что именно я должен сделать, чтобы получить содержание SMS? Может ли кто-нибудь помочь мне решить эту проблему?
Еще один момент: GSM-модуль, который я использую, относится к типу SIM900A (с сайта elementzonline.com). Это не щитовой тип, поэтому я сделал соединения с помощью проводов; соединения Rx, Tx и заземление.
(Извините за плохое объяснение, я полный ноль в Arduino, любитель.)
Заранее спасибо.
3 ответа
Лучший ответ:
Вы должны загрузить набор команд SIM900 (можно найти в Google) и прочитать его. В соответствии с вашими настройками CNMI, смс-уведомления отправляются на Arduino, а не содержимое смс, то есть данные +CMTI, которые вы получаете. SM
говорит вам, что смс хранится на SIM-карте, а следующий за ним номер указывает индекс смс в памяти SIM-карты. С этим индексом вы используете команду AT+CMGR=<index>
, чтобы получить содержимое sms (а также номер отправителя и отметку времени) от модема.
По сути, вы должны проанализировать уведомление CMTI, получить номер в конце и использовать этот номер для извлечения содержимого SMS из модема с помощью команды CMGR. Вы также можете изменить настройки CNMI на (2,2,0,0,0), я думаю, если вы хотите, чтобы модем отправлял содержимое сообщений, а не только уведомления.
В любом случае буфер приема SoftwareSerial, скорее всего, переполнится при получении содержимого sms от модема; потому что вы не можете читать() достаточно быстро. Это сделает сообщение усеченным. Вы должны увеличить размер буфера SoftwareSerial RX, чтобы предотвратить это. Вот ссылка на ответ, где это объясняется. Удачи.
Вместо использования команд At используйте библиотеку GSM для Arduino, ее легче понять и реализовать. код для получения смс
#include <GSM.h>
// PIN-код для SIM-карты
#define PINNUMBER "" // сим-код, если сим-карта заблокирована
// инициализируем экземпляры библиотеки
GSM gsmAccess;
GSM_SMS sms;
// Массив для хранения номера, с которого получено SMS
char senderNumber[20];
void setup() {
// инициализируем последовательную связь и ждем открытия порта:
Serial.begin(9600);
while (!Serial) {
; // ждем подключения последовательного порта. Требуется только для родного порта USB
}
Serial.println("SMS Messages Receiver");
// состояние подключения
boolean notConnected = true;
// Запускаем GSM соединение
while (notConnected) {
if (gsmAccess.begin(PINNUMBER) == GSM_READY) {
notConnected = false;
} else {
Serial.println("Not connected");
delay(1000);
}
}
Serial.println("GSM initialized");
Serial.println("Waiting for messages");
}
void loop() {
char c;
// Если есть доступные SMS()
if (sms.available()) {
Serial.println("Message received from:");
// Получить удаленный номер
sms.remoteNumber(senderNumber, 20);
Serial.println(senderNumber);
// Пример удаления сообщения
// Любые сообщения, начинающиеся с #, должны быть отброшены
if (sms.peek() == '#') {
Serial.println("Discarded SMS");
sms.flush();
}
// Читаем байты сообщения и печатаем их
while (c = sms.read()) {
Serial.print(c);
}
Serial.println("\nEND OF MESSAGE");
// Удалить сообщение из памяти модема
sms.flush();
Serial.println("MESSAGE DELETED");
}
delay(1000);
}
Библиотека GSM используется с Arduino GSM Shield, верно? Здесь я использую другой GSM-модуль SIM900A, а не шилд., @Aparna Shaji Peter
используйте cnmi 2,2,0,0,0, чтобы получить содержимое SMS используйте cnmi 1,2,0,0,0, чтобы получить только уведомление с CMTI+.... если вы хотите прочитать продолжение, вам нужно проанализировать и проверить, какой номер вы получаете в SM, а затем прочитать это пронумерованное сообщение, используя CMGR
Можете ли вы объяснить это по-английски и показать пример?, @SDsolar
- Мини-модем SIM900a, IMEI 0, помощь с контактами TX RX
- Как получить данные из базы данных моего сервера в переменную в моем Arduino?
- Как отправить команду AT на sim800l с помощью SoftwareSerial
- SIM800L не регистрируется в сети
- Как отправлять сообщения на несколько номеров с помощью модуля Arduino uno и SIM800?
- Клиент MQTT на Arduino + SIM900
- Какие контакты Arduino UNO можно использовать в качестве контактов Tx и Rx для подключения к GSM GPRS SIM 900A
- ЖК-дисплей странные символы
Большое спасибо за ответ! Я изменил код, как в ссылке. Я только что попробовал
mySerial.println("AT+CMGR=35");
и получаю содержимое SMS. Вывод такой: «ОК AT+CMGR=35 +CMGR: "REC READ","+919******7","","16.04.06,18:38:49+22" Привет`. В данном случае «Привет» — это собственно содержимое. Но теперь проблема в том, что вывод отображается бесконечно., @Aparna Shaji Peter@AparnaShajiPeter ну, возможно, это потому, что вы поместили его в цикл(). Поместите его в setup(), если хотите, чтобы сообщение печаталось только один раз. Структурируйте свой код так, чтобы он делал то, что вы хотите., @SoreDakeNoKoto
еще одно обновление, теперь я не получаю уведомления. т. е. если я запускаю ту же первую программу, я не получаю сообщения
+CMTI
. проверил соединения, все идеально. Мне тоже звонят. Не знаю, что происходит. :(, @Aparna Shaji Peter@AparnaShajiPeter, ты используешь свой исходный код, верно? А вы не меняли настройки CNMI с (2,2,0,0,0)? А вы отправляли новые сообщения при подключенном модеме? Кроме того, нет команды CMGR?, @SoreDakeNoKoto
сначала запустите команду AT+CNMI, чтобы получить индекс сообщения, а затем, используя этот индекс, запустите команду AT+CMGR. Это идея, да?, @Aparna Shaji Peter
Да, тот же самый код, который я разместил здесь в вопросе. (с CNMI 1,2,0,0,0). Пока модем подключен. И CMGR там нет, потому что я только что попробовал распечатать индекс, первой программы., @Aparna Shaji Peter
@AparnaShajiPeter Нет. AT+CNMI устанавливает режим уведомления модема. Использование настройки (1,0,0,0,0) заставит модем пересылать сообщения на терминал напрямую по мере их получения БЕЗ уведомлений. Тогда как (2,2,0,0,0) заставит модем пересылать только уведомления, а затем вам придется использовать CMGR для получения содержимого SMS. Уведомления CMTI не запрашиваются; вы не запрашиваете их, вы просто ждете, пока данные станут доступны через последовательный порт, а затем анализируете и получаете индекс, @SoreDakeNoKoto
@AparnaShajiPeter Я подозреваю, что память твоей сим-карты заполнена. Максимум около 15 сообщений. Попробуйте эту команду, чтобы удалить все: AT+CMGD=ALL или AT+CMGD="ALL"...не могу вспомнить, что правильно. Поместите его в setup() отдельно и распечатайте результаты. Затем попробуйте исходный код и отправьте еще одно смс., @SoreDakeNoKoto
Я тоже подозревал то же самое и удалил все сообщения, используя
AT+CMGDA="DEL ALL"
, и попытался запустить его снова, но это не дало никаких изменений., @Aparna Shaji Peter@AparnaShajiPeter это неправильная команда. Попробуйте команду, которую я вам дал... также распечатайте результаты, чтобы вы могли знать, удалось ли это., @SoreDakeNoKoto
Давайте [продолжим обсуждение в чате](http://chat.stackexchange.com/rooms/38019/discussion-between-aparna-shaji-peter-and-tisteandii)., @Aparna Shaji Peter