реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Передача информации с помощью ИК, необходимо передавать 4 команды с одного контроллера на другой
eugmai86
сообщение Mar 20 2011, 15:15
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737



Доброго времени суток.
Пытаюсь передавать 4 команды от одного контроллера к другому. МК 1 Трансивер Tiny 13, приемник tiny2313. Передать одну команду(внешнее прерывание в тини) не проблема, все работает. А вот никак не могу разобраться с алгоритмом и его реализацией для нескольких команд.
Для передатчика использую следующий алгоритм:
Если нажата кнопка 1
-передаю 5 раз 20 импульсов с паузой 260мкс после каждого импульса
Если нажата кнопка 2
-передаю 10 раз 20 импульсов с паузой 260мкс после каждого импульса
...
Если нажата кнопка 4
-передаю 20 раз 20 импульсов с паузой 260мкс после каждого импульса


Приемник должен гонять таймер с частотой самого длинного импульса, в моем случае 26мкс(время 1 импульса)*20(кол-во пульсаций)*20(раз передается импульс)+260мкс(задержка после каждой пачки импульсов)*20(пачек импульсов)=15,6 мс. Что равно 64 Гц (если я не ошибаюсь).

В момент когда нажата кнопка на передатчике, на приемнике срабатывает внешнее прерывание

interrupt [EXT_INT0] void ext_int0_isr(void)
{
TCNT0=0xF0; //запускаем таймер 64 Гц, время самого длинного импульса
TCCR0B=0x04;

}

И в этот момент мне нужно посчитать сколько же было послано пачек 5,10, 15, или 20. Как не знаю. Застрял. Помогите. Может быть есть стандартные библиотеки для МК на этот случай.
Пишу в CVAVR
Go to the top of the page
 
+Quote Post
kovigor
сообщение Mar 20 2011, 16:05
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(eugmai86 @ Mar 20 2011, 18:15) *
И в этот момент мне нужно посчитать сколько же было послано пачек 5,10, 15, или 20. Как не знаю. Застрял. Помогите. Может быть есть стандартные библиотеки для МК на этот случай.
Пишу в CVAVR


Очень просто. Цифровой автомат.
Состояние S0: приемник ждет прерывания. При получении прерывания приемник переходит в S1
Состояние S1: приемник принимает импульсы (первые пять). При получении первых 5-ти импульсов, если через заданное время больше импульсов принято не было, то приемник считает, что это команда из пяти импульсов и переходит в S0. Если же импульсы были, то приемник переходит в S2.
Состояние S2: приемник принимает импульсы (очередные пять). При получении очередных 5-ти импульсов, если через заданное время больше импульсов принято не было, то приемник считает, что это команда из десяти импульсов и переходит в S0. Если же импульсы были, то приемник переходит в S3. И так далее.

Но так делать не надо. Почему бы просто не передавать команды по UART, защищая каждую команду (например, такую: "CMD1", "CMD2", ...) байтом CRC8 (или словом CRC16, или CRC32) ? Просто, стандартно, длина команды всегда постоянна, легко добавлять новые команды, реализаций CRC готовых масса ...

Сообщение отредактировал kovigor - Mar 20 2011, 16:07
Go to the top of the page
 
+Quote Post
eugmai86
сообщение Mar 20 2011, 16:40
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737



Дело в том, что у тини 13 нет UART

Т.е. если есть внешнее прерывание вызывается ф-ция обработки, она же считает сколько было изменений на ноге контроллера.
А как правильно таймер запустить чтоб он стартовал с начала сигнала и останавливался по переполнению, а не стартовал при каждом прерывании как у меня. Только не отправляйте в даташит, читал много раз и внимательно. Просто некому один раз в живую объяснить. Спасибо
char tick=0;
interrupt [EXT_INT0] void ext_int0_isr(void)
{
TCNT0=0xF0; //запускаем таймер 64 Гц, время самого длинного импульса
TCCR0B=0x04;
tick++;
}
void tick_calc (void)
{
if (0<<=5)
{
//do smth1
TCNT0=0x00; //останавливаю таймер
TCCR0B=0x00;
tick=0;//сбрасываю тики
}
...
if (15<tick<=20)
{
//do smth4
TCNT0=0x00; //останавливаю таймер
TCCR0B=0x00;
tick=0;
}
}
Go to the top of the page
 
