Урок 14: ИК-пульт Дистанционного Управления
1. Цель эксперимента
Познакомиться с работой инфракрасного приёмника VS1838B и научиться управлять светодиодами при помощи бытового ИК-пульта. Вы научитесь:
подключать 38-кГц приёмник к Arduino;
декодировать сигналы пульта библиотекой IRremote;
выполнять действия (включать / выключать LED) по полученному коду.
2. Компоненты
Кол-во |
Деталь |
---|---|
1 |
Плата Arduino UNO |
1 |
Приёмник VS1838B (38 кГц) |
1 |
ИК-пульт ДУ (любая модель с кодировкой NEC) |
6 |
LED 5 мм |
6 |
Резисторы 220 Ω — ограничение тока LED |
11 |
Перемычки «папа–папа» |
1 |
Макетная плата (breadboard) |
1 |
USB-кабель A-B |
3. Немного знаний
4. Схема подключения

VOUT → 11
GND → GND
VCC → 5 V
LED1 … LED6 → пины 2–7 через резисторы 220 Ω
5. Протокол NEC (кратко)
Бита 1 — 562 µs импульс + 1,69 мс пауза.
Бита 0 — 562 µs импульс + 562 µs пауза.
Адрес (8 бит) и команда (8 бит) передаются в нормальном и инверсном виде для контроля ошибок.
При удержании кнопки каждые 110 мс отправляется «repeat-код».

Особенности NEC-формата
8-битный адрес и 8-битная команда ⇒ всего 16 значимых бит.
Надёжность: сразу после адреса/команды передаются их инвертированные копии (ещё 16 бит). Приёмник сравнивает пары и убеждается, что данные дошли без искажений.
Модуляция импульсного расстояния (
pulse-distance modulation
): логические 0 и 1 различаются длиной паузы после импульса, а не длительностью самого импульса (он всегда 562 µs).Несущая частота — 38 кГц, ширина импульса 562 µs содержит ~21 цикл.
Время передачи одного бита: 1,125 мс (лог.0) или 2,25 мс (лог.1).
Кадр данных
«Заголовок» — 9 мс непрерывного 38-кГц сигнала (AGC burst), после которого 4,5 мс тишины. Такой паттерн легко отфильтровать программно и аппаратно.
32 бит полезных данных (LSB → MSB): адрес, ~адрес, команда, ~команда.
Завершается тишиной ≥40 мс.
Повторяющийся код
Если кнопку удерживать, вместо полного кадра каждые ~110 мс посылается «repeat»: 9 мс AGC + 2,25 мс пауза + 562 µs импульс. Ардуино узнаёт, что кнопку не отпустили, и может повторять действие (например, плавно менять громкость).
Таким образом, чтобы распознать конкретную клавишу, достаточно считать
первые 32 бита кадра. Библиотека IRremote делает это за нас и
возвращает шестнадцатеричный код вида 0x00FF6897
.
6. Коды кнопок (пример пульта)
Ниже приведены HEX-коды, которые часто встречаются у «мини-пульта» из набора. Снимите их своим приёмником и убедитесь, что значения совпадают — производители иногда меняют прошивку.
FFA25D |
FF629D |
FFE21D |
FF22DD |
FF02FD |
FFC23D |
FFE01F |
FFA857 |
FF906F |
FF6897 |
FF9867 |
FFB04F |
FF30CF |
FF18E7 |
FF7A85 |
FF10EF |
FF38C7 |
FF5AA5 |
FF42BD |
FF4AB5 |
FF52AD |
Коды FF6897
и FF9867
использованы в примерах выше для включения
и выключения первого светодиода. Остальные можете привязать к своим
действиям.
7. Установка библиотеки IRremote
Перед компиляцией скетчей убедитесь, что библиотека IRremote +(maintainer Arduino) установлена в среде Arduino IDE.
Откройте Tools ▸ Manage Libraries… (или «Скетч → Подключить библиотеку → Управлять библиотеками…»).
В поле поиска введите
IRremote
.Найдите библиотеку Arduino-IRremote от Arduino (бывшая shirriff).
Нажмите Install и дождитесь окончания загрузки.
Перезапустите IDE, если потребуется.
Альтернативный способ — скачать ZIP-архив с GitHub, затем в IDE выбрать Sketch ▸ Include Library ▸ Add .ZIP Library… и указать скачанный файл.
После установки убедитесь, что в скетче подключается файл
#include <IRremote.h>
(для версии 3.x и выше). Если у вас старая
версия 2.x, путь тот же, но пространство имён меняется — учитывайте это
при миграции.
8. Пример кода: один светодиод
// Урок 14 — ИК-пульт, управление одним LED
#include <IRremote.h>
const byte RECV_PIN = 11; // VOUT приёмника
const byte LED_PIN = 2; // LED на пине 2
const unsigned long ON_CODE = 0x00FF6897; // «включить»
const unsigned long OFF_CODE = 0x00FF9867; // «выключить»
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
irrecv.enableIRIn(); // старт приёмника
}
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX); // выводим код
if (results.value == ON_CODE) digitalWrite(LED_PIN, HIGH);
if (results.value == OFF_CODE) digitalWrite(LED_PIN, LOW);
irrecv.resume(); // слушаем дальше
}
}
9. Пример кода: шесть светодиодов
////////////////////////////////////////////////////////////////
// Проект 14: Дистанционное Управление https://github.com/shirriff/Arduino-IRremote
#include <IRremote.h>
int RECV_PIN = 11; // выбираем цифровой контакт 11 для инфракрасного приемника
int LED1 = 2; // выбираем цифровой контакт 2 для светодиода 1
int LED2 = 3; // выбираем цифровой контакт 3 для светодиода 2
int LED3 = 4; // выбираем цифровой контакт 4 для светодиода 3
int LED4 = 5; // выбираем цифровой контакт 5 для светодиода 4
int LED5 = 6; // выбираем цифровой контакт 6 для светодиода 5
int LED6 = 7; // выбираем цифровой контакт 7 для светодиода 6
long on1 = 0x00FF6897; // код включения для первой кнопки
long off1 = 0x00FF9867; // код выключения для первой кнопки
long on2 = 0x00FFB04F; // код включения для второй кнопки
long off2 = 0x00FF30CF; // код выключения для второй кнопки
long on3 = 0x00FF18E7; // код включения для третьей кнопки
long off3 = 0x00FF7A85; // код выключения для третьей кнопки
long on4 = 0x00FF10EF; // код включения для четвертой кнопки
long off4 = 0x00FF38C7; // код выключения для четвертой кнопки
long on5 = 0x00FF5AA5; // код включения для пятой кнопки
long off5 = 0x00FF42BD; // код выключения для пятой кнопки
long on6 = 0x00FF4AB5; // код включения для шестой кнопки
long off6 = 0x00FF52AD; // код выключения для шестой кнопки
IRrecv irrecv(RECV_PIN); // создание экземпляра приемника ИК-сигналов
decode_results results; // создание экземпляра для результатов декодирования
void dump(decode_results *results) {
int count = results->rawlen;
if (results->decode_type == UNKNOWN) {
Serial.println("Сообщение не удалось декодировать");
} else {
if (results->decode_type == NEC) {
Serial.print("Декодирован NEC: ");
} else if (results->decode_type == SONY) {
Serial.print("Декодирован SONY: ");
} else if (results->decode_type == RC5) {
Serial.print("Декодирован RC5: ");
} else if (results->decode_type == RC6) {
Serial.print("Декодирован RC6: ");
}
Serial.print(results->value, HEX);
Serial.print(" (");
Serial.print(results->bits, DEC);
Serial.println(" бит)");
}
Serial.print("Необработанное (");
Serial.print(count, DEC);
Serial.print("): ");
for (int i = 0; i < count; i++) {
if ((i % 2) == 1) {
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
} else {
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
}
Serial.print(" ");
}
Serial.println("");
}
void setup() {
pinMode(RECV_PIN, INPUT);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);
pinMode(LED6, OUTPUT);
pinMode(13, OUTPUT);
Serial.begin(9600);
irrecv.enableIRIn(); // Запуск приемника
}
int on = 0;
unsigned long last = millis();
void loop() {
if (irrecv.decode(&results)) {
if (millis() - last > 250) {
on = !on;
digitalWrite(13, on ? HIGH : LOW);
dump(&results);
}
if (results.value == on1) digitalWrite(LED1, HIGH);
if (results.value == off1) digitalWrite(LED1, LOW);
if (results.value == on2) digitalWrite(LED2, HIGH);
if (results.value == off2) digitalWrite(LED2, LOW);
if (results.value == on3) digitalWrite(LED3, HIGH);
if (results.value == off3) digitalWrite(LED3, LOW);
if (results.value == on4) digitalWrite(LED4, HIGH);
if (results.value == off4) digitalWrite(LED4, LOW);
if (results.value == on5) digitalWrite(LED5, HIGH);
if (results.value == off5) digitalWrite(LED5, LOW);
if (results.value == on6) digitalWrite(LED6, HIGH);
if (results.value == off6) digitalWrite(LED6, LOW);
last = millis();
irrecv.resume(); // Прием следующего значения
}
}
////////////////////////////////////////////////////////////////
10. Результат теста
После загрузки скетча откройте Serial Monitor на 9600 бод. При нажатии кнопок пульта будут выводиться строки «Decoded NEC: XXXXXXX» — шестнадцатеричные коды кнопок.

11. Что может пойти не так
Симптом |
Причина |
Решение |
---|---|---|
Всегда «FFFFFFFF» |
Приёмник не видит сигнал |
Проверьте питание, частоту 38 кГц, направьте пульт прямо на датчик |
Нет реакции на код |
Неправильное значение |
Выведите код в монитор и подставьте его в скетч |
Светодиоды мигают хаотично |
Помехи от другого пульта / лампы |
Используйте экран, уменьшите дальность, добавьте проверку адреса |
12. Эксперименты
Замените шесть отдельных
if
наswitch
или на таблицу структур — код будет компактнее.Используйте функцию
IrReceiver.decode()
из новой версии библиотеки (2.x) — она сильно упростила API.Управляйте не LED, а сервоприводом или реле: поставьте шаровой штатив и сделайте «ИК-поворотник» для камеры.