Страница 1 из 2

режим PDU и отработка команд

Добавлено: Чт апр 23, 2009 11:57:31
shtorm
Привет всем котам!
стал разбираться в связке (Mega8+SiemensC35)(CodeVision) все вродебы ничего но...непонятны некоторые моменты:

как отрабатывать команду от модема? (только PDU)
вот например читаю смс (терминал)

Код: Выделить всё

+CMGR: 0,,25
07918350000005F1040C9183503032687000009040321174022106537A985E9F03
из этого всего мне надо всеголишь

Код: Выделить всё

06537A985E9F03
т.е. сам текст сообщения, как его оттуда выдрать? как хранить весь ответ от модема в массиве? если просто загнать его в массив с помощью getchar() там будут все данные или только первая строка?

Добавлено: Чт апр 23, 2009 18:57:29
_PM_
Зачем хранить весь ответ. Сделайте хотя б конечный автомат. Нужный
кусок лейте в буфер. В смысле я про то что бывает целесообразней
проводить некоторую алгоритмизацию до этапа ввода.

Добавлено: Чт апр 23, 2009 19:04:44
Aheir
Это отчасти зависит от того, как настроен Ваш приемник. Если работатете по прерыванию, то как правило при этом организуют еще и приемный буфер некоторой конечной длины. Соответственно, сообщение не может быть длиннее этого буфера. Вообще, возможны варианты. Разбор такого рода "посланий"! часто называют "парсинг", поищите, пожет поможет чем-то..

Добавлено: Чт апр 23, 2009 19:07:40
_PM_
Афтор 8), выложите сюда принцип разбора ответа - может поможем с парсингом на лету.

Добавлено: Чт апр 23, 2009 19:50:42
shtorm
задумка такова:
при получении смс с текстом status будем формировать новую смс с данными с датчиков(для начала класический термометр)...и отсылать смс тому кто прислал смс с словом status, с формированием смс вроде как разобрался как разобрать входящий смс тоже принцип понятен а вот как припрут данные точнее как их правильн опринять чтобы отработать нужные участки? по поводу парсинга поищу..спасиб за подсказку

P.S. принимаю не по прерыванию, просто prin=getchar(); в безконечном цикле. других методов незнаю :oops:

Добавлено: Чт апр 23, 2009 21:08:17
_PM_
А.. тогда понятно. Хранить ЭТО не надо - достаточно просто конечного автомата.

Вот псевдокод для понимания (на жабе)/ смысл в нехранении строк.
А в хранении состояния конечного автомата. Ну думаю смысл понятен.

class Parser {

int state = 0;

void parse(char c) {
if (state == 0) {
state = (c == 'S') ? : 1 : 0;
return;
}
if (state == 1) {
state = (c == 'T') ? : 2 : 0;
return;
}
if (state == 2) {
state = (c == 'A') ? : 3 : 0;
return;
}
if (state == 3) {
state = (c == 'T') ? : 4 : 0;
return;
}
if (state == 4) {
state = (c == 'U') ? : 5 : 0;
return;
}
if (state == 5) {
state = (c == 'S') ? : 6 : 0;

if (status == 6) send();
}

}

void send() {
// todo
// create response
}
}

Добавлено: Чт апр 23, 2009 23:26:46
shtorm
_PM_ ну вобщем теоритически я понял что имееться ввиду. в принцепе тоже самое что и предлогал тов. Aheir , а вот как это организовать в CVAVR ?? какие регистры юзать? данные ведь прут сразу пачкой, поочередной переход не получится (((

Добавлено: Пт апр 24, 2009 05:56:07
_PM_
Ну уж извиняйте. От Си у меня изжога. На ассемблере пожалуйста - помогу.
Поочередного перехода не надо - только одну таблицу переходов и 1 регистр для
хранения состояния (можно 1-ну ячейку памяти)

Добавлено: Пт апр 24, 2009 05:56:57
_PM_
storm - киньте побольше информации, что откуда и как. 8)

Добавлено: Пт апр 24, 2009 08:24:10
asteroid7
shtorm
PDU формат парсят только мазохисты.
Считывайте SMS в текстовом режиме. Если нужна кириллица - используйте UCS2 формат.

Добавлено: Пт апр 24, 2009 09:18:32
shtorm
asteroid7 мой модем(Siemens C35) не потдерживает текстовый режим.

смысл в том чтобы при запросе устройство присылало температуру с датчика...так вот для того чтоб разобрать запрос нужно смотреть смски...и только в PDU как выглядят уже писал. мк с телефоном связал, мк нормально отправляет команды, телефон понимает, звонит, а вот обратная связь...тот то и проблема...ну с командами короткими то еще можно просто getchar(); вроде как работает...а вот смс...
putsf("AT");
printf("%c",enter);
prin=getchar();
отправка команды и сходу прием...короткие ответы вроде ловит...но чую это неправльно ))

