Dimmerde Ext int ve seri iletişim birlikte neden çalışmÄ

Başlatan sarikayamusa, 28 Mart 2008, 09:13:03

sarikayamusa

Kac gündür bir programla ugrasıyorum ancak işin icinden cıkamadım artık. foruma yazmaya karar verdim, insallah bu sayede yanlışımı bulduracak arkadaslar çıkar, zira artık aynı koda bakmaktan bıktım ve ümitsizliğe kapıldım denemediğim kalmadı. Kodun en sade şekli aşağıda.

Yapmak istediğim: Seri olarak gelen data ile ext interrupt rutinindeki süreyi ayarlamak. Hepsi bu. Ama bir kac kez datayı aldıktan sonra bilmediğim bir sebeple interrupt disable kalıyor veya disable oluyor? Nedendir bu acaba sayın dostlar?

ALICI:
#include <12f675.h>

#FUSES intrc_io,NOMCLR,nowdt
#use delay(clock=4000000)
#use rs232(baud=1200,rcv=PIN_A5)

signed int16 gecikme;

#define triac   PIN_A4
#define led     PIN_A0

#BIT INTF=0x0B.1
#BIT INTEDG=0x81.6

//*****************************************************************************
#int_Ext
void isr()
{
 
  if (gecikme>=0 && gecikme<=10000)  
  {
   output_low(triac);
   delay_us (gecikme);
   output_high(triac);
   delay_us(300);  
   output_low(triac);
  }
 
  INTEDG=!INTEDG;
  INTF=0;
  //clear_interrupt(INT_EXT);
}
//******************************************************************************
 //         #byte OSCCAL = 0x90   
 //         #rom 0x3ff = {0x3470}


void main()
{   

enable_interrupts(GLOBAL);
enable_interrupts(int_ext);
 
   for(;;)
   {
                  
         if(kbhit())
         {
          disable_interrupts(global);   // Herhangi bir seri data gelmişse disable yapki seri iletişim yapılsın!
          
           // INTRUPTLARI disable edersem  seri iletişimde problem olmuyor!
           if(getc()=='A' && getc()=='C') {  gecikme=100;  enable_interrupts(global);} 
           if(getc()=='K' && getc()=='P') {  gecikme=9900; enable_interrupts(global);}  
         }
           
          enable_interrupts(global);      // Seri data yoksa enable olsun.    
      
    }
}



VERİCİ:

#include <12F675.h>
#fuses intrc_IO,NOWDT,nomclr,put  //dikkat
#use delay (clock=4000000)
#use rs232(baud=1200,xmit=PIN_A2)


#define BUTON1  PIN_A1
#define BUTON2  PIN_A0
#define led     PIN_A5     


void main()

     {   
      do 
      {
      
       if(!input(BUTON2))
        {     output_high(pin_a1);
              printf("AC");
               delay_ms(150);
              
         }
         
        if(!input(BUTON1))
        {      output_low(pin_a1);
               printf("KP");
               delay_ms(150);
        }
     }while(true);
  }


Yardımcı olursanız sevinirim. Belki göremediğim yanlışlıklar yapıyorumdur.
Yanlışım nerde ya? Artık CCS den şuphelenmeye başlıyacağım....
Saygılar...

ete

Sorunun tam olarak ne olduğunu anlamadım ama tahmin edebiliyorum. İşin temelinde zaman paylaşım sorunu yatıyor. Bu konuda zamanında uğraşmış bir kişi olarak cevap yazıyorum. Ben basic de yazmıştım programı. Amacım RF ile dimmer kontrolü idi.
Seninki de benzer şekilde dimmerin kontrolünü yapmak.
Önce hemen belirteyim, dimmer fonksiyonunun yerine getirilmesi için ortalama  0 ile 9800 us lik bir gecikmenin verilmesi gerektiğini biliyoruz. Bu gecikmeleri vermezseniz dimmer fonksiyonu yerine getirilemiyor ve lamba yada kontrol ettiğiniz elemanda kırpışmalar başlıyorki dimmer konusunda hiç de hoş olmayan bir durum.
İşin RF yada seri iletişim yönüne bakarsak, bütün bilgi bit bazında alınıyor ve 1-2us lik gecikmeler bile bu bilgilerin alınmamasına sebep oluyor. İşte Sorunun esas kaynağı burada. Sağlıklı bir haberleşme için sizin seri bilginin alındığı yerde biraz zaman harcamanız gerekiyor. Şayet seri bilgi alımı esnasında kesme oluşurda siz triac gecikmesini vermeye giderseniz gelen bilgiyi de kaçırmış oluyorsunuz. Çünki gelen bilgi orada sizi beklemiyor . Kesme esnasında siz bir iki biti kaçırınca sistem düzgün çalışamıyor tabiiki.
Diyelimki seri haberleşme esnasında kesmeleri kapattınız. Bu durumda bilgi alışı kusursuz çalışacak ama bu seferde dimmer aksayacak.
Sonuç olarak bu olaydan kaçış yok.
Bu konuda çalışan sistemler olduğuna göre bu sorun bir şekilde aşılabiliyor. Epeyce düşündüm. Çözüm, daha kısa zamanlara bölünmüş kesme oluşturmakta yatıyor galiba ama henüz tutarlı bir yol bulamadım desem yeridir. Zaten uğraşmaya değer bir konu değil deyip bıraktım. Sonra bir ara tekrar kafa yoracağım.

Şimdi düşünüyorumda Seri iletişimde hiç şansın yok. Çünki ya alacağın bilgiyi 10 ms lik sürelerden daha kısa bir sürede alacaksın yada başka bir yol bulacaksın. 10 ms den daha kısa süre derken belkide sıfır geçiş noktasını 50 Hz bazında yakalaman gerek. Böylece bir 10 ms lik sana boşluk kalacak. Aksi taktirde 100 Hz lik sıfır geçiş noktaları bazında çalışırsan hiç boş zaman kalmıyor. 100 Hzlik sistemde hemen hemen hiç bir kırpışma olmuyor. Dimmerde güzel olan bu. 50 Hz kontrolde lambanın kırpıştığını görebiliyorsunuz.  İşin zor kolay gelsin.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

sarikayamusa

ETE
Allah razı olsun, yazmadığım şylerinde cevabını vermişsin walla,doktor gibisin.  :) Benimkide rf ile olacak bu arada.

Ben bu kodlarımla buton ile denedim yaptım cok saglıklı calısıyor hicbir kırpışma olmadan dimming ve acma kapama yapabiliyorum. MOC3051 kullanıyorum bu arada. Lakin "en kolay kısım canım nolcak bebek oyuncağı" dedigim seri iletişim de tabir caizse baltayı taşa vurdum. 3 haftadır aynı kodlarla ugrasmaktan kusuntu geldi artık. Gordugun gibi hatayı tespit edebilmek amacıyla kodu o kadar sadeleştirdimki..

Evet sorunum ya seri datayı kacırmak yada dimm yapamamak ikisinden biri mutlaka oluyor. Cozum noktasında senden anladığım: "datayı 10ms den daha kısa surede alabilirsen olur" değilmi?

Şu haliyle bir kac kez acma kapama yapıyor sonrasında ise interrupta girmesi gerekirken bazen girmiyor disable kalıyor. Sorunum böyle. F675 te seri interrupt olsa kullancamda oda yokki..
Acaba diyorum dimm işini her defasında ext intrpta yaptırmasamda bir kere zerocrossing yaptıktan sonra main icinde bir fonksiyona mı yaptırsam dimm işini? Olurmuki acaba?

Dedigine gore bu iş zor ha? Walla, çok azmetmiştim ama ümidim tükenmek üzere....

ete

Dedim ya ben çok düşündüm. Sonuçta tamamen farklı bir sistem yaptım dimmeri.  Bu konuda çözüm şöyle olabilir.
Mademki bizim triac tetikleme gecikmesi max. 10ms dolayında olacak. O halde bu süreyi dilimleyebiliriz. Kısaca 10 ms=10.000 us. ben bunu 100'e bölsem 10.000/100=100 elde ederim. O halde ben 10.000 us lik süre içinde beklemeyip bunu 100 defalık bier süreye bölsem bu arada da seri data geliyuormu diye baksam işim muhtemelen hallolacak.
Kısaca 10000 us lik bekleme süresini 100'e bölüp her 100 us de bir TMR0 kesmesi de oluştursam ve her kesmede gickme süresinden 100 çıkarsam sanırım bu iş olur gibi geliyor bana. Anlatımı biraz karmaşık oldu ama bir kez daha açıklayayım istersen.

Sorunun ana kaynağı triac gecikmesi esnasında benim kesme rutininden çıkamamış olmam. Orada beklemek zorunda kalmasam arada seri data alım işini yapsam muhtemelen sorun hallolacak. O halde bu bekleme süresini bir şekilde kademelere bölmem gerek. Onuda ancak TMR0 kesmesi ile yaparım herhalde. TMR0 kesemsini her zero cross kesmesi oluştuğu zaman açarsam ve bu aşamada süre=gecikme miktarı desem ve her TMR0 kesmesi oluştuğu zaman Süre=Süre-100 desem ve sıfır oluncaya kadar kesme oluşturmaya devam etsem. Sıfır olunca TMR0 kesmesini disable etsem, ve triacı off yapıp kesme den çıksam ve yeniden zero cross kesmesi beklesem nasıl olurdu acaba?
Mutlaka şu andaki neticeden daha iyi olur sanırım. Böylece seri haberleşme için yeterli zaman ayrılmış olur sanırım. Seri datayı da mümkün olan en kısa bilgi şeklinde organize edersen sorun büyük ihtimalle çözülecektir.
AKıl akıldan üstündür diye bir laf vardır. Bazen düşüncede kilitlenirsin. Belkide bu akıldan daha iyisini düşünecek arkadaşlar olabilir. Fikirlerini söyleyen çıkarsa sevinirim.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

