Перейти к содержанию
    

Обработка ответов от модема SIM900

Всем доброго времени суток!

 

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

 

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

 

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

 

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

 

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

 

Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

сделал так: уарт складывает принимаемые данные в свой кольцевой буфер (Б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 );

 

 

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

 

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очень просто. Примерно так-же как описал 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;
}

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

А зачем так хитро делать? Почему бы +CSQ всё время не ловить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо большое за ответы! Голова прояснилась. Изучил как следует формат данных, приходящих с модема и все встало на свои места.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А зачем так хитро делать? Почему бы +CSQ всё время не ловить?

Расширяемость, быстродействие.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подскажите, а каким образом можно проконтролировать реакцию абонента при дозвоне (отбил или "нет связи")?

Имеется ввиду ситуация: набрали номер абонента (здесь по запросам можно отследить что идет дозвон), МК должен заниматься другими делами. Когда абонент отбил приходит 7\r\n или когда нет связи придет 3\r\n, но вдруг это придет в тот момент когда МК будет давать другие запросы модулю (уровень сигнала, температуры и т.д.).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Должен быть один-единственный обработчик всей той фигни, которая сыплется с модуля. Если получено NO CARRIER или BUSY, то понятно, что эти сообщения связаны именно с дозвоном.

Кроме того, мерить температуру или что там еще , во время дозвона, нет никакой веской причины. Хотя если хочется - почему бы и нет.

Изменено пользователем pau62

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В том то и дело, МК проверяет во время дозвона некоторые параметры модуля и проблема, когда МК ожидает ответ на, например, AT+ADC, а модуль в это время присылает NO CARRIER например. МК в свою очередь повторит запрос но NO CARRIER уже потеряет.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Когда абонент отбил приходит 7\r\n или когда нет связи придет 3\r\n

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

 

но вдруг это придет в тот момент когда МК будет давать другие запросы модулю (уровень сигнала, температуры и т.д.).

Запрашивать самому нужные статусы, когда это нужно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...