http://habrahabr.ru/post/229459/
Достаточно трудно найти человека, который не смотрел бы замечательный советский фильм «Кин-Дза-Дза!»
Думаю, что у многих было желание собрать визатор — прибор, который позволяет отличать чатлан от пацаков.
Сейчас я расскажу, как можно собрать это замечательное устройство. Шуточное, конечно же :)
Нет ничего сложного в мигании светодиодами и писке пьезодинамиком. Самое интересное и сложное в этой задаче — получать всегда один и тот же результат для каждого человека. В голове было перебрано много идей, но в итоге было решено, что людей надо всё-таки как-то метить. Само собой, в первую очередь так пометить надо себя, чтобы гордо быть чатланином, перед которым должны делать «Ку!»
Однако, такая метка должна быть невидима для окружающих. Решение пришло достаточно быстро. Я взял пульт от телевизора и убедился, что он отлично пробивает сквозь футболку. Так было решено использовать в визаторе ДУ-приёмник типа TSOP17xx, а под футболку прятать маленькую плату с инфракрасным светодиодом, который соответственно должен мигать аналогично тому, как мигают светодиоды в пультах ДУ.
Делаем «метку»
Я быстро набросал плату такой метки:
В центре микроконтроллер ATmega8A. На самом деле это очень излишне, тут хватило бы и какого-нибудь ATtiny, но ничего проще у меня в наличии не было. Да можно было бы и вообще без микроконтроллера обойтись, но так гораздо проще подстраивать тайминги. Сверху два отверстия под ИК-светодиод, который включается через транзистор, и ещё два отверстия намечены, чтобы можно было продеть нитку и повесить устройство на шею.
Прошивка же проще некуда:
int main (void)
{
// Настраиваем ногу C3 на вывод
DDRC |= (1<<3);
while (1)
{
// Пауза в 50 миллисекунд между сигналами, иначе ДУ-приёмник будет его игнорировать
_delay_ms(50);
int t;
// Мигаем светодиодом 100 раз
for (t = 0; t < 100; t++)
{
// Включаем светодиод
PORTC |= (1<<3);
// Пауза в 11 микросекунд
_delay_us(11);
// Выключаем светодиод
PORTC &= ~(1<<3);
// Пауза в 11 микросекунд
_delay_us(11);
}
}
}
Мигание светодиода будет происходить постоянно, пока подаётся питание. У меня используется пауза в 11 микросекунд, что даёт частоту примерно в 45-46 килогерц. С этим значением стоит поэкспериментировать, оно зависит от типа ДУ-приёмника и сильно влияет на то, как хорошо сигнал будет ловиться через футболку.
Увы, для такого яркого (если так можно сказать про невидимый ИК-свет) свечения требуется достаточно большой ток, поэтому батарейки придётся прятать в карман. Достаточно двух AA батареек, но для полной надёжности лучше взять три или даже четыре.
Вот что получилось:
Если фотографировать себя в темноте и без вспышки, то можно увидеть как он просвечивает сквозь футболку:
Человеческому глазу это, само собой, недоступно. Кстати, крепить метку оказалось гораздо удобнее на обычный пластырь.
Делаем сам визатор
Итак, в визаторе у нас должны быть:
- Микроконтроллер, я взял ту же ATmega8A, но это опять же излишне
- ДУ-приёмник TSOP17xx
- Светодиод зелёный, для пацаков
- Светодиод оранжевый, для чатлан
- Кнопка включения
- Пьезодинамик, т.к. в фильме визатор издавал ещё и звук
Плата получилась такой:
Алгоритм работы такой:
- Пользователь нажимает кнопку, которая просто подаёт питание
- В течении половины секунды ждём сигнала от ДУ-приёмника
- Если сигнал был, зажигаем оранжевый светодиод, иначе зелёный
- В бесконечном цикле издаём соответствующий писк, пока питание не прекратится
Соответственно код:
// Немного дефайнов
#define LED_GREEN_ON PORTC |= (1<<2)
#define LED_GREEN_OFF PORTC &= ~(1<<2)
#define LED_ORANGE_ON PORTC |= (1<<1)
#define LED_ORANGE_OFF PORTC &= ~(1<<1)
#define SOUND_0 PORTD &= ~(1<<5)
#define SOUND_1 PORTD |= (1<<5)
#define SIGNAL (!(PINC&1))
int main (void)
{
// Вход для ДУ-приёмника
DDRC &= ~1;
// Подтяжка
PORTC |= 1;
// Светодиоды изначально выключены
LED_GREEN_OFF;
LED_ORANGE_OFF;
// Светодиоды на вывод
DDRC |= (1<<1) | (1<<2);
// Пищалка на вывод
DDRD |= (1<<5);
// На всякий случай немного ждём, пока питание будет стабильным
_delay_ms(50);
int t;
int chatlanin = 0;
// 500 раз ждём по миллисекунде
for (t = 0; t < 500; t++)
{
// Проверяем - есть ли сигнал на ДУ-приёмнике, если он есть, то это чатланин!
if (SIGNAL) chatlanin = 1;
_delay_ms(1);
}
// Включаем соответствующий светодиод
if (chatlanin)
{
LED_ORANGE_ON;
} else {
LED_GREEN_ON;
}
// Бесконечно воспроизводим звук
while (1)
{
// Высокий для чатлан
if (chatlanin)
{
SOUND_1;
_delay_ms(1);
SOUND_0;
_delay_ms(1);
}
// Пониже для пацаков
else
{
SOUND_1;
_delay_ms(7);
SOUND_0;
_delay_ms(7);
}
}
}
Плата визатора вместе с батарейкой получилась такой:
Простите за грязь на плате, у меня сломалась ультразвуковая ванна.
Затем я быстренько набросал 3D модельку корпуса, чтобы напечатать его на 3D принтере. В этот момент я уже не особо старался, поэтому получилось весьма колхозно:
Теперь можно разыгрывать друзей! Конечно, при условии, что они не читают Хабрахабр. Реакция обычно очень позитивная :) Видео с демонстрацией устройства в работе: