На барахолке за сто рублей ушла горсть пультов: от Philips-DVD, от старого ресивера Sony и от вентилятора безродного бренда. Первый же вечер с читалкой собрал коллекцию сюрпризов. Пульт Philips напечатал протокол RC5, 14 бит — и команда одной и той же кнопки прыгала то 0x10, то 0x11, будто пульт заикается. Пульт Sony показал 12 бит, а удержание громкости засыпало монитор пачкой одинаковых строк — по кадру каждые 45 мс. Вентилятор честно печатал UNKNOWN.
Ни один из трёх не сломан. Это просто другие языки: у каждого протокола свой способ прятать бит во вспышках и свои привычки с повторами. NEC с его паузами и инверсиями — лишь самый распространённый диалект, который мы разобрали по битам, а не единственный стандарт.
Здесь научимся читать пульты вне NEC: чем отличаются три способа кодирования бита, зачем в RC5 живёт toggle-бит, почему Sony при удержании шлёт кадры заново и что делать с пультом, который не узнал ни один шаблон библиотеки.
Три способа спрятать бит во вспышках
Первый способ — кодирование длиной паузы, NEC-стиль: все вспышки одинаковые, смысл бита сидит в тишине после них. Второй — кодирование длиной импульса, как у Sony: паузы, наоборот, одинаковые (600 мкс), а смысл бита несёт длина самой вспышки — 600 мкс значит ноль, 1200 мкс значит единицу. Третий способ хитрее: манчестерское кодирование, как у Philips RC5. Каждый бит длится 1,778 мс и делится на два полубита по 889 мкс, а в середине бита уровень гарантированно меняется — вверх или вниз, и направление этого перепада и есть значение бита.
У трёх способов разные несущие: NEC и большинство клонов светят на 38 кГц, Sony выбрал 40 кГц, Philips — 36 кГц. Звучит как головная боль, но полосовой фильтр приёмника TSOP широкий: 38-килогерцовая деталь обычно видит и 36, и 40 кГц, теряя в дальности десяток процентов, а не кадры целиком. Я не менял приёмники под пульты Sony ни разу — читалка из первого урока съедала их без правок.
Практический вывод: по внешнему виду линии на экране осциллографа протокол различим на глаз — NEC дрожит паузами, Sony дрожит вспышками, RC5 мерно машет уровнем с постоянным шагом. Библиотека делает то же сравнение автоматически, только сравнивает не вид, а числа: интервалы кадра против шаблонов десятков известных кодировок.
У Sony SIRC есть три размера: 12, 15 и 20 бит. В базовом 12-битном варианте 7 бит занимает команда и 5 бит — адрес устройства: телевизор, видеомагнитофон и ресивер одного дома различались пятёркой адреса. Кадр длится около 21–25 мс — вдвое короче NEC. Повтор устроен по-простому: отдельного кадра-повтора нет, при удержании пульт пересылает весь кадр заново примерно каждые 45 мс, поэтому монитор и сыплется одинаковыми строками. Адрес и команда при этом остаются прежними — отличать нажатие от удержания придётся по частоте кадров, а не по содержимому.
RC5 несёт 14 бит: два стартовых, toggle-бит, 5 бит адреса и 6 бит команды. Toggle — решение вечной проблемы пульта: как приёмнику понять, держат кнопку или нажали второй раз? Sony отвечает «смотри на частоту кадров», Philips меняет один бит: каждое новое нажатие переворачивает toggle, удержание шлёт кадр с тем же значением. Отсюда и прыжки команды 0x10/0x11 из вступления: в старых версиях библиотеки toggle смешивался с командой, в четвёртой версии IRremote выносит его в отдельное поле decodedIRData.extra, и команда приходит чистой — назначение полей кадра мы разбирали в уроке про анатомию decodedIRData. Несущая 36 кГц, кадр около 25 мс.
Мнение после года с этой разношёрстной компанией: отдельный приёмник под каждую несущую покупать не нужно, но порядок различий стоит держать в голове, когда пульт «глючит» — чаще всего это не глюк, а честное поведение чужой кодировки, которого ваш скетч просто не ожидал.
#include <IRremote.hpp> const int IR_PIN = 2; void setup() { Serial.begin(9600); IrReceiver.begin(IR_PIN, ENABLE_LED_FEEDBACK); Serial.println("Наведите любой пульт");} void loop() { if (IrReceiver.decode()) { Serial.print("protocol="); Serial.println(IrReceiver.getProtocolString()); Serial.print("bits="); Serial.println(IrReceiver.decodedIRData.numberOfBits); Serial.print("addr=0x"); Serial.println(IrReceiver.decodedIRData.address, HEX); Serial.print("cmd=0x"); Serial.println(IrReceiver.decodedIRData.command, HEX); IrReceiver.resume(); }}RAW: диктофон для неизвестных пультов
Библиотека знает несколько десятков протоколов, но не все: климатическая техника, вентиляторы, светильники из строительных гипермаркетов любят собственные кодировки. Для них библиотека печатает UNKNOWN — и это честный ответ, а не поломка. Кадр при этом доезжает целиком в сырых длительностях, и их можно записать: printIRResultRawlinated(&Serial) печатает интервалы каждого импульса и каждой паузы построчно.
Такой дамп — диктофон: он ничего не понимает, зато запоминает бит в бит. Пары «длительность вспышки — длительность тишины» потом можно воспроизвести передатчиком через IrSender.sendRaw — и ваша плата будет говорить с вентилятором на его собственном языке, не зная грамматики. Точно так же устроен и датчик расстояния HC-SR04: там pulseIn меряет эхо, здесь — свет; метод один — длительности говорят сами за себя. А если длина кадра пугает, помните: декодер считает всё это внутри прерывания, мы разбирали, как такие обработчики устроены.
Мой порядок знакомства с чужим пультом: сначала определитель — вдруг библиотека узнает протокол и всё сделает сама. Не узнала — RAW-дамп в шапку скетча комментарием, таблица кодов по повторяющимся блокам. Самодельный декодер поверх длительностей — последний пункт, и до него в моей практике дело дошло один раз за три года.
void loop() { if (IrReceiver.decode()) { if (IrReceiver.decodedIRData.protocol == UNKNOWN) { // дамп интервалов: каждый импульс и пауза с числами в микросекундах IrReceiver.printIRResultRawlinated(&Serial); } IrReceiver.resume(); }}| Протокол | Как закодирован бит | Кадр | Несущая | Повтор при удержании |
|---|---|---|---|---|
| NEC | длина паузы после вспышки 560 мкс: 560 — ноль, 1690 — единица | 32 бита, 50–85 мс | 38 кГц | короткий кадр-повтор каждые 108 мс |
| Sony SIRC | длина вспышки: 600 мкс — ноль, 1200 — единица | 12/15/20 бит, 21–25 мс | 40 кГц | тот же полный кадр снова, каждые 45 мс |
| Philips RC5 | манчестер: перепад в середине бита, полубит 889 мкс | 14 бит, около 25 мс | 36 кГц | тот же кадр, различается toggle-битом |
| Philips RC6 | манчестер с переменной длиной полубита | от 20 бит (mode 0) | 36 кГц | toggle-бит, как у RC5 |
| RAW | кодировки нет: пишутся длительности как есть | сколько записали | любая | повторы видны в дампе |
Симулятор: разбор команд, который переживёт любой протокол
- Три кодировки: смысл бита в паузе (NEC), в длине вспышки (SIRC), в перепаде середины бита (RC5)
- SIRC: 12/15/20 бит, из них 7 бит команды; удержание — полный кадр снова каждые 45 мс
- RC5: 14 бит на 36 кГц; toggle-бит переворачивается новым нажатием, в IRremote 4.x живёт в decodedIRData.extra
- 38-килогерцовый TSOP обычно видит 36 и 40 кГц — ценой небольшой потери дальности
- UNKNOWN не конец: printIRResultRawlinated записывает длительности, IrSender.sendRaw воспроизводит кадр
- Ниже decode() протокол неважен: скетч работает с командой, кем бы она ни была отправлена
- 1. Где у Sony SIRC сидит значение бита?
- 2. Команда кнопки RC5 приходит то 0x10, то 0x11. Что происходит?
- 3. Кнопку громкости Sony-пульта держат долго. Что прилетает на приёмник?
- 4. Пульт RC5 с несущей 36 кГц и приёмник на 38 кГц — заработают ли?
- 5. Библиотека печатает UNKNOWN. Что делать?
Пультовая коллекция больше не пугает: кодировка опознаётся по числу бит, toggle у RC5 перестал быть мистикой, а UNKNOWN превратился из стены в дверь — за ней лежит RAW-дамп и передатчик. Соберите эту технику в одно устройство: возьмите управление светом из урока про команды и повторы, добавьте определитель из этого урока — и получится пульт-центр, который понимает и NEC, и всё, что в него попадёт с барахолки. Таблицу кодов для него снимите читалкой из самого первого урока раздела — три вечера с горсткой барыжных пультов дают опыт, который не купить за сто рублей.
Частые вопросы по теме урока
- Где у Sony SIRC сидит значение бита?
- SIRC кодирует длиной импульса: паузы постоянные по 600 мкс, а вспышка растягивается вдвое у единиц. NEC — зеркальный случай. В длине самой вспышки: 600 мкс — ноль, 1200 мкс — единица
- Команда кнопки RC5 приходит то 0x10, то 0x11. Что происходит?
- Toggle отличает новое нажатие от удержания. В IRremote 4.x бит вынесен в decodedIRData.extra, и команда больше не пляшет. Это toggle-бит: он переворачивается при каждом новом нажатии
- Кнопку громкости Sony-пульта держат долго. Что прилетает на приёмник?
- Отдельного repeat-кадра у SIRC нет: пульт пересылает весь кадр заново, поэтому монитор заполняют одинаковые строки. Тот же полный кадр снова и снова, примерно каждые 45 мс
- Пульт RC5 с несущей 36 кГц и приёмник на 38 кГц — заработают ли?
- Полоса пропускания TSOP шире одного килогерца: соседние несущие различаются, кадры декодируются, дальность чуть падает. Да: полосовой фильтр широкий, 36 и 40 кГц обычно ловятся с небольшой потерей дальности
- Библиотека печатает UNKNOWN. Что делать?
- Дамп сохраняет интервалы всех импульсов и пауз; передатчиком их можно отправить бит в бит, не понимая смысла. Печатать RAW-дамп длительностей и позже воспроизвести кадр через sendRaw