habrahabr

Визатор своими руками

  • суббота, 12 июля 2014 г. в 03:10:54
http://habrahabr.ru/post/229459/

Достаточно трудно найти человека, который не смотрел бы замечательный советский фильм «Кин-Дза-Дза!»
Думаю, что у многих было желание собрать визатор — прибор, который позволяет отличать чатлан от пацаков.



Сейчас я расскажу, как можно собрать это замечательное устройство. Шуточное, конечно же :)

Нет ничего сложного в мигании светодиодами и писке пьезодинамиком. Самое интересное и сложное в этой задаче — получать всегда один и тот же результат для каждого человека. В голове было перебрано много идей, но в итоге было решено, что людей надо всё-таки как-то метить. Само собой, в первую очередь так пометить надо себя, чтобы гордо быть чатланином, перед которым должны делать «Ку!»

image

Однако, такая метка должна быть невидима для окружающих. Решение пришло достаточно быстро. Я взял пульт от телевизора и убедился, что он отлично пробивает сквозь футболку. Так было решено использовать в визаторе ДУ-приёмник типа 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
  • Светодиод зелёный, для пацаков
  • Светодиод оранжевый, для чатлан
  • Кнопка включения
  • Пьезодинамик, т.к. в фильме визатор издавал ещё и звук


Плата получилась такой:



Алгоритм работы такой:
  1. Пользователь нажимает кнопку, которая просто подаёт питание
  2. В течении половины секунды ждём сигнала от ДУ-приёмника
  3. Если сигнал был, зажигаем оранжевый светодиод, иначе зелёный
  4. В бесконечном цикле издаём соответствующий писк, пока питание не прекратится


Соответственно код:
// Немного дефайнов
#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 принтере. В этот момент я уже не особо старался, поэтому получилось весьма колхозно:



Теперь можно разыгрывать друзей! Конечно, при условии, что они не читают Хабрахабр. Реакция обычно очень позитивная :) Видео с демонстрацией устройства в работе: