Работа с ИК пультом.
- Войдите на сайт для отправки комментариев
Вс, 26/06/2011 - 18:11
Всем привет.
Пытаюсь програмировать прием ИК пачек с пульта ДУ , но появилась проблема.
Вот такой код (для одной кнопки ) работает нормально.
Последовательный прием каждого импульса , после приема последнего инвертируем состояние пина.
Вообще то в пачке 13 импульсов , но мне хватает приема 6.
unsigned long val=0; void setup() { pinMode(7,INPUT);//сюда подключен TSOP pinMode(13,OUTPUT); } void loop() { val=pulseIn(7,LOW); val=(val/1000); if(val==2) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==1) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { digitalWrite(13,!digitalRead(13)); delay(200); } } } } } } }
Эта прграмма работает нормально , но когда я пытаюсь увеличить количество кнопок
(просто размножив блоки кода и вставив соответствующие длины импульсов)
программа начинает работать некоректно (срабатывает раза с десятого , иногда вообще не срабатывает).
Почему так происходит и что с этим делать ?
Вот вторая программа.
unsigned long val=0; void setup() { pinMode(7,INPUT); pinMode(13,OUTPUT); pinMode(12,OUTPUT); pinMode(11,OUTPUT); pinMode(10,OUTPUT); pinMode(9,OUTPUT); pinMode(8,OUTPUT); } void loop() { val=pulseIn(7,LOW); val=(val/1000); if(val==2) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==1) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { digitalWrite(10,!digitalRead(10)); delay(200); } } } } } } //*****************************************************8 val=pulseIn(7,LOW); val=(val/1000); if(val==2) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { digitalWrite(13,!digitalRead(13)); delay(200); } } } } } } //*****************************************************8 val=pulseIn(7,LOW); val=(val/1000); if(val==2) { val=pulseIn(7,LOW); val=(val/1000); if(val==1) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { digitalWrite(11,!digitalRead(11)); delay(200); } } } } } } //***************************************************** val=pulseIn(7,LOW); val=(val/1000); if(val==2) { val=pulseIn(7,LOW); val=(val/1000); if(val==1) { val=pulseIn(7,LOW); val=(val/1000); if(val==1) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { val=pulseIn(7,LOW); val=(val/1000); if(val==0) { digitalWrite(9,!digitalRead(9)); delay(200); } } } } } } //******************************************************** }
Думаю дело вот в чем. Допустим ты нажал кнопку чтобы выполнился второй блок программы (который 13-м пином управляет). Пошел первый импульс (который 2000 или больше микродекунд), а перехватил его первый блок, строка 21 условие же верно выполняется, потом пошел второй импульс, строка 25 условие опять верно выполняется, третий импульс не прокатывает, программа перестает делать дальнейшую проверку и нужная комбинация импульсов не отработала. Дальше если кнопка нажата, пульт ДУ повторно посылает пачку импульсов, опять пошел импульс 2000 микросекунд, а перехватывает его, допустим, третий блок. И так будет до тех пор, пока не произойдет одновременное выполнение программы в строке 77 и приход первого (2000 микросекунд) импульса для второго блока.
Придумал только менять делитель для каждой кнопки , чтобы получать совершенно разные числа .
Попробовал две кнопки - вроде работает.
Да можно проще сделать. Например вот так:
val=pulseIn(7,LOW);
val=(val/1000);
if(val==2) //пришел первый импульс 2000 мкс
{
val2=pulseIn(7,LOW); // записываем в val2 продолжительность второго импульса
val3=pulseIn(7,LOW); // записываем в val3 продолжительность третьего импульса
val4=pulseIn(7,LOW); // и т.д.
val5=pulseIn(7,LOW);
val6=pulseIn(7,LOW);
// здесь проверяем значения val2 - val6 и выполняем нужные действия
}
Не совсем понял. Каким образом проверить заначения пяти переменных одновременно ?
Извиняюсь за глупый вопрос.
Вот так действительно лучше . Спасибо.
Нее, опять не правильно, опять два блока. Должен быть один блок. Например так:
...
val2=val2/1000;
val3=val3/1000;
val4=val4/1000; // в переменных val2 - val6 получаем 1 или 0
val5=val5/1000;
val6=val6/1000;
// дальше можно воспользоваться фуцкцией bitWrite()
//объявим переменную z
byte z = 0;
bitWrite(z, 0, val2); //установим нулевой бит переменной z в значение val2 (0 или 1)
bitWrite(z, 1, val3); //установим первый бит переменной z в значение val3 (0 или 1)
bitWrite(z, 2, val4); // и так далее
bitWrite(z, 3, val5);
bitWrite(z, 4, val6);
// теперь переменная z содержит число в зависимости от значений val2 - val6
// т.е. если val2 - val6 были равны еденицам то получам число B11111100 (вроде так) это в двоичном виде, а в десятичном 252
//если же, например, переменная val4 была равна 0 то z будет B1101100 в двоичном виде, а в десятичном 108
//ну а дальше в зависимомти от значения z выполняем нужные действия
}
а не проще использовать уже готовое решение? IRemote http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
Вот последний твой вариант программы почти правильно написан. Только после строки 39 надо вставить строки 60 - 64 (код же в переменных сохранен), а то что ниже убрать. И так для каждой кнопки на пульте.
Я вот тоже озадачился управлением по ИК. В частности, при достижении в комнате указанной температуры - включать кондиционер.
IRemote - библиотека классная, примеры расписаны хорошо. Но вот как реализовать добавление нового пульта? В библиотеке есть готовые обработчики для брендов Sony, NEC, RC5/6 и собственно всё.
При посылке команды с пульта (кондиционер, не "брендовый" Dantex), соответственно, получаю массив. При попытке отправить его Ардуиной в "кондей" - реакции ноль. При этом музыкальный центр Sony - реагирует на команды Ардуины чётко.
Где "собака порылась"? Никто не пробвал "клонировать" пульт с помощью этой библиотеки?
Клонировать пульт нужно не с помощью библиотеки , а просто читать импульсы и отправлять их в COM .
А потом програмировать МК на прием этих пакетов импульсов.
Я делал так . Все работало.
Клонировать пульт нужно не с помощью библиотеки , а просто читать импульсы и отправлять их в COM .
А потом програмировать МК на прием этих пакетов импульсов.
Я делал так . Все работало.
А можно какой-нибудь пример, в качестве how to? Руководство к действию так сказать?
вот пример - хоуту: freeduino.ru/forum/viewtopic.php
Проще некуда.
Естественно эти импульсы считываются с TSOPа
Получается, что на выходе в serial (в переменной val) получаем длину импульса?
Да , если импульс один.
Получаем длины импульсов (пачка) , если это заводской пульт.
Аналогично можно мерить расстояние между импульсами.
Меняем pulseIn(7, LOW);
на pulseIn(7, HHIGH);