program kilitlenmesi !

Başlatan sinasos, 09 Nisan 2017, 17:34:58

sinasos

Ete hocam merhaba, ısı ve nem kontrolü için bir program hazırladım ancak zaman zaman kilitlenme oluyor ve rölelerin ikiside high pozisyonunda kalıyor. Biliyorum ki gosub return probleminden genelde kilitlenme olur ancak böyle bir problem göremedim.(menüye dahi hiç girmeden bekledim yine kilitlendi) acaba giriş çıkış veya diğer config ayarlarınımı yanlış yapıyorum? bu konuda yardım edebilirmisiniz.
birde şimdi farkettiğim sorun daha var. örneğin sensor 18-19 derecede sistemin ayarıda 37 derecede olsun. enerjiyi verince ısının devreye girmesi gerekiyor ancak devreye girmiyor ve ısıtıcı çalışmıyor. anlayamadım bir türlü ! bu da yeni sorun ! nem de hiç sorun yok acaba ısıda virgülden sonraki değerler yüzünden mi yapıyor bunu ?
şimdiden çok teşekkür ederim.

Include "modedefs.bas"         
@ device pic16F628A, INTRC_OSC_NOCLKOUT, wdt_on, pwrt_on, lvp_off, protect_on
DEFINE OSC 4

'-------------------------- LCD Tanımlama --------------------
DEFINE LCD_DREG PORTB 'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT 4 'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_RSREG PORTB 'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT 1 'LCD RS bacağı Hangi Bite bağlı ?
define lcd_RWREG    PORTB
define LC_RWBIT     2
DEFINE LCD_EREG PORTB 'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT 3 'LCD Enable 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
OPTION_REG.7=1

TRISA=%00011111  'A portu çıkış olarak ayarlandı.
TRISB=0  'B portu çıkış olarak ayarlandı.
PORTA=0:portb=0
CMCON=7

dht_port var PORTA.0
DERECE  CON 223     ' ° işareti

AYAR    VAR BYTE
syc     var byte
AYR     VAR BIT
n       var bit
m       var bit
USTONDA var byte
ALTONDA var byte

USTISI  VAR BYTE
ALTISI  VAR BYTE
USTNEM  VAR BYTE
ALTNEM  VAR BYTE

I       VAR BYTE
TAMRUT  VAR WORD
ONDARUT VAR BYTE
TAMISI  VAR WORD
ONDAISI VAR BYTE
control var byte

y       var byte

symbol yukari=portA.4
symbol asagi=portA.2
symbol MENU=portA.3
symbol isirole=porta.7
symbol nemrole=porta.6
y=0

read 0, USTISI :pause 10       
read 1, ALTISI :pause 10
read 2, USTNEM:pause 10
read 3, ALTNEM:pause 10
read 4, ALTONDA:pause 10
read 5, USTONDA:pause 10
if USTISI<=tamisi or ALTISI>=tamisi then y=10

'*********************************** ANA PROGRAM *******************************
basla:
gosub SENSOROKU 'simülasyondayken bu satırı kapat
gosub GOSTER
GOSUB saydir'
if y=10 then y=0:gosub SINIRBAK
if isirole=0 then n=0
if nemrole=0 then m=0
ana:
    if menu=1 then DONUS
goto basla
'******************************** ANA PROGRAM SONU *****************************

'****************************** YAN PROGRAMLAR *********************************
saydir:
y=y+1
return

SINIRBAK:
if USTISI<=tamisi and USTONDA<=ondaisi then low isirole :n=0
if ALTISI>=tamisi and ALTONDA>=ondaisi then high isirole:n=1'gosub say:
if ustnem<=tamrut then LOW nemrole:m=0
if altnem>=tamrut then HIGH nemrole:m=1
return
'***************************** AYAR KAYIT PROGRAMI *****************************
AYARLANDI:
       IF MENU=1 then AYARLANDI
       gosub temizle
       LCDOUT $FE,$80, "    AYARLAR     "
       LCDOUT $FE,$C0, "   KAYDEDiLDi   "
       AYAR=1:SYC=0
         WRITE 0, USTISI: PAUSE 10
         WRITE 1, ALTISI: PAUSE 10
         WRITE 2, USTNEM: PAUSE 10
         WRITE 3, ALTNEM: PAUSE 10
         write 4, ALTONDA:pause 10
         WRITE 5, USTONDA:PAUSE 10
         PAUSE 500
       GOSUB TEMIZLE
goto BASLA   
'******************************* MENÜ PROĞRAMI *********************************
donus:
read 0, USTISI: PAUSE 10       
read 1, ALTISI: PAUSE 10
read 2, USTNEM : PAUSE 10
read 3, ALTNEM : PAUSE 10
read 4, ALTONDA : PAUSE 10
read 5, USTONDA : PAUSE 10

AYARLA:
LOW ISIROLE:LOW NEMROLE
WHILE MENU=1:WEND
GOSUB TEMIZLE
SYC=0
AYARLAR:
IF YUKARI=1 THEN
WHILE YUKARI=1:WEND
SYC=SYC+1
  IF SYC=5 THEN SYC=0
ENDIF

IF ASAGI=1 THEN
WHILE ASAGI=1:WEND
SYC=SYC-1
  IF SYC=255 THEN SYC=4
ENDIF

SELECT CASE SYC
CASE 0         
LCDOUT $FE,$80, " UST ISI AYARI  "
LCDOUT $FE,$C0, " ISI : ",dec2 USTISI,".",dec1 USTONDA,derece," C     "
IF MENU=1 then
WHILE MENU=1:WEND
GOTO bir
ENDIF
CASE 1         
LCDOUT $FE,$80, " ALT ISI AYARI  "
LCDOUT $FE,$C0, " ISI : ",dec2 ALTISI,".",dec1 ALTONDA,derece," C     "
IF MENU=1 then
WHILE MENU=1:WEND
GOTO iki
ENDIF
CASE 2         
LCDOUT $FE,$80, " UST NEM AYARI  "
LCDOUT $FE,$C0, " NEM : ",dec USTNEM ," %      "
IF MENU=1 then
WHILE MENU=1:WEND
GOTO uc
ENDIF
CASE 3 
LCDOUT $FE,$80,    " ALT NEM AYARI  "
LCDOUT $FE,$C0,    " NEM : ",dec ALTNEM ," %      "
IF MENU=1 then
WHILE MENU=1:WEND
GOTO dort
ENDIF
CASE 4
lcdout $fe,$80,"    MENUDEN     "
LCDOUT $FE,$C0,"     CIKIS      "
IF MENU=1 THEN AYARLANDI
END SELECT
GOTO AYARLAR
'********************************* menü kısmı *****************************************
BIR:   
SET1: 
           LCDOUT $FE,$C0, "=>ISI : ",dec USTISI,".",dec1 USTONDA,derece," C     "
           IF YUKARI=1 then
              USTONDA=USTONDA+1
                IF USTONDA=10 THEN
                USTONDA=0:USTISI=USTISI+1
                ENDIF
              IF USTISI=100 THEN USTISI=0
              PAUSE 75
           ENDIF
           IF ASAGI=1 then
              USTONDA=USTONDA-1
                IF USTONDA=255 then
                USTONDA=9:USTISI=USTISI-1
                ENDIF
              IF USTISI=255 THEN USTISI=37
              PAUSE 75
           ENDIF
               
         IF MENU=1 THEN
         GOTO ayarla
         ENDIF

    GOTO SET1
IKI:   
set2:
           LCDOUT $FE,$C0, "=>ISI : ",dec ALTISI,".",dec1 ALTONDA,derece," C     "
           IF YUKARI=1 then
              ALTONDA=ALTONDA+1
                IF ALTONDA=10 THEN
                ALTONDA=0:ALTISI=ALTISI+1
                ENDIF
              IF ALTISI=50 THEN ALTISI=0
              PAUSE 75
           ENDIF
           IF ASAGI=1 then
              ALTONDA=ALTONDA-1
                IF ALTONDA=255 then
                ALTONDA=9:ALTISI=ALTISI-1
                ENDIF
              IF ALTISI=255 THEN ALTISI=36
              PAUSE 75
           ENDIF
               
         IF MENU=1 THEN
         GOTO AYARLA
         ENDIF

    GOTO SET2       

UC:     