Добавлено: Пт апр 24, 2009 12:36:06
shtorm
я понял свою проблему: немогу принять несколько байт...как это сделать? поискал по сети нашел такой алгоритм:
while (1)
{

for(i=0;i<RX_BUFFER_SIZE;i++){
buff = getchar();
}
{

но он чет не работает, для проверки отправляю с другого мк команду:
putsf("1");
putsf("2");
putsf("3");
putsf("4");
printf("%c",enter);


пробывал и так:
putsf("1234");
printf("%c",enter);


ловлю только первый байт тобишь "1" остальные ячейки массива остаються пустыми,UART настроен с буфером по приему на 8байт, я думаю если разобраться с этим то можно поставить фильтр на приеме что сохранять а что нет...тобишь парсинг если я правильно понял.

Добавлено: Пт апр 24, 2009 20:32:50
asteroid7
shtorm писал(а):asteroid7 мой модем(Siemens C35) не потдерживает текстовый режим.
...
упс... глянул AT документацию. Вот "семёны" халтурщики. Команда есть - реализации нет. Неважно, что модем старый. Не ожидал от них такого.

Добавлено: Вс апр 26, 2009 19:43:43
Aheir
Я вот сам сейчас тем же занят, пока не знаю, как по-нормальному разбирать PDU - уж очень не хочется в дебри лезть.
Мне данные передавать не требуется, только события, так что думаю использовать DTMF-сигналы..

Добавлено: Вс апр 26, 2009 21:24:47
shtorm
сделал так:
выкинул весь текст который сгенерил CVAVR относительно буферизации и вписал туда свой:
interrupt [USART_RXC] void usart_rx_isr(void)
{
char data;
data=UDR;
ovt++;
if(ovt==19){ //когда будит 19 прерываний
start=1; //запускаем заполнение массива
ovt=0; //обнуляем счетчик прерываний
etap++; //выставляем этап1 т.е. загрузка в массив номера тел отправителя
}

if(UDR==10){ //кодга придет код "новая строка" обнуляем счетчики
ovt=0;
i=0;
}
if(start==1){ //начинаес загрузку в массив
buff=data;
i++;

if((i==16&etap==1)||(i==14&etap==2)){ //для №тел 16 значений, для самого смс 14 символов
i=0;
if(etap==1){
strcpy(inc_tel,buff); //копируем с буфера в основной массив (№тел)
}else{
strcpy(inc_sms,buff); //выгребаем с буфера сам текст смс
}
etap=0;
start=0;
ovt=0;
}

}

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

Добавлено: Пн апр 27, 2009 20:19:01
shtorm
вопрос решен, всем спасибо

Добавлено: Вт апр 28, 2009 21:17:43
Aheir
так поделились бы уж, с широкой-то общественностью.. :)

Добавлено: Ср апр 29, 2009 08:08:40
shtorm
...не вопрос 8)
interrupt [USART_RXC] void usart_rx_isr(void)
{

data=UDR;
ovt++;

if(flag==1){
if(ovt==46){
start=1;
}
if(start==1){
buff=data;
i++;
if(i==16){
strcpy(inc_tel,buff);
start=0;
i=0;
flag=2;
}
}
}//flag==1

if(flag==2){
if(ovt==80){
start=1;
}
if(start==1){
buff=data;
i++;
if(i==16){
strcpy(inc_sms,buff);
start=0;
i=0;
flag=3;
ovt=0;
}
}
}//flag==2

if(flag==3){
buff=data;
i++;
if(i==n){
strcpy(state,buff);
i=0;
flag=3;
ovt=0;
}
}



}

\

код не совсем оптимизирован...но почемуто работает только так...хотя кто поскажет как упростить то скажу спасибо ))))

в режиме ожидания flag=3; и n=18, для приема всех данных с порта, т.е. начиная с первого байта и 18шт и сравниваю с статичным массивом
и если это команда о входящем смс то выставляем flag=1 и читаем смс...ну вобщем по коду я думаю понятно...

Добавлено: Ср июл 29, 2009 15:21:22
Krik99
Кто подскажет как лутче принимат ответ на команды OK\ERROR, просто не хочеться изобритать велосипед. Через прерывания по RX ??

Добавлено: Чт июл 30, 2009 10:47:59
Krik99
Что, никто не принимает данные от телефона?