За моим окном на козырьке соседского балкона висит уличный термометр, и раз в минуту он рассказывает своей консоли про температуру на частоте 433,92 МГц. Приёмник XY-MK-5V слышит его из моей комнаты даже без антенны. Час вечера с библиотекой RCSwitch — и в моём мониторе живёт чужая улица: идентификатор датчика, температура, заряд батареи. Второй термометр покупать не пришлось, а график за окном собирается из того, что сосед и так вещает в эфир.
Приём — зеркало первого урока кластера: там FS1000A говорил, здесь слушаем. Но у приёма своя драма: эфир шумит, пакеты теряются, а дешёвый приёмник сыплет мусором без остановки. Разберёмся, почему DATA приёмника ставят именно на пин 2, как отличить настоящий пакет от шума по длине битов и почему правило «пакет настоящий, если пришёл дважды» экономит часы отладки.
Плюс концепция, которая открывает целую вселенную: дешёвые погодные датчики шлют температуру в своих протоколах — биты пакета скрывают идентификатор, знак, целые градусы и десятые. RCSwitch отдаёт сырое число; раскладывать его на градусы — работа для карандаша, листа в клетку и bitRead, и ниже я покажу, как эта работа выглядит на живом примере.
Приёмник на пине 2: ноль — это номер прерывания
XY-MK-5V кормится от 5 В платы, DATA идёт в пин 2, и вот почему: enableReceive(0) принимает номер прерывания, а не пин, и прерывание 0 на Uno сидит ровно на пине 2. Механика та же, что у attachInterrupt из урока про прерывания: библиотека ловит каждый фронт на DATA и по расстояниям между импульсами собирает биты. Перепутаете пины — прерывание назначено, а фронтов на нём нет: сниффер молчит, и выглядит это как брак модуля, хотя виноваты руки.
Вторая правда про дешёвый приёмник: в тишине он не молчит. Суперрегенератор усиливает всё подряд — от импульсной зарядки на столе до соседней макетки, и DATA сыплет обрывками на 1-8 бит. Это не поломка, а природа детали: фильтр по длине пакетов отделяет настоящие посылки от шума, а физика снижает сам уровень мусора. Приёмник, прижатый к макетке с реле, слышит заметно хуже, чем тот же приёмник на двадцати сантиметрах провода-удлинителя, — проверено перестановкой на собственной панели.
Про пины точнее: пин 2 забирает прерывание 0, и этим список кандидатов на DATA не исчерпан — прерывание 1 живёт на пине 3, и если двойка уже занята, приёмник переезжает туда с enableReceive(1). Остальное хозяйство — кнопки, датчики, реле — сажается на пины без прерываний: у RCSwitch принимающий пин один, и делить его не с кем. Дешёвый приёмник при этом прожорлив до шумного питания: тот же модуль на отдельном стабилизаторе с конденсатором по питанию даёт вдвое меньше ложных пакетов, чем на шумной шине макетки.
#include <RCSwitch.h> RCSwitch mySwitch; void setup() { Serial.begin(9600); mySwitch.enableReceive(0); // прерывание 0 = пин 2 Serial.println("Sniffer: pechatayu tolko paketi 24 bit i dlinnee");} void loop() { if (mySwitch.available()) { unsigned long kod = mySwitch.getReceivedValue(); int bit = mySwitch.getReceivedBitlength(); if (bit >= 24) { // короче - мусор: в корзину молча Serial.print("kod="); Serial.print(kod); Serial.print(" bit="); Serial.print(bit); Serial.print(" pulse="); Serial.println(mySwitch.getReceivedDelay()); } mySwitch.resetAvailable(); // готов к следующему пакету }}Фильтр по длине — первая ступень. Вторая — терпение: чужой датчик шлёт свой пакет раз в 30-60 секунд, и у меня уходило полчаса, чтобы собрать десяток его посылок для разбора. Зато пакет живёт стабильной жизнью: один и тот же кадр датчик повторяет трижды-пятикратно с паузами в доли секунды — так производитель борется с помехами. Ловите один и тот же код минимум дважды, и это уже сигнал, а не случайность; одиночная посылка — загадка, которую эфир не обязан раскрывать.
Теперь концепция протокола. В пакете уличного термометра биты лежат по своим местам: старшие разряды — идентификатор, который датчик придумывает сам при подаче питания, дальше — знак температуры, целые градусы, десятые, у части моделей — заряд батареи. Как именно лежат, знает только производитель, и таких схем десятки: энтузиасты проекта rtl_433 каталогизировали большинство, и их таблица — лучший словарь, когда хочется узнать про свою модель заранее. RCSwitch честно отдаёт сырое число, дальше — карандаш: печатаете две посылки в двоичном виде, греете датчик пальцем и смотрите, какие разряды изменились. У моего соседа градусы нашлись в средней трети пакета, а знак — в отдельном бите, и после вечера со сравнением посылок его минусовая ночь больше не выглядела как плюс двести.
Полезно представить, кто и когда занимает эфир вокруг приёмника. Уличный термометр живёт по расписанию: просыпается раз в 30-60 секунд, шлёт пачку из трёх-пяти копий и засыпает — от одной кроны он живёт год, потому что радиотракт включён на доли секунды в минуту. Пульты шлют только по нажатию. Ваш FS1000A из первого урока — по событию в скетче. Столкновения у всех редкие: канал короткий, посылка занимает десятки миллисекунд, и шанс встретиться у двух передатчиков в один момент мал, хотя и не нулевой — вот на этот случай и существуют повторы.
Отсюда дисциплина счётчика приёма, который я веду в журнале: за вечер сосед успевает 60-70 сеансов, доезжает 55-70 — это норма, а не авария, и только пустота в течение часа заставляет идти проверять окно. Приём чужого не стыден: частота свободная, слушать её может каждый, но чужие показания я использую только в своём доме. Если хочется собственного термометра рядом с платой, есть проверенный путь — DHT11 на цифровом пине: в эфир он не шлёт, зато читается когда угодно, и сверять его с соседской улицей — мой первый тест на враньё приёмника.
| Приёмник | Порода | Поведение в квартире | Для чего брать |
|---|---|---|---|
| XY-MK-5V | суперрегенератор | шумит без остановки, слышит на 3-10 м | старт, сниффинг, стенды |
| RXB6 / супергетеродин | селективный приём | стабильнее в разы, меньше ложных пакетов | постоянный приём датчиков |
| Приёмник второй платы | свой канал | ловит свой FS1000A гарантированно | проверка протокола из третьего урока |
Повторяемость: 3 из 5 и правило двух приёмов
Пакеты на радио теряются навсегда: квитанций на 433 МГц нет, получатель не подтверждает приём, отправитель не узнаёт о пропаже. Отсюда правило, которое я вывел после недели мёртвых графиков: считать пакет настоящим только после второго приёма того же кода. Дешёвые датчики и пульты и так шлют повторами — три-пять копий одного кадра, — и потеря пары из них штатна. Мой счётчик прост: пришёл код, запомнил; тот же код в течение секунды — исполняю и пишу в журнал. Одиночная посылка в журнал попадает, но действия не вызывает.
Про помехи конкретнее. Главные враги приёма — импульсные блоки питания, диммеры и сама макетка с реле: их выбросы приёмник честно превращает в короткие пакеты. Лечение физическое, а не программное: подальше от зарядок, земля короткая, антенна — те же 17,3 см провода, но уже на вход приёмника. Проверка сама за себя: включите сниффер рядом с выключенным монитором и с включённым — разница в мусоре покажет, кто шумит у вас на столе. На графике из урока про плоттер чужая температура ложится ступенькой раз в минуту, и выбросы от помех видны на нём иглами, которые хочется удалить, но лучше — устранить.
Соседи по эфиру, которых услышит сниффер в обычной пятиэтажке: пульты радиорозеток, дверные звонки, датчики открывания ворот, уличные термометры, метеостанции. Все на одной частоте, все без шифрования, и каждый пакет кто-то ждёт, а кто-то — нет. Поэтому журнал приёма я веду в духе урока про отладку через Serial: код, длина, время — и через неделю жизни сниффера вы знаете свою эфирную окрестность лучше, чем соседи.
Разбор пакетов удобно вести в двоичном виде: десятичное число 8612345 не говорит ни о чём, а 0b100000111010011110111001 показывает выемки и разряды, по которым бегут градусы. Переводы между системами счисления мы прогоняли в уроке про bin, hex и dec в Serial — там же и печать в BIN с монитора. Мой журнал разбора выглядит как таблица: слева код, справа показание с датчика, и после двадцати строк разряды температуры видно глазами, без калькулятора.
- enableReceive(0) — это прерывание 0 и пин 2 на Uno: DATA приёмника XY-MK-5V ставится только туда
- В тишине дешёвый приёмник шумит: фильтр по длине пакетов (24 бита и длиннее) отделяет настоящие посылки от мусора
- Пакет настоящий, если тот же код пришёл дважды: датчики шлют кадр трижды-пятикратно, и потеря части повторов штатна
- Чужая температура — биты в своих разрядах: две посылки при разной температуре показывают, где лежат градусы
- Помехи — импульсные зарядки и соседство с реле: антенна 17,3 см и двадцать сантиметров от макетки лечат лучше кода
- 1. mySwitch.enableReceive(0) — что значит ноль?
- 2. Приёмник без сигнала сыплет пакетами по 1-8 бит. Что с ними делать?
- 3. Почему команда по радио считается принятой только со второго приёма того же кода?
- 4. Датчик шлёт кадр пять раз, до приёмника доехали два. Что делает правильный скетч?
- 5. Что поднимет дальность приёма сильнее всего?
Частые вопросы по теме урока
- mySwitch.enableReceive(0) — что значит ноль?
- Аргумент — номер прерывания, не пин. Прерывание 0 на Uno соответствует пину 2, и DATA приёмника ставят именно туда. номер прерывания: на Uno оно сидит на пине 2
- Приёмник без сигнала сыплет пакетами по 1-8 бит. Что с ними делать?
- Короткие обрывки — шум суперрегенератора. Фильтр bit >= 24 пропускает только настоящие пакеты и не тратит внимание на мусор. отбрасывать фильтром по длине: настоящие посылки длиннее
- Почему команда по радио считается принятой только со второго приёма того же кода?
- Канал односторонний: получатель не подтверждает, отправитель не узнаёт о пропаже. Датчики сами шлют кадр трижды-пятикратно, и правило двух приёмов отфильтровывает случайности. квитанций на 433 МГц нет, а одиночный приём может оказаться случайностью — датчики шлют повторами
- Датчик шлёт кадр пять раз, до приёмника доехали два. Что делает правильный скетч?
- Порог в скетче урока — минимум три принятых пакета: две копии из пяти означают, что эфир сегодня злой, и честнее дождаться следующего сеанса через минуту. пишет в журнал, но действия не вызывает: три из пяти не собрались
- Что поднимет дальность приёма сильнее всего?
- Приём решают физика и место: четвертьволновая антенна и удаление от источников помех. Скорость порта, номер пина и вызовы библиотеки на дальность не влияют. антенна 17,3 см и расстояние от шумной макетки