Дописал скетч, проверь если не затруднит
Теперь кнопкой можно вкл и выкл, при этом диммер сохраняет уровень яркости и состояние выключателя. Если обесточить, то диммер прочитает последние до выкл. настройки
Код:
#include <CyberLib.h> //Библиотека от Cyber-Place.ru
// Выводы ЭНКОДЕРА
#define CLK 3 // Clock Подключаем к INT1, нельзя переназначать
#define DT 4 // выторой вывод энкодера
#define SW 5 // switch кнопка энкодера
#define ZD 2 // zero detection детектор ноля
#define GT 6 // Gate Triac управление симристором
#define Min 0 // минимальное значение диммера для устранения мерцания
#define Max 255 //максимальное значение диммера для устранения мерцания
volatile uint8_t tic, dimmer;
boolean DT_last, stat_sw, tmp; // последнее состояние энкодера , состояние выключателя
void setup()
{
pinMode(CLK,INPUT_PULLUP); // Clock Подключаем к INT1, нельзя переназначать
pinMode(DT, INPUT_PULLUP); // выторой вывод энкодера
pinMode(SW, INPUT_PULLUP); // кнопка энкодера
pinMode(ZD, INPUT); // детектор нуля
pinMode(GT, OUTPUT); // управление симистором
digitalWrite(GT, 0); // отключить симмистор
attachInterrupt(0, detect_up, LOW); // настроить срабатывание прерывания int0 на низкий уровень
attachInterrupt(1, encoderTick, CHANGE); // прерывания от Энкодера
StartTimer1(halfcycle, 40); // время для одного разряда ШИМ в мкс
StopTimer1(); //остановить таймер
stat_sw=ReadEEPROM_Byte(1);
if(stat_sw) {dimmer=ReadEEPROM_Byte(0);}
else {dimmer=255;}
DT_last = digitalRead(CLK); // считываем положение CLK
Serial.begin(115200); // для отладки
}
void loop()
{
tmp=digitalRead(SW); //прочитать состояние кнопки
delay(50); // исключаем дребезг кнопки
if( !digitalRead(SW) && !stat_sw && !tmp)//если было нажатие кнопки и выключатель в состооянии выкл.
{
dimmer=ReadEEPROM_Byte(0);//прочитать состояние диммера
stat_sw=true;//изменить состояние выключателя
WriteEEPROM_Byte(1, stat_sw);//записать состояние выключателя
while( !digitalRead(SW)){}
StartTimer1(halfcycle, 40); //запустить таймер
}
else
if( !tmp && !digitalRead(SW) && stat_sw )//если было нажатие кнопки и состояние выключателя вкл.
{
StopTimer1(); //остановить таймер
WriteEEPROM_Byte(0, dimmer); //записать состояние диммера
dimmer=255;
stat_sw=false;//изменить состояние выключателя
WriteEEPROM_Byte(1, stat_sw); //записать состояние выключателя
while( !digitalRead(SW)){}
}
//Serial.println(dimmer);
//Serial.println(stat_sw);
delay(50);
}
//********************обработчики прерываний*******************************
void halfcycle() //прерывания таймера
{
tic++; //счетчик
if( dimmer < tic ) digitalWrite(GT, HIGH); //управляем выходом на симистор
}
void detect_up() // обработка внешнего прерывания. Сработает по переднему фронту
{
tic=0; //обнулить счетчик
ResumeTimer1(); //запустить таймер
attachInterrupt(0, detect_down, HIGH); //перепрограммировать прерывание на другой обработчик
}
void detect_down() // обработка внешнего прерывания. Сработает по заднему фронту
{
StopTimer1(); //остановить таймер
digitalWrite(GT, LOW); //логический ноль на выход
tic=0; //обнулить счетчик
attachInterrupt(0, detect_up, LOW); //перепрограммировать прерывание на другой обработчик
}
void encoderTick() // Обратка прерываний от Энкодера
{
uint8_t DT_now = digitalRead(CLK); // считываем текущее положение CLK
if (DT_now != DT_last) // если предыдущее и текущее положение CLK не равны, значит был поворот
{
if (digitalRead(DT) != DT_now) // если DT не равен CLK, значит вращение по часовой стрелке
{
if( dimmer < Max ) dimmer--; // прибавить яркость
} else { // если DT равен CLK, значит вращение против часовой
if( dimmer > Min ) dimmer++; // убавить яркость }
}
}
DT_last = DT_now; // сохранить положение CLK для следующей проверки
}