У меня дома есть телевизор с большим пультом с кучей кнопок . И приставка цифрового тв, с маленьким пультом. И DVD-плеер, с тяжелым неудобным пультом. Почитав про универсальный пульт на ардуине (там, где смартфон и блютуз участвуют), загорелся идеей сделать нечто подобное. Но по иному принципу: задействовать неиспользуемые (в обычном режиме неиспользуемые) кнопки ТВ-пульта для управления прочими устройствами. В моём случае - переключение каналов на ТВ-приставке с ТВ-пульта кнопками "вверх" и "вниз". Также управление громкостью приставки (влево и вправо) , открытие списка каналов (кнопка enter,ОК) и закрытие меню каналов (ексит). Управление DVD - используется на ТВ блок кнопок (плей стоп пауза перемотки). Принцип работы: ловим ИК-приёмником сигнал с ТВ-пульта, если нажата одна из нужных кнопок - передаём ИК-диодом код другого пульта. Нпример, поймали код "влево" от ТВ-пульта - передаём код "влево" от ТВ-приставки. Где взять коды. Отключаем (я заархивировал) библиотеку RobotIRremote. Качаем Arduino-IRremote-master.zip С библиотекой Arduino-IRremote-master идут примеры кода - берём скетч IRrecvDump, загружаем (модифицируем под свой номер вывода ИК-приёмника, у меня 2) и смотрим в мониторе порта данные (светим пультом на приёмник). Понадобится ХЕКС код кнопки (для приёма нужного сигнала) и ХЕКС-код с типом сигнала (NEC, SONY RC5 и т.п.) для передачи. Собствено, скетч (кнопки имитации DVD пока не сделаны, только ТВ-приставка) Тип кодов ТВ-пульта - RAW, приставки - NEC Код (C++): #include <IRremote.h> #include <IRremoteInt.h> /* * автор - AlexKooper * Default is Arduino pin D11. * You can change this to another available Arduino Pin. * Your IR receiver should be connected to the pin defined here */ int RECV_PIN = 2; volatile unsigned long in_signal = 0; IRrecv irrecv(RECV_PIN); decode_results results; IRsend irsend; void setup() { Serial.begin(9600); pinMode(13, OUTPUT); irsend.enableIROut(38); irrecv.enableIRIn(); // Start the receiver } void dump(decode_results *results) { // Dumps out the decode_results structure. // Call this after IRrecv::decode() int count = results->rawlen; if (results->decode_type == UNKNOWN) { Serial.print("Unknown encoding: "); } else if (results->decode_type == NEC) { Serial.print("Decoded NEC: "); } else if (results->decode_type == SONY) { Serial.print("Decoded SONY: "); } else if (results->decode_type == RC5) { Serial.print("Decoded RC5: "); } else if (results->decode_type == RC6) { Serial.print("Decoded RC6: "); } else if (results->decode_type == PANASONIC) { Serial.print("Decoded PANASONIC - Address: "); Serial.print(results->address, HEX); Serial.print(" Value: "); } else if (results->decode_type == LG) { Serial.print("Decoded LG: "); } else if (results->decode_type == JVC) { Serial.print("Decoded JVC: "); } else if (results->decode_type == AIWA_RC_T501) { Serial.print("Decoded AIWA RC T501: "); } else if (results->decode_type == WHYNTER) { Serial.print("Decoded Whynter: "); } Serial.print(results->value, HEX); Serial.print(" ("); Serial.print(results->bits, DEC); Serial.println(" bits)"); Serial.print("Raw ("); Serial.print(count, DEC); Serial.print("): "); for (int i = 1; i < count; i++) { if (i & 1) { Serial.print(results->rawbuf[i]*USECPERTICK, DEC); } else { Serial.write('-'); Serial.print((unsigned long) results->rawbuf[i]*USECPERTICK, DEC); } Serial.print(" "); } Serial.println(); } void loop() { decode_results results; if (irrecv.decode(&results)) { in_signal=results.value; Serial.println(results.value, HEX); dump(&results); if (in_signal==0xE0E006F9){ //кнопка вверх на ТВ-пульте digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) irsend.sendNEC(0x807F22DD, 32);//кнопка вверх на ТВ-приставке delay(200); digitalWrite(13, LOW); // turn the LED on (HIGH is the voltage level) in_signal=0; irrecv.enableIRIn(); // ВАЖНАЯ СТРОЧКА!!!! //ОХ ВАЖНАЯ СТРОЧКА!!!! //БЕЗ НЕЁ ПРИЁМНИК ПЕРЕСТАЁТ РАБОТАТЬ ПОСЛЕ irsend //УБИЛ НА ПОИСК ПРИЧИНЫ НЕДЕЛЮ!!!! }; if (in_signal==0xE0E08679){ //кнопка вниз digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) irsend.sendNEC(0x807F12ED, 32); delay(200); digitalWrite(13, LOW); // turn the LED on (HIGH is the voltage level) in_signal=0; irrecv.enableIRIn(); }; if (in_signal==0xE0E046B9){ //кнопка вправо digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) irsend.sendNEC(0x807F02FD, 32); delay(200); digitalWrite(13, LOW); // turn the LED on (HIGH is the voltage level) in_signal=0; irrecv.enableIRIn(); }; if (in_signal==0xE0E0A659){ //кнопка влево digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) irsend.sendNEC(0x807F32CD, 32); delay(200); digitalWrite(13, LOW); // turn the LED on (HIGH is the voltage level) in_signal=0; irrecv.enableIRIn(); }; if (in_signal==0xE0E016E9){ //кнопка центр digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) irsend.sendNEC(0x807F609F, 32); delay(200); digitalWrite(13, LOW); // turn the LED on (HIGH is the voltage level) in_signal=0; irrecv.enableIRIn(); }; if (in_signal==0xE0E0B44B){ //кнопка ексит digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) irsend.sendNEC(0x807FC03F, 32); delay(200); digitalWrite(13, LOW); // turn the LED on (HIGH is the voltage level) in_signal=0; irrecv.enableIRIn(); }; irrecv.resume(); } } Передающий диод подключен с 3 вывода (вывод 3 не задаётся в скетче, задан жестко в библиотеке) на землю. Люди делали напрямую, но я - последовательно с резистором на 100 Ом. Устройство (прототип) втыкается в разъём УСБ-флешки на лице ТВ-приставки, приёмник смотри вперёд (на зрителя), передатчик - назад, на ИК-приёмник приставки. Дополнительно факт распознавания кода (и срабатывания передатчика)подчеркивается работой зелёного диода на ардуине (встроенный, на 13 кажется выводе). Код можно оптимизировать, убрав анализ дампа и вывод в последовательный порт, но это мне не мешает пока. Готовое устройство скорее всего будет не торчать из порта УСБ, а заныкано за ТВ (запитать там есть чем), с выставленным хвостиком приёмника-передатчика. Если вообще будет сделано, устройство делал больше для практики программирования, чем для практического применения. Самая серьёзная проблема, с которйо столкнулся - после применения irsend параставал работать приём команд. Решилось вызовом irrecv.enableIRIn(); после срабатывания irsend.
Что и? Нигде не было описано решение этой проблемы, про сломавшийся приём после команды irsend. Тепероь описано. пользуйтесь.
Вопрос, копирую ваш скетч в Arduino, а оно не компиляется, вылетает с ошибкой: Arduino: 1.6.6 (Windows 7), Плата:"Arduino/Genuino Uno" sketch_jan14a:49: error: 'class decode_results' has no member named 'address' Serial.print(results->address, HEX); ^ sketch_jan14a:52: error: 'LG' was not declared in this scope else if (results->decode_type == LG) { ^ sketch_jan14a:58: error: 'AIWA_RC_T501' was not declared in this scope else if (results->decode_type == AIWA_RC_T501) { ^ sketch_jan14a:61: error: 'WHYNTER' was not declared in this scope else if (results->decode_type == WHYNTER) { ^ exit status 1 'class decode_results' has no member named 'address' Это сообщение будет содержать больше информации чем "Отображать вывод во время компиляции" включено в Файл > Настройки
По первой ошибке - случайно, не забыли убрать из библиотек RobotIRremote? она конфликтует. Я её просто заархивировал в рар. Если не помогло - дальнейшие действия. Раз ругается на 3 последних добавленых пульта - скорее всего используется более ранняя версия библиотеки. Или поискать версию библиотеки как у меня // IRremote // Version 2.0.1 June, 2015 // Copyright 2009 Ken Shirriff или для своей библиотеки, если есть примеры дампа, взять код процедуры оттуда.У меня оно лежало в у библиотеки папке examples, скетч IRrecvDump.ino Гугль говорит, что проблема может быть именно не в той версии библиотеки. Прикладываю свою. Кстати, у меня на свежей версии IDE не пошла компиляция для ардуино нано, откатился на 1.0.6 - заработало. В последней не было даже выбора, нано на 168 или 368 атмеге.