Главная » Статьи » Проекты

Диммер с сенсорной кнопкой

  По прошествии достаточного количества лет существования замечательного сайта avrproject.ru мной было сделано предложение о расширении его наполнения альтернативными проектами на микроконтроллерах фирм-конкурентов. В частности, в данной статье пойдет речь о применении МК всем известной фирмы Microchip, ну, то есть, как вы уже догадались – PIC контроллерах. Многие true-old программисты начинали свои проекты именно с них, переходя с контроллеров 51 серии, и по своей популярности они ничуть не уступают нашим любимым Atmel’ам. Некоторое время назад мной были куплены по дешевке десяток самых мелких и простых контроллеров PIC10F200 в шестиногом SOT23-6, и периодически туда-сюда я их использовал.
  Поскольку мне, в свое изучавшему в альма-матер язык программирования ПЛ/1, Ассемблер, Бейсик и Паскаль, вводя данные на перфокартах, так и не удалось заставить окостеневший разум привыкнуть к синтаксису линейки языков Си, для изучения возможностей Atmel пришлось освоить Bascom, то, соответственно, был произведен выбор в пользу бейсиков и для пикушек. Совершенно случайно я наткнулся на пакет программ от одного физика-теоретика, и это был не Стивен Хокинг и не Шелдон Купер. Итак, знакомьтесь: Владимир Сосо (Vladimir Soso) и его комплекс программных продуктов Oshonsoft. Предлагаемые им среды разработки (IDE) лично мне понравились своим единым интерфейсом, встроенным эмулятором, логическим «осциллографом», и, самое главное, генерацией ассемблерного листинга. Все программы платные с возможностью 30-ти пробных запусков. По ссылке есть скриншоты программы и описание всех её возможностей.

 

 

  В качестве примера давайте рассмотрим сенсорный регулятор освещенности (диммер) на напряжение 220 Вольт. Подвигнуть меня на изготовление данного устройства побудили следующие обстоятельства:
- достаточно частые перегорания ламп;
- отсутствия у домашних чувства «уходя, гаси свет;
- покупка нового светильника без встроенного выключателя;
- наличие необходимых запчастей и собственно готового устройства от Eddy71 – я думаю, многие его знают как разработчика ряда хороших устройств.
Спаянная плата с запрограммированным контроллером показала свою работоспособность согласно заявленному алгоритму, который мне по итогу не подошел – отсутствовал таймер выключения. Исходники отсутствовали, и было принято решение написать свой алгоритм. В процессе написания программы и ее отладки были внесены незначительные изменения в итоговую схему,  которая представлена ниже

 

 

 Принцип работы диммера всем известен, но повторение – мать учения:

 Каждую полуволну сети 50 Гц, то есть 100 Гц – 0,01 сек. (10 миллисекунд) микроконтроллер отсчитывает временной интервал времени для включения симистора – реализуется фазовое управление симистором. Т.е. регулируется мощность, подаваемая на лампу накаливания, и, тем самым, излучаемая яркость.  Одновременно идет подсчет времени для работы таймера. В случае светодиодных или люминесцентных ламп яркость регулировать не получится – надо замкнуть перемычку на плате – тогда данное устройство работает просто как таймер.
 Диммер различает продолжительность касания и защиту от кратковременных помех. При кратковременном касании сенсора (от 0,1 до 0,5 сек) происходит включение лампы. Контроллер обеспечивает плавное зажигание лампы накаливания, тем самым обеспечивая более долговременную ее работу. Касание сенсора длительностью от 0,5 до 1,5 сек. выключает лампу.
 В случае применения ламп накаливания по истечении запрограммированного времени яркость лампы снижается, экономя тем самым электроэнергию, и в дальнейшем тухнет окончательно.

 Текст программы с построчными комментариями:

Define CONFIG = 0x0009  'GP3 as input - нога 3 как вход

Symbol mode_in = GP3 'ножка определяет принцип работы - лампа накаливания или нет
Symbol gate_out = GP0 'выход на симистор
Symbol zero_input = GP1 'вход детектора нуля
'Symbol sens_input = GP2 - вход сенсора, подключенный к транзистору

'Переменные:

