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

Отправка начинается по команде CRWP. Отправляется первая часть:
Цитата
ebdat9_01SendToModem((u8*)"AT+CMGS=\"+XXXXXXXX\"\r",23);


Взводится флаг ожидания приглашения ">" и инициализируется счетчик SMSFlagsClear:

Цитата
if (p1==2) {//Команда CRWP = 2
SMSFlagsClear=3; WaitSMS = 1; //Сброс флагов WaitSMS и SMSReady через 9с при неответе
ebdat9_01SendToModem((u8*)"AT+CMGS=\"+79653749528\"\r",23);} //Отправляем адресат


SMSFlagsClear обрабатывается (на вычитание) в событии EVENT_TIMER (период - 3с) и при обнулении обнуляет также флаги
WaitSMS и SMSReady:

Цитата
if (SMSFlagsClear) //Обнуление флагов SMSReady и WaitSMS
SMSFlagsClear--; //по таймеру SMSFlagsClear
if (!SMSFlagsClear) {SMSReady = 0; WaitSMS = 0;}}


Флаг SMSReady устанавливается в событии EVENT_MODEMDATA при ответе приглашением ">":

Цитата
if (WaitSMS) //Если идет отправка СМС
pKey = (s8*)strstr(string,">");//pKey<>0 если есть ">"
if (pKey) {SMSReady = 1;}} //Флаг ответа модема


Т.е. - отправили первую часть, ждем приглашения, отправляем вторую часть.
В итоге получается громоздко. Может кто знает - как проще?
IvanPetrov010203
Димон,
ожидание- не лучший способ.
Все равно отправлять смс лучше дожидаясь реакции на отправку/неотправку предыдущего.
Думаю, лучший способ - это написать нормальный парсер на сообщения, принимаемые от модуля и по ним организовать finite state machine. ebdat9_03SeеModemdataToFL(TRUE); должна направить сообщения от модуля в Embedded Aplication.
Я имею в виду, что ожидание между оправками сделать не по времени, а по факту получения от модуля "+CMGS: <value>".
То же можно сделать для ожидания приглашения.

В общем, анализируйте, что присылает модем.
Отслеживайте это в EVENT_UARTDATA, и, в случае обнаружения '>' будет вызывайте ф-ю наполнения смс символами. А в случае получения другой строки (строка заканчивается символами \r\n) от модуля - поступайте как нужно..))) Например, если поймаете "+CMGS: 225\r\n", значит предыдущее сообщение отправлено и можно засылать "AT+CMGS=\"+XXXXXXXX\"\r" для отправки следующего.

Подобным образом, можно дополнить парсер для других любых сообщений, поддержав реакцию на все сообщения.

Иметь кучу флагов ожидания в программе - не лучший способ - можно запутаться, когда программа разрастется ))
Димон Безпарольный
Цитата(IvanPetrov010203 @ Mar 17 2014, 10:11) *
Димон,
ожидание- не лучший способ.
Все равно отправлять смс лучше дожидаясь реакции на отправку/неотправку предыдущего.
Думаю, лучший способ - это написать нормальный парсер на сообщения, принимаемые от модуля и по ним организовать finite state machine. ebdat9_03SeеModemdataToFL(TRUE); должна направить сообщения от модуля в Embedded Aplication.
Я имею в виду, что ожидание между оправками сделать не по времени, а по факту получения от модуля "+CMGS: <value>".
То же можно сделать для ожидания приглашения.

В общем, анализируйте, что присылает модем.
Отслеживайте это в EVENT_UARTDATA, и, в случае обнаружения '>' будет вызывайте ф-ю наполнения смс символами. А в случае получения другой строки (строка заканчивается символами \r\n) от модуля - поступайте как нужно..))) Например, если поймаете "+CMGS: 225\r\n", значит предыдущее сообщение отправлено и можно засылать "AT+CMGS=\"+XXXXXXXX\"\r" для отправки следующего.

Подобным образом, можно дополнить парсер для других любых сообщений, поддержав реакцию на все сообщения.

Иметь кучу флагов ожидания в программе - не лучший способ - можно запутаться, когда программа разрастется ))

