220V AC Dimmer

Yayınlandı: Şubat 27, 2013 / AC dimmer, dimmer, DMX, DMX512, sıfır geçiş, Triac, zero cross

220V AC Dimmer

Bir ihtiyaçtan dolayı akkor lambalar için dimmer yapmam gerekiyordu.
Finalde 3 kanallı ve PC/DMX kontrollü bir kart olacak. 

AC sinyalde triac tetikleme ile ilgili dökümanlar, nette mevcut, o nedenle fazla detaya girmiyorum. Kısaca bahsetmek gerekirse, Çalışma mantığı şöyle;

  • Şebeke sıfır geçiş noktasını bul
  • istenilen gecikme kadar bekle
  • triac’ı tetikle

her alternansta bu işi tekrarla. 

AC gerilim altında, triac’ı 1 kez tetiklediğinizde, bir dahaki sıfır geçişine kadar iletimde kalır. 2 geçiş noktası arasında (50Hz şebekede 10mS) ne kadar önce tetiklerseniz lamba, o kadar parlak yanar.

Diyelimki lambayı %50 parlaklıkta yakmak istiyoruz.
Sıfır geçişini tespit ettik, timer’ı sıfırladık, 5mS bekledik ve triac’ı tetikledik. sonraki 5mS boyunca (bir dahaki sıfır geçişine kadar) triac iletimde kalacaktır.

Sıfır geçişini nasıl buluruz? Bunun da bir kaç yöntemi var. 
Benim kullandığım devre aşağıdaki gibi.

dimmer_zcross


Bu devrenin çıkışını PIC’in RB0 pinine giriyoruz. Gerekli interrupt konfigürasyonu yapıldığında, her sıfır geçişinde bir kesmemiz oluyor.

Bundan sonrası, gecikme zamanını saymak ve çıkışı tetiklemek.
Triac sürücü devresi de aşağıdaki gibi.

dimmer_driver


ben, BT138 triac ve sürmek için de MOC30xx serisi optodiac kulllandım. PIC ile doğrudan triac sürmek de mümkün. Test devresinde snubber kullanmadım. İsterseniz, triac’ın A1-A2 uçları arasına; 39ohm ve 100nf’ı seri bağlayabilirsiniz.

 Pic

PIC 16F628A XT: 20MHz


RA0 portu Triac sürücü devresine bağlanacak, RB0 girişi de sıfır geçiş dedektörünün çıkışına. RA1’de led var, bu led, sıfır geçişi algılanıyorsa, periyodik olarak yanıp söner.
Triac, 255 kademede sürülebilir. Kademe (parlaklık) ayarı için RA2 ve RA3 portlarına bağlı butonları kullanabilirsiniz. 

Aşağıda, devrenin giriş ve çıkış sinyallerini görebilirsiniz.
Kırmızı sinyal şebeke voltajıdır. Bu sinyalin sıfır geçişlerinde üretilen sinyal de yeşil ile gösterilmiştir. (zero dedektör çıkışı)

Sarı ile gösterilen sinyal de yarı güçte sürülen triac’ın tetikleme sinyalidir.

signal2
 Dimmer_ac


Not: Kullanılan dirençler, seçilecek komponentlere göre yeniden hesaplanmalıdır. 

 

//***********************************************************
//
// 16F628 – 20MHz AC Dimmer
//
// skymurat@gmail.com
//
//***********************************************************

program Dimmer_Test_F628;

var
counter, dim_val, delay: word;
say, j, k: byte;
zero_cross: boolean;

var triac: sbit at PORTA.0; //TRIAC out
var z_led: sbit at PORTA.1; //zero dedect led
procedure init_ISR;
begin
//TMR2 Prescaler 1:1
//TMR2 PostScaler 1:1
INTCON := 0;
T2CON := 0;
T2CON.TMR2ON := 1;
T2CON.T2CKPS1 := 0;
T2CON.T2CKPS0 := 0;

PR2 := 174; // Initialize Timer2 register
PIE1.TMR2IE := 1; // enable TMR2 interupt

INTCON.GIE := 1;
INTCON.PEIE := 1;
INTCON.INTE := 1; //Enable B0 interrupt

INTCON.INTF := 0; //clear flag
PIR1.TMR2IF := 0; //clear flag
end;

procedure interrupt;
begin
ClrWDT();

if (PIR1.TMR2IF <> 0) then begin //Period = 35,00 µs
inc(counter);

if (dim_val < 255) then triac := 0;

if (dim_val > 0) and (dim_val < 255) and zero_cross then begin
delay := (256 – dim_val);
if (counter = delay) then begin
triac := 1;
zero_cross := false;
end;
end;

PR2 := 174;
PIR1.TMR2IF := 0; // clears TMR2IF
PIE1.TMR2IE := 1; // enable TMR2 interupt
end;

if (INTCON.INTF = 1) then begin
zero_cross := true;
counter := 0;

inc(say);
if (say > 30) then say := 0; //300ms
z_led := (say > 15); //150ms blink

INTCON.INTF := 0;
INTCON.INTE := 1; //Enable B0 interrupt
end;
end;

begin
CMCON := 0x07; //all port digital, comparator off
OPTION_REG.7 := 0x01; //pull-up disabled
OPTION_REG.6 := 0x00; //rising edge of B0/INT

