Ардуино: инфракрасный пульт и приемник

Инфракрасный пульт дистанционного управления — один из самых простых способов взаимодействия с электронными приборами. Так, практически в каждом доме есть несколько таких устройств: телевизор, музыкальный центр, видеоплеер, кондиционер. Но самое интересное применение инфракрасного пульта — дистанционное правление роботом. Собственно, на этом уроке мы попытаемся реализовать такой способ управления с помощью популярного контроллера Ардуино Уно.

1. ИК-пульт

Что нужно для того, чтобы научить робота слушаться инфракрасного (ИК) пульта? Во-первых, нам потребуется сам пульт. Можно использовать обычный пульт от телевизора, а можно приобрести миниатюрный пульт от автомагнитолы. Именно такие пульты часто используются для управления роботами. Инфракрасный пульт На таком пульте есть 10 цифровых кнопок и 11 кнопок для манипуляции с музыкой: громкость, перемотка, play, stop, и т.д. Для наших целей более чем достаточно.

2. ИК-датчик

Во-вторых, для приема сигнала с пульта нам потребуется специальный ИК-датчик. Вообще, мы можем детектировать инфракрасное излучение обычным фотодиодом/фототранзистором, но в отличие от него, наш ИК-датчик воспринимает инфракрасный сигнал только на частоте 38 кГц (иногда 40кГц). Именно такое свойство позволяет датчику игнорировать много посторонних световых шумов от ламп освещения и солнца. Для этого урока воспользуемся популярным ИК-датчиком VS1838B, который обладает следующими характеристиками:
  • несущая частота: 38 кГц;
  • напряжение питания: 2,7 — 5,5 В;
  • потребляемый ток: 50 мкА.
Можно использовать и другие датчики, например: TSOP4838, TSOP1736, SFH506.

3. Подключение

Датчик имеет три вывода (три ноги). Если посмотреть на датчик со стороны приёмника ИК сигнала, как показано на рисунке,
  • то слева будет — выход на контроллер,
  • по центру — отрицательный контакт питания (земля),
  • и справа — положительный контакт питания (2.7 — 5.5В).
Принципиальная схема подключения ardu-ir_схема Внешний вид макета ardu-ir_bb

4. Программа

Подключив ИК-датчик будем писать программу для Ардуино Уно. Для этого воспользуемся стандартной библиотекой IRremote, которая предназначена как раз для упрощения работы с приёмом и передачей ИК сигналов. С помощью этой библиотеки будем принимать команды с пульта, и для начала, просто выводить их в окно монитора последовательного порта. Эта программа нам пригодится для того, чтобы понять какой код дает каждая кнопка.
#include "IRremote.h"

IRrecv irrecv(2); // указываем вывод, к которому подключен приемник

decode_results results;

void setup() {
  Serial.begin(9600); // выставляем скорость COM порта
  irrecv.enableIRIn(); // запускаем прием
}

void loop() {
  if ( irrecv.decode( &results )) { // если данные пришли
    Serial.println( results.value, HEX ); // печатаем данные
    irrecv.resume(); // принимаем следующую команду
  }
}
Загружаем программу на Ардуино. После этого, пробуем получать команды с пульта. Открываем монитор последовательного порта (Ctrl+Shift+M), берём в руки пульт, и направляем его на датчик. Нажимая разные кнопочки, наблюдаем в окне монитора соответствующие этим кнопкам коды. ir-sensor Проблема с загрузкой программы В некоторых случаях, при попытке загрузить программу в контроллер, может появиться ошибка: TDK2 was not declared In his scope Чтобы ее исправить, достаточно удалить два файла из папки библиотеки. Заходим в проводник. Переходим в папку, где установлено приложение Arduino IDE (скорее всего это «C:\Program Files (x86)\Arduino»). Затем в папку с библиотекой: …\Arduino\libraries\RobotIRremote , и удаляем файлы: IRremoteTools.cpp и IRremoteTools.h. Затем, перезапускаем Arduino IDE, и снова пробуем загрузить программу на контроллер.

5. Управляем светодиодом с помощью ИК-пульта

Теперь, когда мы знаем, какие коды соответствуют кнопкам пульта, пробуем запрограммировать контроллер на зажигание и гашение светодиода при нажатии на кнопки громкости. Для этого нам потребуется коды (могут отличаться, в зависимости от пульта):
  • FFA857 — увеличение громкости;
  • FFE01F — уменьшение громкости.
В качестве светодиода, используем встроенный светодиод на выводе №13, так что схема подключения останется прежней. Итак, программа:
#include "IRremote.h"

IRrecv irrecv(2); // указываем вывод, к которому подключен приемник

decode_results results;

void setup() {
  irrecv.enableIRIn(); // запускаем прием
}

void loop() {
  if ( irrecv.decode( &results )) { // если данные пришли
    switch ( results.value ) {
    case 0xFFA857:
        digitalWrite( 13, HIGH );
        break;
    case 0xFFE01F:
        digitalWrite( 13, LOW );
        break;
    }    
    irrecv.resume(); // принимаем следующую команду
  }
}
Загружаем на Ардуино и тестируем. Жмем vol+ — светодиод зажигается. Жмем vol- — гаснет. Теперь, зная как это все работает, можно вместо светодиода управлять двигателями робота, или другими самодельными микроэлектронными устройствами!
3+

Изменено:

Ардуино: инфракрасный пульт и приемник: 53 комментария

  1. Во-первых спасибо за пример!
    но он не работал у меня(

    пришлось его доделать=)

    #include «IRremote.h»

    IRrecv irrecv(2); // указываем вывод, к которому подключен приемник

    decode_results results;
    int Relay = 4;

    void setup()
    {
    pinMode(Relay, OUTPUT);
    irrecv.enableIRIn(); // запускаем прием
    }
    void loop() {
    if ( irrecv.decode( &results )) { // если данные пришли
    switch ( results.value ) {
    case 0x40BF807F:
    digitalWrite( Relay, HIGH );
    break;
    case 0x40BF40BF:
    digitalWrite( Relay, LOW );
    break;
    }
    irrecv.resume(); // принимаем следующую команду
    }
    }

    6+
  2. Большое спасибо за познавательный урок, я бы хотел попросить вас усложнить задачку и сделать при помощи ШИМ плавное вкл/откл светодиода. Спасибо!

    3+
    • Дополнить программу кодом в данном месте (для увеличения яркости)
      case 0xFFA857:
      // например
      int val = 0;
      val += 50; // значение может быть любым
      // или val++; для более плавного перехода
      if (val > 255) val = 255
      analogWrite( 13, val );
      break;

      4+
          • Нужно подключать к выходам с ШИМ (PWM)

            2+
      • У вас ошибка в коде. При таком алгоритме значение val всегда будет 50, так как постоянно при нажатии на кнопку пульта у вас будет переопределяться переменная val. Во избежание этого следует добавить слово «static» к типу данных val.

        3+
  3. Подключил как в гайде, но все равно не работает( Имею в виду что монитор не показывает что я нажал пультом) но это не такой пульт как в этом гайде. В чем может быть проблема?

    2+
    • Скетч залился успешно, без ошибок? Причины могут быть разные. Например, пульт дает сигнал на частоте 40КГц, а приемник скорее всего 38КГц.

      2+
      • Я пробовал и таким же пультом и пультом от телевизора все работает. Посмотри все ли у тебя подключено правильно.

        3+
  4. А почему на схеме и на внешнем виде макета отличается подключение выводов? На схеме у вас (слева направо) идёт земля выход вход, а на макете земля вход выход.

    Я просмотрел уже несколько сайтов по подключению этого приёмника — везде подключают по разному, у одних левый вывод это выход, у других земля. Чепуха какая-то.

    2+
    • Спасибо за замечание! Оказалось, что в редакторе схем fritzing ИК-датчик отображается неверно. Заменили на правильный вариант. Теперь всё как надо. Если не заработает, ищите проблему в другом.

      2+
  5. Я пишу скетч на управление сервой с помощью ик приёмника и вылетает ошибка:
    ‘results’ was not declared in this scope

    Скетч:
    #include
    #include
    #include

    Servo MyServo;

    IRrecv irrecv(2);

    void setup() {
    Serial.begin(9600);
    irrecv.enableIRIn(); // запускаем прием
    MyServo.attach(4);

    }

    void loop() {
    if ( irrecv.decode( &results )) {
    switch ( results.value ) {
    case 0xFFA25D:
    MyServo.write(0);
    break;
    case 0xFF629D:
    MyServo.write(90); //поворот на 90 градусов
    break;
    }
    irrecv.resume(); // принимаем следующую команду
    }

    1+
  6. Спасибо за пример! Заработал с первого раза. Очень доходчиво и просто. Спасибо.

    1+
  7. Добрый день!

    Использовал скетчи из этой темы для того, что бы сделать лазертаг мишень: принимает ИК сигнал выстрела, загорается и гаснет, но вот какие вопросы:
    1. Как только программа загружается в Ардуино — диод горит сразу.
    2. Что надо сделать, что бы принял сигнал — моргнул 500 мсек — погас?

    #include «IRremote.h»

    IRrecv irrecv(2); // указываем вывод, к которому подключен приемник

    decode_results results;

    void setup() {
    Serial.begin(9600); // выставляем скорость COM порта
    irrecv.enableIRIn(); // запускаем прием
    pinMode(3, OUTPUT);
    }

    void loop() {
    if ( irrecv.decode( &results )) { // если данные пришли
    switch ( results.value ) {
    case 0x2FD58A7:
    digitalWrite ( 3, HIGH );
    delay (10);
    case 0x2FDD827:
    digitalWrite ( 3, LOW);
    delay (100);
    }
    Serial.println( results.value, HEX ); // печатаем данные
    irrecv.resume(); // принимаем следующую команду
    }

    }

    1+
  8. Автору респект.
    Alexandr, отдельная благодарность.
    Светодиод горел на авторском скетче вполнакала,
    с Вашей поправкой все заработало отлично.

    1+
  9. Добрый день.
    Не подскажете, в чем может быть проблема?
    #include «IRremote.h»
    void setup() {}
    void loop(){}
    Не компилируется:
    IRremote.h: No such file or directory

    Спасибо.

    1+
  10. Использую код из ваших примеров, но среда упорно пишет «Ошибка компиляции для платы Arduino/Genuino Uno». Никаких подробностей не указано больше. В чем проблема может быть?

    0
    • Бывает такое при подключении платы с уже запущенным приложением Arduino IDE. Закрой ИДЕшку, извлеки провод, с помощью которого прошиваешь плату, запусти ИДЕ, подключи плату(ардуинку). PROFIT

      0
  11. Добрый день? возможно ли подключить к uno серво шилд и wi-fi шилд? если нет, то какой вариант возможен?

    0
  12. извините,но в вашем коде какая то фигня… Вставте ваш код в word и вы поймёте.

    0
  13. собрал все по схеме светодиодом моргать получается а когда вместо светодиода цепляю реле неработает

    0
    • Скорее всего тока не хватает для управления реле.
      Какое реле подключаете?

      1+
  14. Доброго времени суток!
    Господа, я новичок в освоении Ардуино, Но!
    Получаю команды с пульта всегда в двух числах, исходя из этого
    хотел бы спросить профессионалов — Почему 2 цифры?
    Как я понял одна из них и есть код сигнала, а вторая преселектор (т.е доп сигнал, для считывания нажатия комбинации кнопок в момент времени),.
    Так, как в моем случае, мне нужна быстрая реакция на нажатие, я включил их в обработку
    Пример ниже…

    Текст Кода

    #include «IRremote.h»

    IRrecv irrecv(2); // указываем вывод, к которому подключен приемник

    decode_results results;

    void setup() {
    pinMode(13,OUTPUT);
    pinMode(12,OUTPUT);
    Serial.begin(9600); // выставляем скорость COM порта
    irrecv.enableIRIn(); // запускаем прием
    }

    void loop() {
    if ( irrecv.decode( &results )) { // если данные пришли
    Serial.println( results.value ); // печатаем данные

    if (results.value ==32||results.value==2080)
    {
    digitalWrite( 13, HIGH );
    }
    if (results.value ==33||results.value==2081)
    {
    digitalWrite( 13, LOW );
    }
    if (results.value ==17||results.value==2065)
    {
    digitalWrite( 12, HIGH );
    }
    if (results.value ==16||results.value==2064)
    {
    digitalWrite( 12, LOW );
    }
    irrecv.resume(); // принимаем следующую команду
    }
    }

    0
    • Какая ошибка? case неверный? Допишите перед вашим значением кода 0x Например case 0xCE1972FD

      1+
  15. Почему приёмник иногда пишет в консоль разные коды на одну и ту же кнопку? Как эти коды можно контролировать в понятный для Android вид чтобы создать программный пульт?

    1+
    • ТЫ НА ПУЛЬТЕ НАЖИМАЕШЬ РАЗНЫЕ КНОПКИ ПРОСТО СМОТРИ НА ПУЛЬТ И НАЖИМАЙ НОГТЕМ НА ОДНУ КНОПКУ НЕ УДЕРЖИВАЯ ПРИМЕРНО МЕНЬШЕ СЕКУНДЫ!

      2+
  16. ГДЕ ВЫ ПОКАЗАЛИ КАК ПОДКЛЮЧАТЬ ИК ДАТЧИК ТАМ НЕ ПРАВИЛЬНО МОЖНО БЫЛО ПОДКЛЮЧИТЬ НА 3 ВОЛЬТА А МОТОР НА 5 ИЛИ НА СЕМЬ ВОЛЬТ МЕНЬШЕ ПЯТИ ВОЛЬТ МОТОРУ НЕ ХВАТАЕТ МОЩНОСТИ!

    1+
  17. Если использовать в одном скрипте + tone для пищалки, то вылетает ошибка
    >>
    Arduino: 1.8.8 (Windows XP), Плата:»Arduino/Genuino Uno»
    Tone.cpp.o (symbol from plugin): In function `timer0_pin_port’:
    (.text+0x0): multiple definition of `__vector_7′
    libraries\IRremote\IRremote.cpp.o (symbol from plugin):(.text+0x0): first defined here
    collect2.exe: error: ld returned 1 exit status
    exit status 1
    Ошибка компиляции для платы Arduino/Genuino Uno.
    <<
    Куда копать?

    1+
    • Функция tone () использует таймер 2, который по умолчанию IRremote также использует при использовании чипа ATmega2560.
      В файле IRremoteInt.h вы можете определить, какой таймер использовать. Или скачайте библиотеку TonePlayer

      1+
  18. копировал, поменял на сигнал для своего пульта, закинул, выдает
    Arduino: 1.8.9 Hourly Build 2019/03/18 11:33 (Windows 10), Плата: «Arduino BT, ATmega328P»

    Скетч використовує 6502 байтів (22%) місця зберігання для програм. Межа 28672 байтів.
    Глобальні змінні використовують 236 байтів (11%) динамічної пам’яті, залишаючи 1812 байтів для локальних змінних. Межа 2048 байтів.
    avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x78
    avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x86
    avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x60
    avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x66
    avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x86
    avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x78
    avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x06
    avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x18
    avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x60
    avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xe6
    Сталася помилка при вивантаженні скетча

    Цей звіт міститиме більше інформації, якщо
    в меню Файл -> Налаштування увімкнути опцію
    «Показати докладний звіт при компіляції».

    0
    • Судя по ошибке, Arduino IDE не может залить скетч на плату по каким-то причинам. При этом скетч скомпилирован, к программе уже претензий нет. Проверьте кабель, подключение. Может загрузчик слетел с ардуины, такое тоже бывает.

      1+

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.