Подключение деталей · Датчики
ИК-приёмник (VS1838B): подключение к ESP32 и Arduino
Приёмник инфракрасного пульта
Принимает команды обычного пульта от телевизора. Каждая кнопка — свой код, и им можно управлять чем угодно.
Как работает
Пульт мигает инфракрасным светодиодом с частотой 38 кГц , а приёмник выделяет эту несущую и выдаёт на OUT уже огибающую — последовательность импульсов (выход инверсный: есть сигнал — LOW). Длительности пауз кодируют биты команды; самый распространённый протокол — NEC .
Библиотека IRremote : IrReceiver.begin(вывод), а в loop — if (IrReceiver.decode()) { код = IrReceiver.decodedIRData.command; IrReceiver.resume(); }.
Питание 2,7–5,5 В Несущая 38 кГц Выход OUT, активный LOW Библиотека IRremote (версия 3 и новее)
Выводы
Вывод Назначение
OUT выход сигнала VCC питание GND общий провод
Подключение к ESP32
Код скетча
// Приём ИК-пульта на блоке RMT.
//
// Обычным digitalRead этот сигнал не поймать: кадр NEC укладывает
// тридцать два разряда в шестьдесят миллисекунд импульсами по 560 мкс.
// RMT ловит их сам и складывает в память парами «уровень и длительность».
#include <driver/rmt.h>
const rmt_channel_t CH = RMT_CHANNEL_0;
const gpio_num_t IR_PIN = GPIO_NUM_15;
// Допуск на длительность: у настоящих пультов разброс заметный, и
// сравнивать с точностью до микросекунды бессмысленно.
bool near(int value, int want) {
return value > want - 250 && value < want + 250;
}
void setup() {
Serial.begin(115200);
rmt_config_t cfg = RMT_DEFAULT_CONFIG_RX(IR_PIN, CH);
cfg.clk_div = 80; // такт в микросекунду
cfg.mem_block_num = 2; // кадру NEC нужно 68 записей, в блоке 64
cfg.rx_config.idle_threshold = 12000; // тишина 12 мс — конец кадра
cfg.rx_config.filter_en = true;
cfg.rx_config.filter_ticks_thresh = 100;
rmt_config(&cfg);
rmt_driver_install(CH, 1024, 0);
rmt_rx_start(CH, true);
Serial.println("жду пульт");
}
void loop() {
RingbufHandle_t rb = NULL;
rmt_get_ringbuf_handle(CH, &rb);
if (!rb) return;
size_t size = 0;
rmt_item32_t *items = (rmt_item32_t *)xRingbufferReceive(rb, &size, pdMS_TO_TICKS(200));
if (!items) return;
int count = size / sizeof(rmt_item32_t);
// Заголовок: 9 мс несущей и 4.5 мс паузы. По нему кадр и опознаётся.
if (count >= 34 && near(items[0].duration0, 9000) && near(items[0].duration1, 4500)) {
uint32_t code = 0;
for (int i = 1; i <= 32; i++) {
// Разряд задаёт не импульс, а пауза после него: 560 мкс — ноль,
// 1690 — единица.
code = (code << 1) | (items[i].duration1 > 1000 ? 1 : 0);
}
Serial.printf("код 0x%08X\n", code);
} else {
Serial.printf("кадр не похож на NEC: %d записей\n", count);
}
vRingbufferReturnItem(rb, (void *)items);
}
В железе
Порядок выводов у разных приёмников разный (у VS1838B и TSOP1838 — не совпадает). Сверяйтесь с маркировкой модуля или паспортом.
Частые ошибки
Код из старых примеров (irrecv.decode(&results)) не собирается — в IRremote 3+ другой интерфейс: IrReceiver.decode(). Коды «прыгают» — солнечный свет или люминесцентная лампа засвечивают приёмник. Держание кнопки даёт код повтора (у NEC — 0xFFFFFFFF или флаг repeat), а не код кнопки. Забыт resume() — принимается только первая команда.