Все началось в какой-то из вечеров, когда после работы очень хотелось просто полежать на диване, но у ребенка были другие планы на папу. Мне было поручено управлять игрушечным светофором и включать машинкам красный и зеленый свет, причем светофор должен был располагаться как можно дальше от дивана. И тут родилась идея! А что, если сделать светофор на радиоуправлении?
![Эволюция светофора в домашних условиях. Слева - магазинный вариант Эволюция светофора в домашних условиях. Слева - магазинный вариант](https://habrastorage.org/getpro/habr/upload_files/45e/078/dc4/45e078dc46035c9fcecd844435fc5a3c.jpg)
Идея готова, оставалось придумать, как ее реализовать. По сути, для первого варианта оказалось необходимо совсем немного компонентов:
Плата Arduino
Что-то типа светодиодов
Пульт управления и приемник сигналов
Элемент питания
Корпус
Arduino
Выбрано самое простое решение в виде Arduino Nano. Можно было бы взять более компактную Arduino Pro Mini, однако на тот момент у меня было совсем мало опыта и знаний в области Arduino, и я выбрал первое, что казалось подходящим.
Светодиоды
В качестве сигналов светофора очевидным выбором являются разноцветные светодиоды, но стандартные 5-миллиметровые светодиоды даже в детском масштабе выглядят уж слишком мелко. Можно, наверное, было бы найти для них какие-то линзы побольше и собрать вполне приличный светофор, если бы в это время в гугле мне не попалось вот такое чудесное изделие под названием Waveshare RGB LED HAT.
![Waveshare RGB LED HAT Waveshare RGB LED HAT](https://habrastorage.org/getpro/habr/upload_files/f98/70f/a0a/f9870fa0ac2acefd1fa9999228b93c04.jpg)
По сути, RGB LED HAT — это лента из 32 адресных светодиодов WS2812b, которые напаяны на плату в виде матрицы 4х8. И такой вариант мне понравился сразу по нескольким причинам:
матрица 4х8 дает простор для более разнообразных цветных эффектов, помимо собственно сигналов светофора
можно самому не паять светодиоды на макетной плате, плюс фабричная пайка всегда выглядит аккуратнее – а это важно, учитывая, что должна получиться более-менее эстетичная игрушка
Дистанционное управление
Для реализации основного замысла – дистанционного управления - я решил использовать обычный пульт от умного дома, передающий сигналы на частоте 433 МГц. А к Arduino подключил типовой радиомодуль-приемник на 433 МГц.
![Готовые компоненты - это всегда хорошо Готовые компоненты - это всегда хорошо](https://habrastorage.org/getpro/habr/upload_files/b7e/58a/a38/b7e58aa388c27b2546ef9df6aae169d5.jpg)
Питание
Это, на самом деле, оказался самый сложный вопрос. С одной стороны, сейчас повсюду литиевые аккумуляторы и USB-зарядки. Тут они не подошли сразу по многим причинам:
напрямую один аккумулятор 3.7В к Arduino Nano не подключить – нужен повышающий DC-DC преобразователь до 5В. Беглый поиск привел меня к выводу, что качественные платы занимают много места, а компактные – это совсем хлам, который не может выдать ток силой даже 1А, при этом такие платы греются, перегорают, в общем, вариант для детской игрушки не совсем безопасный
если взять два аккумулятора, чтобы получить 7.4В для питания напрямую через VIN, то возникают сложности с размещением внутри компактной игрушки 2-х элементов типоразмера 18650
можно было бы рассмотреть более компактные элементы 14500 или даже 10400, но к ним у меня также настороженное отношение, поскольку ребенок случайно может перепутать их с уже привычными ему NiMh аккумуляторами формата АА/ААА от своих радиоуправляемых игрушек, и в результате тоже что-то сгорит.
наконец, остается вариант с Li-Pol-пакетиком (также на 7.4В) – его уже ни с чем не перепутаешь, места занимает мало, но, к сожалению, этот вариант вызывает еще больше вопросов, чем решает. Такой аккумулятор надо делать либо съемным и заряжать внешним зарядным устройством (то есть пакетик будет не спрятан внутри игрушки, а будет в доступе у ребенка, а неосторожное обращение с Li-Pol это еще хуже, чем перепутать 10400 Li-Ion с NiMh), либо же внутри игрушки надо размещать еще и разъем для зарядки с BMS-платой (с ними те же вопросы качества и надежности, как с DC преобразователями).
![Самый простой вариант автономного питания для Arduino Самый простой вариант автономного питания для Arduino](https://habrastorage.org/getpro/habr/upload_files/644/b92/44f/644b9244f33d61fa4554a047a3700aa4.jpg)
В общем, в итоге я выбрал наиболее простое решение – светофор будет питаться от 9В батарейки типа «Крона». Тут, с точки зрения применимости в детской игрушке, одни плюсы:
невозможно перепутать полярность (несимметричные контакты)
компактный размер
можно подключить питание напрямую к Arduino, без дополнительных преобразователей и прочих схем защиты
Основной минус – это дороговизна и маленькая емкость Кроны. Сейчас это уже вряд ли минус: некоторое время назад появились и получили распространение аккумуляторы в типоразмере 6F22 со встроенной защитой и зарядкой (Аккумуляторы «Крона»: нюансы и подвохи), и в отличие от батареек, у них такого недостатка в принципе нет – ребенок вполне безопасно может сам перезарядить такой элемент питания от USB.
Питание адресной ленты, по-хорошему, надо было бы подключить через отдельную 5В линию, что потребовало бы уже понижающий преобразователь. Каждый светодиод потребляет в пике, на максимальной яркости в белом цвете до 50мА, но такая яркость оказалась совершенно избыточной, в комнатных условиях хватает 1/8 от максимальной, а в самых объемных изображениях у меня включается максимум половина из 32 светодиодов. Поэтому, я посчитал, что встроенного в Arduino Nano преобразователя на 800мА мне хватит и для питания матрицы.
Корпус для первоначального варианта
Прототип хотелось завершить и отдать ребенку побыстрее, поэтому все перечисленные выше элементы были втиснуты в какой-то стандартный корпус для РЭА с прозрачной крышкой, а в качестве опор для конструкции послужил белый кабель-канал 40х25 мм. Из всех функций, которые только можно придумать для светофора, в MVP попали буквально простейшие:
проверка светодиодной матрицы при включении питания
собственно индикация светофора при команде от пульта управления
переключения стиля: привычное последовательное включение сигналов красный-желтый-зеленый либо стартовый сигнал в стиле F1 (гаснущие по очереди красные огни)
![Сборка прототипа Сборка прототипа](https://habrastorage.org/getpro/habr/upload_files/8a1/09a/785/8a109a78511e46732f8d420817a50083.jpg)
За пару выходных, пока ребенок был на даче, первый прототип светофора был все-таки завершен и передан конечному пользователю на испытания. Естественно, мой сын был очень доволен такой необычной игрушкой, и я, конечно, тоже.
Развитие идеи год спустя
Еще в процессе создания первой версии, у меня постоянно появлялись идеи дополнительных функций, которые можно было бы реализовать в этой игрушке. Все они были исключены из MVP и отправлены, как это обычно случается, в бэклог.
Тем временим прошел год. Прототип за это время немного подустал, хоть и оставался вполне рабочим.
Этим летом ребенок был отправлен на дачу сразу на несколько недель, и я решил все-таки доделать задуманное. Предварительно нам удалось договориться, что на время каникул ребенок отдаст мне обратно старый прототип, чтобы я использовал его детали для создания новой, улучшенной версии (все-таки RGB LED HAT – достаточно ценная плата).
А задумок в бэклоге накопилось достаточно много:
Автоматическое отключение питания для экономии заряда аккумулятора
Сделать систему – к существующему светофору добавить аналогичную конструкцию, выполняющую роль финишной линии.
Добавить измерение и отображение скорости проезжающих машин с помощью оптического датчика (этот пункт позаимствован у Hot Wheels – раньше они выпускали дополнение для трасс под названием Digital Speedometer)
Контроль проезда на красный (фальстарт)
Измерение времени проезда между стартом и финишем
Дополнительный режим работы системы – подсчет кругов и лучшего времени круга
Добавить к светофору звуковые эффекты
Новый корпус, напечатанный на 3D принтере
По вечерам, за пару недель все из этого было постепенно реализовано.
Новая схема питания
В первой версии светофора включение и отключение питания осуществлялось с помощью закрепленного на корпусе обычного выключателя с фиксированными положениями. У такой схемы есть пара существенных недостатков. Первый – дребезг контактов при включении/выключении питания, что для электроники все-таки нехорошо. Второй, и главный, недостаток этой схемы – ребенок оставлял игрушку включенной, из-за чего аккумулятор приходилось очень часто заряжать.
Для решения этой проблемы я нашел вот такую схему управления питанием (https://compacttool.ru/praktika/knopka-vklyucheniya-pitaniya-dlya-arduino, раздел «Другой вариант схемы»)
![Схема для управления питанием Arduino Схема для управления питанием Arduino](https://habrastorage.org/getpro/habr/upload_files/8c9/b39/583/8c9b395833a2f6e7353819557131254b.png)
Схема позволяет включать питание нажатием тактовой кнопки, а отключать питание уже программно из Arduino – либо по таймеру, либо при обработке нажатия на эту же кнопку.
Удивительно, но до сих пор такую схему не реализовали и не продают в виде готового модуля (похожие модули – есть, но нет именно такого, где есть одновременно и программное отключение, и доступ к состоянию самой кнопки). Предполагаю, что такие модули пользовались бы популярностью среди начинающих любителей Arduino. А пока пришлось всю схему собирать самому прямо на макетной плате.
Оптический датчик проезда машинки
В рамку светофора теперь будет встроена оптопара. С одной стороны это ИК светодиод (с резистором конечно же), а с другой стороны – ИК датчик, представляющий собой небольшую схему из фотодиода и биполярного транзистора, которая позволяет регистрировать даже не очень сильные ИК сигналы.
![Оптический датчик Оптический датчик](https://habrastorage.org/getpro/habr/upload_files/24a/8df/bae/24a8dfbae800edf0020403a77c4333ff.jpg)
Номиналы компонентов на этой схеме приведены достаточно условно (а для ИК свето- и фотодиода их вообще нет, поскольку их не было на самих компонентах, которые оказались у меня под рукой). Поэтому, хотя я и перепроверил работоспособность оптического датчика, сделанного именно на этих элементах, возможно, в вашем случае нужно внести корректировки в соответствии с характеристиками конкретного транзистора, свето- и фотодиода. Также обратите внимание, что в отличие от светодиода, фотодиод подключается с обратной полярностью, у него катод – это «минус».
При включенном ИК светодиоде и отсутствии «препятствия» в виде машинки, ИК излучение попадает на фотодиод, поэтому ток идет через него «мимо» базы транзистора, этот транзистор оказывается закрыт, и на пине, предварительно переведенном в режим INPUT_PULLUP, считывается «1». При проезде машинки между источником и приемником ИК излучения, ток через фотодиод течь перестает и идет на базу транзистора, который открывается, в результате чего пин Arduino соединяется с землей, возникает прерывание и считывается «0». По сути, вся схема работает как кнопка, соединяющая с землей пин, изначально притянутый к питанию.
Таким образом можно, во-первых, определять сам факт проезда машинки через старт и финиш, а во-вторых, измеряя время, в течение которого на пине был «0», можно примерно вычислить скорость машинки:
где T - это время, в течение которого ИК датчик был закрыт машинкой, а L - длина машинки. Так как нет возможности программно измерить саму длину машинки, принимаем в качестве значения средний размер машинки масштаба 1:64 (Hot Wheels), это примерно 70мм.
Нужно учитывать, что ИК засветку может давать не только светодиод. Например, в теплую и солнечную погоду даже внутри помещения и на достаточно большом расстоянии от окна, естественного ИК излучения хватает, чтобы открыть чувствительный фототранзистор в оптическом датчике. Поэтому в коде при обработке сигналов датчика добавлены дополнительные проверки – явно случайные значения игнорируются, а также в целом делается проверка, реагирует ли датчик на включение и отключение ИК светодиода, либо же он всегда засвечен или, наоборот, постоянно закрыт каким-то препятствием и не реагирует на включение/отключение питания источника ИК излучения.
И, кстати, подобный оптический датчик можно купить в готовом виде (на маркетплейсах называется QT30CM) и хотя бы эту часть схемы не собирать на макетной плате.
![Уже готовый датчик с маркетплейса Уже готовый датчик с маркетплейса](https://habrastorage.org/getpro/habr/upload_files/37f/f47/bdf/37ff47bdfc5b942d0049609847f493d2.jpg)
Радиообмен между контроллерами Arduino
Теперь система будет состоять из двух рамок – старта и финиша. В каждом из них – свой контроллер Arduino, а точнее RF-Nano. Это очень универсальная и компактная плата, объединяющая в себе одновременно Arduino Nano (в том числе сохранено расположение пинов) и дополнительный контроллер NRF24L01, уже соединенный с необходимыми пинами самой Arduino. Использование RF-Nano значительно экономит место и сокращает число проводов на макетной плате.
При этом в модуле старта все равно остался приемник 433 МГц для получения сигналов от пульта дистанционного управления.
![RF-Nano RF-Nano](https://habrastorage.org/getpro/habr/upload_files/c61/8b8/23f/c618b823f8fd40e4a6c1bf81b4a90818.jpg)
Нюансы радиобмена:
NRF24L01 допускает только однонаправленный обмен данными, то есть в один момент времени контроллер может находиться либо в режиме прослушивания, либо в режиме отправки данных. Но можно имитировать полудуплексный режим радиообмена, когда контроллер большую часть времени находится в режиме прослушивания, переключаясь в режим отправки только при необходимости посылки данных, и сразу после этого возвращаясь обратно в режим прослушивания
NRF24L01 поддерживает отправку пакетов с контролем получения (получатель проверяет контрольные суммы и отправляет обратно отправителю Ack-и). Но сама отправка данных по радио все равно осуществляется с несколькими повторениями, чтобы получатель с больше долей вероятности получил корректные данные в условиях неустойчивого сигнала или при помехах. Так вот, похоже, что либо в самом чипе NRF24L01, либо в популярной библиотеке RF24 (до конца я так и не выяснил) есть встроенный механизм защиты, чтобы эти повторные пакеты не дошли до обработчика в коде. Такая защита от дубликатов безусловно хороша, но в случае, когда сами пакеты не очень разнообразные (а статусная модель системы старт-финиш не слишком сложная, и соседние пакеты обмена статусом выглядят одинаково), это приводит к игнорированию на стороне получателя тех пакетов, которые намеренно было отправлены со стороны отправителя. Потратил на отладку «неработающего» радиообмена и поиска «пропавших» пакетов несколько часов, в итоге после того, как понял в чем дело, добавил к каждому пакету timestamp, что сделало отличающимися соседние пакеты с одинаковыми данными внутри него.
LCD1602 и русские буквы
На финишной рамке расположен LCD дисплей, который должен отображать информацию о скорости и времени проезда машинки.
LCD1602 – достаточно стандартный элемент в Arduino проектах. Бывает нескольких видов:
Простейший вариант LCD1602, который требует целых 10 проводов для подключения к плате Arduino. Такими дисплеями, наверное, уже никто не пользуется (по крайне мере мне неизвестны причины, по которым это может быть оправдано применительно к Arduino)
LCD1602 с припаянным к нему I2C адаптером, что увеличивает размер модуля дисплея, но позволяет подключить его к Arduino всего 4 проводами
Неожиданно (для меня) обнаружился еще один вариант LCD1602 – на плате с чипом AIP31068. Этот чип имеет подключение сразу через I2C (то есть теми же 4 проводами), поэтому дополнительный I2C адаптер не требуется. Такой вариант LCD1602 в результате немного более компактный по размерам, поэтому он и был куплен.
![Сравнение размеров LCD1602 с чипом AIP31068 (слева) и с классическим I2C адаптером (справа) Сравнение размеров LCD1602 с чипом AIP31068 (слева) и с классическим I2C адаптером (справа)](https://habrastorage.org/getpro/habr/upload_files/bbc/ff4/2b3/bbcff42b330596a569258625fabb7872.jpg)
Для работы Arduino с дисплеем через AIP31068 была найдена готовая библиотека - LiquidCrystal_AIP31068
Тут нужно вспомнить другую особенность LCD1602 – абсолютное большинство экземпляров поддерживают только латинские символы. Для вывода кириллицы на «обычные» LCD1602 есть несколько Arduino библиотек, в их числе популярная LCD_1602_RUS
Я объединил эти две библиотеки в одну новую (LCD_AIP31068_I2C_WCHAR), с помощью которой стало возможно выводить кириллицу на LCD1602 с чипом AIP31068.
![Новая библиотека в действии Новая библиотека в действии](https://habrastorage.org/getpro/habr/upload_files/b17/a65/284/b17a652845013d26e41f6e7884725f50.jpg)
Схема сборки
Хотя старт и финиш отличаются набором используемых компонентов, я приведу общую схему их соединения – большая ее часть все же одинаковая. Для сборки понадобятся:
В двойном количестве все общие компоненты: RF-Nano, резисторы, транзисторы, светодиоды и фотодиоды, кнопки, аккумуляторы, buzzer модули
Для старта: RGB LED HAT 4x8 (либо аналогичная адресная лента / матрица), приемник с антенной на 433 МГц, пульт дистанционного управления
Для финиша: LCD1602 дисплей с подключением по I2C
![Схема компонентов Схема компонентов](https://habrastorage.org/getpro/habr/upload_files/6c9/75b/17f/6c975b17f453640c450f52651ba05d25.png)
Дополнительные комментарии по схеме:
питание оптических элементов подключено к пинам A2/A3, они хоть и аналоговые, но весь функционал цифровых в них тоже есть. Пришлось их использовать, потому что все цифровые закончились – те, что на схеме выглядят свободными, на самом деле уже заняты под SPI от NRF24L01
на схеме две разные шины питания – первая на 9В от аккумулятора для схемы управления включением / отключением Arduino, а вторая 5В уже от Arduino для подключения остальных компонентов
Скетч для старта и финиша тоже общий, разница в логике контроллера определяется через #define
внутри настроечного Settings.h
перед заливкой скетча. Можно было бы сделать чуть более продвинуто, и зашить эту настройку в EEPROM, но эта идея пришла уже только при написании статьи.
3D модель нового корпуса
Пока я отлаживал логику работы системы, все компоненты располагались прямо у меня на рабочем столе. Я сделал своеобразный тестовый стенд – по трассе, сделанной все из того же кабель-канала, ездила настоящая машинка Hot Wheels, что было очень удобно для экспериментов с оптическими датчиками.
![Тестовый стенд Тестовый стенд](https://habrastorage.org/getpro/habr/upload_files/b66/df6/8c2/b66df68c2c203fdb7b653a3182a62f86.jpg)
По мере готовности кода, все меньше и меньше оставалось желания делать новый корпус снова из подручных материалов – все-таки хотелось сделать новую игрушку более аккуратной и долговечной по сравнению с первым прототипом. Раньше у меня уже был некоторый опыт 3D моделирования, поэтому спроектировать форму для размещения электроники не составило особого труда.
![Разработка модели для 3D-печати корпуса Разработка модели для 3D-печати корпуса](https://habrastorage.org/getpro/habr/upload_files/b82/a5b/b1b/b82a5bb1be3bde1bc8fd1280d1fd97f7.jpg)
3D модель включает в себя несколько составных частей:
основной корпус с отверстием для вставки прозрачного акрила и размещением экрана за ним. Внутри корпуса предусмотрены крепления для внутренних компонентов
детали крепления LCD и RGB матрицы
крышки корпуса и отсека под аккумулятор
плоская подставка для старта и финиша с возможностью присоединения трассы Hot Wheels
Как ни странно, но крупных ошибок при проектировании модели удалось не допустить, и после того, как по заказу изготовили все детали, из них даже получилось собрать то, что задумывалось. Да, в некоторых местах все-таки пришлось что-то досверлить (немного не угадал с диаметром отверстий для ввинчивания саморезов), где-то присутствуют слишком большие зазоры (я оставлял максимальный рекомендуемый запас на погрешность принтера и усадку PLA материала, но, видимо, можно оставлять не такие большие запасы, как пишут в статьях), но в целом получившийся корпус превзошел в плане эстетики то, что я мог бы сделать из подручных материалов. Хотя тут, естественно, все зависит от прямоты рук и умения создавать ими материальные объекты, а не только писать код и двигать мышкой в 3D редакторе, мне, например, проще второе.
![Финальный этап сборки Финальный этап сборки](https://habrastorage.org/getpro/habr/upload_files/4c5/52f/069/4c552f0690764baf11b932ce2e83ae65.jpg)
Итоговую сборку деталей и заливку скетчей из Arduino IDE мы делали уже вместе с ребенком. И хотя ему еще и сложна для понимания вся электроника и код на С++, мне очень хочется, чтобы он уже сейчас знал, что находится внутри различных устройств и был готов к тому, что для получения работающего результата нужны желание, знание и терпение.
А пока что главный результат – это огромное количество положительных эмоций у всех участников процесса!
Исходники проекта
Все исходники проекта доступны в моем репозитории на GitHub, в том числе
код скетча Arduino
схема компонентов
STL объекты для 3D-печати
Комментарии (12)
ret77876
15.08.2024 14:07А если заменить на самом светофоре Arduino на wemos mini или подобную плату с встроенным WiFi трансивером. В таком случае в качестве пульта можно использовать любой телефон (с веб клиентом)
pink0D Автор
15.08.2024 14:07+2Можно, но отдавать ребенку дополнительно еще и девайс с наличием WiFi - это уже перебор, с таким девайсом интерес к машинкам пропадает сразу :)
И еще: WiFi + TCP стек дает солидный прирост к пингу между устройствами (порядка 3-5 миллисекунд в ESP8266). У NRF24L01, даже с Ack-ами - менее 1 миллисекунды. Не то чтобы такая разница очень критична в игрушечной телеметрии, но все же она есть.
Если использовать ESP8266/ESP32 - то там есть другой интересный протокол, под названием ESP-NOW, тоже 2.4 ГГц, но своя, закрытая, реализация от Espressif. Там пинги сильно ниже, чем в WiFi, т.к. стек сильно упрощен.
pink0D Автор
15.08.2024 14:07Но сама идея заменить 433 МГц на что-то альтернативное мне очень нравится.
На последнем видео можно заметить, что иногда не срабатывает прерывание по оптическому датчику, и круг не засчитывается. Пока до конца не разобрался, но, кажется, именно приемник 433 МГц является причиной - из-за обилия сигналов на этой частоте, даже не от моего пульта, приемник в любом случае генерирует тонну паразитных прерываний, они хоть и не проходят сквозь библиотеку RCSwitch, но задерживают обработку прерываний от другого пина - датчик не успевает срабатывать.
NutsUnderline
15.08.2024 14:07покупаем недорогую игрушку под названием RLT SDR смотрим эфир узнаем очень много нового. вообще дешевые радиомодули довольно "грубые", обычная "морзянка" по сути, но может и частота плавать и не совпадать, и с мощностью что нить не то...
в современном дроностроении популярен протокол на основе модулей с модуляцией LORA там и дальность и надежность и пинг хорошие
ret77876
15.08.2024 14:07Да, на 433 Мгц много шумов от раций охранников и кучи других пультов. Тем более эффективная антенна на 433 Мгц по размерам больше, чем на 2.4 Ггц
Swarg32
15.08.2024 14:07смысла лепить два модуля не очень много, разве что просто уже есть модули с мк и приёмо-передатчиком. это как минимум из-за габаритов. ещё есп стоят очень недорого, а ресурсов у неё прилично.
что с 8266, что с какой из 32х, если очень хочется или действительно нужно (в данном случае смысла не вижу совершенно) можно не использовать высокоуровневые протоколы, все эти соединения, шифрование и прочее. в некоторых есп есть блютуз, тоже иногда очень удобный вариант.
NutsUnderline
15.08.2024 14:07но в целом я чего не понял так это вообще зачем пульт светофору то, он как бы автоматически работать должен
damirg
15.08.2024 14:07+3Мне было поручено управлять игрушечным светофором и включать машинкам красный и зеленый свет
Самодельный светофор из деталей с алиэкспресса Тоже приходится сидеть и нажимать кнопки, пока ребенок играет в машинки))
tormozedison
15.08.2024 14:07+1В моём детстве такая хреновина содержала одну лампу накаливания, перемещаемую механически между тремя линзами.
Markscheider
А в покое (в режиме ожидания нажатия кнопки) она сколько потребляет?
pink0D Автор
В выключенном состоянии потребления нет - полевой транзистор находится в запертом состоянии, цепь разорвана.