Dim zero_cross As Byte 'переменная для детектирования нуля
Dim touch_on As Byte 'длительность касания
Dim touch_off As Byte 'длительность отпускания сенсора
Dim power_on As Byte 'время включения симистора
Dim power_off As Byte 'время выключения симистора
Dim min_power As Byte 'минимальная мощность
Dim counter_decisecond As Byte 'счетчик сотых долей секунд
Dim counter_second As Byte 'счетчик секунд
Dim counter_minute As Byte ' счетчик минут
Dim timer_volume As Byte 'текущее значение таймера микроконтроллера

Const edge_zero = 15 'длительность детектирования нуля
Const gate_on_time = 20 'длительность включения симистора
Const max_count = 75 'максимальное значение цикла подпрограммы
Const count_cycle = 70 'значение таймера, при котором происходит отсчет времени
Const touch_first = 38 'значение таймера, при котором происходит опрос сенсора
Const touch_second = 40 'значение, при котором происходит анализ длительности касания сенсора

'начало программы
TRISIO = %1110 'устанавливаем ножку 1 как выход на ножку симистора
OPTION_REG = %11010110 
'Prescaler Rate 1:128  => 1 000 000 : 100 : 128 = Max count TMR0 = 78

gate_out = 0 'гасим симистор

' выбор режима работы
' если ножка mode_in заземлена, то диммер не используется

min_power = 1
If mode_in = 1 Then min_power = 50 'значение минимальной мощности лампы


' старт программы
start:

' детектор перехода с 0 на 1
zero_cross = edge_zero
While zero_cross > 0
If zero_input = 1 Then zero_cross = zero_cross - 1
Wend

Call work_mode()       ' вызов подпрограммы

'детектор перехода с 1 на 0
zero_cross = edge_zero
While zero_cross > 0
If zero_input = 0 Then zero_cross = zero_cross - 1
Wend

Call work_mode()        '  вызов подпрограммы

Goto start                '  возврат на старт программы

End                            '  конец программы


'тело подпрограммы

Proc work_mode()

TMR0 = 0 'обнуляем таймер микроконтроллера (МК)
timer_volume = 0 'и буферную переменную, куда данное значение копируется

While timer_volume < max_count 'пока значение таймера меньше макс. значения, выполняем цикл

        While timer_volume = TMR0 'ждем, когда значение таймера изменится
        Wend

        timer_volume = TMR0 'присваиваем буферной переменной значение таймера МК

' Проверяем, включен ли свет, если да, то назначаем время выключения симистора
        If power_on = 0 Then
                power_off = 0
        Else
                power_off = power_on + 5
        Endif
' конец данного условия

' Формируем импульс для симистора
        If power_on < timer_volume And timer_volume < power_off Then

        High gate_out
        WaitUs gate_on_time
        Low gate_out

        Endif
' конец данного условия

' в зависимости от значения буферной переменной, выполняем разные действия

        Select Case timer_volume

' Измеряем длительность касания/отпускания сенсора
        Case touch_first  'count length touch to on: 0.2-1s, to off > 1s
                zero_cross = GPIO And %00000110
                If zero_cross = %00000010 Then touch_on = touch_on + 1
                If zero_cross = %00000110 Then touch_off = touch_off + 1
' конец данного условия

' В зависимости от длительности касания/отпускания сенсора, включаем/выключаем лампу
        Case touch_second
                If touch_off > 20 Then
                        If touch_on > 50 And touch_on < 151 Then
                        power_on = 0
                        Endif
                        If touch_on > 10 And touch_on < 51 Then
                        power_on = min_power
                        Endif
                        touch_off = 0
                        touch_on = 0
                Endif
' конец данного условия

' В данном случае считаем количество импульсов для таймера
        Case count_cycle  'count second & minute
                If power_on = 0 Then
                        counter_decisecond = 0
                        counter_second = 0
                        counter_minute = 0
                Else
                        counter_decisecond = counter_decisecond + 1
                        If counter_decisecond = 250 Then
                                counter_second = counter_second + 1  '2.5 second
                                counter_decisecond = 0
                                If counter_second = 6 Then  '15 second - тестовый вариант
