Pavel V. 0 24 января, 2012 Опубликовано 24 января, 2012 · Жалоба Всем доброго времени суток! Начал разбираться с модемом SIM900 и сейчас нахожусь на стадии написания кода для обмена данными. Интересует, как с технической точки зрения правильно организовать анализ данных, поступающих от модема. Если бы работа с модемом велась только в формате запрос-ответ, проблем нет - отправил команду, подождал ответ, разобрал его и пошел дальше. Но часть команд приходит асинхронно (звонок, смс и т.п.). Получается, необходимо организовать непрерывный прием и разбор принимаемых данных? Существует ли где-то перечень команд, которые модем может отправлять по собственной инициативе? Или может быть их можно игнорировать, пользуясь только линией RI? Как у вас организовано общение с модемом? Хотя бы в общих словах. Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 8 24 января, 2012 Опубликовано 24 января, 2012 · Жалоба Если же вы прямо в векторе приема по уарту будете проверять что приходит и парсить то грешно это. сделал так: уарт складывает принимаемые данные в свой кольцевой буфер (Б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= 0 24 января, 2012 Опубликовано 24 января, 2012 · Жалоба Очень просто. Примерно так-же как описал 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 0 25 января, 2012 Опубликовано 25 января, 2012 · Жалоба В итого получаем примерно так: А зачем так хитро делать? Почему бы +CSQ всё время не ловить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pavel V. 0 25 января, 2012 Опубликовано 25 января, 2012 · Жалоба Спасибо большое за ответы! Голова прояснилась. Изучил как следует формат данных, приходящих с модема и все встало на свои места. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=F8= 0 25 января, 2012 Опубликовано 25 января, 2012 · Жалоба А зачем так хитро делать? Почему бы +CSQ всё время не ловить? Расширяемость, быстродействие. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Romashki 0 25 января, 2012 Опубликовано 25 января, 2012 · Жалоба Подскажите, а каким образом можно проконтролировать реакцию абонента при дозвоне (отбил или "нет связи")? Имеется ввиду ситуация: набрали номер абонента (здесь по запросам можно отследить что идет дозвон), МК должен заниматься другими делами. Когда абонент отбил приходит 7\r\n или когда нет связи придет 3\r\n, но вдруг это придет в тот момент когда МК будет давать другие запросы модулю (уровень сигнала, температуры и т.д.). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pau62 0 25 января, 2012 Опубликовано 25 января, 2012 (изменено) · Жалоба Должен быть один-единственный обработчик всей той фигни, которая сыплется с модуля. Если получено NO CARRIER или BUSY, то понятно, что эти сообщения связаны именно с дозвоном. Кроме того, мерить температуру или что там еще , во время дозвона, нет никакой веской причины. Хотя если хочется - почему бы и нет. Изменено 25 января, 2012 пользователем pau62 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Romashki 0 25 января, 2012 Опубликовано 25 января, 2012 · Жалоба В том то и дело, МК проверяет во время дозвона некоторые параметры модуля и проблема, когда МК ожидает ответ на, например, AT+ADC, а модуль в это время присылает NO CARRIER например. МК в свою очередь повторит запрос но NO CARRIER уже потеряет. или имеется ввиду создать обработчик, который сравнивал бы строки (то что пришло), заведомо прописанные и выставлял просто флаги? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pau62 0 25 января, 2012 Опубликовано 25 января, 2012 · Жалоба Ну да, ждать ответа имхо можно только при начальной инициализации. При дальнейшей работе один общий обработчик ответов модема должен ничего не упуская сравнивать все ответы с шаблонами, выставлять флаги, а интересующую инфу типа уровня или текстов смс или разбирать немедленно, если быстродействие позволяет, или в специальные буфферы переписывать Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 25 января, 2012 Опубликовано 25 января, 2012 · Жалоба Когда абонент отбил приходит 7\r\n или когда нет связи придет 3\r\n Как настраивали, что модуль даёт такие ответы? но вдруг это придет в тот момент когда МК будет давать другие запросы модулю (уровень сигнала, температуры и т.д.). Запрашивать самому нужные статусы, когда это нужно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться