ИК-пульт и ИК-приемник на Arduino

Инфракрасная (ИК) связь — это широко используемая и простая в реализации беспроводная технология, имеющая множество полезных применений. Наиболее яркими примерами в повседневной жизни являются пульты дистанционного управления телевизором, датчики движения и инфракрасные термометры.

Существует множество интересных проектов Arduino, которые также используют ИК-связь. С помощью простого ИК-передатчика и приемника вы можете создавать роботов с дистанционным управлением, датчики расстояния, мониторы сердечного ритма, пульты дистанционного управления телевизором и многое другое.

В этой статье сначала рассмотрим, что такое инфракрасное излучение и как оно работает. А затем рассмотрим, как подключить ИК-приемник к Ардуино.

Что значит инфракрасный?

Инфракрасное излучение — это форма света, похожая на тот, который мы видим вокруг себя. Единственное различие между ИК-излучением и видимым светом заключается в частоте и длине волны. Инфракрасное излучение находится за пределами диапазона видимого света, поэтому люди не могут его видеть:

Разновидности электромагнитного излучения
Рисунок 1. Разновидности электромагнитного излучения

Поскольку ИК — это тип света, ИК-связь требует прямой видимости от приемника к передатчику. Он не может передавать данные через стены или другие материалы, такие как Wi-Fi или Bluetooth.

Как работают ИК-пульты и ИК-приемники

Типичная система инфракрасной связи требует ИК-передатчика и ИК-приемника. Передатчик выглядит как стандартный светодиод, за исключением того, что он излучает свет в ИК-спектре, а не в видимом спектре. Если вы посмотрите на переднюю часть пульта телевизора, вы увидите светодиод ИК-передатчика:

IR remote control
Рисунок 2. ИК-пуль

Светодиоды такого же типа используется в модулях ИК-передатчика для Arduino. Вот один из них, KY-005:

KY-005 IR-transmitter
Рисунок 3. Модуль ИК-передатчика KY-005
IR diodes
Рисунок 4. ИК-приемники

ИК-приемник представляет собой фотодиод и предварительный усилитель, преобразующий ИК-излучение в электрический сигнал. Диоды ИК-приемника обычно выглядят следующим образом:

Можно встретить вот такой готовый модуль, KY-022:

KY-022 module
Рисунок 5. Модуль ИК-приемника KY-022

Модуляция ИК-сигнала

Инфракрасный свет излучается солнцем, лампочками и всем остальным, что выделяет тепло. Это означает, что вокруг нас много шума от инфракрасного излучения. Чтобы этот шум не мешал ИК-сигналу, используется метод модуляции сигнала.

При модуляции ИК-сигнала происходит следующее:

  • энкодер на пульте дистанционного управления преобразует двоичный сигнал в модулированный электрический сигнал;
  • этот электрический сигнал отправляется на передающий светодиод;
  • передающий светодиод преобразует модулированный электрический сигнал в модулированный ИК-световой сигнал;
  • затем ИК-приемник демодулирует ИК-световой сигнал и преобразует его обратно в двоичный формат перед передачей информации в микроконтроллер.
ИК-связь
Рисунок 6. Передача сигнала по инфракрасному каналу

Модулированный ИК-сигнал представляет собой серию импульсов инфракрасных световых импульсов, включаемых и выключаемых на высокой частоте, известной как несущая частота. Несущая частота, используемая большинством передатчиков, составляет 38 кГц, поскольку она встречается редко в природе и ее можно отличить от окружающего шума.

Диод приемника обнаруживает все частоты ИК-излучения, но он оснащен полосовым фильтром и пропускает ИК-излучение только на частоте 38 кГц. Затем он усиливает модулированный сигнал с помощью предусилителя и преобразует его в двоичный сигнал.

Протоколы ИК-передачи

Схема, по которой модулированный ИК-сигнал преобразуется в двоичный, определяется протоколом передачи. Существует множество протоколов ИК-передачи. NEC, RC5, Sony и Panasonic являются одними из наиболее распространенных протоколов.

Протокол NEC также является наиболее распространенным ИК протоколом в проектах Arduino, поэтому рассмотрим его на примере.

Логическая 1 начинается с высокого импульса (HIGH) длительностью 562,5 мкс при ИК-диапазоне 38 кГц, за которым следует низкий импульс (LOW) длительностью 1687,5 мкс.

Логический 0 передается с высоким импульсом (HIGH) длительностью 562,5 мкс, за которым следует низкий импульс (LOW) длительностью 562,5 мкс:

NEC - Logic 0 and Logic 1
Рисунок 7. Логическая 0 и логическая 1 в протоколе NEC

Так протокол NEC кодирует и декодирует двоичные данные в модулированный сигнал. Другие протоколы отличаются только длительностью отдельных импульсов HIGH и LOW.

ИК-коды

Каждый раз, когда вы нажимаете кнопку на пульте дистанционного управления, генерируется уникальный шестнадцатеричный код. Это информация, которая модулируется и передается по ИК-каналу на приемник. Чтобы расшифровать, какая кнопка нажата, принимающему микроконтроллеру необходимо знать, какой код соответствует каждой кнопке на пульте.

Разные пульты отправляют разные коды при нажатии клавиш, поэтому вам нужно будет определить код, сгенерированный для каждой клавиши на вашем пульте. Если вы сможете найти техническую документацию на пульт, то там должны быть указаны коды. Если нет, то есть простой скетч для Arduino, который считывает большинство популярных пультов и выводит шестнадцатеричные коды в монитор порта. Я покажу вам, как это настроить, через минуту, но сначала нам нужно подключить приемник к Arduino

Как подключить ИК-приемник к Arduino

Существует различные типы ИК-приемников. Лучше всего, конечно, найти техническое описание вашего конкретного ИК-приемника, поскольку контакты могут быть расположены иначе, чем у модуля ИК-приемника KY-022 (на базе HX1838) или ИК-диода TSOP312. Однако все ИК-приемники будут иметь три контакта: сигнал S, земля GND и питание Vcc.

Распиновка модуля KY-022
Рисунок 8. Модуль KY-022
Распиновка ИК-приемника TSOP312
Рисунок 9. ИК-приемник TSOP312
Распиновка HX1838
Рисунок 10. ИК-приемник HX1838

Как подключить ИК-приемник и модуль KY-022 к Arduino показано на картинках ниже:

Подключение ИК-приемника к Ардуино
Рисунок 11. Подключение ИК-приемника к Ардуино
Подключение KY-022 к Arduino
Рисунок 12. Подключение модуля KY-022 ИК-приемника к Ардуино

Модуль KY-022 это тот же ИК-диод, только дополнительно имеет токоограничивающий резистор и светодиод, который загорается при приеме сигнала.

Установка библиотеки IRremote

Как установить библиотеку можно прочитать здесь.

Скачать библиотеку можно по ссылкам:

Как считать коды вашего пульта ДУ

Чтобы найти коды кнопок для вашего пульта, загрузите этот код в Arduino и откройте последовательный монитор.

Обратите внимание!


Для версий библиотек 2.0.1 и 4.2.0 код будет отличаться.

Код для версии 2.0.1 библиотеки IRremote

#include <IRremote.h>           // Подключаем библиотеку

const int RECV_PIN = 7;         // Сигнальный вывод, подключенный к Ардуино
IRrecv irrecv(RECV_PIN);        // Создаем объект 
decode_results results;         // Объявляем переменную для хранения принятого значения

void setup()
{
  Serial.begin(9600);           // Инициализируем последовательный порт
  irrecv.enableIRIn();          // Включаем ИК
  irrecv.blink13(true);         // Если сигнал пришел, диод D13 будет мигать
}

void loop()
{
  if (irrecv.decode(&results))  // Проверяем, пришли ли данные
  {
        Serial.println(results.value, HEX); // Выводим в порт
        irrecv.resume();                    // Ловим следующий пакет
  }
}

Для версии 4.2.0 библиотеки IRremote

#include <IRremote.hpp>         // Подключаем библиотеку

#define IR_RECEIVE_PIN 7        // Сигнальный вывод, подключенный к Ардуино

void setup()
{
  Serial.begin(9600); 
  IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // Инициализация приемника
}

void loop() {
  if (IrReceiver.decode()) {        // // Проверяем, пришли ли данные
      Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX); // Выводим в порт
      IrReceiver.resume(); // Включение приема следующего значения
  }
}

Теперь понажимайте на кнопки и запишите шестнадцатеричный код, который будет выводиться в монитор порта.

Обратите внимание!