ete

Bu arada belirtmeyi unutmuşum. Aslında HPWM kullanarak bir dimmer yapmak istiyor idim. Ancak HPWM sinyalleri ile AC voltajı kontrol etmek gerçekten zor ve hiç tecrübemin olmadığı bir konu idi. Bende bir arkadaşımın tavsiyesi üzerine 555 timer'ın bir özelliğini kullnarak bu işi yapmayı düşündüm vede yaptım. Yaptığım sistemle HPWM sinyali ile 0-5V arası değişen bir voltaj elde ediyorum ve 555'e trigger bacağına zerocross sinyalini giriyorum. 5 nolu bacaktanda 0-5v sinyalini girince 3 nolu çıkıştan istediğim gibi traic'ı kontrol edebileck sinyali üretebiliyorum. Bu şekilde yaptığım dimmer güzel çalıştı.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

sarikayamusa

Yani o halde ben bir 555 ve pic kullansam picle dataı alsam ve 555 lede bahsettigin sekilde triacı dimm yapma işinde kullansam olacak oylemi? Maliyeti yukseliyor aslında ama en azından çalışsa.

Benimse aklıma fikir olarak en son: Piyasada klasik dimmerler var hepimizin ic yapısını bildigi. Ondaki potu cıkarıp yerine 100k lık dijital pot entegresi kullansam olmazmı?  Veya diger bir secenek dijital pot entegresinin yapacagı işi pice yaptıramazmıyız? Aslında seninkine cıkıyor gibi bunun sonu yine .....

Selametle

ete

Digital potların +5V da çalışması gerekiyor. Sorun orada.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

aliveli

bir adet ssr (solid state relay) alıp girişinede pwm vererek duty cycle da yapacağın ayarlama ile dimming yapabilirsin
yada
sadece lamba dimmimg yapacaksan köprü diyot ile gerilimi dc ye çevir
daha sonra da gene transistör-mosfet(bc 547-ırf 540) ikilisi ile pwm kullanablirsin
ayrıca yazdığın kodlara dikkat etmeni öneririm

sarikayamusa

Alıntı YapAliveli
bir adet ssr (solid state relay) alıp girişinede pwm vererek duty cycle da yapacağın ayarlama ile dimming yapabilirsin
yada
sadece lamba dimmimg yapacaksan köprü diyot ile gerilimi dc ye çevir
daha sonra da gene transistör-mosfet(bc 547-ırf 540) ikilisi ile pwm kullanablirsin
ayrıca yazdığın kodlara dikkat etmeni öneririm


tam anlayamadım kastettigini?
sadece lamba dimming yapacagım ve triac kullanıyorum, pwm ile nasıl olacak dimming?  bahsettigin sekilde lamba (220VAC ampul) dimm işini hangi elemana yaptıracagım,mosfete mi? tam anlayamadım?Eger pwm ile yapabilirsem problemim de cozulebilir aslında? Rica etsem biraz acabilirmiisn?
Ayrıca kodda yanlısım nerede ben bulamadım? Neresine dikkat edeyim?
Saygılar...

aliveli

pwm kullanabilmem için ilk olarak  220v ac yi uygun köprü diyotla dc'ye çevirmen gerekir.Flamanlı lambalar(ampul) için ac dc farketmez

Daha sonrada devreni pic->bc547->mosfet->lamba şeklinde bağlayarak pwm uygulayabilirsin.(pic mosfeti direk süremez)
#include <12f675.h>

#FUSES intrc_io,NOMCLR,nowdt******buraya NOLVP eklemelisin 
#use delay(clock=4000000)
#use rs232(baud=1200,rcv=PIN_A5)

signed int16 gecikme;

#define triac   PIN_A4
#define led     PIN_A0

#BIT INTF=0x0B.1******bunları niye kullandın?
#BIT INTEDG=0x81.6*****

//*****************************************************************************
#int_Ext
void isr()
{
 
  if (gecikme>=0 && gecikme<=10000) 
  {
   output_low(triac);
   delay_us (gecikme);
   output_high(triac);
   delay_us(300); 
   output_low(triac);
  }
 
  INTEDG=!INTEDG; ***???
  INTF=0;
  //clear_interrupt(INT_EXT);
}
//******************************************************************************
 //         #byte OSCCAL = 0x90   
 //         #rom 0x3ff = {0x3470}


void main()
{   

enable_interrupts(GLOBAL);
enable_interrupts(int_ext);
 
   for(;;)
   {
                 
         if(kbhit())
         {
          disable_interrupts(global);   // Herhangi bir seri data gelmişse disable yapki seri iletişim yapılsın!
         
           // INTRUPTLARI disable edersem  seri iletişimde problem olmuyor!
           if(getc()=='A' && getc()=='C') {  gecikme=100;  enable_interrupts(global);}
           if(getc()=='K' && getc()=='P') {  gecikme=9900; enable_interrupts(global);} 
         }
      ***Eğer vericiden bilgi gelmezse aşağıdaki satır ile saniyede 1 milyon kez
      ****enable interrupt yaptırmış olursun sanırım bu nedenlede interrupt sapıtıyor
      **if'in içine yazmalısın
          enable_interrupts(global);      // Seri data yoksa enable olsun.   
     
    }
}


rf ile çalışacaksan lamba kısmı ile alıcı modul arasını iyi izole etmen gerekir ki parazit olmasın

iyonosfer

@sarikayamusa

interrupt rutini içinde gecikme kullanmamaya çalışın, hele hele bu koddaki gibi gecikmeler hiç kullanmayın. gecikmeler için timer kullanın, timer gecikmeyi oluştururken kodunuz calışmaya devam etsin :). şöyle birşeyler yapabilirsin

boolean tetikleme;

ext_isr_rutini() {

set_timer1(xdegeri)  // tetiklemeyi başlatacağın yere kadar gecikme 
enable_interrupts(int_timer1);
INTEDGE = !INTEDGE

}


timer1_isr_rutini() {

disable_interrupts(int_timer1);

if(tetikleme) {
output_low(triac);
tetikleme = 0;
}
else {
tetikleme = 1;
output_high(triac); // tetikleme puls oluşturuldu
set_timer1(xdegeri) // 300 us gecikme için ayarlanacak değer
enable_interrupts(int_timer1);

}

}

main() {


diğer_işlemler()

}

Ben ilk çalıştığım işyerinde dimmer çok yaptım.  hem powerline haberleşiyor hem buton kontrolü var. tamamen interruptlar kullanılarak yapılması gerekiyor sağlıklı çalışması için.
Blog Sayfam: www.teknobakis.com

sarikayamusa

Danıstıgım ahmet arkadasımda senin dedigin seyi soyledi yani gecikmeyi delay fonksiyonuyla deil, timer ile ayarlamamı.Simdi deneyecegim gercek ortamda bakalım sonuc ne olacak?
Syglr...

sarikayamusa

Alıntı yapılan: "aliveli"
rf ile çalışacaksan lamba kısmı ile alıcı modul arasını iyi izole etmen gerekir ki parazit olmasın

Aliveli.
Şu izole konusunda ne yapmalıyım biraz izah edebilirmisin? Parazit olmaması için Ne şekilde ve nasıl izole yapmam gerekli? fikir verebilirimisn biraz?

ete

izole den kast ettiği şey arada MOC021 gibi bir opto izolatör kullanmak sanırım.
MOC021 sıfır geçiş noktası tespiti olmayan bir opto izolatördür. MOC040 seirisinde zero crossing vardır dikkat et.

Bu arada triak tetikleme gecikmesini Timer'a verip sonucu alabildinmi. Sonucu derken RF ile birlikte çalıştırabildinmi?.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

sarikayamusa

Alıntı yapılan: "ete"izole den kast ettiği şey arada MOC021 gibi bir opto izolatör kullanmak sanırım.
MOC021 sıfır geçiş noktası tespiti olmayan bir opto izolatördür. MOC040 seirisinde zero crossing vardır dikkat et.

Bu arada triak tetikleme gecikmesini Timer'a verip sonucu alabildinmi. Sonucu derken RF ile birlikte çalıştırabildinmi?.

Ete

Suan denemelerim; alıcı verici picleri - seri olarak direk bagladım. RF e gecmedim henuz ve triac gecikmeleri timer ile yaptım. Sonuc aldım evet. İstersen sana kodları yollıyım. Sadece bir sorunum var oda, parlaklıgı azaltırken belli bir voltajın asagısında lamba voltajı birden 120Vlere filan cıkıyor ve parlaklıkta kırpışmalar oluyor anlamadım bunu. (Lamba voltajı 10Vların altına dustugunde 120-130V oluyor?)

Bu arada benim optom MOC3052 ymiş. Zero crossing yok heralde bunda.
Henuz denemedim ama İzole dedigim sey AC şebekeden kaynaklanan parazitin rf iletişimi etkileyip etkilemeyecegi hususu? Bu konuda bir tavsiyen varmı?