Амперка corporate blog
19 October 2010

Ethernet-лампа для Continuous Integration и не только

image Всем хабрапользователям привет! Не так давно был запущен проект Амперка. Интерес был проявлен заметный, поэтому мы продолжаем развиваться. И это наш первый пост в корпоративный блог.

Сегодня мне хочется поделиться опытом создания гаджета на базе Ардуино, который может оказаться полезным и для вас. А если и не окажется полезным, надеюсь интересными окажутся отдельные моменты работы над устройством.

Этот гаджет — лампа, которая светится разными цветами в зависимости от сообщений, идущим к ней по локальной сети. Зачем это нужно? Лично мне, как участнику команды из четырёх программистов, эта штуковина нужна для индикации работы Continuous Integration сервера. Сервер, конечно, умеет при провале сборки посылать уведомления на e-mail и в jabber, но это скучно и не удобно: нет способа взглянуть куда-нибудь и мгновенно понять что происходит с проектом: всё в порядке, всё плохо или вот прям сейчас идёт сборка.

Проблема не новая. Я несколько раз читал как народ изголялся, прикручивая к компьютеру светофор, лава-лампы и usb-мигалки. Захотелось сделать что-то простое, что можно принести в офис, воткнуть в хаб и всё! И чтобы оно работало и без бубна. Что ж, попробуем!

Нам понадобится Ардуино, Ethernet Shield для него, бракованый светильник из Леруа-Мерлен, три светодиодные ленты разных цветов, горсть мелочёвки и запас терпения.

Устройство должно работать без настроек, сразу, черпая информацию из ethernet-хаба. Раздумывая над тем как лучше это сделать, я решил: а пусть лампа просто получает свой IP через DHCP, а потом слушает определённый порт и ловит UDP пакеты, которые говорят ей цвет, которым нужно светиться. Каким сказали последним, таким и светимся. А кто уж там их посылать будет, лампу не касается. Если сделать так, то гаджет можно будет использовать для чего угодно, не только для CI-сервера.

Прототип


Пусть устройство слушает порт 7190, и ловит пакеты вида: «4 байта заголовок, 1 байт — любой для будущих нужд, 3 байта RGB цвет». А если сигнала не будет 30 секунд, пусть светится белым: так можно будет понять, что что-то не так.

Садимся писать прошивку. И тут же первое разочарование: стандартная библиотека для Ардуино не предоставляет ни DHCP, ни UDP. Но Ардуино им бы не был, если бы не сообщество. Нужные разработки от энтузиастов нашлись довольно быстро (DHCP, UDP). Не стану загромождать кодом этот пост. Весь исходный код прошивки чудо-лампы открыт на Bitbucket. Здесь и сама прошивка и сопутствующие утилиты, о которых будет рассказано далее. Если просто интересно как выглядит код, начните копать с главного файла app.cpp. При базовом знании C++ код должен быть понятен.

Чтобы быстро тестировать понимает ли лампа сетевые пакеты, сделаем небольшой скрипт который бы из командной строки принимал цвет, который нужно вещать и вещал бы его, скажем, каждую секунду. Мммм… но какой IP выдадут лампе? Можно, конечно, заморочиться и реализовать какой-нибудь discovery-сервис для поиска ethernet-ламп в сети, но мне кажется — это перебор. Тут я вспомнил, что есть замечательная
штука IP-broadcast. Суть такова: если слать пакет на IP 192.168.1.255, то его услышат все устройства с IP вида 192.168.1.xxx.
Получился вот такой вот скрипт.

С software разобрались, берёмся за hardware. В прошивке, для управления цветами задействованы выходы 7, 8, 9 и предполагается, что будут использованы красный, зелёный и белый цвета. Собираем вот такую схему:

image

Прошиваем Ардуино. Ничего не работает! Исправляем, прошиваем, пробуем. Исправляем, прошиваем, пробуем. И так много раз пока код прошивки не становится отлаженым и делающим то, что от него требуется. Success!

image

На фото изображена ситуация, когда по сети посылаются пакеты с просьбой светиться красным и зелёным.

Больше света


Для прототипа использовались маломощные 5мм светодиоды. Слабовато для гикового светильника. А вот светодиодная лента для наружной рекламы — вещь, что нужно. Но есть небольшая проблема. Предполагается, что на ленту будет подаваться 12 В, а Ардуно на свои лапки может выдавать только 5.
Их не хватит даже на то, чтобы хоть как-то поджечь ленту. Если Ардуино запитать отдельным блоком питания, а не USB, можно подавать на вход от 7.5 до 12 В. Это напряжение затем, на самом Ардуино проходит через регулятор напряжения, чтобы превратиться в родные 5 В, но перед этим напряжение можно забрать с контакта Vin.

Решено. На ленты будем подавать Vin, а блокировать/разрешать течение тока будем с помощью транзисторов:

image

Включаем! Барабанная дробь… Штанга! Не светится! Ethernet shield, Ардуино своими лампочками мигают, а ленты молчат. Прозвонил всю схему: вроде бы всё должно работать. Но нет. Долго плясал вокруг до около, но без результата. Оставив всю конструкцию подключеной, ушёл делать чай. И каково же было моё удивление, когда вернувшись, я увидел, что белая лента светится. Тем самым устройство сообщало, что IP адрес получен, подключение есть, просто UDP-команд пока не было. Отлично! Посылаем команду, чтобы включился красный. Барабанная дробь… Снова штанга! Как был белый, так и остался.