'If counter_second = 240 Then  '10 minute - рабочий вариант
                                        counter_minute = counter_minute + 1
                                        counter_second = 0
                                Endif
                        Endif
                        If counter_minute > 3 Then power_on = min_power
                        If counter_minute > 5 Then power_on = 0
                Endif

' Плавное зажигание лампы накаливания
                If power_on > 1 And counter_minute = 0 Then power_on = power_on - 1

' конец данного условия

        Case Else
        EndSelect

Wend
'  возврат в начало подпрограммы и ожидание следующего значения таймера МК

End Proc
' конец подпрограммы и возврат в основной цикл

 

 Ниже приведен универсальный (работа как с PIC10F200, так и с Attiny13) и усовершенствованный вариант платы диммера - добавлены помехоподавляющие элементы: RC цепочка (3*1,2 кОм и 0,1*275V) и дроссель 220 мкГн. Включение возможно как по трехпроводной схеме – основная разводка, так и по двухпроводной вместо обычного выключателя – добавлено место под перемычку. Данные элементы выделены красным цветом. Размер платы и расположение элементов выбирались исходя из корпуса – верхней части блока питания от старой Nokia, малогабаритный трансформатор от которой ушел на другие проекты. В качестве сенсора используется советский транзистор КТ605 с никелированной крышечкой – получилось достаточно эстетично. Плата выполнена на одной стороне, прикручена 3 шурупчиками к существующим стойкам и корпус в сборе посажен на двухсторонний скотч. Тиристор припаян к плате и вокруг него напаяно несколько ребер из жести для охлаждения. Видимое на фотографии отверстие служит для конвекции воздуха.

 

ВАЖНО: не забываем про работу с 220 Вольт. Диммер чувствителен к включению в розетку – при неправильной фазировке просто переверните вилку.

 

Перевести данный алгоритм в Bascom для Attiny13 не составит труда – главное правильно настроить порты и таймер, но эту задачу я оставлю желающим.

Пример настройки таймера на частоту 1,2 МГц приведен ниже.
TCCR0A = %00000000
TCCR0B = %00000011
OCR0B = 187
'Prescaler Rate 1:64  => 1 200 000 : 100 : 64 = Max count TMR0 = 187
'WDTCR = %00000100  'Prescaler Rate 1:32K = 0.25 sec

 

Печатная плата в формате Lay

Схема в Splan

Исходники и готовая прошивка

 

автор: Pchela5

 

Категория: Проекты | Добавлено: 24.05.2016
Просмотров: 17527 | Комментарии: 7 | Теги: dimmer, pic | Рейтинг: 5.0/6
Всего комментариев: 7
7 valeriy2650   (27.04.2018 09:26) [Материал]
Здравствуйте exersizze!
Прошу Вас заглянуть на страничку с "ЭНКОДЕР И BASCOM-AVR. СЧЕТЧИК ИМПУЛЬСОВ" пост 52

0  
6 exersizze   (09.01.2018 20:26) [Материал]
artcore, отпиши автору этого диммера, может он ответит. Адрес написал в личку

5 artcore   (01.01.2018 03:00) [Материал]
Доброго новогоднего настроения всем читающим =) из приведённого кода мне не понятен один кусок - как организован захват перехода волны как с минуса в плюс, так и с плюса в минус? этот завхат в коде прост в чтении, но логика в чём?

4 pchela5   (25.05.2016 17:25) [Материал]
Ну основная проблема - настройка управляющих регистров. Так даташит на используемый камень надо знать по-любому, имхо. А так языки схожи. Конкретный плюс при использовании мелких МК - генерация ассемблерного листинга, редактирование которого позволяет оптимизировать программу, если чуть не хватает памяти, а засунуть именно в данный камень надо.

0  
3 exersizze   (25.05.2016 15:05) [Материал]
Ага, язык то один. Дольше придется с аппаратной частью разбираться чем кодить, отличия все-таки в архитектуре значительные. На рутрекере есть патченные версии компилятора, в которых ограничений нет.

0  
2 RD3AVJ   (25.05.2016 11:55) [Материал]
Действительно похожи языки. То что среда платная - уже хуже. Проблема решена?)))

1 Scorpushka   (24.05.2016 20:36) [Материал]
занятно)

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]






авторизация