DİJİTAL LCD FAN HIZ KONTROLÜ pic 16f877A HAK.

Başlatan Makmuh, 05 Nisan 2018, 15:40:31

Makmuh

İyi günler,
Fan hız kontrolunu yapmak istiyorum fan 220 volt yaklaşık 2-3 A akım çekiyor bunu dijital olarak kumanda etmek istiyorum. Kumanda sistemi 0 kapalı konum dan ayrı 5 kademe olarak yapmayı planlıyorum. Bir haftadır sitedeki diğer örneklere baktım ve anlamadığım yerler var onu sormak istiyorum size
1. Sorum kurmuş olduğum dimmer devresinde mantıksal bir hata var mı varsa nedir?
2. Sorum pic programında kesme kullanmam gerekiyormuş (okuduklarımdan anladığım) bu kesmeyi nasıl  aktif hale getirmemiz gerektiğini anlayamadım. Ve nasıl bir kesme  yapacağımıda anlamadım. Açıkcası kesmeler konusunda hiç birsey bilmiyorum. Nasıl bir program yazamam gerekir.


'****************************************************************
'*  Name    : ete.BAS                                   *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 12.05.2011                                        *
'*  Version : 1.5                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
'16F877A işlemci
@ __config _BODEN_OFF  & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _XT_OSC


CMCON=7
'-------------------------------------------------------------------------------
DEFINE OSC 4

ADCON1=7
OPTION_REG.7=0
'***********Port Ayarları***********
TRISA=%00000100
TRISB=%101111111
TRISC=%10000000
TRISD=%00000000
TRISE=%00000000
PORTA=0
PORTB=0
PORTC=0
PORTD=0
PORTE=0

'***********LCD Tanımlamaları***********

DEFINE LCD_DREG        PORTD    'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT        4        'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_EREG        PORTC    'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT        7        'LCD Enable Bacağı Hangi bite bağlı ?
define LCD RWREG    PORTC   'LCD R/W Bacağı Hangi Porta bağlı?
define LCD_RWBIT    6       'LCD R/W Bacağı Hangi bite bağlı ?
DEFINE LCD_RSREG    PORTC    'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT    5        'LCD RS bacağı Hangi Bite bağlı  ?
DEFINE LCD_BITS     4        'LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES    2        'LCD Kaç sıra yazabiliyor   

'***********Özel Karakter Tanımlamaları
LCDOUT $FE,$40, 6, 9, 9, 6, 0, 0, 0, 0 'Derece İşareti
LCDOUT $FE,$48, 4, 14, 4, 4, 4, 4,14,0 'İ Harfi
LCDOUT $FE,$50, 14, 17, 16, 16,16,17,14,4 'Ç Harfi
LCDOUT $FE,$58, 14, 17, 16, 14,1, 17,14,4 'Ş Harfi


'****************SEMBOLLER*********************

SYMBOL ARTI  =PORTB.4
SYMBOL OK=PORTB.5
SYMBOL EKSI=PORTB.6
SYMBOL OPTO=PORTC.0
'***********Sensör Tanımlamaları***********


FANSET     VAR WORD         ' FAN SET DEĞERİ 0-5 ARASI
SURE VAR WORD
I VAR WORD

'***********LCD yi Kullanıma Hazır Hale Getir***********

LOW PORTC.6 'RW bacağı ekrana yazmaya imkan vermek için LOW yapıldı.



lcdout $FE,1
PAUSE 200   ' LCD nin kullanıma hazır hale gelebilmesi için gerekli süre

LCDOUT $FE,$80,"FAN DIMMER"                 
LCDOUT $FE,$C0, "5 KADEME"
pause 1000
lcdout $FE,1 
FANSET=2
SURE=8500
'***********Program Başlangıcı***********
ON INTERRUPT GoTo KESME
BASLA:

LCDOUT $FE,$80,"FAN:",#FANSET,"."               
LCDOUT $FE,$C0, " KADEME"

IF FANSET=0 THEN
OPTO=0
ELSE
SURE=5000+700*FANSET
ENDIF
TOGGLE OPTO
PAUSE 4

   

'***************FAN AYAR KISMI***********
IF ARTI=0 OR EKSI=0 THEN
GOSUB FANAYAR
PAUSE 45
ENDIF
GOTO BASLA

'*******************KESME*****************
DISABLE


KESME:

PAUSEUS SURE
OPTO=1
PAUSEUS 10
OPTO=0

INTCON.1=0   
Resume 


Enable   



   
'*************************** FAN AYARAYAR YAP************************
FANAYAR:


lcdout $FE,1     
LCDOUT $FE,$80,"FAN HIZ AYARLA"                 
LCDOUT $FE,$C0, "FAN: ",#FANSET,". KADEME"       

pause 75
     
    if FANSET=5 then
    else
        if ARTI=0 then 
        FANSET=FANSET+1
        pause 100
        endif
    endif
     
    if FANSET=0 then
     else
         if EKSI=0 then
          FANSET=FANSET-1
         pause 100
         endif
     endif
          if OK=0 then
         LCDOUT $FE,$80,"AYAR KAYDEDILDI "
     pause 1000
     lcdout $FE,1
     goto basla
    endif
       
   
goto FANAYAR

END

ete

Biraz bilgiye ihtiyacın var senin. AC voltaj sinüs sinyal şekline sahiptir. X-Y koordinat eksini üzerinde düşünürsek, Sinyal X eksesnini her 10 ms de bir keserek bir aşağı bir yukarı çıkar. İşte X eksinini kestiği her noktada AC voltajı sıfırdır. Bu nedenle bu noktalara sıfır noktası adı verillir ve Kesmenin temel amacı bu noktaları yakalamaktır.
Her hangi bir aleti (bu motor , lamba , ısıtıcı vs olabilir) 220V ac ile çalıştırmak için arada ya bir röle yada bir Triac kullanırsınız.
Röle kullanılır ise zaten yapılacak hiç bir şey yoktur röle aktif olduğu müddetçe aleti sürer.
Ama bir devir yada voltaj kontrolü söz konusu olunca triac kullanmak zorunlu hale gelir. Triac öyle bir alettir ki bir kere Gate ucundan tetikledinizmi bir daha kapatamazsınız. Ama Sinüs sinyal şeklinden dolayı voltaj sıfır noktasında iken Triac da kesime gider. Çünki temel kural bunda giriş ile çıkış arasındaki voltaj farkı sıfır olmalıdır. Voltaj sıfır iken bu kaide geçerli olur ve triac kapanır. Yani voltaj geçirmez olur. Bu nedenle her sıfır noktasından geçtikten sonra triac yeniden tetiklenmelidir.
Bazı opto copuler triac lar MOC serisinden bunu otomatik yapar çünki içlerinde sıfır noktası tespit mekaniz ması vardır ve triacı yeniden tetikler. Ama MOC21 gibi opto triac lar yeniden tetikleme yapmazlar sizden bir tetik beklerler. İşte bunları kullanarak sıfır noktasından hemen sonra yada belirli bir süre sonra triac tetiklenerek cihazlar sürülür .
Bir lamba yı esas alır isek. Sıfır noktasından hemen sonra trac tetiklenir ise Lamba tam parlaklıkta yanar.  Şayet 10ms lik sürenin %30'u olan 3 ms sonra triac'ı tetiklerseniz lambanız %70 parlaklıkta yanar. Çünki %30 luk sürede lamba sürülmemiş olur.
Şayet triacı 5 ms sonra tetiklerseniz lambanız %50 parlaklıkta yanar. Bumantık çerçevesinde dimmerler yapılmıştır.
İşin temelinde bir devre yardımı ile sıfır geçiş noktası pic tarafından yakalanır (kesme ile elbette) sonra gerekli gecikme uygulanarak triac tetiklenir ve bu sisteme de dimmer adı verilir.

Yazdığın kodlar büyük oranda alıntı. Bu nedenle üzerinde kafa yormak yersiz.
Öncelikle sıfır geçiş yakalama sistemi üzernde çalışmalısın. Bu sitede daha önce iyi çalışan devrelere ait örnekler yayınlandı araştır bulursun. Bulamazsan haber ver ben bulayım yada arşivimi karıştırıp vereyim.

Kesmeler konusunda ise gerekli bilgi yine Bu sitede yayınlanan Basic Dersleri içinde bir ders konusu olarak anlatılmış bilgi mevcut. Şu kadarını söyleyeyim. Hariçten giriş yapılarak bir kesme oluşturacaksın buna INT kesmesi yada PORTB.0 kesmesi adı verilir Çünki PORTB.0 pininin bu özelliği vardır.
Yapman gereken ana program kısmında süre ayarına imkan tanıyacak kodları yazacaksın ayarlanan süre kadar kesme oluşunca program gecikme uygulayıp ardından Triacı tetikleyecek ve 100us bekleyip Triacı kapatacak. Sen kapatmış olsanda o kapanmayacak elbette taaki sıfır noktasına gelinceye kadar o noktada gate de tetik sinyali olmadığı için Triac kesime gidecek ve dimmer sistemin çalışmış olacaktır.

Hepsi bu.
Bu arada yer gelmiş iken söyleyeyim, Motor gibi bobini olan indüktif yükler bu tür dimmerler için pek uygun değildir. Sebebi motor bobinlerinin indüktans yaratarak sünüs işaretinde faz kayması yaratmasıdır. Bu bazı motorlarda çok belirgin olur ve bu sistem doğru dürüst çalışmaz bazılarında etkisi çok azdır nispeten çalışır Sistem daha ziyade dirençsel yükler için uygundur.
Endüktif yükler için Trail Edge dimmer sistemi kullanılır. her nedense bu konuda pek bilgi bulunmuyor devlet sırrı gibi pek açık edilmeyen bir konu. Temeli ise sıfır noktasından triac ın tetiklenmiş olarak çıkması ve uygulanacak gecikme noktasından triacın bir şekilde kesime götürülerek bir dahaki sıfır noktasına kadar sistemin kesimde kalmasının sağlanması. Tabbiki bu mantığa Triac Pek uymuyor. Bu nedenle bu sistemde Triac yerine Mosfet transistörler kullanılmaktadır.
SIrf merakımdan bu sistemi uğraşa uğraşa yaptım. İlk denememde gördümki motor devir ayarlamak için bu sistem gerçekten mükemmel.

Ete



Makmuh

O kadar yazı okudum hiç kimse yazmamış (yada bana denk gelmedi) 10 ms sıfırdan sıfır noktasına ulaşır. Sıfır noktasında tetikleme yaparsan %100 olur , 3 ms geçiktirirsen %70 olur diye kafamda çözemediğim yer buydu bu kelimeleri okuduktan  sonra kesmeleride dimmerleride biraz anlamaya başladım. Ama hala çok eksiğim.


Hocam söylediklerinizden anladığımı ben bi anlatayım yanlışlarımı siz düzeltiniz lütfen.
Hocam öncelikle yazdığınızdan anladığım bana kesmeyi tetiklemesi için sıfır geçiş noktasını yakalayan bir devre gerekli bu devreyi sizin daha önceki paylaşımlarınızdan aldım ve aynen kullandım
Osilatorun B çıkışına bağlı olan uçu  portb.0  girdim. Pic buradan tetik almasını sağladık.
OPTION_REG.6=1      'RB0 da YUKSELEN kenarda kesme oluşur.
INTCON=%10010000
kodlarıyla kesmeyi aktif hale getirdim
Benim dımmerim 5 kademe oluşacağı için
1 kademe de sure 8 ms dedim
2. kademede sure 6 ms dedim
....  5. Kademede sure 0ms dedım ve kesmeyi şu şekil yazdım.

'*******************KESME*****************
DISABLE
KESME:
PAUSE SURE
OPTO=1
PAUSEUS 100 '100 us bekleme suresi
OPTO=0
INTCON.1=0   
Resume 
Enable   

Program proteusta çalışmıyor  tetikleme olmuyor. Sorunun ne oldugunu anlayamadım. Devrenin son halini ve kodların tamamı burada yardımcı olurmusunuz.


'****************************************************************
'*  Name    : ete.BAS                                   *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 12.05.2011                                        *
'*  Version : 1.5                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
'16F877A işlemci
@ __config _BODEN_OFF  & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _XT_OSC


CMCON=7
'-------------------------------------------------------------------------------
DEFINE OSC 4

ADCON1=7
OPTION_REG.7=0
OPTION_REG.6=1      'RB0 da YUKSELEN kenarda kesme oluşur
INTCON=%10010000    'TUM KESMELER ACILDI

'***********Port Ayarları***********
TRISA=%00000100
TRISB=%101111111
TRISC=%00000000
TRISD=%00000000
TRISE=%00000000
PORTA=0
PORTB=0
PORTC=0
PORTD=0
PORTE=0

'***********LCD Tanımlamaları***********

DEFINE LCD_DREG        PORTD    'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT        4        'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_EREG        PORTC    'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT        7        'LCD Enable Bacağı Hangi bite bağlı ?
define LCD RWREG    PORTC   'LCD R/W Bacağı Hangi Porta bağlı?
define LCD_RWBIT    6       'LCD R/W Bacağı Hangi bite bağlı ?
DEFINE LCD_RSREG    PORTC    'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT    5        'LCD RS bacağı Hangi Bite bağlı  ?
DEFINE LCD_BITS     4        'LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES    2        'LCD Kaç sıra yazabiliyor   

'***********Özel Karakter Tanımlamaları
LCDOUT $FE,$40, 6, 9, 9, 6, 0, 0, 0, 0 'Derece İşareti
LCDOUT $FE,$48, 4, 14, 4, 4, 4, 4,14,0 'İ Harfi
LCDOUT $FE,$50, 14, 17, 16, 16,16,17,14,4 'Ç Harfi
LCDOUT $FE,$58, 14, 17, 16, 14,1, 17,14,4 'Ş Harfi


'****************SEMBOLLER*********************

SYMBOL ARTI  =PORTB.4
SYMBOL OK=PORTB.5
SYMBOL EKSI=PORTB.6
SYMBOL OPTO=PORTB.1
'***********Sensör Tanımlamaları***********


FANSET     VAR WORD         ' FAN SET DEĞERİ 0-5 ARASI
SURE VAR WORD               ' BELEME SURESI




'***********LCD yi Kullanıma Hazır Hale Getir***********

LOW PORTC.6 'RW bacağı ekrana yazmaya imkan vermek için LOW yapıldı.



lcdout $FE,1
PAUSE 200   ' LCD nin kullanıma hazır hale gelebilmesi için gerekli süre

LCDOUT $FE,$80,"FAN DIMMER"                 
LCDOUT $FE,$C0, "5 KADEME"

pause 1000
lcdout $FE,1 
FANSET=5
SURE=0
INTCON.1=0
'***********Program Başlangıcı***********

ON INTERRUPT GoTo KESME

BASLA:

LCDOUT $FE,$80,"FAN:",#FANSET,"."               
LCDOUT $FE,$C0, " KADEME S:",#sure



   

'***************FAN AYAR KISMI***********
IF ARTI=0 OR EKSI=0 THEN
GOSUB FANAYAR
PAUSE 4

IF FANSET=1 THEN
SURE=8
ENDIF
IF FANSET=2 THEN
SURE=6
ENDIF
IF FANSET=3 THEN
SURE=4
ENDIF
IF FANSET=4 THEN
SURE=2
ENDIF
  IF FANSET=5 THEN
SURE=0
ENDIF
ENDIF

GOTO BASLA

'*******************KESME*****************
DISABLE


KESME:
PAUSE SURE
OPTO=1
PAUSEUS 100 '100 us bekleme suresi
OPTO=0

INTCON.1=0   
Resume 


Enable   



   
'*************************** FAN AYARAYAR YAP************************
FANAYAR:


lcdout $FE,1     
LCDOUT $FE,$80,"FAN HIZ AYARLA"                 
LCDOUT $FE,$C0, "FAN: ",#FANSET,". KADEME"       

pause 75
     
    if FANSET=5 then
    else
        if ARTI=0 then 
        FANSET=FANSET+1
        pause 100
        endif
    endif
     
    if FANSET=0 then
     else
         if EKSI=0 then
          FANSET=FANSET-1
         pause 100
         endif
     endif
          if OK=0 then
         LCDOUT $FE,$80,"AYAR KAYDEDILDI "
     pause 1000
     lcdout $FE,1
    return
    endif
       
   
goto FANAYAR

END


ete

#3
Simulasyonda AC kaynağı iyi ayarlamak gerekiyor. Bunun nasıl yapıldığını göstermek amacıile bir dimmer devreside ben ekleyeyim istedim.
İlişikteki devreyi inceleyin hex dosyasınıda verdim çalıştırıp dim ayarıda yapın ve tetik noktasının hangi aralıkta değiştiğini görün. Birde sıfır geçiş sistemi ekledim çalışırken onuda görebilirsiniz.

Ete

Eski versiyon simulasyon da ekledim.

Makmuh

Hocam sizin kullandığınız proteus programı üst versiyon olduğu için açılmıyor. Benim programım 8.6 internetten üst versiyonu bulmaya çalıştım ama crakı yok yani sizin similasyona bakamadım.
Kendi devrem üzerinde biraz daha uğrastım da devreyi sadeleştirdim kesme oluşuyor mu diye optokuplerli kısmı çıkartıp led bağladım ve osilatörle de pals leri kontrol etmeye calıştım, kesmeler oluşuyor fakat proteusta simülasyon başladıktan kısa bir süre sonra resimini koyaduğum hataları alıyorum. bu yüzden entegre palsleri doğru vuruyormu göremedim.
Bu hatanın sebebini internette bulamadım. Benim program kaynaklı olabileceğini düşündüğümden programı ve hex dosyasını ekte veriyorum bi bakabilirmisiniz.

ete


onurinci

hocam şebeke 50Hz buda 20mS eder siz sıfır geçişi 100Hz üzerindenmi uyguluyorsunuz ?,zira opto'da köprü diyot var..

ete

Aynı yönde tepeden tepeye düre 20 ms dir. Ama sıfır geçiş her 10 ms de birdir.
Şebekeyi bir köprü diyottan geçirip kondansatör bağlamadan çıkış alırdsn sana her 10 ms de bir kesme yaratır.
Ete

Makmuh

Hocam dimmer devresini inceledim 
Şimdi entegreden çıkan palsleriniz sıfır geçişte eldettiğiniz palslerinizle aynı anda oluşuyor.
Dımmerinizi %100 olarak çalıştırdığım zaman entegreden çıkan pals süresi  (yaklaşık ) 0,6 msn
%50 olarak çalıştırdığım zaman entegreden çıkan pals süresi 5,8 msn
%30 olarak çalıştırdığım zaman  entegreden çıkan pals süresi 7,3 msn

Bu şelikde pals üretmesi için programımı tekrar düzenledim. Şimdi simülatörü çaluştırdığım zaman entegre ilk çıkış palsini doğru zamanda gönderiyor. Daha sonra oluşan kesmelerde  palsı ilk vurduğu noktadan kayarak 3 ms kadar ilerliyor sonra tekrar başa sıfır noktasına dönüyor. bu şelikde kayma oluşuyor.

Benim biraz daha bilgiye ihtiyacım var sanırım.

'****************************************************************
'*  Name    : ete.BAS                                   *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 12.05.2011                                        *
'*  Version : 1.5                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
'16F877A işlemci
@ __config _BODEN_OFF  & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _XT_OSC


CMCON=7
'-------------------------------------------------------------------------------
DEFINE OSC 4

ADCON1=7
OPTION_REG.7=0
OPTION_REG.6=1      'RB0 da YUKSELEN kenarda kesme oluşur
INTCON=%10010000    'TUM KESMELER ACILDI

'***********Port Ayarları***********
TRISA=%00000100
TRISB=%101111111
TRISC=%00000000
TRISD=%00000000
TRISE=%00000000
PORTA=0
PORTB=0
PORTC=0
PORTD=0
PORTE=0

'***********LCD Tanımlamaları***********

DEFINE LCD_DREG        PORTD    'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT        4        'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_EREG        PORTC    'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT        7        'LCD Enable Bacağı Hangi bite bağlı ?
define LCD RWREG    PORTC   'LCD R/W Bacağı Hangi Porta bağlı?
define LCD_RWBIT    6       'LCD R/W Bacağı Hangi bite bağlı ?
DEFINE LCD_RSREG    PORTC    'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT    5        'LCD RS bacağı Hangi Bite bağlı  ?
DEFINE LCD_BITS     4        'LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES    2        'LCD Kaç sıra yazabiliyor   

'***********Özel Karakter Tanımlamaları
LCDOUT $FE,$40, 6, 9, 9, 6, 0, 0, 0, 0 'Derece İşareti
LCDOUT $FE,$48, 4, 14, 4, 4, 4, 4,14,0 'İ Harfi
LCDOUT $FE,$50, 14, 17, 16, 16,16,17,14,4 'Ç Harfi
LCDOUT $FE,$58, 14, 17, 16, 14,1, 17,14,4 'Ş Harfi


'****************SEMBOLLER*********************

SYMBOL ARTI  =PORTB.4
SYMBOL OK=PORTB.5
SYMBOL EKSI=PORTB.6
SYMBOL OPTO=PORTC.2
'***********Sensör Tanımlamaları***********


FANSET     VAR WORD         ' FAN SET DEĞERİ 0-5 ARASI
SURE VAR WORD               ' BELEME SURESI
I VAR WORD
XSET VAR WORD





'***********LCD yi Kullanıma Hazır Hale Getir***********

LOW PORTC.6 'RW bacağı ekrana yazmaya imkan vermek için LOW yapıldı.



lcdout $FE,1
PAUSE 200   ' LCD nin kullanıma hazır hale gelebilmesi için gerekli süre

LCDOUT $FE,$80,"FAN DIMMER"                 
LCDOUT $FE,$C0, "5 KADEME"

pause 1000
lcdout $FE,1 
FANSET=5
SURE=1
XSET=1400
INTCON.1=0
'***********Program Başlangıcı***********

ON INTERRUPT GoTo KESME

BASLA:

LCDOUT $FE,$80,"FAN:",#FANSET,"."               
LCDOUT $FE,$C0, " KADEME S:",#sure



   

'***************FAN AYAR KISMI***********
IF ARTI=0 OR EKSI=0 THEN
GOSUB FANAYAR
PAUSE 4

IF FANSET=1 THEN
SURE=8
ENDIF
IF FANSET=2 THEN
SURE=6
ENDIF
IF FANSET=3 THEN
SURE=4
ENDIF
IF FANSET=4 THEN
SURE=2
ENDIF
  IF FANSET=5 THEN
SURE=1
ENDIF
ENDIF

GOTO BASLA

'*******************KESME*****************
DISABLE


KESME:
OPTO=1
PAUSE SURE

OPTO=0
INTCON.1=0

 
Resume 


Enable   



   
'*************************** FAN AYARAYAR YAP************************
FANAYAR:


lcdout $FE,1     
LCDOUT $FE,$80,"FAN HIZ AYARLA"                 
LCDOUT $FE,$C0, "FAN: ",#FANSET,". KADEME"       

pause 75
     
    if FANSET=5 then
    else
        if ARTI=0 then 
        FANSET=FANSET+1
        pause 100
        endif
    endif
     
    if FANSET=0 then
     else
         if EKSI=0 then
          FANSET=FANSET-1
         pause 100
         endif
     endif
          if OK=0 then
         LCDOUT $FE,$80,"AYAR KAYDEDILDI "
     pause 1000
     lcdout $FE,1
    return
    endif
       
   
goto FANAYAR

END

ete

Simule nin bu kadar hassas olmasını bekleme. Sıfır geçiş pulsleri programa bağlı bir şey değil devreden dolayı oluşuyor ve o farklar bana kalırsa simule nin kusuru. Senin bu konuya değil de süre ayarı ve triac tetiklenmesine konsantre olman gerek.
Ete

Makmuh

