Привет!
28 декабря, за четыре дня до Нового года, у меня возникла проблема: я осознал, что имеющие в продаже новогодние гирлянды — редкостная китайская дрянь. Дело в том, что у меня дома маленькая искусственная ёлка, а также маленький ребёнок — поэтому я не хотел, чтобы на ёлке в каком-либо виде присутствовали 220 В, а также не нуждался в гирляндах на несколько сотен лампочек. И быстро обнаружил, что после вычёркивания всего, подпадающего под эти пункты, в окрестных магазинах остаются исключительно товары категории «обнять и плакать».
Поэтому мне пришлось сделать гирлянду самому. И у этой гирлянды есть IP-адрес.
Впрочем, если говорить серьёзно, я преследовал две цели: не только сделать гирлянду себе, но и показать вам, как на нашем нанокомпьютер Black Swift можно делать различные проекты, от накопленных до вполне себе профессиональных — чтобы показать вам, что это довольно просто и быстро. С попутным обсуждением разных интересных моментов.
Текст рассчитан на людей, которые более-менее понимают, как пишут программы, умеют держать в руке паяльник, но не более того — с какой стороны подойти к нанокомпьютеру с OpenWRT, остаётся загадкой. Попробуем её отгадать, тем более, что весь процесс не требует каких-то особенных (выходящих за вышеуказанные рамки) знаний или специального оборудования — программаторов, адаптеров и т.п.
Так как это — первая статья по теме, я разобью её на три части, чтобы не получалась огромная простыня:
- Гирлянда, подключение Black Swift и среда сборки под OpenWRT на C/C++
- Управляющая программа на C и прямая и быстрая работа с GPIO
- Веб-интерфейс и приложение для Android
В реальном времени все три части легко укладываются в рамки «проекта выходного дня».
Итак, сама гирлянда. Ассортимент ближайших магазинов был широк, но печален, поэтому, потыкавшись в сайт Чип-и-Дипа (у них, скажем так, недёшево, но 28 декабря альтернатив было мало), её саму я также решил спаять.
На гирлянду нам потребуется много провода сечением 0,2-0,3 кв.мм., много разноцветных светодиодов (я выбрал Betlux с углом 160 градусов — яркие, крупные с широким углом, удобные в монтаже), и много резисторов. Впрочем, резисторов — вдвое меньше, чем светодиодов: я решил включать светодиоды встречно-параллельно, поэтому на каждую пару нужен только один резистор. Это сокращает количество проводов, хотя усложняет управление гирляндой.
Ножки светодиодов были отогнуты на 90 градусов прямо у основания корпуса (вообще так делать не стоит — корпуса не рассчитываются на такое приложение нагрузки, но для себя и с пониманием риска сломать пару светодиодов — можно), после чего спаял их попарно. Удобно объединять синий с жёлтым и красный с зелёным — не только с точки зрения цветовых сочетаний, но и потому, что у этих моделей Betlux у разных цветов разная полярность включения светодиода. При таком сочетании цветов вместе соединяются одинаковые выводы, что уменьшает путаницу.
К каждой паре припаивается по одному резистору, номинал считается стандартно R > (U — 2,5)/0,02, где U — напряжение питания гирлянды, 2,5 В — примерное падение напряжения на светодиоде (зависит от цвета, но нам большая точность не нужна), 0,02 А — максимальный ток через светодиод. При питании гирлянды от +5 В сопротивление получается 125 Ом, соответственно, берём резисторы на 130 или 150 Ом. Конкретно у меня был мешок резисторов на 1 кОм и блок питания на 15 В, поэтому гирлянду я питал от 15 В, а на плату поставил дополнительный стабилизатор на 5 В — но вам так делать не обязательно.
У меня в гирлянде было 80 светодиодов (спасибо, добрый продавец, что ссыпал все четыре цвета в один пакетик!), одновременно при встречно-параллельном включении могут работать 40 из них, это ток 0,8 А. То есть банальной зарядки от мобильника на 5 В 1 А для счастья хватит.
Провода были нарезаны, зачищены, запаяны и закрыты термоусадкой. Это наиболее банальная часть, отмечу только два момента: во-первых, к середине чувствуешь себя китайской девочкой на конвейере и начинаешь ценить секунды, во-вторых, гирлянду я сделал из двух независимых веток — красно-зелёной и сине-жёлтой.
Для управления этим хозяйством нужны четыре полумоста: по два на каждую ветку, чтобы обеспечить возможность переключения полярности питания светодиодов и, соответственно, выбирать цвет. К счастью, есть такой прекрасный чип, как L293D, в котором как раз собраны четыре полумоста.
Схема получается сравнительно банальной:
Пять транзисторов на входе (подойдут любые маломощные N-MOSFET) нужны для согласования уровней напряжения: Black Swift работает от +3,3 В, L293 — от +5 В. В принципе в некоторых случаях можно подключать выход 3,3-В схемы к входу 5-В без согласования, но осторожно: во-первых, надо быть уверенным, что напряжения «1» на выходе первой хватит для уверенного переключения второй, во-вторых, и это важнее, что в обратную сторону ничего за пределами 0...3,3 В не прилетит ни при каких обстоятельствах.
Для двустороннего согласования есть специальные микросхемы (хотя можно и двустороннее на транзисторах), но так как у нас согласование одностороннее, а на календаре уже 29 декабря, делаем, долго не думая, из первых попавшихся транзисторов. У меня это были IRLML6344, если вам интересно.
Собираем это всё на макетке и подключаем Black Swift:
Обратите внимание, что подключён он у меня очень простым способом: в нужные линии GPIO и питания просто запаяны провода. Не самый универсальный способ, но зато очень простой и надёжный. Отдельного стабилизатора для BSB не надо — он может питаться от тех же +5 В, что и L293D.
Подготовка OpenWRT
Писать основное приложение я буду на C, а потому мне нужна среда сборки. К сожаления, штатная среда — OpenWRT SDK — работает только под Linux, к счастью, у меня есть домашний сервер под CentOS 6.
Если у вас тоже есть такой или похожий, вам достаточно скачать и распаковать на нём штатный SDK для платформы ar71xx. Он только для платформы x86-64.
Если у вас линукс бегает на каком-нибудь стареньком 32-битном процессоре (я знаю, у многих так), то мы собрали для вас SDK под 32 бита. Вот он.
Если у вас вообще нет линукса, то мы сделали для вас образ виртуальной машины для Oracle VirtualBox с установленным в нём CentOS 6 и уже распакованным в папку /home/openwrt/Openwrt-SDK-BB вышеупомянутым SDK. ОС и SDK 32-битные, поэтому работают примерно на всём; пароли — root/openwrt и openwrt/openwrt. Вот этот образ.
Итак, скачиваем виртуальную машину, распаковываем zip-файл в vdi, запускаем VirtualBox, создаём новую VM под 32-битный линукс и в качестве диска для неё указываем имеющийся vdi-файл. Запускаем, загружаемся, делаем cd Openwrt-SDK-BB — и voila, мы готовы к работе.
Пакеты для сборки лежат в каталоге packages, который пока пуст. Точнее говоря, в оригинальном варианте там лежат не сами пакеты, а только Makefile, в котором указано, откуда исходиники пакета скачивать — и при сборке они скачиваются, распаковываются и компилируются. По крайней мере, в 99 из 100 примеров по сборке под OpenWRT описывается именно эта схема.
В нашем случае это довольно неудобно — вряд ли вы будете программу управления самодельной елочной гирляндой первым делом заливать на GitHub. Поэтому напишем Makefile, который будет брать исходники тут же, ниоткуда их не скачивая.
Итак, пути будут:
packages/treelights — общая папка
packages/treelights/src — исходники программы
packages/treelights/Makefiles — инструкции для OpenWRT
Теперь пишем сам Makefile для OpenWRT. Он не контролирует то, как именно пакет будет собираться, это дело других makefile'ов, которые уже будут лежать внутри src — он описывает, что с этим добром должна делать OpenWRT.
include $(TOPDIR)/rules.mk
# Задаём имя пакета, версию, номер сборки. Имена переменных PKG_* - стандартные.
PKG_NAME:=treelights
PKG_VERSION:=0.0.1
PKG_RELEASE:=1
# Задаём каталог, в котором будет производиться сборка пакета. Здесь особой фантазии не надо
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
# Теперь пошли описания пакета
# Наш в меню пакетов OpenWRT попадёт в категорию утилит, в основную секцию, по умолчанию собираться не будет,
# называться в меню будет "Christmas tree lights controller", URL у него понятно какой
# Переменная DEPENDS тут приведена для примера - в ней надо перечислить пакеты, от которых ваш зависит
# Так как я пишу на простом C, на самом деле мне сейчас библиотека libstdc++ нужна не будет
define Package/treelights
SECTION:=base
CATEGORY:=Utilities
DEFAULT:=n
TITLE:=Christmas tree lights controller
URL:=http://black-swift.com
DEPENDS:=+libstdcpp
endef
# Описание пакета. Тут можно внутри блока написать про него что-нибудь длинное, на пару строк
define Package/treelights/description
Christmas tree lights controller
endef
# Действия перед сборкой пакета
# 1. Создаём каталог для сборки
# 2. Копируем в него исходники из нашего подкаталога src
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
# Действия по сборке, ничего особенного нам не надо
define Build/Configure
$(call Build/Configure/Default,--with-linux-headers=$(LINUX_DIR))
endef
# Действия по установке
# 1. Указываем каталог для установки (если его в системе нет, он будет создан)
# 2. Фактически ручками копируем в него исполняемые файлы
# Если файлов для установки много (несколько исполняемых, конфиг какой-нибудь) - их все
# надо перечислить отдельными строками
define Package/treelights/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/treelights $(1)/usr/bin/
endef
$(eval $(call BuildPackage,treelights))
Положив такой Makefile в packages/treelights/, а исходники программы — в packages/treelights/src/, можем смело из корня папки OpenWRT SDK запускать make menuconfig
Откроется меню конфигурации пакетов, внутри которого будет наша утилита Christmas tree lights controiller, по умолчанию выключенная. Ставим на неё курсор, жмём пробел — перед утилитой появляется отметка (M), означающая, что она будет собрана отдельным пакетом.
Выходим из menuconfig, сохраняя конфигурацию, и запускаем собственно сборку пакета командой make package/treelights/compile
Если всё проходит хорошо — через несколько секунд в папке bin/ar71xx/ появляется подкаталог, в котором лежит наш пакет в файле формата ipk. Забираем его оттуда в удобное нам место, подключаемся к включённому Black Swift, например, с помощью WinSCP, копируем на него этот файл. Открываем любимый SSH-клиент, подключаемся им к консоли BSB и запускаем команду opkg install treelights*ipk. Ещё несколько секунд — и можно запускать программу, она лежит в /usr/bin/treelights и готова к работе. Удаление программы — opkg remove treelights, обновление — снова opkg install, удалять вручную старую версию перед обновлением не требуется.
Если сборка проходит с ошибкой — запускаем её снова командой make package/treelights/compile V=99, выводящей подробную выдачу компилятора, со всеми ошибками.
Если у нас несколько пакетов, которые надо собрать одновременно — просто говорим make или make V=99, без указания конкретного пакета. Соберётся всё, что было включено в menuconfig. Команда make clean стирает промежуточные файлы, созданные при сборке, make dirclean — промежуточные и финальные файлы, make distclean стирает всё, возвращая папку в первоначальное состояние.
Другие подробности о сборке под OpenWRT можно посмотреть на официальном сайте.
Автор: olartamonov