Здравствуйте! Вопрос такой, как сделать, чтобы при получении конкретных команд включались светодиоды на пинах ардуино?ардуина принимает и распознаёт сигналы пульта. То есть напрмер кнопка "вкл" расшифровыется - 502A0540 а кнопка off - F0FE1FC3 Полученные значения свободно выводяся в ком порт Вот нашел аналогичный вопрос, но ответа на него так и не нашел: http://arduino.ru/forum/programmirovanie/vypolnit-komandy-s-ik-pulta Пробовал через оператор If ничего не выходит =( вот код: Код (Text): volatile unsigned long IR_KEY; //код кнопки на пульте void setup() { Serial.begin(9600); pinMode(2, INPUT); // ИК приемник подключим сюда IR_KEY = 0; attachInterrupt(0,IRinterrupt,FALLING); // назначим прерывание } void loop() { if(IR_KEY) { Serial.println(IR_KEY,HEX); //выводим код в терминал. IR_KEY = 0; } } /* обработчик прерывания*/ void IRinterrupt(){ static unsigned long key, prevTime; unsigned long currTime, d; currTime = micros(); d = currTime - prevTime; if(d < 1100) return; // "дребезг" if(d < 1400){ // "0" key = key << 1; prevTime = currTime; return; } if(d < 2400){ // "1" key = key << 1; key++; prevTime = currTime; return;} if(d < 13000) IR_KEY = key; // код кнопки получен prevTime = currTime; }
Ну вы верно мыслите, сравнивайте IR_KEY с известными кодами через if-else или switch-case и прописывайте реакции на команды. Код (Text): switch (IR_KEY) { case 0x502A0540UL: { // turn LED on break; } case 0xF0FE1FC3UL: { // turn LED off break; } default: { // reaction for unknown code break; } } Единственная проблема здесь, поскольку платформа программно 16-разрядная (а аппаратно вообще 8-разрядная), то для обработки 32-разрядных чисел возможно что-то придется подкорректировать.
Должен, должен получиться if: Код (Text): void loop() { if (!IR_KEY) { return; } // пусть, если кнопка не известна включается // светодиод на пине 13 int ledToLightUp = 13; if (IR_KEY == 0x502A0540) ledToLightUp = 12; else if (IR_KEY == 0xF0FE1FC3) ledToLightUp = 11; digitalWrite(ledToLightUp, HIGH); Serial.println(IR_KEY,HEX); //выводим код в терминал. IR_KEY = 0; } Ясна ли идея?
Спасибо большое за ответ. Я попробовал вот так: Код (Text): volatile unsigned long IR_KEY; //код кнопки на пульте int ledPin = 11; int ledPin2 = 13; void setup() { pinMode(ledPin, OUTPUT); pinMode(ledPin2, OUTPUT); Serial.begin(9600); pinMode(2, INPUT); // ИК приемник подключим сюда IR_KEY = 0; attachInterrupt(0,IRinterrupt,FALLING); // назначим прерывание } void loop() { if(IR_KEY) { Serial.println(IR_KEY,HEX); //выводим код в терминал. IR_KEY = 0; } } /* обработчик прерывания*/ void IRinterrupt(){ static unsigned long key, prevTime; unsigned long currTime, d; currTime = micros(); d = currTime - prevTime; if(d < 1100) return; // "дребезг" if(d < 1400){ // "0" key = key << 1; prevTime = currTime; return; } if(d < 2400){ // "1" key = key << 1; key++; prevTime = currTime; return;} if(d < 13000) IR_KEY = key; // код кнопки получен prevTime = currTime; if (!IR_KEY) { return; } // пусть, если кнопка не известна включается // светодиод на пине 13 int ledToLightUp = 13; if (IR_KEY == 0x502A0540) ledToLightUp = 12; else if (IR_KEY == 0xF0FE1FC3) ledToLightUp = 11; digitalWrite(ledToLightUp, HIGH); Serial.println(IR_KEY,HEX); //выводим код в терминал. IR_KEY = 0; } При нажатии 13 пин светится, аналогично при нажатии кнопки off светится светодиод на пине 11. Но оба они еле светят.
Еле светят — странно. Можно было бы объяснить эффектом ШИМ, но мы же их нигде не выключаем, только включаем. Уверенны, что это не аппаратная проблема? Не забыли ли для них сделать pinMode(lala, OUTPUT)? Можете в setup'е их напрямую включить и посмотреть на яркость?
Unixon, Спасибо! Очень хорошая и понятная система switch-case вот по вашему примеру: Код (Text): switch (IR_KEY) { case 0x502A0540UL: digitalWrite(ledPin,HIGH); // при нажатии на кнопку светодиод ставим в HIGH { break; } case 0xF0FE1FC3UL: digitalWrite(ledPin,LOW); // нажатием на другую кнопку светодиод выключаем { break; } default: { break; } } И еще можно подробнее о default: { break; СПАСИБО ОГРОМНОЕ ЗА ПОМОЩЬ!
Default описывает состояние, когда ни одно значение не совпадает с предлагаемыми. То есть, если сравниваемый параметр/значение не совпадает с перечисляемыми внутри оператора switch, то происходит действие по умолчанию (default), описываемое внутри самого default. Default не является обязательным, его можно опустить, тогда по умолчанию, если совпадений нет, действия не будет происходить. Иначе можно представить условным оператором и уже внутри условного оператора описывать действие в случае если совпадений не было. Но это изобретение велосипеда и нужно лишь тогда, когда надо проверить изменяемые переменные или массивы переменных. По поводу break - прерыватель/выход из цикла, то есть если конец явно не указан, то перебор будет осуществляться по всем параметрам, а не до первого совпадения.
Нет, не обязательно. Но, видите какое дело... Тут выбор то не велик: или постоянный опрос датчика (polling) или прерывания, третьего способа как то пока никто не придумал. Опрос означает либо невозможность делать что-то еще, либо вероятный пропуск команд. Прерывания в этом смысле более надежны, поскольку позволяют МК заниматься своими делами, пока от датчика ничего не приходит, но гарантируют своевременную реакцию на отслеживаемое воздействие
Ну да, иначе говоря, с прерываниями МК будет действовать с запозданием, то есть часть начальных команд он пропустит. Если опрос ведется постоянно, то МК принимает все состояния датчика с нужной нам частотой. Вот конкретно с прерыванием команды опроса датчика я себе плохо представляю, так как если импульс приходит от передатчика к приемнику а МК в этот момент его не опрашивает, а скажем просто следит за изменением напряжения на выходе датчика (что проще), то какое-то начальное количество команд он пропустит и только потом через n попыток начинает обрабатывать последовательность команд. Например, нажимаем на пульте кнопку включения 5 раз и только на 5й раз команда включения была обработана МК, так как он не опрашивал порт, а только следил за изменением напряжения, то есть напряжение изменилось, МК перешел в режим опроса.
Ровно наоборот. С прерываниями пропуск возможен только если другое прерывание происходит во время обработки первого и приоритет прерываний всего один. Вы как то не так себе обработку прерывания представляете. Как оно работает: дернулась нога - МК положил текущий адрес в стек и немедленно перешел к обработчику прерывания (который у вас тут же считывает команду с датчика) потом МК берет адрес со стека и продолжает выполнение основной программы. И так по каждому фронту импулься. С ИК приемниками разница между частотой импульсов и тактовой частотой МК такая, что ничего пропустить невозможно.
Здравствуйте! Появился вопросик как можно изменить код: Код (Text): volatile unsigned long IR_KEY; //код кнопки на пульте int ledPin = 11; int ledPin3 = 12; int ledPin2 = 13; void setup() { pinMode(ledPin, OUTPUT); pinMode(ledPin2, OUTPUT); pinMode(ledPin3, OUTPUT); Serial.begin(9600); pinMode(2, INPUT); // ИК приемник подключим сюда IR_KEY = 0; attachInterrupt(0,IRinterrupt,FALLING); // назначим прерывание } void loop() { if(IR_KEY) { Serial.println(IR_KEY,HEX); //выводим код в терминал. IR_KEY = 0; } } /* обработчик прерывания*/ void IRinterrupt(){ static unsigned long key, prevTime; unsigned long currTime, d; currTime = micros(); d = currTime - prevTime; if(d < 1100) return; // "дребезг" if(d < 1400){ // "0" key = key << 1; prevTime = currTime; return; } if(d < 2400){ // "1" key = key << 1; key++; prevTime = currTime; return;} if(d < 13000) IR_KEY = key; // код кнопки получен prevTime = currTime; // ПОЛУЧЕНИЕ КОДА С ПУЛЬТА switch (IR_KEY) { case 0x2E7265CE: digitalWrite(ledPin,HIGH); { // turn LED on break; } case 0x2E74E5CE: digitalWrite(ledPin,LOW); case 0x2E7065CE: digitalWrite(ledPin3,HIGH); { // turn LED on break; } case 0x2E7465CE: digitalWrite(ledPin3,LOW); { // turn LED off break; } { // reaction for unknown code break; } } } Цель: чтобы при зажатии кнопки светодиод светился, а как бросил сразу же погас. прошу помочь!
В обработчике прерывания если (d>=13000), т.е. код не получен, можно все выключать. Вообще, лучше всё, начиная с switch(IR_KEY), вынести в loop(). Старайтесь всегда делать обработчики прерываний максимально короткими. Добавьте что-нибудь вроде if (d>26000) IR_KEY=0; т.е. через два максимальных времени приема убираем код команды, а switch внури loop() при этом пойдет по ветке case default и внутри нее отключит индикацию.
здравствуйте, помогите реализовать вкючение выключение.. т.е. одной кнопеой включать и её же выключать... т.е. когда выключено то на другие кнопки с ик пульта чтобы не реагировал..
Зависит от пульта. Если у Вас пульт имеет на одной кнопке два кода, которые чередуются, то просто расписывайте действие для каждого кода. Если же только один, то можно воспользоваться банальным счетчиком PHP: int h; // Жмем кнопку пульта if (results.value == 66589) { h = h + 1; // к переменной "h" каждый раз, при нажатии одной кнопки, прибавляем +1 // Если нужно вернуться к первому действию при достижении последнего if (h == 2) { h = 0; // сбрасываем "h", возвращаемся в начало } } // Тут выполняем любые действия согласно нашему счетчику if (h == 0) // изначально выключено { off; } if (h == 1) // нажали кнопку - включили { on; }