#10
Iyi akşamlar
Hocam daha önce sizin söylediğiniz şekilde yazdığım portB.0 kesmesi kullanarak yapılmış olan bir dimmer programım var.
Birde sıcaklık kontrolünü yaptığım sıcaklıkta gore 3 adet role çektirdiğim ve aynı zamanda zaman tuttuğum bir programım var. Bu programda zamanı programı bir döngü içerisine alarak program 280 defa döndüğünde 1 sn elde ediyorum.
Şimdi benim size sormak istediğim bu dimmer programı ile sıcaklık kontrol yaptığım programımı birlestirip kullanmam gerekiyor. Bunu iki yolla yapabilirim diye düşünüyorum birisi iki programıda hiç birşeyi değiştirmeden birleştirmek (yanı dimmeri portB.0. Kesmesi ile zamanida döngü kullanarak saydırma.
Aklıma gelen diğer yöntemde programda değişiklik yaparak dimmeri yine portB.0 kesmesi ile zamanida timer kesmesi ile tutmak.
Endişem iki tane kesme olursa kesmeler cakisir dimmeri yada zamanı düzgün çalıştırmaz mi?  Zamanı çok hassas tutmam gerekmiyor 1 dakikada 1 saniye   kaymış çok önemli değil
Sizce bu iki programı hangi yolla birlestirmeliyim.

Harici bi clok modülü kullanmak ta istemiyorum 



'****************************************************************
'*  Name    : ete.BAS                                   *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 12.05.2011                                        *
'*  Version : 1.5                                               *
'*  Notes   :FAN KADEME AYARI YERINE ON OFF YAPILDI                                                   *
'*          : ILK GUNCELLEMEDE SENSOR YOK EKLE  , REDUKTOR BAsžLAMA SICAKLIGINI 28 YAP                                                 *
'****************************************************************
'16F877A iþlemci
@ __config _BODEN_OFF  & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _XT_OSC

CMCON=7
'-------------------------------------------------------------------------------
DEFINE OSC 4

ADCON1=7
OPTION_REG.7=0
'***********Port Ayarlari***********
   
TRISA=%11111111                       
TRISB=%11111111   
TRISC=%10000000     
TRISD=%10000000 
TRISE=%00100000
PORTA=0
PORTB=0
PORTC=0
PORTD=0
PORTE=0

'***********LCD Tanimlamalari***********

DEFINE LCD_DREG        PORTD    'LCD data bacaklari hangi porta bagli?
DEFINE LCD_DBIT        4        'LCD data bacaklari hangi bitten basliyor?
DEFINE LCD_EREG        PORTC    'LCD Enable Bacagi Hangi Porta bagli?
DEFINE LCD_EBIT        7        'LCD Enable Bacagi Hangi bite bagli ?
define LCD RWREG    PORTC   'LCD R/W Bacagi Hangi Porta bagli?
define LCD_RWBIT    6       'LCD R/W Bacagi Hangi bite bagli ?
DEFINE LCD_RSREG    PORTC    'LCD RS Bacagi Hangi Porta bagli ?
DEFINE LCD_RSBIT    5        'LCD RS bacagi Hangi Bite bagli  ?
DEFINE LCD_BITS     4        'LCD 4 bit mi yoksa 8 bit olarak bagli?
DEFINE LCD_LINES    2        'LCD Kac sira yazabiliyor   

'***********Özel Karakter Tanimlamalari
LCDOUT $FE,$40, 6, 9, 9, 6, 0, 0, 0, 0 'Derece Ysareti
LCDOUT $FE,$48, 4, 14, 4, 4, 4, 4,14,0 'Y Harfi
LCDOUT $FE,$50, 14, 17, 16, 16,16,17,14,4 'Ç Harfi
LCDOUT $FE,$58, 14, 17, 16, 14,1, 17,14,4 '? Harfi


'****************SEMBOLLER*********************

SYMBOL ARTI  =PORTB.4
SYMBOL OK=PORTB.5
SYMBOL EKSI=PORTB.6
symbol FAN =PORTB.7  ' GECICI OLARAK AC KAPA YAPILDI
SYMBOL BEKLEME=PORTB.3
SYMBOL BESLEME=PORTB.2
SYMBOL REDUKTOROFF=PORTB.1
SYMBOL ELLE=PORTA.0
SYMBOL COMM_PIN =PORTC.0
SYMBOL FANROLE  =PORTC.1
SYMBOL POMPAROLE  =PORTC.2
SYMBOL REDUKTORROLE  =PORTC.3
SYMBOL ODATERMOSTAT  =PORTA.1
SYMBOL POMPALED=PORTC.4
SYMBOL FANLED=PORTD.3
SYMBOL REDLED=PORTD.2

'SYMBOL REDONOFF=PORTA.0
SYMBOL ISIK=PORTE.1
SYMBOL OTOLED=PORTE.0
SYMBOL FANOTOLED=PORTD.1
'***********Sensör Tanimlamalari***********

Busy        VAR BIT         ' Bus y Status-Bit
HAM         VAR    WORD     ' Sensör HAM okuma degeri
ISI         VAR WORD        ' Hesaplanmis ISI degeri
Float       VAR WORD        ' Holds remainder for + temp C display
X           VAR WORD       
ISARET_BITI VAR HAM.Bit11   '   +/- sicaklik Ysaret biti,  1 = olursa eksi sicaklik
EKSI_ISI    CON 1           ' Sifir altinda isaret biti=1  oluyor kontrol icin
DERECE      CON 223         ' ° isareti
ISARET      VAR BYTE        '  ISI degeri icin  +/-  isaret
TEMP        VAR word        ' Div32 bit hesap icin gecici degisken

ALTSET      VAR BYTE        ' ALT ISI DE?ERY TANIMLANDI
FANSET     VAR BYTE         ' FAN SET DE?ERY 0-5 ARASI
SET         VAR BYTE        ' SET DEGERI
SBESLE       VAR BYTE       ' AYARLANMIS BESLEME
SBEKLE       VAR word        'AYARLANMIS BEKLEME
D            VAR BYTE        '
I            var byte        '
ZBEKLE        VAR WORD       ' GERY SAYILAN BEKLEME
ZBESLE        VAR WORD       '  GERY SAYILAN BESLEME
XT             var byte      'OTO KAPALI KONUMU
YT             VAR BYTE       ' SICAKLIK ISTENILEN DURUM USTU ISE
SURE          VAR WORD
Z              VAR WORD
DURUM            VAR BYTE    ' KAZANIN KAPALI ACIK OLMASI HALI
FANOTO           VAR BYTE    'FAN OTO ACIK KAPALI
'***********LCD yi Kullanima Hazir Hale Getir***********

LOW PORTC.6 'RW bacagi ekrana yazmaya imkan vermek icin LOW yapildi.
ISIK=1
lcdout $FE,1

gosub sensoroku
PAUSE 200   ' LCD nin kullanima hazir hale gelebilmesi icin gerekli sure
LCDOUT $FE,$80,"ULKU MUHENDISLIK"                 
LCDOUT $FE,$C0, "*0332 447 3355*"
pause 4000
lcdout $FE,1 
READ 1,SET
READ 2,SBESLE
READ 5,SBEKLE.Byte1,SBEKLE.BYTE0
READ 4,FANSET
READ 6,FANOTOLED
READ 10,DURUM 
IF SBEKLE>600 OR SBESLE>60 THEN
SBEKLE=600
SBESLE=8
ENDIF
IF SBEKLE<60 THEN
SBEKLE=60
ENDIF

IF SET=255 THEN
SET=41
SBESLE=4
FANSET=3
sbekle=300
ENDIF
ALTSET=SET-4
ZBEKLE=SBEKLE
ZBESLE=SBESLE
'REDONOFF=1
OTOLED=1
XT=1
SURE=0

IF DURUM =1 THEN
  GOTO KAPATMA
ENDIF
Gosub BEKLE


'***********Program Baslangici***********   
BASLA:
      IF SURE=5 THEN
       GOSUB SENSOROKU
      endIF

      IF SURE=7 THEN
        GOSUB BEKLE
      ENDIF
     
      IF SURE=10 THEN
        ISIK=0
        SURE=0
      ELSE
        SURE=SURE+1
      ENDIF

      IF ODATERMOSTAT=1 THEN
        LCDOUT $FE,$80,"KAZAN:",DEC ISI,"C SET:",#set,"C"
'       LCDOUT $FE,$C0, #ZBEKLE," BEKLE ",#ZBESLE, " BESLE "
        LCDOUT $FE,$C0, "ODA TERM. AKTIF "
        FANROLE=0
        FANLED=0
        YT=0
        REDUKTORROLE=0
        REDLED=0   
      ELSE
        LCDOUT $FE,$80,"KAZAN:",DEC ISI,"C SET:",#set,"C"
        LCDOUT $FE,$C0, #ZBEKLE," BEKLE ",#ZBESLE, " BESLE "
'       LCDOUT $FE,$C0, #TBEKLE2," BEKLE ",#TBEKLE1, " BESLE"
        IF ISI<ALTSET THEN
          IF FANOTOLED=1 THEN
            FANROLE=1
            FANLED=1
    '       ELSE
    '       FANROLE=0
    '       FANLED=0
    '       YT=0
          ENDIF

          IF XT=0 OR YT=0 THEN
            ZBEKLE=SBEKLE
            ZBESLE=SBESLE
            REDUKTORROLE=0
            REDLED=0
          ELSE
            IF ZBEKLE=0 THEN
              LCDOUT $FE,$80,"KOMUR GONDERIYOR"
              LCDOUT $FE,$C0, #ZBEKLE," BEKLE ",#ZBESLE, " BESLE "
              ZBEKLE=1
              REDUKTORROLE=1
              REDLED=1   
              IF ZBESLE=0 THEN
                ZBEKLE=SBEKLE
                REDUKTORROLE=0
                REDLED=0
                LCDOUT $FE,$80,"KAZAN:",DEC ISI,"C SET:",#set,"C"
                LCDOUT $FE,$C0, #ZBEKLE," BEKLE ",#ZBESLE, " BESLE "
                ZBESLE=SBESLE+1
              ENDIF
              ZBESLE=ZBESLE-1
            ENDIF
            ZBEKLE=ZBEKLE-1
          ENDIF
        ENDIF

        IF FANOTOLED=0 THEN
          FANROLE=0
        ENDIF
 
'*************ISI KARSILASTIRMA KISMI***************
        IF ISI=>SET then
          FANROLE=0
          FANLED=0
          YT=0
        ENDIF

        IF ISI>10 THEN  'REDUKTOR BASLAMA SICAKLIGI
          YT=1
        ELSE
          YT=0
        ENDIF
    ENDIF

     IF ISI>34 THEN
       POMPAROLE=1
       POMPALED=1
     ENDIF
     IF ISI<29 THEN
        POMPAROLE=0
        POMPALED=0
     ENDIF
     IF ISI<10 THEN
        POMPAROLE=1
        POMPALED=1
     'TOGGLE ISIK
        PAUSE 2000
        LCDOUT $FE,$80,"*-POMPA  AKTIF-*"
        LCDOUT $FE,$C0, "DON KORUMA MODU."
        I=I+100
     ENDIF
     IF ISI>85 THEN
        POMPAROLE=1
        POMPALED=1
     'TOGGLE ISIK
        PAUSE 2000
        LCDOUT $FE,$80,"POMPA CALISMIYOR"
        LCDOUT $FE,$C0, "* ASIRI ISINMA*"
        I=I+100
     ENDIF
     
     pause 4
   
   for I=0 to 128     
'**********AC KAPA
      PAUSE 4
      IF FAN=0 THEN
         TOGGLE FANOTOLED
         WRITE 6,FANOTOLED
         ISIK=1
         SURE=0
         Z=0
         WHILE FAN=0 AND Z<1000
           Z=Z+1
           PAUSE 1
         WEND
      endIF
 
      IF Z=1000 THEN
         lcdout $FE,1
         LCDOUT $FE,$80,"KAZAN KAPANIYOR"
         DURUM=1
         WRITE 10,DURUM
         PAUSE 10
         GOSUB KAPATMA
      ENDIF
     
'****************SICAKLIK AYAR KISMI******
      IF ARTI=0 OR EKSI=0 THEN
         SURE=0
         ISIK=1
         lcdout $FE,1
         REDUKTORROLE=0
         REDLED=0
         GOTO SETAYAR       
      ELSE
         ALTSET=SET-4
      ENDIF
'***************FAN AYAR KISMI***********
         'IF FAN=0 THEN
        'SURE=0
        'ISIK=1
         'REDUKTORROLE=0
         'REDLED=0
        'lcdout $FE,1
        'GOSUB FANAYAR
        'PAUSE 45
         'ENDIF
'***************BEKLEME AYAR KISMI***********
       IF BEKLEME=0 THEN
          SURE=0
          ISIK=1
          REDUKTORROLE=0
          REDLED=0
          lcdout $FE,1
          GOSUB BEKLEMEAYAR
         'PAUSE 50
       ENDIF
'***************BESLEME AYAR KISMI***********
       IF BESLEME=0 THEN
          SURE=0
          ISIK=1
          REDUKTORROLE=0
          REDLED=0
          lcdout $FE,1   
          GOSUB BESLEMEAYAR
       ENDIF
  '***************OTOMATYK ON OFF KISMI***********   
       IF REDUKTOROFF=0 THEN
          SURE=0
          ISIK=1
          GOSUB DE
       ENDIF

'***************ELLE YUKLEME KISMI***********

      IF ELLE=0 THEN
        SURE=0
        ISIK=1
        lcdout $FE,1
        GOSUB ELLEYUKLE
      ENDIf
   next
   
   gosub bekle 

   GOTO BASLA


'************************ SENSOR OKU **************************

SENSOROKU:
          OWOUT   Comm_Pin, 1, [$CC, $44]' ISI degerini oku
          return

Bekle:
'           OWIN    Comm_Pin, 4, [Busy]    ' Busy degerini oku
          IF      Busy = 0 THEN Bekle    ' hala mesgulmu? , evet ise goto Bekle..!
          OWOUT   Comm_Pin, 1, [$CC, $BE]' scratchpad memory oku
          OWIN    Comm_Pin, 2, [HAM.Lowbyte, HAM.Highbyte]' Yki byte oku ve okumayi bitir   

Hesapla:                 ' Ham degerden Santigrat derece hesabi
        ISARET  = "+"
        IF ISARET_BITI = EKSI_ISI THEN
           ISARET   = "-" 
           HAM=~HAM+2
        ENDIF
        ISI = ((HAM*10)/16)
        FLOAT = ISI//10
        ISI=ISI/10
        RETURN

'*************************** SICAKLIK AYARAYAR YAP************************

SETAYAR:
        SURE=SURE+1
        PAUSE 100     
        FOR I=0 TO 300     
          'LCDOUT $FE,$80,"SUR:",#SURE
          LCDOUT $FE,$80,"SICAKLIK AYARLA"                 
          LCDOUT $FE,$C0, "SET : ",#set,".0 C "
          if set=75 then
       
          else
            if ARTI=0 then 
              set=set+1
              SURE=0
              pause 300
            endif
          endif
     
          if set=35 then
     
          else
            if EKSI=0 then
              set=set-1
              SURE=0
              pause 300
            endif
          endif
     
          IF SURE=15 THEN       
             LCDOUT $FE,$80,"AYAR KAYDEDILDI "
             WRITE 1,SET
             PAUSE 2000           
             GOTO BASLA
          ENDIF
         
         if OK=0 then
            LCDOUT $FE,$80,"AYAR KAYDEDILDI "
            WRITE 1,SET
            PAUSE 2000
            goto basla
         endif
     NEXT     
   
     goto SETAYAR   

'*************************** FAN AYARAYAR YAP************************

FANAYAR:

         SURE=SURE+1
         FOR I=0 TO 300     
            'LCDOUT $FE,$80,"SUR:",#SURE     
            LCDOUT $FE,$80,"FAN HIZ AYARLA"                 
            LCDOUT $FE,$C0, "FAN: ",#FANSET,". KADEME"       
               
            if FANSET=5 then
            else
                if ARTI=0 then
                SURE=0 
                FANSET=FANSET+1
                pause 500
                endif
            endif
             
            if FANSET=0 then
             else
                 if EKSI=0 then
                 SURE=0
                 FANSET=FANSET-1
                 pause 500
                 endif
             endif
             
             if OK=0 then
               LCDOUT $FE,$80,"AYAR KAYDEDILDI "
               WRITE 4,FANSET
               pause 2000
               goto basla
             endif
             
             IF SURE=15 THEN
                LCDOUT $FE,$80,"AYAR KAYDEDILDI "
                WRITE 4,FANSET
                pause 2000
                goto basla
             ENDIF
           NEXT
                   
           goto FANAYAR
'*************************** BEKLEME AYARAYAR YAP************************

BEKLEMEAYAR:
             SURE=SURE+1
             FOR I=0 TO 300
     
                'LCDOUT $FE,$80,"SUR:",#SURE       
                LCDOUT $FE,$80,"BEKLEME SURE AYR"                 
                LCDOUT $FE,$C0, "BEKLE: ",#SBEKLE," SANiYE"       
                PAUSE 40
     
                if SBEKLE=>600 then
                else
                  if ARTI=0 then 
                     SBEKLE=SBEKLE+5
                     SURE=0
                     pause 200
                  endif
                endif
                PAUSE 40
               
                if SBEKLE=60 then
                else
                  if EKSI=0 then
                     SBEKLE=SBEKLE-5
                     SURE=0
                     pause 200
                  endif
                endif
         
                if OK=0 then
                   LCDOUT $FE,$80,"AYAR KAYDEDILDI "
                   WRITE 5,SBEKLE.Byte1,SBEKLE.BYTE0
                   ZBEKLE=SBEKLE
                   pause 2000
                   goto basla
                endif
   
                IF SURE=15 THEN
                   LCDOUT $FE,$80,"AYAR KAYDEDILDI "
                   WRITE 5,SBEKLE.Byte1,SBEKLE.BYTE0
                   ZBEKLE=SBEKLE
                   pause 2000
                   goto basla
                ENDIF
                PAUSE 40
             NEXT
               
             goto BEKLEMEAYAR
'*************************** BESLEME AYARAYAR YAP************************

BESLEMEAYAR:
             SURE=SURE+1
             FOR I=0 TO 300     
              'LCDOUT $FE,$80,"SUR:",#SURE
 
               LCDOUT $FE,$80,"BESLEME SURE AYR"                 
               LCDOUT $FE,$C0, "BESLE: ",#SBESLE," SANiYE"       
       
               if SBESLE=20 then
               else
                 if ARTI=0 then 
                   SBESLE=SBESLE+1
                   SURE=0
                   pause 200
                 endif
               endif
     
               if SBESLE=1 then
               else
                 if EKSI=0 then
                   SBESLE=SBESLE-1
                   SURE=0
                   pause 200
                 endif
               endif
         
               if OK=0 then
                  LCDOUT $FE,$80,"AYAR KAYDEDILDI "
                  WRITE 2, SBESLE
                  ZBESLE=SBESLE
                  pause 2000
                  goto basla
               endif
       
               IF SURE=15 THEN
                  LCDOUT $FE,$80,"AYAR KAYDEDILDI "
                  WRITE 2, SBESLE
                  ZBESLE=SBESLE
                  pause 2000
                  goto basla
               ENDIF
             NEXT
           
            goto BESLEMEAYAR

'*************************** ELLE YUKLE************************
ELLEYUKLE:
           IF ELLE=0 THEN
              REDUKTORROLE=1
              REDLED=1
              LCDOUT $FE,$80,"KOMUR"                 
              LCDOUT $FE,$C0, "GONDERILIYOR==>"
           ENDIF
           
           IF ELLE=1 THEN
             REDUKTORROLE=0
             REDLED=0
             RETURN
           ENDIF
           GOTO ELLEYUKLE


'***************DE

DE:
   IF XT=0 THEN
      PAUSE 500
      XT=1 
      OTOLED=1
      RETURN
   ENDIF
   IF XT=1 THEN
      PAUSE 500
      XT=0
      ZBEKLE=SBEKLE
      ZBESLE=SBESLE
      OTOLED=0
      RETURN
   ENDIF
   RETURN
'*****************KAPATMA**********
KAPATMA:
         Z=0
         OWOUT   Comm_Pin, 1, [$CC, $44]' ISI degerini oku
'           OWIN    Comm_Pin, 4, [Busy]    ' Busy degerini oku
'           IF      Busy = 0 THEN Bekle    ' hala mesgulmu? , evet ise goto Bekle..!
         OWOUT   Comm_Pin, 1, [$CC, $BE]' scratchpad memory oku
         OWIN    Comm_Pin, 2, [HAM.Lowbyte, HAM.Highbyte]' Yki byte oku ve okumayi bitir                  ' Ham degerden Santigrat derece hesabi

         ISARET  = "+"
         IF ISARET_BITI = EKSI_ISI THEN
            ISARET   = "-" 
            HAM=~HAM+2
         ENDIF
         ISI = ((HAM*10)/16)
         FLOAT = ISI//10
         ISI=ISI/10
         PAUSE 1000
         lcdout $FE,1
         ISIK=0 
         FANROLE=0
         FANLED=0
         REDUKTORROLE=0
         REDLED=0
         OTOLED=0
         POMPAROLE=0
         POMPALED=0
         IF ISI>50 THEN
            POMPAROLE=1
            POMPALED=1
            lcdout $FE,1
            LCDOUT $FE,$80," POMPA OTOMATIK "                 
            LCDOUT $FE,$C0, "-> KAPANACAK <-"
            PAUSE 1000
            TOGGLE ISIK
            IF ISI>85 THEN
               LCDOUT $FE,$80,"POMPA CALISMIYOR"
               LCDOUT $FE,$C0, "* ASIRI ISINMA*"
               PAUSE 1000
               TOGGLE ISIK
            ENDIF
         ELSE
            IF ISI<10 THEN
               POMPAROLE=1
               POMPALED=1
               lcdout $FE,1
               LCDOUT $FE,$80,"DON KORUMA MODU "                 
               LCDOUT $FE,$C0, "POMPA ACIK"
       
               'TOGGLE  REDONOFF
               PAUSE 500
               TOGGLE ISIK
               PAUSE 500
               TOGGLE FANLED
               PAUSE 500
               TOGGLE REDLED
               PAUSE 500
               TOGGLE OTOLED
               PAUSE 500
            ELSE
               POMPAROLE=0
               POMPALED=0
            ENDIF
         ENDIF
         
         IF FAN=0 THEN
            Z=0
            WHILE FAN=0 AND Z<1000
              Z=Z+1
              PAUSE 1
            WEND
         endIF
         IF Z=1000 THEN
            ISIK=1
            lcdout $FE,1
            LCDOUT $FE,$80,"KAZAN ACILIYOR"
            PAUSE 1000
            LCDOUT $FE,$80,"ULKU MUHENDISLIK"                 
            LCDOUT $FE,$C0, "*0332 447 3355*"
            pause 4000
            lcdout $FE,1   
            Z=0
            SURE=0
            DURUM=0
            WRITE 10,DURUM
            PAUSE 10       
            IF XT=1 THEN
               OTOLED=1
            ENDIF
            GOTO BASLA

         ENDIF
         GOTO KAPATMA
END


ete

Öncelikle bu işin mümkün olup olamayacağına bakalım.
He riki programda kendi açısından bağımsız olarak yazılmış. Bunu sıcaklık kontrol programına bakarak ve diğerinide olması gerekeni tahmim ederek söylüyorum. Sıcaklık kontrol programında bol keseden pasue kullanılmış ve bu dimmer programı ile birleştirilmesine engel olacak en büyük faktör. Hadi bunu bir şekilde halledersin diye düşünelim. Yinede dimmer sistemine ters gelebilecek başka faktörlerde çıkacaktır. Bu nedenle ben olsam ayrı tek bir program şeklinde yeniden yazmayı denerdim.

Sorunların hepsini aşarım ve bu ikisini nasıl birleştireyim dersen zaman tutmanın yollarına bakmamız gerekecek.
İşin çözümü Timer-1 de derim. Bunu kesme olmadan while wend döngüsü içinde kullanarak zamanı tutman gerekir.
Önce bir zaman dilimi belirlersin ki ben genelde ya 250 ms yada 500 ms lik dilimler kullanırım. Hassas işlerde 100 ms lik dilimler kullanıp dilim sayarım. Böylece istediğim süreye ulaşınca yapacaklarımı yapar dilim döngüsü içinde de diğer yapılacak işleri yaptırırım.
Burada ip ucu Timer-1 sayacının Kesme bayrağıdır. PIR1.0 biti ile kontrol edilir. Bunu sıfırlayıp Timer'a ön yükleme değerini verdikten sonra WHILE PIR1.0=0 ...... Wend döngüsünü kurarsan dilim süresi sonunda PIR1.0=1 olacağı için sistem döngüden çıkar ve sende Döngü=Döngü+1 ile döngü sayasın. ütün bu işler ana kesmeden bağımsız olarak kendi içinde çalışır ve kesmelerini etkilemez.

İkinci bir kesme kaynağı dimmeri etkileyebilir. Bu nedenle kesme üzerinden zaman tutmanın bir diğer yolu da kullanılabilir.
Şayet dimmer sistemin her 20 ms de bir kesme oluşturuyor ise kesmeleri sayarak zaman tutabilirsin. Yapman gereken şey kesme içinde KES=KES+1 şeklinde bir satırlık bir eklenti kullanman bu dimmeri etkilemez.
Ana bölüm içinde de IF KES=50 the süre 1000ms diyebilirsin.

Daha fazla fikir üretilebilirmi bilmiyorum ama bence bu ikisinden birisi senin işini görür.

Ete

Makmuh

Hocam ilk söylediğiniz timer-1 çözümünü anlamadım. Anlamadım derken benim programdaki kullandığım for  döngüsüyle sizin söylediğiniz döngü arasında farkı çözemedim mutlaka fark vardır ama ben acemi olduğum için kavrayamadım.
ikinci söylediğinizi anladım dimmer için oluşturduğun kesmeleri sayarak süre tutmak güzelmiş benim hiç aklıma gelmemişti. Düşündükçe hem daha hassas bir süre tutmuş  oluyorum hemde işlemci daha az iş yapıyor gibi geldi. Cevabınız için teşekkur ederim.

ete

Buraya koyduğun programa bir bakacak olursa rutin olarak belirli işleri bir döngü içerisinde yaptığını görebiliyoruz.
Bunlardan bazılari kritik zamanlama gerektiriyor. Mesela sıcaklık sensörü okunması gibi. Sensör okuma emri verildikten 750 ms sonra okunmalı. Önceden okumaya kalkarsan henüz ısı çevrimi tamamlanmadığı için program orada boşuna bekleyecektir.
O halde öyle bir zamanlama yapmalıyımki tam olarak 750 ms sonra (760 da olabilir) gidip sıcaklığı okumalıyım. Okuma kısmındaki bekle etiketini artık kaldırmak gerekir. Zira orası zaman dolmamış ise programı orada bekletmek amaçlı kullanılan bir yöntem. Ama 750 ms sonra sen oraya gidersen program zaten beklemeden direk okuma yapabilecek durumda olacaktır.

Daha sonra buton kontrollerinin yapıldığı kısım var. Bunlar sürekli kontrol edilmeli belirli bir zamana bağlı işler olmamalı.
Ayrıca karşılaştırma kısımları var bunlarda süreklilik arzeden işler sınıfında olan şeyler.
Bu durumda 250 ms lik diliimleri olan şöyle bir timer-1 döngüsü kursam ;
Zaman_Döngüsü:
       KES=3:T1CON=%00110001      'bölme oranı 1/8 ve timer1 aktif edildi
       GOSUB SENSOR_OKU_EMRIVER  'burada sensöre okuma emrini verdik
ZAMAN_BIR:
       TMR1H=$85:TMR1L=$EE  'timer'a ön yükleme değeri verdik  'her kesme 250ms süre alıyor.       
       PIR1.0=0  'kesme bayrağını sıfırladık
       WHILE PIR1.0=0  'bayrak set edilmediği sürece aşağıdaki işleri yap diyoruz
          GOSUB TUS_KONTROL 'git tusları kontrol et basılan varsa işlemi yap ve return ile geri dön
          GOSUB KARSILASTIR  'okunan sıcaklık ile set değerlerini karşılaştır ve yapılması gerekenleri yapıp geri dön
           ..........'varsa diğer işleri de buraya eklersin
        WEND  '250 ms lik süre bitince PIR1.0 set edilecek otomatikman ve program alt satıra geçecektir.
        KES=KES-1:IF KES>0 THEN ZAMAN_BIR  '750 ms henüz dolmadı yeniden bir dilim saymaya git.
       'program bu satıra gelirse KES=0 olmuş ve 750 ms geçmiş olacaktır.  Ohalde hazır olan sıcaklığı gidip okman gerekir.
       GOSUB SICAKLIK_AL
       GOTO ZAMAN_DONGUSU


Hepsi bu kadar. Bütün işleri 250 ms lik döngü zamanı içine yapacağım ve 750 ms lik dilim sonunda ise sıcaklığı okuyacağım.
Bu sistem de Timer1 kesmesinden yararlandık ama Global kesme içine sokmadık. Sadece kesme bayrağından faydalandık. Kesme bayrakları her zaman kesme oluşturacak sebep gerçekleştiğinde geri planda set edilir. Bu özellikten yararlanmış olduk ama Tmr1 kesmesini asıl kesme içine katmamış olduk. Böylece olası dimmer sistemi kesmesinin bundan etkilenmesini engellemiş olacağız.
Bu sistem uygulaması kolay ve programına düzen katacak bir sistemdir. Her şey belirli bir zaman düzeni içinde yerine getirilir.
Bir çok projemde bu sistemi kullanıyorum.
Sıfır geçiş kesmelerini saymak da işine yarayacak bir sistem olabilir. Üzerinde düşünüp geliştirebilirsin.

Ete
   

ete

Makmuh,
Bazı enteresan kod yazma tekniklerini görüyorum. Mesela aşağıdaki gibi pek çok yerde bunu kullanmışsın.
      IF SBESLE=20 then 
               ELSE
                  IF ARTI=0 then 
                      SBESLE=SBESLE+1
                     SURE=0
                     pause 200
                  endif
               endif

IF SBESLE=0 then deuip şartı goğrulayan bir koda yazmadan doğrulamayan kısmına kod eklemek bana enteresan geldi ve bu konuda sağ elin ile sol kulağını tutuyorsun gibi geliyor bana. Mantığını açıklarsan sevinirim yanlışım varsa düzeltirim.
Bu yazdığın şekle bakınca sanki IF SBESLE 20 ye eşit değil ise şunu yap demişsin gibi geliyor bana. Yani yukarıdaki kod şöyle yazılsa da doğru olurdu;
               if SBESLE<>20 and ARTI=0 then 
                   SBESLE=SBESLE+1
                   SURE=0
                   pause 200                 
               endif
ne dersin?

Program yazarken bütün satırları aynı hizadan yazmak okuyana eziyet yazanada ayrı eziyet oluyor. Programlar aradan günler geçtikten sonra anlaşılması zor hale gelir çünki program hakimiyetini kaybedersin ve bu kodları benmi yazmışım acaba neden böyle yazmışım dersin. Heleki senin yazdığın gibi hepsini alt alta aynı hizdan başlayacak şekilde yazarsan anlamakta iyice zorlanırsın.
Bunu önlemek için kod yazma şeklini düzeltmelisin. Yukarıda verdiğin kodu olması gereken şekilde düzenledim. Yaptığım düzenlemeyi BASLA satırından sonraki satırlara uyguladım ve böylece her bir if-endif ,  while - wend veya for - next döngüleri kendi içinde hizalanmış duruma gelmiş oldu. Böylece baktığın zaman kolaylıkla baktığın satırın hangi döngüye ait olduğunu kolaylıkla anlarsın. Program bu şekilde yazılmalıdır.
Bu kurala dikkat etmenizi özellikle öneriyorum.

Aşağıdaki kodlara dikkat edersen iki farklı şarta karşılık yapılan işlem aynı gözüküyor.
               if OK=0 then
                  LCDOUT $FE,$80,"AYAR KAYDEDILDI "
                  WRITE 2, SBESLE
                  ZBESLE=SBESLE
                  pause 2000
                  goto basla
               endif
       
               IF SURE=15 THEN
                  LCDOUT $FE,$80,"AYAR KAYDEDILDI "
                  WRITE 2, SBESLE
                  ZBESLE=SBESLE
                  pause 2000
                  goto basla
               ENDIF

Bu kodları birleştirmek mümkün şöyle;
      if OK=0 or SURE=15 then
                  LCDOUT $FE,$80,"AYAR KAYDEDILDI "
                  WRITE 2, SBESLE
                  ZBESLE=SBESLE
                  pause 2000
                  goto basla
               endif

Bu gibi kısaltmalarda dikkat etmek gerek. Özellikle uzun kodlar yazdığınızda hafıza doldu uyarısından kaçınmak için zorunlu kısaltmalardır bunlar.
Görebildiklerim bunlar.
Ete

Powered by EzPortal