Ожидание - не лучший способ, точно. Куча флагов мне тоже не нравится, хотя приложение там не зацикливается. Описание функции ebdat9_03SeеModemdataToFL(TRUE); не нашел, пользуюсь ebdat9_03SetModemdataToFL(TRUE);

Именно она мне и возвращает приглашение ">", которое я в первом случае отслеживаю флагами, а во втором - жду. Написать нормальный парсер пока не могу. Мозгов не хватает.

IvanPetrov010203
Очепятался я)
С EmbeddedAT и его API я дела пока не имел, предыдущее сообщение настрочил, бегло пробежавшись по мануалу.
Идея все-же следующая: собираем то, что присылает модем, складываем в строку, анализируем строку (если есть символ '>', то получили приглашение, если "...\r\n" - от получили законченный ответ от модуля), предпринимаем действия, чистим строку, в которую складывали посылки от модема...

Если анализируемая строка содержит "+CMGS:", то сообщение отправлено, можно отправлять следующее.
Димон Безпарольный
Цитата(IvanPetrov010203 @ Mar 17 2014, 12:21) *
Очепятался я)
С EmbeddedAT и его API я дела пока не имел, предыдущее сообщение настрочил, бегло пробежавшись по мануалу.
Идея все-же следующая: собираем то, что присылает модем, складываем в строку, анализируем строку (если есть символ '>', то получили приглашение, если "...\r\n" - от получили законченный ответ от модуля), предпринимаем действия, чистим строку, в которую складывали посылки от модема...

Если анализируемая строка содержит "+CMGS:", то сообщение отправлено, можно отправлять следующее.

Вроде именно так у меня и сделано:

Цитата
case EVENT_MODEMDATA:
{if(flEventBuffer.eventData.modemdata_evt.type == MODEM_CMD)
{ s8 *pKey=0;
char *string = (char *)flEventBuffer.eventData.modemdata_evt.data;
ebdat9_02SendToSerialPort(string, flEventBuffer.eventData.modemdata_evt.length);//Вывод в порт 0
//Парсер ответов модема
pKey = (s8*)strstr(string,"OK");
if (pKey) {OKFLAG = 1;} //ответа ОК
pKey = 0;
pKey = (s8*)strstr(string,"ERROR");
if (pKey) {ERRORFlag = 1;}
pKey = 0; //
IvanPetrov010203
Цитата
case EVENT_MODEMDATA:
{if(flEventBuffer.eventData.modemdata_evt.type == MODEM_CMD)
{ s8 *pKey=0;
char *string = (char *)flEventBuffer.eventData.modemdata_evt.data;
ebdat9_02SendToSerialPort(string, flEventBuffer.eventData.modemdata_evt.length);//Вывод в порт 0
//Парсер ответов модема
pKey = (s8*)strstr(string,"OK");
if (pKey) {OKFLAG = 1;} //ответа ОК
pKey = 0;
pKey = (s8*)strstr(string,"ERROR");
if (pKey) {ERRORFlag = 1;}
pKey = 0; //


добавьте анализ на "+CMGS" или "+CMGS: <value>" и оптимизируйте строковый анализатор (например, после OKFLAG =1; добавьте return; или break; если дальнейший анализ уже не имеет смысла).
Вроде, это все, что можно/нужно сделать.
Если я не ошибаюсь, memset(&flEventBuffer.eventData.modemdata_evt.data[0],'\0',EVENT_MAX_DATA); должна почистить буфер.
Димон Безпарольный
Цитата(IvanPetrov010203 @ Mar 17 2014, 13:00) *
добавьте анализ на "+CMGS" или "+CMGS: <value>" и оптимизируйте строковый анализатор (например, после OKFLAG =1; добавьте return; или break; если дальнейший анализ уже не имеет смысла).
Вроде, это все, что можно/нужно сделать.
Если я не ошибаюсь, memset(&flEventBuffer.eventData.modemdata_evt.data[0],'\0',EVENT_MAX_DATA); должна почистить буфер.

ОК. Спасибо. break; там точно не хватает...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.