Главная » Статьи » Проекты |
Вот представьте, заходишь в комнату, темнота, ничего не видно, ползком по стеночке идешь до включателя освещения... Или просто лень встать и дойти до выключателя чтобы выключить свет в комнате.... а лень как известно двигатель прогресса. Захотелось собрать такую девайсину, чтобы свет вырубала по хлопку, но по одному хлопку слишком просто и не эффективно - будет светомузыка не по делу, поэтому сделал детектор двух хлопков с определенным интервалом. Заодно разобрался как задействовать прерывание от встроенного в МК компаратора.
При появлении первого хлопка, фиксируем его появление, запускаем таймер, выжидаем некоторое время чтобы эхо утихло и ждем появление следующего хлопка. Если следующий импульс пришел слишком рано и попал в красную зону, считаем что это посторонний шум и объявляем сессию ошибочной. Останавливаем и сбрасываем таймер, обнуляем переменные. Если импульс попал в зеленую зону (зону ожидания хлопка), фиксируем его появление увеличением значения переменной и ждем пока таймер переполнится и вызовет прерывание. Если после второго импульса была тишина, то в обработчике прерывания таймера переключим нагрузку. Если второй хлопок пришел слишком поздно и попал в красную зону будем считать, что это тоже был шум. Если после второго удачного хлопка, во время ожидания переполнения таймера, появился еще один импульс, так же будем считать что это шум и объявим ошибку. С общим алгоритмом разобрались, теперь к железу. В качестве мозга выбран attiny2313, с задачей бы справилась и attiny13, но такой мелочи у меня не оказалось. Да и памяти в мк остается свободной достаточно, чтобы навесить на устройство еще какую-нибудь задачку. Поэтому свободные ноги не помешают. Например, можно навесить фотодиод и позволять включать свет только когда достаточно темно. Или объединить устройства в общую сеть посредством UART и мониторить в какое время и на сколько включалось освещение. В общем почвы для фантазии более чем достаточно. В качестве исполнительного устройства, взял симистор BTB16-600CW и оптопару для него MOC3022 без детектора нуля. Хотя пойдет и с зеро-кросс, лампочке пофиг. Роль звукоуловителя у меня выполняет пьезопищалка от китайских часов, такие еще в системниках пищат. Пробовал динамик 3-ГДШ, ловит хлопки замечательно, а вот размеры совсем не те.... Если есть динамик КМЭ-3 его тоже можно применить в этой схеме (спасибо товарищу Вольдемору за испытания):
Использовав предусилитель, как на схеме:
Сигнал с динамика заводится на инверсный вход компаратора микроконтроллера. А на прямой вход заведен вывод с подстроечного резистора. Это позволяет регулировать уровень сигнала от которого будет срабатывать компаратор, тоесть настраивать чувствительность схемы. Вот что получилось:
$regfile = Attiny2313.dat
$crystal = 4000000 'частота 4 МГЦ Dim I As Byte 'проверяем эту переменную на число срабатываний, 'если равно 2 тогда нагрузку включаем/выключаем Dim R As Byte 'инкрементируем переменную в прерывании от компаратора Dim A As Word 'переменная которую приравниваем со значением таймера 1 Dim Fail As Bit 'переменная ошибки, если не равно 0, тогда в сессии 'произлошла ошибка. Нагрузка переключена не будет 'конфигурация перефирии 'настройка таймера1, переполнение будет происходить ~ каждую 1 сек Config Timer1 = Timer , Prescale = 64 , Capture Edge = Falling 'настраиваем компаратор на прерывание по нисхдящему фронту Config Aci = On , Trigger = Falling 'настраиваем выход для исполнительного устройство включения/выключения Config Portb.2 = Output 'настраиваем выход для подключения светодиода Config Portd.4 = Output 'настраиваем прерывание INT0, подключается кнопка Config Int0 = Falling 'ссылки на обработчики прерываний On Timer1 Res: On Aci Comp: On Int0 Button: 'разрешаем все что включили Enable Interrupts Enable Aci Enable Capture1 Enable Timer1 Enable Int0 'останавливаем и сбрасываем таймер Stop Timer1 Timer1 = 0 Portd.4 = 0 'выставляем на ноге светодиода 0 Do 'основной цикл программы If I = 2 Then Disable Interrupts Toggle Portb.2 I = 0 Reset Portd.4 Wait 1 Enable Interrupts End If Loop Comp: 'обработчик прерываний от компаратора Acsr.3 = 0 'вырубаем прерывания от компаратора If R = 0 Then 'проверяется значение переменной, если значение переменной равно 0, 'значит это первое срабатывание компаратора Incr R 'инкрементируем переменную Start Timer1 'запускаем таймер1 Set Portd.4 'зажигаем светодиод Waitms 110 'ждем некоторое время, чтобы не ловить эхо Else 'в противном случае (если переменная не равна 0) считаем, что 'это не первый импульс A = Timer1 'присваиваем переменной текущее значение таймера1 (для Т1 от 0 до 65535) If A <= 26000 Then 'если значение переменной меньше заданной величины (примерно 400 мс), 'тогда считаем что пришедший сигнал является шумом R = 0 'сбрасываем переменную Stop Timer1 'останавливаем таймер Timer1 = 0 'сбрасываем таймер в 0 Reset Portd.4 'гасим светодиод Else 'в противном случае, сравниваем переменную с другим значением If A > 40000 Then 'если переменная больше заданного значения (примерно 600 мс), 'считаем что сигнал пришел слишком поздно и он тоже является шумом Fail = 1 'ставится флаг ошибки Else 'в противном случае (второй сигнал пришел тогда когда нужно) Incr R 'увеличиваем значение переменной Waitms 110 'ждем чтобы исключить эхо End If End If End If Acsr.3 = 1 'снова включаем прерывания от компаратора Acsr.4 = 1 'сбрасываем флаг прерывания от компаратора, так как импульс пришедший 'вслед за предыдущим записывается сюда и как только закончится обработка 'первого события тут же произойдет обработка второго события, что вызовет ошибку. Return 'возращаемся в основной цикл и ждем прерывания от Т1 Res: 'прерывание от таймера1 Stop Timer1 'останавливаем таймер Timer1 = 0 'сбрасываем значение таймера1 в 0 Reset Portd.4 'гасим светодиод If Fail = 0 Then 'проверка флага ошибки, если ошибки нет тогда I = R 'присваиваем переменной значение другой переменной) R = 0 'сбрасываем первую переменную в 0 Else 'иначе, если флаг ошибки > 0 Fail = 0 'сбрасываем флаг ошибки в 0 R = 0 'сбрасываем переменную в 0 End If Return Button: 'прерывание от кнопки, можем включать/выключать нагрузку кнопкой Toggle Portb.2 Wait 1 Gifr = 64 'сбрасываем регистр хранения внешнего прерывания INT0 Return End А это уже испытания. Предупреждаю тех, кто захочит повторить: хоть развязка контроллера в схеме предусмотрена, все равно имеются открытые участки находящиеся под высоким сетевым напряжением. Лучше использовать симисторы в герметичных корпусах TO220FP или залить всю плату после сборки эпоксидкой....или постараться работать аккуратно. Короче я предупредил =)
В архиве ниже можно скачать откомпилированный файл. В нем также находятся исходник | |
Просмотров: 79657 | Комментарии: 189
| Теги: |
Всего комментариев: 189 | 1 2 3 ... 6 7 » | ||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
1-30 31-60 61-90 ... 151-180 181-189 | |||||||||||||||||||||||||||||
Проекты [46] |
Как подключить [32] |
Инструменты [3] |
Полезная информация [18] |
Объявления [3] |