Пятница, 15.12.2017, 05:34
Вы вошли как Гость | Группа "Гости"Приветствую Вас Гость | RSS
Главная | Дистанционное управление на радиомодулях - Форум | Мой профиль | Регистрация | Выход | Вход
Обитель RC-инженера
Форма входа
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 1 из 212»
Модератор форума: ВитГо 
Форум » Разработка электронных устройств » Разрабатываю ! » Дистанционное управление на радиомодулях (Система управления с обратной связью)
Дистанционное управление на радиомодулях
SergiДата: Суббота, 08.12.2012, 11:45 | Сообщение # 1
Майор
Группа: Проверенные
Сообщений: 472
Репутация: 10
Статус: Offline
Пытаюсь сделать систему управления с обратной связью на микросхемах ATMega и MRF49. Собственно односторонний канал работает. Проблема при разрешении коллизий (пропадание связи, запрос от другого устройства на пульт и пр.).
Вот схема пульта и приемника. Часть кода передачи пакета и разбора принятого пакета.
Передача:
[void rtx_pack (unsigned char ack)
{
unsigned char crc,ar1,ar2;
ar1=0xAA;
ar2=(~PINC)&0x0f;;
//ar3=read_adc(6);

crc=0x80%0x31;
crc=(crc+xas)%0x31;
crc=(crc+yas)%0x31;
crc=(crc+ar2)%0x31;
crc=(crc+ar1)%0x31;
crc=(crc+ack)%0x31;
RF12_SEND(0xAA);//PREAMBLE
RF12_SEND(0xAA);//PREAMBLE
RF12_SEND(0xAA);//PREAMBLE
RF12_SEND(0x2D);//SYNC HI BYTE
RF12_SEND(0xD4);//SYNC LOW BYTE
RF12_SEND(0x20);
RF12_SEND(0x6a);
RF12_SEND(0x80);
RF12_SEND(xas);
RF12_SEND(yas);
RF12_SEND(ar2);
RF12_SEND(ar1);
RF12_SEND(ack);
RF12_SEND(crc);
RF12_SEND(0xAA);//DUMMY BYTE
RF12_SEND(0xAA);//DUMMY BYTE
};]
Прием:
[ w0=0;w1=0;crc_in=0;
lb1: while (!(data_rf==0x2D)) {rfxx_flag=1;};
while (!(data_rf==0xD4)) {rfxx_flag=1;};
while (!(data_rf==0x20)) {rfxx_flag=1;};
while (!(data_rf==0x6A)) {rfxx_flag=1;}; // начало пакета

while (rfxx_flag) {};
inbuff[0]=data_rf,rfxx_flag=1,crc_in=inbuff[0]%0x31;
while (rfxx_flag) {};
inbuff[1]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[1])%0x31;
while (rfxx_flag) {};
inbuff[2]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[2])%0x31;
while (rfxx_flag) {};
inbuff[3]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[3])%0x31;
while (rfxx_flag) {};
inbuff[4]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[4])%0x31;
while (rfxx_flag) {};
inbuff[5]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[5])%0x31;
while (rfxx_flag) {};
inbuff[6]=data_rf,rfxx_flag=1;

if (!(inbuff[6]==crc_in)) goto lb1; //конец пакета]
Как мне восстановить связь после обрыва без зависания? Пока в приемнике выхожу по ВотчДогу, в передатчике его нет.
Прикрепления: PULT_01.dch(150Kb) · BORT_01.dch(176Kb)
 
ВитГоДата: Воскресенье, 09.12.2012, 14:30 | Сообщение # 2
Полковник
Группа: Администраторы
Сообщений: 2428
Репутация: 19
Статус: Offline
настроить сторожевой таймер и ставить флаг исполняемой операции ?
если после сброса флаг - ожидание связи - то сразу туда и идти...


Виталий (аka ВитГо)
 
SergiДата: Воскресенье, 09.12.2012, 19:23 | Сообщение # 3
Майор
Группа: Проверенные
Сообщений: 472
Репутация: 10
Статус: Offline
Я включал TIM0 на частоте 12695гц. Генерилось прерывание по переполнению с частотой 50гц. В подпрограмме разбора байта при получении сбрасывал таймер. Но чего-то все равно не заработало.
Код обработчика прерывания:

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
data_rf=0;
rfto_flag=0;
}

Код разбора:
RFXX_WRT_CMD(0x82D9);//переключаем на прием
w0=0;w1=0;crc_in=0;
rfto_flag=1;
TCNT0=0x00;
while (!(data_rf==0x2D)&&(rfto_flag)) {rfxx_flag=1;};
TCNT0=0x00;rfto_flag=1;
while (!(data_rf==0xD4)&&(rfxx_flag)) {rfxx_flag=1;};
TCNT0=0x00;rfto_flag=1;
while (!(data_rf==0x6A)&&(rfxx_flag)) {rfxx_flag=1;};
TCNT0=0x00;rfto_flag=1;
while (!(data_rf==0x20)&&(rfxx_flag)) {rfxx_flag=1;}; // начало пакета
TCNT0=0x00;rfto_flag=1;

while (rfxx_flag&&rfto_flag) {};
TCNT0=0x00;rfto_flag=1;
inbuff[0]=data_rf,rfxx_flag=1,crc_in=inbuff[0]%0x31;
while (rfxx_flag&&rfto_flag) {};
TCNT0=0x00;rfto_flag=1;
inbuff[1]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[1])%0x31;
while (rfxx_flag&&rfto_flag) {};
TCNT0=0x00;rfto_flag=1;
inbuff[2]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[2])%0x31;
while (rfxx_flag&&rfto_flag) {};
TCNT0=0x00;rfto_flag=1;
inbuff[3]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[3])%0x31;
while (rfxx_flag&&rfto_flag) {};
TCNT0=0x00;rfto_flag=1;
inbuff[4]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[4])%0x31;
while (rfxx_flag&&rfto_flag) {};
TCNT0=0x00;rfto_flag=1;
inbuff[5]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[5])%0x31;
while (rfxx_flag&&rfto_flag) {};
TCNT0=0x00;rfto_flag=1;
inbuff[6]=data_rf,rfxx_flag=1;

if (!(inbuff[6]==crc_in))
{for(i=0;i<7;i++) inbuff[i]=0;}; //конец пакета
И здесь если контрольная сумма не совпала пакет обнуляется. Потом проверяю inbuff[0]. Если "0"-> ошибка, если "80"-> посылка верная.


Сообщение отредактировал Sergi - Воскресенье, 09.12.2012, 19:33
 
ВитГоДата: Воскресенье, 09.12.2012, 21:02 | Сообщение # 4
Полковник
Группа: Администраторы
Сообщений: 2428
Репутация: 19
Статус: Offline
как то ты влоб пишешь :-( может подумать над конечным автоматом ?

Виталий (аka ВитГо)
 
SergiДата: Воскресенье, 09.12.2012, 23:41 | Сообщение # 5
Майор
Группа: Проверенные
Сообщений: 472
Репутация: 10
Статус: Offline
Разобрался немного. Опечатка была. Перепутал флаги. Хорошо что сообщения на дисплей можно выводить!
Теперь можно пробовать связать по времени.
Автомат здоровый получается. Это только кусок. У меня 1 мастер и 4 слейва, причем по прерываниях на слейвах они к мастеру должны вне очереди достучаться. Без постоянного опроса наверно не получиться, а это энергия батареи!

Добавлено (09.12.2012, 23:41)
---------------------------------------------
Не хотят они дружить!
А можно в прерывании дополнительный буфер заполнять, а потом его разбирать?
Вот здесь я получаю байт и сбрасываю флаг:
interrupt [EXT_INT0] void ext_int0_isr(void)
{
data_rf=(char)((RFXX_WRT_CMD(0xB000))&0x00FF);
rfxx_flag=0;
}
А если насобирать здесь 16 байт, а потом их проверить в основной программе?

 
ВитГоДата: Понедельник, 10.12.2012, 07:24 | Сообщение # 6
Полковник
Группа: Администраторы
Сообщений: 2428
Репутация: 19
Статус: Offline
угу, именно так и нужно делать...

только нужно наверное буфер объявить как volatile


Виталий (аka ВитГо)
 
SergiДата: Вторник, 18.12.2012, 20:37 | Сообщение # 7
Майор
Группа: Проверенные
Сообщений: 472
Репутация: 10
Статус: Offline
Это наподобие буфера USART. Вечерком посмотрю, где-то был подробный разбор процедуры обмена.

Добавлено (10.12.2012, 23:41)
---------------------------------------------
Что то не разберусь. В описании fifo буферов указывается - средняя скорость выборки больше средней скорости записи.
Это как раз не мой вариант. У меня наоборот: данные могут валиться в буфер в любой момент (и много разных), а я их буду разбирать в определенное время. То есть часть данных потеряется. Соответственно алгоритм на подобие PING работать не будет. Я хотел так: отправил команду - получил ответ, отправил следующую. Только отправка у меня примерно 10 раз в секунду и не зависит от принятия ответа.
Прямую передачу осилил, а телеметрию получить не могу sad .
Вот тело борта, работает и с получением телеметрии и отбрасыванием:
while (1)
{
w0=0;w1=0;crc_in=0;
lb1: while (!(data_rf==0x2D)) {rfxx_flag=1;};
while (!(data_rf==0xD4)) {rfxx_flag=1;};
while (!(data_rf==0x20)) {rfxx_flag=1;};
while (!(data_rf==0x6A)) {rfxx_flag=1;}; // начало пакета

while (rfxx_flag) {};
inbuff[0]=data_rf,rfxx_flag=1,crc_in=inbuff[0]%0x31;
while (rfxx_flag) {};
inbuff[1]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[1])%0x31;
while (rfxx_flag) {};
inbuff[2]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[2])%0x31;
while (rfxx_flag) {};
inbuff[3]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[3])%0x31;
while (rfxx_flag) {};
inbuff[4]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[4])%0x31;
while (rfxx_flag) {};
inbuff[5]=data_rf,rfxx_flag=1,crc_in=(crc_in+inbuff[5])%0x31;
while (rfxx_flag) {};
inbuff[6]=data_rf,rfxx_flag=1;

if (!(inbuff[6]==crc_in)) goto lb1; //конец пакета
#asm("wdr")

// обработка пакета

direct=inbuff[1];
speed=inbuff[2];
if (direct>=0x10) PORTD.7=0,PORTB.0=1;
else PORTB.0=0,PORTD.7=1;
PORTC&=~0x3C;
PORTC|=(inbuff[3])<<2;
if (speed>=0x10) PORTC.1=0,PORTD.4=1;
else PORTD.4=0,PORTC.1=1;
OCR0A=((abs(0x10-direct))<<4)+1;OCR0B=((abs(0x10-speed))<<4)+1;
sost=inbuff[0]+1;

// отправляем обратно телеметрию

RFXX_WRT_CMD(0x8239);//переключить на передачу
delay_ms(10);
rtx_pack (0x20);
RFXX_WRT_CMD(0x82D9);//переключаем на прием

};
Может у меня приемник не успевает обратку обработать?

Добавлено (18.12.2012, 20:37)
---------------------------------------------
Разбирался с пультом. Похоже не работает передатчик на борту. В mrf49 есть вывод уровня сигнала радиочастоты, и вот пульт не видит передачу от борта и выходит по таймауту. Разбираюсь дальше.

 
ВитГоДата: Среда, 19.12.2012, 06:33 | Сообщение # 8
Полковник
Группа: Администраторы
Сообщений: 2428
Репутация: 19
Статус: Offline
а я взял на ебай модули на 2.4 ггц... причем удалось выиграть аукцион и мне 2 модуля обошлись в 2.35 $...
правда еще не пришли...

кстати по твоим модулям есть у дихалта тема http://forum.easyelectronics.ru/


Виталий (аka ВитГо)
 
SergiДата: Понедельник, 24.12.2012, 21:51 | Сообщение # 9
Майор
Группа: Проверенные
Сообщений: 472
Репутация: 10
Статус: Offline
Снова танцы с бубном. Переписал инициализацию из рабочих примеров. Работа модулей не изменилась. С пульта передаю команды, управляю моторами и прочим. Назад не получаю ответ. Спасая нервы, поменял местами радиомодули. Результат тот-же.
За одно проверил дальность. На частоте 868Мгц при скорости 4800 кбит передача шла на расстоянии более 150 метров (дальше визуально не разглядеть) на четвертьволновой кусок провода.
Прикрепил исходники, работающие на данный момент. Программа немного исправлена из-за изменений в схеме.
Прикрепления: Radio_mrf49.zip(308Kb)


Сообщение отредактировал Sergi - Понедельник, 24.12.2012, 22:04
 
ВитГоДата: Среда, 26.12.2012, 18:29 | Сообщение # 10
Полковник
Группа: Администраторы
Сообщений: 2428
Репутация: 19
Статус: Offline
может быть нужно перед сменой направления выполнить инициализацию ?

Виталий (аka ВитГо)
 
SergiДата: Среда, 26.12.2012, 21:36 | Сообщение # 11
Майор
Группа: Проверенные
Сообщений: 472
Репутация: 10
Статус: Offline
Пробовал, не помогло. Осталось добавлять задержки. Наверно кто-то не успевает.
 
ВитГоДата: Среда, 26.12.2012, 21:46 | Сообщение # 12
Полковник
Группа: Администраторы
Сообщений: 2428
Репутация: 19
Статус: Offline
а эти модули "трансиверы" ?

если да - то точно нужно добавлять задержки, и возможно дублировать передачу.. (например передавать информацию дважды\трижды) чтобы гарантировано она была принята


Виталий (аka ВитГо)
 
SergiДата: Пятница, 28.12.2012, 10:47 | Сообщение # 13
Майор
Группа: Проверенные
Сообщений: 472
Репутация: 10
Статус: Offline
Это трансиверы. Я передаю на борт 4 пакета в секунду. При скорости 4800 б/с длина пакета 30 мс. Потом переключение и возврат. Всего 70 мс. Но не принимаю ничего. Нужно еще один модуль запустить для слежения за эфиром и выводом на ком-порт. Будем искать! biggrin
 
ВитГоДата: Пятница, 28.12.2012, 11:36 | Сообщение # 14
Полковник
Группа: Администраторы
Сообщений: 2428
Репутация: 19
Статус: Offline
может быть после переключения еще паузу сделать в 4 пакета и только потом передавать в обратном направлении?

Виталий (аka ВитГо)
 
ВитГоДата: Четверг, 03.01.2013, 23:21 | Сообщение # 15
Полковник
Группа: Администраторы
Сообщений: 2428
Репутация: 19
Статус: Offline
где схема регулятора коллекторного двигателя ?

Виталий (аka ВитГо)
 
Форум » Разработка электронных устройств » Разрабатываю ! » Дистанционное управление на радиомодулях (Система управления с обратной связью)
Страница 1 из 212»
Поиск:


Copyright MyCorp © 2017
Сделать бесплатный сайт с uCoz