реклама на сайте
подробности

 
 
> SIM900R как правильно отправлять СМС?, Сделал. Работает, но хотелось бы посоветоваться.
Димон Безпарольн...
сообщение Mar 16 2014, 03:23
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Идея в том, чтобы не вешать процесс намертво ожиданиями.

Отправка начинается по команде 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;}} //Флаг ответа модема


Т.е. - отправили первую часть, ждем приглашения, отправляем вторую часть.
В итоге получается громоздко. Может кто знает - как проще?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 6)
IvanPetrov010203
сообщение Mar 17 2014, 07:11
Сообщение #2





Группа: Новичок
Сообщений: 7
Регистрация: 14-01-14
Пользователь №: 80 035



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

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

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

Иметь кучу флагов ожидания в программе - не лучший способ - можно запутаться, когда программа разрастется ))
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Mar 17 2014, 08:13
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(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);

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

Go to the top of the page
 
+Quote Post
IvanPetrov010203
сообщение Mar 17 2014, 09:21
Сообщение #4





Группа: Новичок
Сообщений: 7
Регистрация: 14-01-14
Пользователь №: 80 035



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

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

Сообщение отредактировал IvanPetrov010203 - Mar 17 2014, 09:23
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Mar 17 2014, 09:35
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(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; //


Сообщение отредактировал Димон Безпарольный - Mar 17 2014, 09:36
Go to the top of the page
 
+Quote Post
IvanPetrov010203
сообщение Mar 17 2014, 10:00
Сообщение #6





Группа: Новичок
Сообщений: 7
Регистрация: 14-01-14
Пользователь №: 80 035



Цитата
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, 10:04
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Mar 17 2014, 10:10
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(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; там точно не хватает...

Сообщение отредактировал Димон Безпарольный - Mar 17 2014, 10:10
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 22:50
Рейтинг@Mail.ru


Страница сгенерированна за 0.01728 секунд с 7
ELECTRONIX ©2004-2016