Вы можете заметить, что коды для разных версий библиотек отличаются, хотя были нажаты одни и те же кнопки одного и того же пульта ДУ.

Это связано с изменением последовательности битов. В библиотеке версии 2.0.1 первым шел старший бит (MSB), а в библиотеке 4.2.0 первым идет младший бит (LSB), согласно протоколам ИК-передачи.

Чтобы преобразовать одно значение в другое, нужно «отзеркалить»/отразить двоичный код . Например:

0xFFA25D = 0000 0000 1111 1111 1010 0010 0101 11012 — полученный код кнопки «1», при использовании версии 2.0.1

0xBA45FF00 = 1011 1010 0100 0101 1111 1111 0000 00002 — полученный код кнопки «1», при использовании версии 4.2.0

Монитор порта для версии 2.0.1 библиотеки IRremote

Монитор порта для версии 4.2.0 библиотеки IRremote

Используя приведенные выше программы, были получены таблицы кодов кнопок пульта, который шел в комплекте с модулем KY-022.

Кнопка на пультеКод
1FFA25D
2FF629D
3FFE21D
4FF22DD
5FF02FD
6FFC23D
7FFE01F
8FFA857
9FF906F
0FF9867
*FF6897
#FFB04F
FF18E7
FF4AB5
FF10EF
FF5AA5
OKFF38C7
При использовании библиотеки версии 2.0.1
Кнопка на пультеКод
1BA45FF00
2B946FF00
3B847FF00
4BB44FF00
5BF40FF00
6BC43FF00
7F807FF00
8EA15FF00
9F609FF00
0E619FF00
*E916FF00
#F20DFF00
E718FF00
AD52FF00
F708FF00
A55AFF00
OKE31CFF00
При использовании библиотеки версии 4.2.0

Обратите внимание!


При непрерывном нажатии кнопки вы получаете код 0xFFFFFFFF в версии 2.0.1 и 0 в версии 4.2.0

Версия 2.0.1
Версия 4.2.0

Определение протокола пульта

Знание того, какой протокол использует ваш пульт, может быть полезно, если вы будете работать над более сложными проектами. Или просто от любопытства. Приведенная ниже программа определит протокол, используемый вашим пультом.

Для версии 2.0.1

#include <IRremote.h>           // Подключаем библиотеку

const int RECV_PIN = 7;         // Сигнальный вывод, подключенный к Ардуино
IRrecv irrecv(RECV_PIN);        // Создаем объект 
decode_results results;         // Объявляем переменную для хранения принятого значения

void setup()
{
  Serial.begin(9600);           // Инициализируем последовательный порт
  irrecv.enableIRIn();          // Включаем ИК
  irrecv.blink13(true);         // Если сигнал пришел, диод D13 будет мигать
}

void loop()
{
  if (irrecv.decode(&results))  // Проверяем, есть пришли ли данные
  {
        Serial.println(results.value, HEX); // Выводим в порт
        /* Выводим протокол ИК-связи */
        switch (results.decode_type){
            case NEC: Serial.println("NEC"); break ;
            case SONY: Serial.println("SONY"); break ;
            case RC5: Serial.println("RC5"); break ;
            case RC6: Serial.println("RC6"); break ;
            case DISH: Serial.println("DISH"); break ;
            case SHARP: Serial.println("SHARP"); break ;
            case JVC: Serial.println("JVC"); break ;
            case SAMSUNG: Serial.println("SAMSUNG"); break ;
            case LG: Serial.println("LG"); break ;
            case WHYNTER: Serial.println("WHYNTER"); break ;
            case PANASONIC: Serial.println("PANASONIC"); break ;
            case DENON: Serial.println("DENON"); break ;
          default:
            case UNKNOWN: Serial.println("UNKNOWN"); break ;
          }
        irrecv.resume();                    // Ловим следующий пакет
  }
}

Для версии 4.2.0

Здесь для вывода детальной информации можно использовать метод printIRResultShort:

#include <IRremote.hpp>         // Подключаем библиотеку

#define IR_RECEIVE_PIN 7        // Сигнальный вывод, подключенный к Ардуино

void setup()
{
  Serial.begin(9600); 
  IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // Инициализация приемника
}

void loop() {
  if (IrReceiver.decode()) {        // // Проверяем, пришли ли данные
      IrReceiver.printIRResultShort(&Serial);   // Вывод в порт результата
      IrReceiver.resume(); // Включение приема следующего значения
  }
}

Вот такой вывод будет в мониторе порта:

Действия, при нажатии определенных кнопок

Можно дополнить приведенный выше код, чтобы печатать название кнопки вместо шестнадцатеричного кода. Или выполнять другое какое либо действие, увеличить/уменьшить переменную, включить/выключить реле или светодиод, ввести код и тому подобное.

Для версии 2.0.1

#include <IRremote.h>           // Подключаем библиотеку

const int RECV_PIN = 7;         // Сигнальный вывод, подключенный к Ардуино
IRrecv irrecv(RECV_PIN);        // Создаем объект 
decode_results results;         // Объявляем переменную для хранения принятого значения

void setup()
{
  Serial.begin(9600);           // Инициализируем последовательный порт
  irrecv.enableIRIn();          // Включаем ИК
  irrecv.blink13(true);         // Если сигнал пришел, диод D13 будет мигать
}

void loop()
{
  if (irrecv.decode(&results))  // Проверяем, есть пришли ли данные
  {
         switch(results.value){ // Сравниваем код кнопки и выводим в порт название при совпадении
          case 0xFFB04F:
          Serial.println("#");
          break;
          case 0xFF6897:
          Serial.println("*");
          break;
          case 0xFF18E7:
          Serial.println("UP");
          break;  
          case 0xFF4AB5:
          Serial.println("DOWN");
          break;               
          case 0xFF10EF:
          Serial.println("LEFT");
          break;  
          case 0xFF5AA5:
          Serial.println("RIGHT");
          break;  
          case 0xFF38C7:
          Serial.println("OK");
          break;  
          case 0xFF9867:
          Serial.println("0");
          break;  
          case 0xFFA25D:
          Serial.println("1");
          break;
          case 0xFF629D:
          Serial.println("2");
          break;
          case 0xFFE21D:
          Serial.println("3");
          break;
          case 0xFF22DD:
          Serial.println("4");
          break;
          case 0xFF02FD:
          Serial.println("5");
          break;
          case 0xFFC23D:
          Serial.println("6");
          break;
          case 0xFFE01F:
          Serial.println("7");
          break;
          case 0xFFA857:
          Serial.println("8");
          break;
          case 0xFF906F:
          Serial.println("9");
          break;      
        }
        irrecv.resume();
  }
}

Для версии 4.2.0

#include <IRremote.hpp>         // Подключаем библиотеку

#define IR_RECEIVE_PIN 7        // Сигнальный вывод, подключенный к Ардуино

void setup()
{
  Serial.begin(9600); 
  IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // Инициализация приемника
}

void loop() {
  if (IrReceiver.decode()) {        // // Проверяем, пришли ли данные
      switch(IrReceiver.decodedIRData.decodedRawData){
          case 0xF20DFF00:
          Serial.println("#");
          break;
          case 0xE916FF00:
          Serial.println("*");
          break;
          case 0xE718FF00:
          Serial.println("UP");
          break;  
          case 0xAD52FF00:
          Serial.println("DOWN");
          break;               
          case 0xF708FF00:
          Serial.println("LEFT");
          break;  
          case 0xA55AFF00:
          Serial.println("RIGHT");
          break;  
          case 0xE31CFF00:
          Serial.println("OK");
          break;  
          case 0xE619FF00:
          Serial.println("0");
          break;  
          case 0xBA45FF00:
          Serial.println("1");
          break;
          case 0xB946FF00:
          Serial.println("2");
          break;
          case 0xB847FF00:
          Serial.println("3");
          break;
          case 0xBB44FF00:
          Serial.println("4");
          break;
          case 0xBF40FF00:
          Serial.println("5");
          break;
          case 0xBC43FF00:
          Serial.println("6");
          break;
          case 0xF807FF00:
          Serial.println("7");
          break;
          case 0xEA15FF00:
          Serial.println("8");
          break;
          case 0xF609FF00:
          Serial.println("9");
          break;      
        }
      IrReceiver.resume(); // Включение приема следующего значения
  }
}

Если ваш пульт отправляет коды, которые отличаются от приведенных в таблице выше, просто замените шестнадцатеричный код для каждой кнопки:

case 0xF20DFF00:
Serial.println("#");

Вот здесь, когда получен шестнадцатеричный код 0xF20DFF00, Arduino печатает символ “#“.

Где купить

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии