Диммер

kazakoff
Offline
Зарегистрирован: 07.06.2013

Всем привет, сделал диммер с этого сайта http://cxem.net/arduino/arduino71.php  делал я его для домашнего вентилятора на 220в, все хорошо вентилятором управляю, но хотелось управлять с ик пульта но тут пробелма библиотека IRremote использует timer2 и разработчик данного диммера тоже его использует, вот код

int AC_LOAD = 3;    // Output to Opto Triac pin
int dimming = 128;  // Dimming level (0-128)  0 = ON, 128 = OFF

void setup()
{
  pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
  attachInterrupt(0, zero_crosss_int, RISING);  // Choose the zero cross interrupt # from the table above
}
// the interrupt function must take no parameters and return nothing
void zero_crosss_int()  // function to be fired at the zero crossing to dim the light
{
  // Firing angle calculation : 1 full 50Hz wave =1/50=20ms 
  // Every zerocrossing thus: (50Hz)-> 10ms (1/2 Cycle) For 60Hz => 8.33ms 
  // 10ms=10000us
  // (10000us - 10us) / 128 = 75 (Approx) For 60Hz =>65
  int dimtime = (75*dimming);    // For 60Hz =>65    
  delayMicroseconds(dimtime);    // Off cycle
  digitalWrite(AC_LOAD, HIGH);   // triac firing
  delayMicroseconds(10);         // triac On propogation delay (for 60Hz use 8.33)
  digitalWrite(AC_LOAD, LOW);    // triac Off
}

void loop()  {
 
  for (int i=5; i <= 128; i++){
    dimming=i;
      delay(10);
   }
}

Далее нашел вот такой пример 

#include  <TimerOne.h>          // Avaiable from  http://www.arduino.cc/playground/Code/Timer1


volatile int i=0;               // Variable to use as a counter
volatile boolean zero_cross=0;  // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin = 11;                // Output to Opto Triac
int dim = 0;                    // Dimming level (0-128)  0 = on, 128 = 0ff
int inc=1;                      // counting up or down, 1=up, -1=down

int freqStep = 65;    // This is the delay-per-brightness step in microseconds.
// It is calculated based on the frequency of your voltage supply (50Hz or 60Hz)
// and the number of brightness steps you want. 
// 
// The only tricky part is that the chopper circuit chops the AC wave twice per
// cycle, once on the positive half and once at the negative half. This meeans
// the chopping happens at 120Hz for a 60Hz supply or 100Hz for a 50Hz supply. 

// To calculate freqStep you divide the length of one full half-wave of the power
// cycle (in microseconds) by the number of brightness steps. 
//
// (1000000 uS / 120 Hz) / 128 brightness steps = 65 uS / brightness step
//
// 1000000 us / 120 Hz = 8333 uS, length of one half-wave.

void setup() {                                      // Begin setup
  pinMode(AC_pin, OUTPUT);                          // Set the Triac pin as output
  attachInterrupt(0, zero_cross_detect, RISING);   // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
  Timer1.initialize(freqStep);                      // Initialize TimerOne library for the freq we need
  Timer1.attachInterrupt(dim_check, freqStep);      
  // Use the TimerOne Library to attach an interrupt
  // to the function we use to check to see if it is 
  // the right time to fire the triac.  This function 
  // will now run every freqStep in microseconds.                                            
}

void zero_cross_detect() {    
  zero_cross = true;               // set the boolean to true to tell our dimming function that a zero cross has occured
  i=0;
  digitalWrite(AC_pin, LOW);       // turn off TRIAC (and AC)
}                                 

// Turn on the TRIAC at the appropriate time
void dim_check() {                   
  if(zero_cross == true) {              
    if(i>=dim) {                     
      digitalWrite(AC_pin, HIGH); // turn on light       
      i=0;  // reset time step counter                         
      zero_cross = false; //reset zero cross detection
    } 
    else {
      i++; // increment time step counter                     
    }                                
  }                                  
}                                   

void loop() {                        
  dim+=inc;
  if((dim>=128) || (dim<=0))
    inc*=-1;
  delay(18);
}

И тут уже хорошо IRremote работает, НО опять проблема, вентилятором неудается управлять а лампочкой да.

Есть у кого какие идеи? как таймеры разрулить?

maksim
Offline
Зарегистрирован: 12.02.2012
kazakoff
Offline
Зарегистрирован: 07.06.2013

Спасибо, но я это пробовал это непомогает.

maksim
Offline
Зарегистрирован: 12.02.2012

Значит дело не в таймере.

carduino.ru
Offline
Зарегистрирован: 06.12.2011
kazakoff
Offline
Зарегистрирован: 07.06.2013

Ваш код так же неработает с IRremote.

kazakoff
Offline
Зарегистрирован: 07.06.2013

Если смотреть монитор то ir получает всякий мусор

maksim
Offline
Зарегистрирован: 12.02.2012

С вашим кодом выше это и не удивительно, так как вы в обработчике прерывания используете задержки, а вот если вы используете код #4, переписав его под 1 канал (убрать лишние каналы), то очень сильно сомникаюсь, что работа диммера будет мешать приему данных от ИК-приемника.

kazakoff
Offline
Зарегистрирован: 07.06.2013

Так ну пульт работает) но теперь проблема, неполучается управлять вентилятором на 220в

Код который я представил выше, можно управлять вентилятором.

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Я готовлю программную часть к своему регулятору нагревателя приточной вентиляции, написал функцию которая по прерыванию от Zero Cross в зависимости от полученного задания в % мощности пропускает или не пропускает определенные полупериоды равномерно распределяя на 100 полупериодов.

Немогли бы Вы проверить на своем железе работу моей функции т.к. мне до железа есче долеко (времени не хватает катострофически).

В Вашем скетче всего нужно заменить функцию zero_cross_detect() моей OutPWR().http://arduino.ru/forum/programmirovanie/algoritm-ravnomernogo-raspredeleniya

Буду примного благодарен. Если необходимо помогу с внедрением своей функции.

//тип переменных pwr - int, er- int, reg- int, out- boolean
void OutPWR()
{
	   reg = pwr + er; //pwr- задание выходной мощности в %, er- ошибка округления
	     if (reg < 50)
	       {
	         out=0;
	         er = reg ; // reg- переменная для расчетов
	       }
	          else
	        {
	          out=1;
	          er=reg-100;
	        }
	 digitalWrite(13,out);//пин через который осуществляется дискретное управление
}

Вот код из первого Вашего поста с замененной функцией обработчика прерывания по ZeroCross.

int AC_LOAD = 3;    // Выход на управляющий Triac
int dimming = 0;  // Уровень мощности (0-100%)  0 = OFF, 100 = ON
int reg = 0;
int er=0;
boolean out=0;
void setup()
{
  pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
  attachInterrupt(0, zero_crosss_int, RISING);  // Choose the zero cross interrupt # from the table above
}
// the interrupt function must take no parameters and return nothing
void zero_crosss_int()
{
  reg = dimming + er; //dimming- задание выходной мощности в %, er- ошибка округления
  if (reg < 50)
   {
     out=0;
     er = reg ; // reg- переменная для расчетов
   }
   else
   {
     out=1;
     er=reg-100;
   }
     digitalWrite(AC_LOAD,out);//пин через который осуществляется управление
}	

void loop()  {
  for (int i=0; i <= 100; i++)
  {
    dimming=i;
    delay(10);
  }
}