Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Обработка ответов от модема SIM900
Форум разработчиков электроники ELECTRONIX.ru > Интерфейсы > Форумы по интерфейсам > Сотовая связь и ее приложения
Pavel V.
Всем доброго времени суток!

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

Если бы работа с модемом велась только в формате запрос-ответ, проблем нет - отправил команду, подождал ответ, разобрал его и пошел дальше. Но часть команд приходит асинхронно (звонок, смс и т.п.). Получается, необходимо организовать непрерывный прием и разбор принимаемых данных?

Существует ли где-то перечень команд, которые модем может отправлять по собственной инициативе?

Или может быть их можно игнорировать, пользуясь только линией RI?

Как у вас организовано общение с модемом? Хотя бы в общих словах.

Спасибо!
megajohn
Если же вы прямо в векторе приема по уарту будете проверять что приходит и парсить то грешно это.

сделал так: уарт складывает принимаемые данные в свой кольцевой буфер (Б1)
Приложение, ответсвенное за модем, имеет собсвенный линейный буфер (Б2) и проверяет наличие данных в приемном буфере и забирает по одному. Как только поймали '\n' то обработка приема Б2 и указать что складывать данные в начале Б2.

по \n стоит парсер на флаги то есть:

if( memcmp( rx_buff, "OK\r\n", 4 ) == 0 ) { history_flag( mdm_tx_ok, set ); return; }
if( memcmp( rx_buff, "ERROR\r\n", 6 ) == 0 ) { history_flag( mdm_tx_error, set ); return; }
if( memcmp( rx_buff, "+CME ERROR:", 11 ) == 0 ) { history_flag( mdm_tx_error_cme, set ); return; }
if( memcmp( rx_buff, "+CMS ERROR:", 11 ) == 0 ) { history_flag( mdm_tx_error_cms, set ); return; }
if( memcmp( rx_buff, "#CGSN: ", 7 ) == 0 ) { history_flag( mdm_tx_cgsn_imei, set ); extract_add_func( mdm_tx_cgsn_imei ); return; }
if( memcmp( rx_buff, "+CLIP:", 6 ) == 0 ) { history_flag( mdm_tx_clip, set ); extract_add_func( mdm_tx_clip ); return; }
if( memcmp( rx_buff, "+CMTI:", 6 ) == 0 ) { history_flag( mdm_tx_cmti, set ); extract_add_func( mdm_tx_cmti ); return; }

флаги это биты в u32

и весь алгоритм тупо

if( retval == at_ok ) retval = at_send( SET_CMD_ECHO_MODE_EXEC_OFF, mdm_tx_ok, mdm_tx_error, 1000, 10, 1000 );
if( retval == at_ok ) retval = at_send( SET_FIXED_LOCAL_RATE_115200 );
if( retval == at_ok ) retval = at_send( SET_REPORT_MOBILE_ERROR );
if( retval == at_ok ) retval = at_send( SELECT_INTERFACE_STYLE );


всё что выше от что для симкома что для телита.




=F8=
Очень просто. Примерно так-же как описал megajohn только с маленькой поправкой. В потоке который читает порт обрабатываем только необходимые незапрашиваемые коды и стандартные ответы, для обработки ответов спецефических для консретной команды добавляем указатель на функцию обработчик. В итого получаем примерно так:
Код
void *p_data = NULL;
void (*p_func)(char*, void*) = NULL;
BOOL buffer[BUFFER_SIZE+1];


void Parcer(char *buff)
{
   if(strcmp(buf, "OK")==0){....}
   else if(strcmp(buf, "ERROR")==0){....}
   else if(strncmp(buf, "+CME ERROR", 10)==0){....}
   ........................................................
  else if(p_func)if(p_func(buf, p_data)) p_func = NULL;//Тут обрабатываем спецефические ответы
}


BOOL csq_cb(char *buf, void *p)
{
  int *res = (int*)p;
  if(strncmp(buf, "+CSQ", 4)
  {//Обрабатываем ответ +CSQ.....
   .....................
   res=xxxx;
   return TRUE;
  }
  return FALSE;
}

int GetCSQ()
{
    int res = -1;
    p_data = &res;
    p_func = csq_cb;
    if(PutCommand("AT+CSQ", 1000)==OK_RES)//Отправляем команду AT+CSQ и ждем ответа OK или ERROR
   {
      p_func = NULL;
      return res;
   }
   p_func = NULL;
   return -1;
}


andrewlekar
Цитата
В итого получаем примерно так:

А зачем так хитро делать? Почему бы +CSQ всё время не ловить?
Pavel V.
Спасибо большое за ответы! Голова прояснилась. Изучил как следует формат данных, приходящих с модема и все встало на свои места.
=F8=
Цитата(andrewlekar @ Jan 25 2012, 10:11) *
А зачем так хитро делать? Почему бы +CSQ всё время не ловить?

Расширяемость, быстродействие.
Romashki
Подскажите, а каким образом можно проконтролировать реакцию абонента при дозвоне (отбил или "нет связи")?
Имеется ввиду ситуация: набрали номер абонента (здесь по запросам можно отследить что идет дозвон), МК должен заниматься другими делами. Когда абонент отбил приходит 7\r\n или когда нет связи придет 3\r\n, но вдруг это придет в тот момент когда МК будет давать другие запросы модулю (уровень сигнала, температуры и т.д.).
pau62
Должен быть один-единственный обработчик всей той фигни, которая сыплется с модуля. Если получено NO CARRIER или BUSY, то понятно, что эти сообщения связаны именно с дозвоном.
Кроме того, мерить температуру или что там еще , во время дозвона, нет никакой веской причины. Хотя если хочется - почему бы и нет.
Romashki
В том то и дело, МК проверяет во время дозвона некоторые параметры модуля и проблема, когда МК ожидает ответ на, например, AT+ADC, а модуль в это время присылает NO CARRIER например. МК в свою очередь повторит запрос но NO CARRIER уже потеряет.

или имеется ввиду создать обработчик, который сравнивал бы строки (то что пришло), заведомо прописанные и выставлял просто флаги?
pau62
Ну да, ждать ответа имхо можно только при начальной инициализации. При дальнейшей работе один общий обработчик ответов модема должен ничего не упуская сравнивать все ответы с шаблонами, выставлять флаги, а интересующую инфу типа уровня или текстов смс или разбирать немедленно, если быстродействие позволяет, или в специальные буфферы переписывать
_Артём_
Цитата(Romashki @ Jan 25 2012, 13:42) *
Когда абонент отбил приходит 7\r\n или когда нет связи придет 3\r\n

Как настраивали, что модуль даёт такие ответы?

Цитата(Romashki @ Jan 25 2012, 13:42) *
но вдруг это придет в тот момент когда МК будет давать другие запросы модулю (уровень сигнала, температуры и т.д.).

Запрашивать самому нужные статусы, когда это нужно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.