set3:
            LCDOUT $FE,$C0, "=>NEM : ",dec USTNEM ," %      "
            IF YUKARI=1 then
                USTNEM=USTNEM+1
                ENDIF
              IF USTNEM=100 THEN USTNEM=0
              PAUSE 75
           IF ASAGI=1 then
                USTNEM=USTNEM-1
                ENDIF
              IF USTNEM=255 THEN USTNEM=65
              PAUSE 75
         IF MENU=1 THEN
         GOTO AYARLA
         ENDIF
    GOTO SET3       

DORT:   
SET4:       
            LCDOUT $FE,$C0,    "=>NEM : ",dec ALTNEM ," %      "
            IF YUKARI=1 then
                ALTNEM=ALTNEM+1
                ENDIF
              IF ALTNEM=99 THEN ALTNEM=1
              PAUSE 75
           IF ASAGI=1 then
                ALTNEM=ALTNEM-1
                ENDIF
              IF ALTNEM=255 THEN ALTNEM=60
              PAUSE 75
         IF MENU=1 THEN
         GOTO AYARLA
         ENDIF
    GOTO SET4

goto ana

temizle:
LCDOUT  $FE,1
return

GOSTER:

    LCDOUT  $FE,1
    LCDOUT  $FE,$80," NEM : ",dec2 tamrut,".",dec1 ondarut," %  ",dec m
    LCDOUT  $FE,$C0," ISI : ",dec2 tamisi,".",dec1 ondaisi,derece,"C","  ",dec n
    PAUSE   100
    return

SENSOROKU:

          output dht_port 
           dht_port=1:PAUSEUS 5
           dht_port=0
           Pause 5      '1-10 ms bekle
           dht_port=1         'Data pinini High yap
           Pauseus 40      '40 us bekle
           input dht_port
           pauseus 5
           WHILE dht_port=0:WEND
           PAUSEUS 80

           TAMRUT=0
            FOR I=15 to 0 STEP-1  'MSB bitleri önce geleceği için döngümüzü tersten kuruyoruz.
              WHILE dht_port=0:WEND 
               Pauseus 30
              IF dht_port=1 then TAMRUT.0[I]=1
              while dht_port=1:wend
             Next

            TAMISI=0
            FOR I=15 to 0 STEP-1  'MSB bitleri önce geleceği için döngümüzü tersten kuruyoruz.
              WHILE dht_port=0:WEND
               Pauseus 30
              IF dht_port=1 then TAMISI.0[I]=1
              while dht_port=1:wend
            Next           

            control=0
            FOR I=7 to 0 STEP-1  'MSB bitleri önce geleceği için döngümüzü tersten kuruyoruz.
              WHILE dht_port=0:WEND
               Pauseus 30
              IF dht_port=1 then control.0[I]=1
              while dht_port=1:wend 
            Next
            output dht_port
            dht_port=1
            pauseus 50
            dht_port=0
            ONDARUT=TAMRUT//10:TAMRUT=TAMRUT/10
            ONDAISI=TAMISI//10:TAMISI=TAMISI/10                       
            return



END

ete

Bu gibi durumlarda programı simulasyonda çalıştırmak en doğrusu. O size varsa bir stack taşması vs hemen gösteriyor. Bu şekilde bulmak daha kolay.

Programada çöyle bir baktım. İncelemesi saatler alabilir. Ama en başta hemen farkettiğim eksiklikler var.
1. LCDOUT $FE,1 komut satırı değişken tanımlamadan hemen sonra verilerek peşine 200 ms lik bir gecikme koyulmalı. Bu LCD nin kendi registerlerini yerli yerine koyması için gerekli olan bir komuttur ve bunu yapmadan başlatırsan programı programda rastgele çalışır. Kitlenebilirde.
2. Otomatikman bir açılış gecikmeside yok programda. Bu gecikmede pic kendi registerlerinin açılıştan sonra yerleştirilmesi için gereklidir. Hiç bir işlemci voltajı verdiğin zaman direk çalışmaya başlamaz. Önce programın kullandığı değişkenleri ram alanına yerleştirir onların adreslerini alır bir yerlere kayıt eder bunlar zaman alan işlerdir ve en azından bu işler için programa 200-300 ms lik bir gecikme vererek açmak zorundasın.
3. Donus isimli bir etiket altında bir çok adresten eprom okuması yapıyorsun ve her birine 10 ms lik gecikme koymuşsun. Epromdan okuma yaparken gecikme son derece gereksizdir. Gecikme sadece yazmada gereklidir zaman alan bir iş olduğundan ikinci yazmaden önce en azından 10 ms geçmesi beklenmelidir.
4. Yalnızca Y=Y+1 işlemi için Gosub saydır demek bence hatalı direk o komutu gosub dediğin yere yazman senin için daha doru olurdu.
5. Isı kontrolü Y=10 ise yapılıyor. Hiç kontrol ettinmi Y=10 olabiliyormu? ya arada engel çıkıyor ise ısı kontrolün bu nedenle yapılmıyor olabilir.
6. Isı karşılaştırmasında bir sorun göremedim. Yinede simulasyonda değişken değerleri takip edilerek bir çalıştırma yapıp kimin ne değer aldığına bakmak en doğrusu olur sorun varsa ancak bu şekilde bulunabilir.

