Ардуино диммер на переменном напряжении 220В

Краткое описание работы Ардуино диммера
Работает регулятор мощности диммер в режиме фазового управления. Ардуино ловит прохождение синусоиды через нулевую точку переменного напряжения, когда ноль зарегистрирован контроллером, то от этой точки начинает отсчет времени для открытия симистора(отсечка лишней мощности). Arduino открывает симистор на 40 мкс и далее симистор в следующей нулевой точке закрывается сам, а контроллер начнет новый отсчет и так по кругу. Таким образом происходит отсечка полупериода. Чем больше отсечка тем меньше мощность.

Схема подключения диммера к Arduino
Резисторы 43 кОм желательно 0,5 Вт. Так как на них большое падение напряжение и при токе 2,5 мА рассеивается лишняя мощность примерно 0,5 Вт, по этому для безопасности лучше с двойным запасом.

Код для Ардуино
Приведенный ниже код использует timer1 и внешнее прерывание 0
Число одновременно работающих Dimmer каналов проверенных мной 10 шт. использовал для них выходы D4 по D13, можно увеличивать и дальше, но мне лень это было делать потому как больше 10 думаю ни кому не понадобится. Сразу скажу что 0-это максимальное свечение, 200-это минимальное свечение, 255 отключить свет. Для тестов добавил управление первым каналом Dimmer через UART. Если в сериал мониторе послать заглавную русскую букву "Г" то лампочка будет светится минимальным свечением. Если в сериал мониторе послать маленькую английскую букву "d" то лампочка будет светится на 50%. Если в сериал мониторе пробел то лампочка будет светится почти на максимуме.
#include "CyberLib.h" //Библиотека от Cyber-Place.ru
volatile uint8_t tic, Dimmer1, Dimmer2, Dimmer3;
uint8_t data;
void setup()
{
D4_Out; D5_Out; D6_Out; //Настраиваем порты на выход
D4_Low; D5_Low; D6_Low; //установить на выходах низкий уровень сигнала
D2_In; //настраиваем порт на вход для отслеживания прохождения сигнала через ноль
StartTimer1(halfcycle, 40); //время для одного разряда ШИМ
StopTimer1(); //остановить таймер
UART_Init(115200); //инициализация порта
//CHANGE – прерывание вызывается при любом изменении значения на входе;
//RISING – вызов прерывания при изменении уровня напряжения с низкого (Low) на высокий(HIGH)
//FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкий (Low)
attachInterrupt(0, detect_up, LOW); // настроить срабатывание прерывания interrupt0 на pin 2 на низкий уровень
}
//********************обработчики прерываний*******************************
void halfcycle() //прерывания таймера
{
tic++; //счетчик
if(Dimmer1 < tic ) D4_High; //управляем выходом
if(Dimmer2 < tic ) D5_High; //управляем выходом
if(Dimmer3 < tic ) D6_High; //управляем выходом
}
void detect_up() // обработка внешнего прерывания. Сработает по переднему фронту
{
tic=0; //обнулить счетчик
ResumeTimer1(); //запустить таймер
attachInterrupt(0, detect_down, HIGH); //перепрограммировать прерывание на другой обработчик
}
void detect_down() // обработка внешнего прерывания. Сработает по заднему фронту
{
StopTimer1(); //остановить таймер
D4_Low; D5_Low; D6_Low; //логический ноль на выходы
tic=0; //обнулить счетчик
attachInterrupt(0, detect_up, LOW); //перепрограммировать прерывание на другой обработчик
}
//*************************************************************************
void loop()
{Start
if (UART_ReadByte(data)) Dimmer1=data;
Dimmer2=195; //200=мин. 0=макс
Dimmer3=0; //200=мин. 0=макс
End}
3 комментария
- Почему не включать симистор в момент перехода через 0, а выключать уже по времени? В этом случае при сильноточной нагрузке пусковой ток через симистор будет мал, и риск выхода из строя устройства низок.