Пару раз повторив экперимент я заподозрил, что Ethernet Shield'у не хватает питания. Да, так и есть. Если в дополнение к внешнему 12 В питанию подключить USB, то всё работает.

image

Пару часов пытаясь понять почему так я отступил и решил продолжить: ну и пусть USB нужно будет включать. Гаджет стационарный, «для себя», и к тому же так остаётся лазейка, через которую можно будет доступиться до микроконтроллера, не разбирая светильник.

Оставив работать устройство на продолжительное время, я заметил, что регулятор напряжения на Ардуино прилично разогрелся. Палец долго не продержишь. Поскольку хочется, чтобы лампа работала круглосуточно, на всякий пожарный, с помощью термоклея я прикрепил к нему маленький радиатор

image

Упаковка


Всю эту конструкцию теперь нужно поместить в корпус. Для этого я купил обычный светильник из непонятного мягкого материала, похожего на склееные вместе кусочки плотного полиэтилена. Итак, потрошим светильник: достаём всю родную начинку и отправляем её в мусорное ведро

image

Вместе с breadboard'ом поместить всё это дело внутрь светильника было проблематично. Не надёжно это. Поэтому с макетной доски переносим всю схему на монтажную плату. В качесте платы вполне подойдёт Proto Shield. Припаиваем ножки, устанавливаем транзисторы, распаиваем провода. Прозваниваем полученную плату, чтобы убедиться в том, что там где нужно контакты есть, а там где не нужно — нет. Вроде бы всё хорошо. Собираем конструкцию воедино. Получается вот такой вот бутерброд:

image

Скрещиваем пальцы, включаем. Работает!

Теперь все потроха необходимо разместить внутри кубика. Чтобы свечение было более равномерным, я спутал светодиодные ленты в клубок, зафиксировал их пластиковыми хомутами, а внутрь куба запихнул смятый полупрозрачный полиэтиленовый пакет. Для крышки было решено использовать квадратный кусок
картона. Ардуино прикреплён к нему с помощью двустороннего скотча.

image

Аккуратно закрываем крышку и фиксируем её на 4 шурупа, которые раньше держали родную начинку светильника

image

Интеграция с Team City


Именно эту систему мы используем в качестве CI-сервера. Теперь нужно сделать так, чтобы на нужные события, через IP-broadcast сервер отправлял понятные лампе UDP-пакеты. По-хорошему стоило бы написать плагин на Java для Team City. Вероятно, я в итоге его напишу. Но сейчас, чтобы не
тратить время на изучение API, воспользуемся quick'n'dirty способом: пусть будет скрипт, который раз в X секунд будет смотреть web-страницу отчёта Team City и по ней понимать в каком состоянии всё находится.

Исходный код скрипта находится там же, рядышком с прошивкой. Если у вас Hudson, CruiseControl, да что угодно — можно использовать аналогичный подход.

Генеральная репетиция


Создаём для нашей лампы интимную обстановку, делаем простенький проект в Team City, скрещиваем пальцы, всё включаем и замираем с чувством полного удовлетворения:

image
image
image
image

Что получилось и не получилось



Получилось решить задачу: у нас есть лампа, которая показывает в каком состоянии сейчас находится проект.

Кроме того, вещь получилась вполне самостоятельная и уведомлять она при желании может о разных вещах: уровне пробок на дорогах, работоспособности какого-нибудь сайта, наличии непрочитанных писем и т.д.

Не получилось сделать совсем простое устройство. Из лампы торчит аж три провода. USB явно лишний, но решить проблему питания так и не удалось. Да и само питание, быть может лишнее. Ведь есть же технология PoE (Power over Ethernet). Если приложить побольше усилий, то мне кажется можно сделать
так, чтобы из лампы торчал только патч-корд витой пары.

Тема с USB-питанием не даёт мне покоя. Быть может кто-то из хабраэкспертов сможет объяснить такое поведение? Заранее расскажу что я пробовал делать, чтобы обойти её:

  • Добавлял резервные конденсаторы к выходу Vin
  • Пропускал Vin через отдельный регулятор напряжения, выход с которого подавал на контакт +5 В самого Ардуино
  • Пробовал входной вольтаж 7.5, 9 и 12 В
  • Использовал блок питания на 1000 мА


Ничто из этого не помогло. Известно, что сам Ардуино употребляет не более 50 мА; Ethernet Shield — 150 мА; одна лента при 12 В — 45 мА. Есть мнения?

И в целом, как вам гаджет?

UPD: Сейчас на e-mail магазина написал человек, который видимо неправильно написал свой обратный адрес — не могу ему ответить, а написал он следующее:

а резисторы токоограничивающие в базы транзисторов не забыли??? Без них можно ардуино и спалить… Ну и их отсутствие однозначно может быть причиной повышенного потребления тока, вы же базами транзисторов ноги порта почти на землю закоротили.

И ведь он прав! И ведь это просто, как только я это упустил? Я подумал, что коли в самой ленте резисторы есть — всё ок, но они ведь не на том участке цепи. Спасибо, добрый человек!

+74
20.1k 59
Comments 33