пятница, 27 августа 2010 г.

Простой индикатор посетителей

В предыдущем посте я писал о том, как поднял сервер со своей домашней страничкой на роутере D-Link DIR-320 под управлением OpenWrt. Разумеется, мне хотелось узнавать о новых посетителях странички. Заглядывать в логи быстро надоело и возникла идея сделать аппаратный индикатор посетителей. Хотелось, чтобы сигналы устройства не оставались незамеченными, так что вариант использовать светодиоды роутера сразу отпал. Также устройство не должно отвлекать внимание на чтение показаний, и в то же время должно уметь информировать меня о разных событиях. Ещё хотелось, чтобы устройство подключалось аккуратным шнуром к USB-хабу, а не кучей разномастных проводочков к GPIO, разведённым на плате роутера. Решение было найдено, и, в качестве бонуса, оказалось ещё и кросплатформенным :)

Пошарившись у себя в чемодане, я нашёл пакетик RGB светодиодов FYL-5015 RGBC. Светодиоды яркие и умеют светить почти любым цветом. То, что нужно!



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



В какой-то коробочке наткнулся на микроконтроллер ATmega48 (по проще не было) в DIP корпусе. Также были откопаны: кварц на 16 МГц, парочка стабилитронов на 3,6 В, несколько резисторов и конденсаторов, а также хвост от старой мышки.



Я использовал библиотеку AVR-USB (сейчас переименованную с подачи копирастов в V-USB). Эта замечательная и очень качественная библиотека умеет эмулировать порт USB 1.1. Для этой библиотечки есть несколько стандартных схем включения, я выбрал ту, в которой на микроконтроллере 5 В.



Нарисовал плату в Sprint-Layout, но тут меня ждал облом. Недавно купленный тонер абсолютно ни каким образом не хотел приставать к фольге. Порадовать себя качественной красивой платкой не удалось, пришлось лепить на каком-то огрызочке макетки :(



Прошивка очень простая, использует 2 таймера. На одном — программный, трёхканальный, восьмибитный ШИМ, второй — отсчитывает время вспышки и паузы, а также достаёт команды из буфера и перезагружает «регистр» ШИМа. Когда приходит Control Transfer-пакет, библиотека дёргает специальный коллбэк, который добавляет принятую команду в очередь. В ATmega48 целых 512 байт ОЗУ, что значительно превышает потребности этой простенькой прошивки, так что 75% ОЗУ отведено под очередь команд на 96 слотов. Одна команда занимает 4 байта — цвет в формате R8G8B8 и время вспышки в юнитах по 10 мс.

Простенькая программа управления была написана в среде Visual C с использованием libusb-win32. Утилитка парсит командную строку, ищет устройства с заданным VID:PID на шине и посылает им команды. Пример:

> blink 255,0,255,1000

Работает!



Кстати, стоит заметить на счёт VID:PID. Стандарт USB приписывает компаниям регистрировать VID (подобно тому, как регистрируются 3 байта MAC-адреса), понятно, не бесплатно. Поскольку у нас, естественно, нет желания регистрировать VID или покупать у кого-то пару VID:PID, можно или вопользоваться общедоступной парой, идущей в виде бонуса к V-USB, или придумать свою. Первый способ имеет массу недостатков, а иногда и вовсе не применим, второй способ их не имеет (если конечно, мы не хотим продавать наше устройство, особенно серийно). Себе я придумал VID 0xeffe, а PID'ы стал присваивать по порядку. Данный девайсик получил PID 0x0002 :)

Устройство я поместил вот в такую безделушку (по слухам, звёздочку кто-то откусил задолго до меня :) ).



Подключим устройство к роутеру, чтобы посмотреть определиться ли оно вообще (понадобится пакет usbutils):

$ lsusb
root@openwrt:~# lsusb
(...)
Bus 002 Device 008: ID effe:0002 redsh LedNotifer
(...)


Установим libusb:

$ opkg install libusb

Теперь нужно собрать утилитку управления под Linux. В этом нам поможет gcc. Аналогично, собрать утилитку под роутер нам поможет gcc из Buildroot'а OpenWrt.

$ gcc blink.c -lusb -out blink

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



Индикацию посетителей я просто интегрировал в счётчик посещений и другие скрипты сайта. Приход нового посетителя я обозначил белой вспышкой. Простую отдачу странички — синей, сообщение в гостевой — вспышками всех цветов радуги :) Простенький скрипт на Perl мониторит размер лога FTP, увеличение размера лога — и зелёная вспышка. Ещё я написал небольшой скриптик, позволяющий мигать светодиодом удалённо с помощью GET-запросов. Пример:

GET /lamp.php?r=255&g=100&b=0&ms=1500 HTTP/1.1

Есть и другие способы применения девайса. Например, научить светодиод мигать, когда кто-нибудь открывает твой топик, можно, разместив в нём картинку, генерируемую скриптом. Механизм, думаю, понятен.

Чтобы использовать устройство в Linux, достаточно установить библиотеку libusb и утилитку управления. Windows при подключении устройства попросит драйвер, тут пригодится подготовленный ini-файлик, который установит libusb-win32 и ассоциирует устройство с библиотекой. Небольшие проблемки возникли в Windows 7 (как известно, самой удобной и дружелюбной к пользователю ОС в истории человечества). Чтобы заставить драйвер libusb загружаться, достаточно всего лишь при каждой загрузке ОС нажимать F8 и отключать принудительную проверку цифровых подписей драйверов. Впрочем, есть информация, что libusb под Windows 7 всё же завели, уж не знаю — помогли танцы с бубном или библиотеку всё же подписали. Мне не очень интересно.

Скачать проект.

Успехов!


Источник: Хабрахабр - DIY или Сделай Сам
Оригинальная страница: Простой индикатор посетителей

Комментариев нет:

Отправить комментарий