PORTA := 0x00;
PORTB := 0x00;
TRISA := %00011100;
TRISB := %11111011;

counter := 0;
dim_val := 50;
zero_cross := false;

init_ISR; //Timer2 & B0/INT set and active

while TRUE do begin
if (dim_val = 0) then triac := 0;
if (dim_val = 255) then triac := 1;

if Button(PORTA, 2, 1, 1) then begin
inc(dim_val);
if (dim_val > 255) then dim_val := 255;
Delay_ms(25);
end;

if Button(PORTA, 3, 1, 1) then begin
dec(dim_val);
if (dim_val < 1) then dim_val := 0;
Delay_ms(25);
end;

end;
end.
//***********************************************************************

Aşağıdaki linkten hex dosyasını indirebilirsiniz. 

Dimmer_Test_F628.hex

yorum
  1. huseyin ceran dedi ki:

    link kırık indiremiyorum

  2. seda balaban dedi ki:

    link kırık düzeltebilir misinizz

  3. ahmet dedi ki:

    merhabalar, projenize benzer bir proje yapıyorum. yazılım kısmında bir yerde takıldım yardımcı olurmusunuz.

    • sky dedi ki:

      merhaba, takıldığınız konu nedir?

      • ahmet dedi ki:

        triac deilde ben tristör ile dc dimmer yapıyorum.zero crossda 0 geçişleri yakalayıp potansiyometre kullanarak yani adc ile pulse gecikmesini ayarlamak istiyorum.fakat pot değerini değiştirmeme rağmen hep 0. saniyelerde tetikleme veriyor. mail adresim: a.burakacikel93@gmail.com dönüş yaparsanız proje dosyalarını burdan gönderebilirim.

        unsigned int x;
        unsigned char FlagReg;
        sbit ZC at FlagReg.B0;
        void interrupt()
        {
        if (INTCON.INTF){ //kesme oluşması için INTCON.INTF bayrağı kaldırdı
        ZC = 1;
        INTCON.INTF = 0;
        }
        }
        unsigned int sayi1, sayi2;

        void main() {

        ADCON0 =0b00000001;
        ADCON1 =0x0C;

        TRISA= 0b00000001;
        TRISD = 0b11111110; // RD0 is output
        TRISB = 0x01; //RB0 giriş yapıldı

        OPTION_REG.INTEDG = 1; //yükselen kenarda tetikleme
        INTCON.INTF = 0; // INT bayrağını sil
        INTCON.INTE = 1; //Rb0 KESMESİNE MÜSADE ET
        INTCON.GIE = 1; //BÜTÜN KESMELERE MÜSADE ET
        do
        {
        x = ADC_Read(0); // Get 10-bit results of AD conversion
        //PORTD = temp_res;
        //PORTE = temp_res >> 8; // Send 2 most significant bits to RC1, RC0

        sayi1 =x; // okunan değer
        sayi2 = sayi1/10;
        if(sayi2>42){
        sayi2=sayi2-1;
        }
        if(sayi2>84){
        sayi2=sayi2-1;
        }
        sayi2=sayi2/10;
        if (ZC){ //zero crossing oluştu

        Vdelay_ms(x); // tetikleme pulsenin gecikme süresi (ÇALIŞMAYAN KISIM)

        PORTD.b0 = 1;
        delay_us(1000); //1000us pulse göndersin
        PORTD.f0 = 0;
        ZC = 0;
        }
        }
        while(1);
        }

  4. serdar dedi ki:

    linki düzeltebilir misiniz

  5. Ahmet dedi ki:

    İyi günler kolay gelsin
    Ben bitirme projesi olarak sıfır geçiş tespiti yapan pic ile çalışan triyak ile sürülen ac motor hız kontrolü aldım fakat büte kaldım internette gördüğüm bir iki proje de çalışmadı sizde gördüğüm çalışma var onun devre şemasını açık ve net bir şekilde hatta varsa proteus haliyle atabilir misiniz

  6. ömer ateş dedi ki:

    iyi günler kolay gelsin

    Ben proje ödevi için pıc16f877a ile dimmer devresi yapıyorum ve bunun için bana yazılımı ve isis konusunda yardımcı olabilir misiniz

    • sky dedi ki:

      Merhaba,
      Nasıl bir yardım istiyorsunuz?
      isis için nette bolca döküman bulabilirsiniz.
      PIC’e Hangi derleyici ile yazacaksınız? Kaynak kod sayfada var, microPascal ile yazacaksanız F877’ye uyarlamak yeterli.
      Başka bir derleyici kullanacaksanız, yine bu koddan faydalanabilirsiniz.

  7. Abdullah Güven dedi ki:

    devreyi proteusta denetim led yanıp sönuyor fakat triyak tetikleme sinyali çıkmıyor..

    • sky dedi ki:

      Merhaba,
      bu devreyi yapıp çalıştırmıştım, proteus’da da çalıştı diye hatırlıyorum çünkü osiloskop çıktısını almışım.
      led yanıp sönüyorsa interrupt çalışıyor demektir. burada dim_val değerinin 0’dan büyük olması lazım, tetikleme için.
      örnek kodu kullanıyorsanız bu değeri kod içinden verip deneyebilirsiniz.

Ahmet için bir cevap yazın Cevabı iptal et