Ete


sinasos

teşekkür ederim hocam;
söylediklerinizi uyguladım şimdi teste aldım. söylediğiniz gibi y=10 atlıyormuş ekrana yazdırıp denedim. zaman zaman 255 e kadar sayıyordu bende y>=10 ilave ettim düzeldi orada sıkıntı kalmadı. ancak başlangıçta yaşanan sorun devam ediyor. ısı 18-20 li derecelerde, ayar 37.2 de ilk enerjiyi verdiğimizde çoğunlukla ısı rölesini aktif etmiyor.10-15 dakika bekliyorum bir türlü aktif olmuyor. ne zaman ki sensör ısısını yükseltirsek o zaman devreye giriyor ve o zaman sistem normal çalışıyor.
sizce bu neden olabilir ?

ete

Bana kalırsa karşılaştırma mantığın yanlış. Aşağıdaki satıra bakalım
IF ALTISI>=TAMISI and ALTONDA>=ONDAISI THEN HIGH ISIROLE:n=1'
Bu satıra göre şöyle bir varsayımımız olsun  ortam sıcaklığı 18,7 olsun (TAMISI=18 ,ONDAISI=7) ve ALT Set sıcaklığımız da 20,5 olsun (ALTISI=20 ve ALTONDA=5) Şimdi malum karşılaştırmayı yapalım bakalım ne olacak ?
Bir defa ortam sıcaklığı alt ısıdan küçük olduğu için rölenin çekmesi gerekir öyle değilmi?
birinci karşılaştırma ALTISI>=TAMISI şartına bakalım 20>=18 bu doğru oluyor bunu geçiyor program
ikinci karşılaştırmaya bakalım ALTONDA>=ONDAISI  5>=7
IF USTISI<=TAMISI and USTONDA<=ONDAISI bu yanlış oluyor 5 , 7 den büyük değildir. O halde bu satır otomatikman atlanıyor. Ne yapman lazım? tabiiki ondalık kısmı tam sayıya katıp öyle karşılaştırma yapman gerekiyor.  Ya da ondılk kısmı değerlendirmeyi şayet tam sayı kısmı doğru ise yapman gerekiyor. Yani şöyle
IF ALTISI>= TAMISI THEN
   IF ALTONDA>=ONDAISI THEN
       ISIROLE=1:N=1
   ENDIF
ENDIF

şeklinde olması gerekir.
Yada,
OKUNANISI=TAMISI*10+ONDAISI: SETISI=ALTISI*10+USTONDA 
IF SETISI=>OKUNANISI THEN
    ISIROLE=1:N=1
ENDIF

şeklinde yapman gerekir.

Ete

sinasos

nasıl söylenir bilmiyorum ama! çok teşekkür ederim hocam. ilgi ve alakanıza. emeğinize sağlık...

ete

Y nin atlandığını söylemiştin. Düzelttim dedinama nasıl oduğunu bilmiyorum. Bu nedenle
Y=Y+1 altına;
IF Y=11 then Y=0 yazıver oda düzelmiş olsun. Artırma nerede ise limit belirleme orada yapılmalı.
Sen artırmayı bir yerde limiti başka yerde hallediyorsun buda yanlış.
Ete

Powered by EzPortal