Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Последовательное вычитывание СМС с SIM900R
Форум разработчиков электроники ELECTRONIX.ru > Интерфейсы > Форумы по интерфейсам > Сотовая связь и ее приложения
Yaumen
Возможно этот вопрос уже поднимался, я сегодня пролистал 15 страниц, упарился искать ... wink.gif

Задача: вычитывать СМС,обрабатывать их и удалять.
Ограничения: Входной буфер для работы с SIM900R небольшой (около 1 кБ)

Обычная моя работа с SIM - это отправка запроса о ожидание необходимых ответов, типа OK, ERROR или CMS ERROR. После получения ОК, происходит разбор всего принятого пакета.

Для вычитывания СМС вижу 2 команды:
1) CGMR - очень удобная команда, но чтобы ей воспользоваться, необходимо знать индекс СМС сообщения, а они могут быть не все по порядку. Признака, типа вернуть первое доступное СМС сообщение у нее вроде нет.
2) CGML - умеет возвращать все имеющиеся сообщения, однако при наличии большого числа СМС, может просто не хватить моего входного буфера. Ограничить количество возвращаемых за один раз сообщений, типа вернуть только одно сообщений у нее вроде нет.

Конечно можно предположить, что СМС сообщения будут приходить с большим интервалом и команда CGML будет возвращать 1-2-3 сообщения, которые поместяться у меня во входном буфере. Однако практика показывает, что в жизни бывает всякое и надо быть готовым к худшему случаю.

Кто как с такими задачами справляется или есть еще способ работы с СМС сообщениями, который я проглядел.
megajohn
вариант 3: Использовать Flow Control на UART и подать соответсвующую команду на модем
вариант 4: в телитах можно настроить at+cnmi=2,1,0,0,0 чтобы было сообщение о каждом пришедшем СМС, и эти сообщения парсить ( +CMTI: "SM",2\r\n +CMTI: "SM",34\r\n +CMTI: "SM",125\r\n ) и складировать в очередь, чтобы потом извлекать уже нужные номера СМС ( может что подобное в симкоме есть )
Yaumen
Цитата(megajohn @ Feb 26 2015, 18:02) *
вариант 3: Использовать Flow Control на UART и подать соответсвующую команду на модем
вариант 4: в телитах можно настроить at+cnmi=2,1,0,0,0 чтобы было сообщение о каждом пришедшем СМС, и эти сообщения парсить ( +CMTI: "SM",2\r\n +CMTI: "SM",34\r\n +CMTI: "SM",125\r\n ) и складировать в очередь, чтобы потом извлекать уже нужные номера СМС ( может что подобное в симкоме есть )


насчет варианта 3 не понял. Если вы предлагаете с помощью RTC и CTS останавливать передачу данных от SIM, то такой вариант плох тем, что "ОК" ждаь нельзя, так как его не будет в первых пакетах. Во-вторых обработка всех сразу СМС в цикле, подвесит модуль, пока все СМС сообщения не будут обработаны. С этим конечно можно побороться, с помощью каких-то там флагов, запоминанием текущего состояния и прочего, но очень сильно усложнит прозрачность кода и как следствие, большую вероятность появления ошибки. А самое гланое, оно напрочь поломает всю ту структуру взаимодействия между микроконтроллером и SIM. Хотя как вариант, возможен. Отсавлю его на самый последний вариант, если других не останется.
Я уже думал в плане использования листинга, собирать на лету только ID СМС, а потом по одному уже работать с ними. В таком случае ломать мне меньше. Но тут другая проьблема вылазит - это количество СМС, которые могут находиться в памяти, чтобы выделить для их хранения память. Есть тут какие-то цифры или нет!? Сколько например может быть СМС или каков максимальный индекс?

Вариант 4 симпатичен, но не решает вопрос первого запуска, когда в карточке могут уже находиться какие-либо сообщения. Хотя, врядли это будут нужные сообщения и их можно просто по включению удалить, но все таки!
Baser
Цитата(Yaumen @ Feb 26 2015, 19:00) *
Но тут другая проьблема вылазит - это количество СМС, которые могут находиться в памяти, чтобы выделить для их хранения память. Есть тут какие-то цифры или нет!? Сколько например может быть СМС или каков максимальный индекс?

Вариант 4 симпатичен, но не решает вопрос первого запуска, когда в карточке могут уже находиться какие-либо сообщения. Хотя, врядли это будут нужные сообщения и их можно просто по включению удалить, но все таки!


Недавно решал подобный вопрос. В моем устройстве СМСки это неосновная редко применяемая фича, поэтому выбрал след. алгоритм:
Уведомления о приходе СМС у меня выключены, чтобы не мешались biggrin.gif (+CNMI: 0,0,0,0,0)
Поэтому раз в минуту запускаю функцию, которая:

1) запрашивает кол-во смс на симке:
AT+CPMS?
+CPMS: "SM",9,15,"SM",9,15,"SM",9,15....OK..
первый раз может быть много нестертых смс, потом будут только пришедшие за минуту.

если на симке ничего нет, все заканчивается, если кол-во больше нуля, то:

2) зная общее кол-во индексов на симке в цикле вычитывает по одному индексу:
AT+CMGR=1,0.
+CMGR: 1,"xxxxxxx",43..0123456789ABCDxxxxxxxx....OK..

если индекс пустой, возвращается только ОК

3) прочтенная смс обрабатывается на предмет того, нужна она нам или нет,
если нужна, выполняются нужные действия (например высылается ответная смс)

