|
SIM900R как правильно отправлять СМС?, Сделал. Работает, но хотелось бы посоветоваться. |
|
|
|
Mar 16 2014, 03:23
|
Знающий
   
Группа: Участник
Сообщений: 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;}} //Флаг ответа модема Т.е. - отправили первую часть, ждем приглашения, отправляем вторую часть. В итоге получается громоздко. Может кто знает - как проще?
|
|
|
|
|
 |
Ответов
(1 - 6)
|
Mar 17 2014, 07:11
|
Группа: Новичок
Сообщений: 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" для отправки следующего.
Подобным образом, можно дополнить парсер для других любых сообщений, поддержав реакцию на все сообщения.
Иметь кучу флагов ожидания в программе - не лучший способ - можно запутаться, когда программа разрастется ))
|
|
|
|
|
Mar 17 2014, 08:13
|
Знающий
   
Группа: Участник
Сообщений: 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); Именно она мне и возвращает приглашение ">", которое я в первом случае отслеживаю флагами, а во втором - жду. Написать нормальный парсер пока не могу. Мозгов не хватает.
|
|
|
|
|
Mar 17 2014, 09:21
|
Группа: Новичок
Сообщений: 7
Регистрация: 14-01-14
Пользователь №: 80 035

|
Очепятался я) С EmbeddedAT и его API я дела пока не имел, предыдущее сообщение настрочил, бегло пробежавшись по мануалу. Идея все-же следующая: собираем то, что присылает модем, складываем в строку, анализируем строку (если есть символ '>', то получили приглашение, если "...\r\n" - от получили законченный ответ от модуля), предпринимаем действия, чистим строку, в которую складывали посылки от модема...
Если анализируемая строка содержит "+CMGS:", то сообщение отправлено, можно отправлять следующее.
Сообщение отредактировал IvanPetrov010203 - Mar 17 2014, 09:23
|
|
|
|
|
Mar 17 2014, 09:35
|
Знающий
   
Группа: Участник
Сообщений: 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
|
|
|
|
|
Mar 17 2014, 10:00
|
Группа: Новичок
Сообщений: 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
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|