+Quote Post
SKov
сообщение Mar 20 2011, 16:44
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 812
Регистрация: 22-01-05
Из: SPb
Пользователь №: 2 119



Цитата(eugmai86 @ Mar 20 2011, 18:15) *
-передаю 5 раз 20 импульсов с паузой 260мкс после каждого импульса
...
26мкс(время 1 импульса)

Уточните, плз, чем вы принимаете такой затейливый ИК-сигнал.
Go to the top of the page
 
+Quote Post
eugmai86
сообщение Mar 20 2011, 16:49
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737



На Tiny2313 включено внешнее прерывание на INT0, на эту ногу повешен выход TSOP4838
Go to the top of the page
 
+Quote Post
Xecutor
сообщение Mar 20 2011, 17:01
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 57
Регистрация: 31-10-10
Пользователь №: 60 558



ИК-сигнал не очень стабильная среда передачи информации. Вы уверенны, что вам не требуется подтверждения приёма команд со стороны приёмника?
Ну и может стоит обратить внимание на "старые" проверенные протоколы для ПДУ бытовой техники или расширить их введя избыточность данных.
Go to the top of the page
 
+Quote Post
eugmai86
сообщение Mar 20 2011, 17:07
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737



Прикрепленный файл  IRDA.zip ( 4.77 килобайт ) Кол-во скачиваний: 106
На данном этапе обратная связь не требуется, смотрел образцы для NEC и Sony(см приложение). Так и не смог разобраться. Опыта маловато.
Go to the top of the page
 
+Quote Post
SKov
сообщение Mar 20 2011, 18:15
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 812
Регистрация: 22-01-05
Из: SPb
Пользователь №: 2 119



Цитата(eugmai86 @ Mar 20 2011, 19:49) *
На Tiny2313 включено внешнее прерывание на INT0, на эту ногу повешен выход TSOP4838


Тогда у вас, возможно, не очень четко написано в посте. Надо передавать импульсы 26мкс с интервалом 26мкс и передавать не менее десяти импульсов (лучше 20 импульсов). А вот уже после такой пачки можно делать перерыв. Или не делать. У вас так и сделано?
Go to the top of the page
 
+Quote Post
eugmai86
сообщение Mar 20 2011, 18:35
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737



Прикрепленный файл  main.zip ( 1.46 килобайт ) Кол-во скачиваний: 124
Смотрите в приложении. Или часть кода тут:
#define IR_LED PORTB.0
volatile bit button_pressed1, button_pressed2, button_pressed3, button_pressed4; //флаг
void press_key (void)
{ char i;
for(i=0;i<=19;i++)//пачка из 30 импульсов
{
delay_us(13);// почти меандр 38кГц
IR_LED=1;
delay_us(13);
IR_LED=0;
};
delay_us(260);//та самая пауза,
};
Дальше в main:
if (PINB.1 == 0 && button_pressed1 == 0) //Если нажата кнопка 1
{
char k;
for (k=0;k<5;k++)
{
press_key();
};
button_pressed1 = 1;

}
...
if (PINB.4 == 0 && button_pressed4 == 0) //Если нажата кнопка 4
{
char k;
for (k=0;k<20;k++)
{
press_key();
};
button_pressed4 = 1;

}
if (PINB.4 == 1) button_pressed4 = 0; //сбрасываем флаг

Получается я передаю 30 импульсов а за ними пауза.
Go to the top of the page
 
+Quote Post
kovigor
сообщение Mar 20 2011, 19:34
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(eugmai86 @ Mar 20 2011, 22:35) *
Получается я передаю 30 импульсов а за ними пауза.