4) прочтенная смс стирается

Вот и все cool.gif
Работает неспешно, но надежно.

з.ы. индексов на симке может быть от 10 до нескольких десятков. У меня на очень старой симке (ей ок. 10 лет) - 10 штук,
на другой, новее - 15 штук.
SIM900 смс пишет на симку начиная с младших индексов: если все чисто, то в первый, если есть дырки - в младшую дырку
andrey videoplus
у меня похожий принцип работы: мк по прерыванию от RI определяет смс и читает входящее по команде CMGL после прочтения сразу удаление. Правда есть но! смс что приходят у меня небольше 70симвл.
Yaumen
Baser,
Отличный алгоритм, спасибо. А можно ли как-то узнать, максимальный размер индекса СМС, чтобы оперировать с конкретным значением, а не подбирать под конкретные симки!?
Baser
Цитата(Yaumen @ Feb 27 2015, 07:11) *
А можно ли как-то узнать, максимальный размер индекса СМС, чтобы оперировать с конкретным значением, а не подбирать под конкретные симки!?

Не понял вопроса laughing.gif
Если имеется ввиду кол-во индексов на конкретной симке (мест хранения смс), то его выдает команда AT+CPMS? В моем примере = 15.
Если имеется ввиду макс. длина смски для рассчета длины приемного буфера, то считайте исходя из своего режима работы модема (текст или PDU, кодировка, что включено у модема для ответов и т.д.) Макс. длина смс считается по стандарту GSM 03.40 глава 9. Длиные смски хранятся кусками, как они передаются в сети ГСМ, а не так, как показывает телефон. Напр., если пришла длиная смс из 5-и кусков, то они будут занимать 5 индексов. Я длиные смс не применял, так что для работы с ними алгоритм нужно усложнять.
Для своего случая я прикидывал длину, но сейчас этих данных под рукой нет, могу вечером отписать, но там меньше 1 кбайта.
Yaumen
Цитата(Baser @ Feb 27 2015, 14:03) *
Не понял вопроса laughing.gif
Если имеется ввиду кол-во индексов на конкретной симке (мест хранения смс), то его выдает команда AT+CPMS? В моем примере = 15.


Извиняюсь, не дочитал про команду CPMS. Она действительно возвращает количество использованых ячеек для хранения СМС и максимальное возможных число СМС, т.е. как раз то, что мне и нужно.
Спасибо огромное за наводку и разъяснение. Этим путем и пойдем sm.gif
Alechek
Цитата(Yaumen @ Feb 26 2015, 22:00) *
насчет варианта 3 не понял. Если вы предлагаете с помощью RTC и CTS останавливать передачу данных от SIM, то такой вариант плох тем, что "ОК" ждаь нельзя, так как его не будет в первых пакетах. Во-вторых обработка всех сразу СМС в цикле, подвесит модуль, пока все СМС сообщения не будут обработаны.

А никто не заставляет сразу в цикле обрабатывать.
1. Используем +CMGL чтобы узнать индекс первой необработанной СМС
2. Обязательно ждем конца листинга (OK)
3. В свободное время делаем +CMGR наденного индекса.
Yaumen
Цитата(Alechek @ Mar 2 2015, 13:39) *
А никто не заставляет сразу в цикле обрабатывать.
1. Используем +CMGL чтобы узнать индекс первой необработанной СМС
2. Обязательно ждем конца листинга (OK)
3. В свободное время делаем +CMGR наденного индекса.

Этот алгоритм сложнее для меня.
Во-первых, надо ли иметь достаточное количество памяти буфера для приема сообщения, чтобы поймав "ОК", найти первое "+CMGL:" и отпределеить его индекс. Либо налету сначала отлавливать первый "+CMGL:", определеять индекс сообщения, а затем ждать "ОК".
Во-вторых. В любом случае, приходится принимать большой фрагмент ненужного "мусора", так как все остальные принятые сообщения одновременно не будут обрабатываться, а в следующем цикле придется все повторять по новому: посылать команду CMGL и принимать повторно "мусор" только для того, чтобы узнать индекс следующего сообщения. Либо, чтобы повторно не выполнять команду CMGL, придется под нее выделить достаточно большо буфер, чтобы в ней хранился весь последний запрос, а затем его потихоньку разбирать. А это накладно для меня.

В идеале было бы здорово, если была бы команда, позволяющая вернуть индекс первого доступного сообщения или хотя бы возможность управлять командой CMGL, указывая ей, сколько сообщений я готов принять одновременно. Но таких команд вроде бы нет. Поэтому алгоритм, предложенный Baser для меня предпочтительнее. Хотя в моем случае придется перебирать 30 ячеек с SMS (такая симка попалась), для поиска не обработанного сообщения.
RadikX
Имейте в виду, встречал прошивки, где на команду AT+CMGR, у которой индекс указывает на ячейку где нет СМС возвращается не ОК с пустым ответом, а ERROR. А на некоторых симках в такой ситуации очень надолго задумывался ( чуть меньше минуты) на каждую СМС,поэтому если у вас 30 ячеек и единственная СМС лежит в последней ячейке, то считывание будет занимать более 20 минут.

Можно предложить вариант запоминание начал пакетов на лету (они все начинаются и заканчиваются символами с кодами 0x0D 0x0A) и парсить уже от них. Если даже первые считанные СМС затрутся( произойдет переполнение кольцевого буфера) то последние СМСки можно не спеша разобрать.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.