Показать сообщение отдельно
Старый 07.03.2018, 10:39   #827
Admin
Administrator
 
Аватар для Admin
 
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 9,240
Вес репутации: 9439
Admin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant future
По умолчанию

Регулировки диммера осуществряется энкодером https://duino.ru/product_info.php/in...ti-dimmer.html
Нажатием на энкодер можно вкл и выкл диммер, при этом диммер сохраняет уровень яркости и состояние выключателя. Если обесточить, то диммер прочитает последние состояние которое было до выключения
Код не проверялся на реальном устройстве, так что прошу отписаться после проверки
PHP код:
#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 ticdimmer;
boolean DT_laststat_swtmp// последнее состояние энкодера , состояние выключателя


void setup()  
{
  
pinMode(CLK,INPUT_PULLUP); // Clock Подключаем к INT1, нельзя переназначать
  
pinMode(DTINPUT_PULLUP); // выторой вывод энкодера
  
pinMode(SWINPUT_PULLUP); // кнопка энкодера
  
pinMode(ZDINPUT);     // детектор нуля
  
pinMode(GTOUTPUT);    // управление симистором
  
digitalWrite(GT0);    // отключить симмистор


  
attachInterrupt(0detect_upLOW);  // настроить срабатывание прерывания int0 на низкий уровень
  
attachInterrupt(1encoderTickCHANGE); // прерывания от Энкодера
  
  
StartTimer1(halfcycle40);        // время для одного разряда ШИМ в мкс
  
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(1stat_sw);//записать состояние выключателя
      
while( !digitalRead(SW)){}
      
StartTimer1(halfcycle40);   //запустить таймер
    
}
      else 
      if( !
tmp && !digitalRead(SW) && stat_sw )//если было нажатие кнопки и состояние выключателя вкл.
      

         
StopTimer1(); //остановить таймер
         
WriteEEPROM_Byte(0dimmer); //записать состояние диммера
         
dimmer=255;
         
stat_sw=false;//изменить состояние выключателя
         
WriteEEPROM_Byte(1stat_sw); //записать состояние выключателя
         
while( !digitalRead(SW)){} 
      }
  
  
//Serial.println(dimmer); 
  //Serial.println(stat_sw);
  
delay(50);         
}
//********************обработчики прерываний*******************************
void halfcycle()  //прерывания таймера

  
tic++;  //счетчик  
  
if( dimmer tic digitalWrite(GTHIGH); //управляем выходом на симистор
}


void  detect_up()  // обработка внешнего прерывания. Сработает по переднему фронту
{  
 
tic=0;             //обнулить счетчик
 
ResumeTimer1();   //запустить таймер
 
attachInterrupt(0detect_downHIGH);  //перепрограммировать прерывание на другой обработчик
}  


void  detect_down()  // обработка внешнего прерывания. Сработает по заднему фронту
{   
 
StopTimer1();                      //остановить таймер
 
digitalWrite(GTLOW);             //логический ноль на выход
 
tic=0;       //обнулить счетчик
 
attachInterrupt(0detect_upLOW); //перепрограммировать прерывание на другой обработчик



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 для следующей проверки

Admin вне форума   Ответить с цитированием