SIM900 Как прочитать длинное SMS с SIM карты?
- Войдите на сайт для отправки комментариев
Добрый день!
Подскажите пожалуйста, как прочитать длинное SMS с SIM карты?
Есть код
void setup() { Serial.begin(115200); // SIM900 Serial1.begin(115200); String vGSMStr = ""; Serial.println("Start"); // подавляем эхо Serial1.println("ATE0"); delay(200); // выключаем текстовый текстовый режим потому как SMS в PDU Serial1.println("AT+CMGF=1"); delay(200); // чистим буфер while (Serial1.available()) { Serial1.read(); } // читаем первую СМС Serial1.println("AT+CMGR=1,1"); delay(500); while (Serial1.available()) { // чиаем побайтово char inChar = (char)Serial1.read(); vGSMStr += inChar; } // выводим в Serial Serial.println("1 SMS"); Serial.println(vGSMStr); vGSMStr = ""; // читаем вторую СМС Serial1.println("AT+CMGR=2,1"); delay(500); while (Serial1.available()) { // чиаем побайтово char inChar = (char)Serial1.read(); vGSMStr += inChar; } // выводим в Serial Serial.println("\n\n2 SMS"); Serial.println(vGSMStr); vGSMStr = ""; } void loop(void) { }
На SIM карте есть 2 SMS. Пробую их читать командой "AT+CMGR"
Но получаю такую картину, СМС не выводится полностью, только статус, номер и дата. Самого текста СМС нет.
Порылся на форумах, нашел решение. Надо увеличить буфер для чтения в файле HardwareSerial.h
было 64, поставил 256.
Все заработало, теперь выводит и текст и сообщение, но решение меня не совсем устраивает, так как солидно кушает память.
Буфер 256 - Глобальные переменные используют 1 193 байт (14%) динамической памяти
Буфер 64 - Глобальные переменные используют 425 байт (5%) динамической памятил
Подскажите может кто сталкивался с подобной проблемой, можно както решить не внося изменения в стандартные библиотеки?
Смею утверждать, что других решений не существует (хотя рад бы ошибиться).
Во-первых, я думаю необязательно оба буфера увеличивать, можно только RX.
Во-вторых, дело в том, что сначала отправляется команда прочитать такую-то смс, а потом delay(500), пока это время идет, вся смс уже отправлена на вход микроконтроллера, а места в буфере не хватает, так как надо считывать постоянно в loop, без delay.
Можно придумать еще вариантик, что-то типа:
Теоретически должно сработать, но вариант так себе, если не сработает, можно попробовать скорость поставить меньше, например Serial1.begin(9600); еще можно почитать про функции readBytesUntil() и readStringUntil() и т.п., там есть timeout, может тоже что получится.
Во-первых, я думаю необязательно оба буфера увеличивать, можно только RX.
Именно так, размер буфера передачи (TX) никоим образом не связан с обсуждаемой проблемой.
Во-вторых, дело в том, что сначала отправляется команда прочитать такую-то смс, а потом delay(500), пока это время идет, вся смс уже отправлена на вход микроконтроллера, а места в буфере не хватает, так как надо считывать постоянно в loop, без delay.
...
Теоретически должно сработать, но вариант так себе, если не сработает, можно попробовать скорость поставить меньше, например Serial1.begin(9600); еще можно почитать про функции readBytesUntil() и readStringUntil() и т.п., там есть timeout, может тоже что получится.
Я делал ряд попыток пойти этим путем, успехом не увенчалось. А потом как-то прочитал внятную статью о том, как работает последовательный порт и его буферизация. Увы.
Странно, я считывал смс в loop без изменений конф. файлов, правда через SoftwareSerial стандартным примером, и там вроде буфер тоже 64, если только он по-другому работает...
еще можно почитать про функции readBytesUntil() и readStringUntil() и т.п., там есть timeout, может тоже что получится.
Спасибо огромное, вот этот код работает
Но компилятор пишет предупреждение
можно так
но тогда надо читать 3 строки.
с readBytesUntil() пока не получилось, вместо сообщения возвращает "яяяяяяяяяяяяяяяяя...."
Но главное направление верное! Буду копать!
А с циклом for не работает?
А с циклом for не работает?
не захотел. да и логики я не понял
переписал так
выводит гдето 80 символов и все. останавливается
Спасибо огромное, вот этот код работает
Интересно-интересно, эту функцию не пробовал, тоже займусь.
UPD: Хотя в исходнике её ничего неожиданного не вижу:
Интересно-интересно, эту функцию не пробовал, тоже займусь.
UPD: Хотя в исходнике её ничего неожиданного не вижу:
Araris Если не трудно протестируйте.
Вот такой код работает отлично, то есть в конце строка выдает 0 в принципе условие
как ни странно срабатывает нормально.
не захотел. да и логики я не понял
переписал так
выводит гдето 80 символов и все. останавливается
Странно, так то точно неправильно будет работать, попробуйте так:
Точно должно заработать (правда если модуль шлет данные не останавливаясь, любой затык и выход из while, в таком случае в цикл while можно добавить delay(1) или больше, но это все неправильно, лучше той функцией). Логика простая, делим delay(500) на 500 по 1 мс, и каждый раз проверяем не пришли ли данные, если пришли, останавливаем цикл и дальше начинаем читать =)
Точно должно заработать =) Логика простая, делим delay(500) на 500 по 1 мс, и каждый раз проверяем не пришли ли данные, если пришли, останавливаем цикл и дальше начинаем читать =)
Вот код
Вот что в терминале
Если ставлю скорость
То ничего не выводит. Скорость у модуля SIM900 стоит в АВТО.
Ясно, спасибо за проверку, значит все таки микроконтроллер быстрее модуля хочет считать данные, что в принципе логично, несколько МГц все таки, думаю с delay в while заработает, но как уже написал это неправильно, надо ведь ждать только когда нет данных, нет смысла ждать когда они еще есть.