Я бы смотрел в сторону RC5. Все это уже давно разработано и испытано. А ваш метод никуда не годится. Один импульс пропал - и всей передаче крышка ...

http://digit-el.com/files/open/rc5/rc5.html

P.S. А передатчик UART элементарно реализуется чисто программно на любой из ножек любого из портов ...

Сообщение отредактировал kovigor - Mar 20 2011, 19:36
Go to the top of the page
 
+Quote Post
SKov
сообщение Mar 20 2011, 19:39
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 812
Регистрация: 22-01-05
Из: SPb
Пользователь №: 2 119



Цитата(eugmai86 @ Mar 20 2011, 21:35) *
Получается я передаю 30 импульсов а за ними пауза.

Ну значит в этом месте все правильно. Только паузу между пачками лучше побольше раза в два-три.
Я бы посоветовал кодировать кнопки интервалами между пачками.
Go to the top of the page
 
+Quote Post
eugmai86
сообщение Mar 20 2011, 20:22
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737



Так всеже как правильно таймер запустить чтоб он стартовал с начала сигнала и останавливался по переполнению, а не стартовал при каждом прерывании. Вопрос то по сути не сложный, недавно програмирую, мало что знаю поэтому и спрашиваю.
Нужно при появлении низкого уровня (внешнее прерывание) посчитать кол-во импульсов. Какие импульсы, их длины все написал, подскажите как. Я знаю что есть RC-5 RC-6 еще вагон протоколов, но ведь требуется передать 4 (четыре) команды а не 20.
Go to the top of the page
 
+Quote Post
SKov
сообщение Mar 20 2011, 20:45
Сообщение #13


Знающий
****

Группа: Свой
Сообщений: 812
Регистрация: 22-01-05
Из: SPb
Пользователь №: 2 119



Цитата(eugmai86 @ Mar 20 2011, 23:22) *
Так всеже как правильно таймер запустить чтоб он стартовал с начала сигнала и останавливался по переполнению, а не стартовал при каждом прерывании. Вопрос то по сути не сложный, недавно програмирую, мало что знаю поэтому и спрашиваю.
Нужно при появлении низкого уровня (внешнее прерывание) посчитать кол-во импульсов. Какие импульсы, их длины все написал, подскажите как. Я знаю что есть RC-5 RC-6 еще вагон протоколов, но ведь требуется передать 4 (четыре) команды а не 20.

Не морочьте себе голову с протоколами. В вашем описании немного сбивает с толку, что вы называете импульсами и короткие импульсы на выходе ИК-передатчика и сигналы на выходе ИК-приемника. У приемника на выходе уже имульсы, примерно совпадающие с длительностью пачки из 30коротких импульсов.
Теперь относительно измерения интервала времени между пачками. (Это я предполагаю, что вы вняли моему предложению кодировать кнопки интервалами между пачками.) При поступлении пачки у вас происходит прерывание. Вы должны в подпрограмме обработки перерывания проверить состояние таймера, который заполняется импульсами от основного ТГ контроллера (через прескалер, если он там есть - точно не помню). Тут времянку надо аккуратно посчитать, чтобы таймер не переполнялся при самом большом интервале меду пачками. Дальше, вы посмотрели на содержимое таймера и решили, какая кнопка нажата. После этого вы обнуляете таймер и выходите из прерывания. До прихода следующей пачки. Для пущей надежности окончательное решение о нажатой кнопке можно принимать, когда накопилось три (или пять) одинаковых решений относительно кнопки (я предполагаю, что пачек за время нажатия кнопки уйдет не менее 5-ти).
Как-то так. А с вашей программой вряд ли кто будет подробно разбираться. Ну, если у кого совсем много свободного времени. wink.gif
Go to the top of the page
 
+Quote Post
eugmai86
сообщение Mar 20 2011, 20:55
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737



ясно, спасибо. тут еще порекомендовали попробовать без таймера. просто считать сколько прерывание случилось. разбираюсь. спасибо
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 21:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01472 секунд с 7
ELECTRONIX ©2004-2016