avatar_Celal Kızılırmak

DS18B20 ISI OKUMA SORUNU

Başlatan Celal Kızılırmak, 27 Ocak 2019, 02:34:42

Celal Kızılırmak

HOCALARIM ISI SENSÖRÜNÜ BİR TÜRLÜ OKUTAMADIM KODLAR DAMI BİR HATA VAR ACABA YARDIMCI OLURSANIZ SEVİNİRİM.




'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2019 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 27.01.2019                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
'***********Sigorta Ayarları***********

@ __config  _WDT_OFF & _MCLRE_ON & _LVP_OFF & _CP_OFF & _INTRC_OSC_NOCLKOUT

'***********Seri İletişim Dosyası***********

Include "MODEDEFS.BAS"
DEFINE OSC 4
'***********LCD Tanımlamaları***********

DEFINE LCD_DREG PORTA
DEFINE LCD_DBIT 0
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT  7
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 6
DEFINE LCD_BITS 4
DEFINE LCD_LINES        2

'***********Port Ayarları***********

OPTION_REG=%0000000
INTCON=%10010000
CMCON=7
TrisA=%00000000
TrisB=%00000111
PortA=0
PortB=0 

'***********Sensör Tanımlamaları***********
Comm_Pin    VAR PORTA.4
Busy        VAR BIT
HAM         VAR WORD
ISI         VAR WORD
SIGN        VAR BYTE
SIGN_BITI   VAR HAM.Bit11
NEGAT_ISI   CON 1
TEMP        VAR BYTE
Float       VAR WORD
SYMBOL ARTTIR=PORTB.1
SYMBOL AZALT=PORTB.2
SYMBOL EKRANAYD=PORTB.4
SYMBOL CIKIS=PORTA.3
SET         VAR BYTE
SETONDA     VAR BYTE
Y           VAR BYTE
Y=0
SET=18
ON INTERRUPT  GOTO KESME

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

lcdout $FE,1
PAUSE 50
BASLA:

gosub SENSOROKU
GOSUB SETLCD
GOSUB SETKONTROL
GOTO BASLA

SENSOROKU:           
OWOUT   Comm_Pin, 1, [$CC, $44]' ISI değerini oku

Bekle:
OWIN    Comm_Pin, 4, [Busy]    ' Busy değerini oku
IF      Busy = 0 THEN Bekle  ' hala meşgulmü? , evet ise goto Bekle..!
OWOUT   Comm_Pin, 1, [$CC, $BE]' scratchpad memory oku
OWIN    Comm_Pin, 2, [HAM.Lowbyte, HAM.Highbyte]' İki byte oku ve okumayı bitir.
GOSUB   Hesapla
RETURN
   
Hesapla:                 ' Ham değerden Santigrat derece hesabı
Sign  = "+"
IF SIGN_BITI = NEGAT_ISI THEN
Sign   = "-" 
temp=($ffff-ham+1)*625
ISI  = DIV32 10
GOTO GEC   
endif
TEMP = 625 * (HAM+1)        '
ISI = DIV32 10          ' Div32 hassas derece hesabı için 32 bit bölme yapıyoruz.
GEC:
FLOAT = (ISI //1000)/100
ISI=(ISI/1000)-1
lcdout $FE,$80,"SICAKLIK:",Sign,DEC ISI,".",DEC1 (Float),0,"C " '2. satırda ısı
if ISI=65535 then
lcdout $FE,$80,"                "
lcdout $FE,$80,"1. SENSORU TAKIN"   
endif
RETURN


SETLCD:
LCDOUT $FE,$C0,"SET:      ",DEC2 SET,".",DEC1 SETONDA,0,"C"
RETURN

SETKONTROL:
IF ISI=SET THEN
if (FLOAT)<SETONDA then
CIKIS=1
ELSE
CIKIS=0
ENDIF
ENDIF
RETURN


DISABLE
KESME:
EKRANAYD=1
pause 100
IF ARTTIR=0 THEN
FOR Y=0 TO 10 STEP 1
LCDOUT $FE,$C0,"SET:      ",DEC2 SET,".",DEC1 SETONDA,0,"C"
PAUSE 100
IF ARTTIR=0 THEN
SETONDA=SETONDA+1
IF SETONDA=10 THEN
SET=SET+1
SETONDA=0
ENDIF
Y=0
PAUSE 100
ENDIF
IF AZALT=0 THEN
SETONDA=SETONDA-1
IF SETONDA=255 THEN
SETONDA=9
SET=SET-1
ENDIF
Y=0
PAUSE 100
ENDIF
NEXT Y
ENDIF
IF AZALT=0 THEN
FOR Y=0 TO 10 STEP 1
LCDOUT $FE,$C0,"SET:      ",DEC2 SET,".",DEC1 SETONDA,0,"C"
PAUSE 100
IF ARTTIR=0 THEN
SETONDA=SETONDA+1
IF SETONDA=9 THEN
SET=SET+1
SETONDA=0
ENDIF
Y=0
PAUSE 100
ENDIF
IF AZALT=0 THEN
SETONDA=SETONDA-1
IF SETONDA=255 THEN
SETONDA=9
SET=SET-1
ENDIF
Y=0
PAUSE 100
ENDIF
NEXT Y
ENDIF
LCDOUT $FE,$1
INTCON.1=0
RESUME
ENABLE
END



ete

Bütün programı kesme içine yazmışın ve oraya da lüzümsuz bir sürü pause eklemişsin. Bu bir kusur ölümcül hata değil ama bu mantıkla program yazmamalısın. Kesme özel bir konumdur. Özel anlarda oraya gidilir ve ana amaç olarak da bir an önce oradan çıkılması gerekir. Sen ise en büyük oyalanmayı orada yapmışsın.

Diyelimki bu şekilde çalışmasını bekliyoruz. Nasıl kesmeye girecek program? INT kesmesi aktive ettiğine göre PORTB.0 pinindeki değişiklik programı kesmeye götürecek. Şema eklememiş olduğun için o kısım nasıl çalışıyor anlamak mümkün değil. Ne olup bittiğin anlamak için Option registerine bakıyorum.  OPTION_REG=%0000000 değeri verilmiş. Say bakalım kaç bitlik değer verilmiş. Ben 7 sayıyorum. Bunlara dikkat edin 8 bitlik registere 7 bitlik değer veriyorsun. Buda bir kusur.
Hadi diyelimki %00000000 değeri verilmiş bu ne anlama gelecek. Aslında bizi ilgilendiren 2 bit var. Bit.7 dahili Pullup ların aktif edildiğini gösterecek sen 1 bit eksik yazdığın için bu bit ne olacak bu belli değil maalesef.
Bit.6 ise INT kesmesinin hangi konumda gerçekleşeceğini gösterir. Bu bit sıfır olduğu için HIGH dan LOW a geçişte kesme oluşacak demektir. Peki senin devren buna uygunmu bunuda ancak şemanı gördükten sonra söyleyebilirdik göremediğimiz için sen karar vereceksin artık. Ama bir ip ucu var diğer buto pinlerini IF PIN=0 ise şeklinde kullandığına göre pulluplar aktif beklerken low a çekerek kullanıyorsun bu doğru seçim oluyor.

Biraz da DS18B20 den bahsetmek isterim. Bu sensör sıcaklık okuma işlemini yaklaşık 750 ms de gerçekleştiriyor.
Bu durumda elinde 2 alternatif var demektir. Ya okuma emrini verip seninde programında yapmış olduğun gibi 750 ms boyunca sensörün başında bekleyeip işlem tamamlanınca sıcaklık bilgisini alıp oradan ayrılacaksın, yada en güzeli okuma emrini verip oradan ayrılacak ve yaklaşık 750 ms oyalandıktan veya başka işler yaptıktan sonra gelip hazır olan sıcaklık bilgisini okuyup alacaksın. Ben genelde bu ikinci metodu tercih ediyorum.
Bu açıklamayıda dikkate alarak programını ben olsam şöyle yazardım.
- Sıcaklık okuma emrini verip dönerim.
OWOUT   Comm_Pin, 1, [$CC, $44]' ISI değerini oku
RETURN

- Daha sonra kesme olmaksızın Tuş kontrolüne giderim. Burada yaklaşık 750 ms zamanım var istediğim gibi vakit harcaya bilirim bütün tuşları kontrol eder ve sonunda dönerim.
En güzeli TMR1 sayacını yaklaşık 250 ms ye ye ayarlarım ve 3 adet kesme oluşturmasını sayarım. Bunun için kesmeyide ektif etmen gerekmiyor. Sadece PIR1.0 bitinin HIGH olup olmadığını kontrol edeceksin ve olmuş  ise KES=KES+1 yapacak ve KES=3 olduğunda 750 ms geçmiş olacaktır. Bu anda artık tuş kontrolünü bırakıp doğruca sıcaklık okumaya gitmem gerekir.
- Sıcaklığı alıp ekrana verir ve ardından tekrar okuma emrini verip,  setkontrol ve tuşkontrol işlerini yeniden kontrol ederim.
Bu döngüyü bu şekilde çevirirsen hiç bir şey aksamaz.
Unutma sensörün başında beklersen ve arada kesme oluşursa program sensörden ayrılacak ve bağ kopacaktır. Böylece okuma başarısız olur. Bu nedenle 750 ms lik süre zarfından sensörün başından ayrılmamaya özen göstermek gerekir. Yada ikinci metodu kullanarak her şeyi sorunsuz halletmen gerekir.

Timer1 sayacını kullanarak zaman tutma işini biraz daha açayım istersen.
Sensöre okuma emrini verdin ve döndün diyelim.
250 ms lik süre ayarı için TMR1 sayacını 34286 dan başlatıp 65535 e kadar saydırman gerekiyor. Bölme oranıda 1/8 olacak. 65536-34286=31250 adım sayacak bölme=1/8 olduğu için bunu 8 ile çarparız tam tamına 250.000 adım ederki her bir adım 1us olduğu için bu tam tamına 250 ms lik bir gecikmeye eşdeğer olacaktır. 34286 nın HEX karşılığı $85EE dir. O halde işe başlarken şunları yapacağız. Öncelikele T1CON registerini aktif edip 1/8 bölme oranını vereceğiz.
T1CON=%00110001:KES=3 
Ardından bir etiket adı belirleyip her 250 ms bittiğinde aynı işi tekrar yapmak üzere bu etikete geleceğiz.
TEKRAR:
Tmr1H=$85:TMRL=$EE:PIR1.0=0
WHILE PIR1.0=0
  GOSUB TUSBAK
WEND
KES=KES-1:IF KES>0 then TEKRAR
Bu noktada 750 ms zaman geçmiş olacak Önce T1CON=0 verip sayacı durduracağız.
Daha sonra Gidip sensörü okumak gerekecek  GOSUB SICAKLIK_AL
SICAKLIK_AL kısmında ise ;
OWOUT   Comm_Pin, 1, [$CC, $BE]' scratchpad memory oku
OWIN    Comm_Pin, 2, [HAM.Lowbyte, HAM.Highbyte]' İki byte oku ve okumayı bitir.
GOSUB   Hesapla
şeklinde komut satırları olması yeterli. Önceki kod da yer alan BEKLE işlemine artık gerek olmadığı için onu çıkartıyoruz.
Şimdi GOSUB SETKONTROL deyip sıcaklığı karşılaştırmak gerekecek. Ardından da Goto basla deyip bütün işlemleri

Sana kalan yalnızca Tuş kontrolünü bir alt program şeklinde yazıp dönüşünü RETURN ile yapmak olmalı.
Böylece sistemin kusursuz çalışacaktır.
Bu arada Comm pini olarak PORTA.4 kullanmışsın. Bu pin kendi başına HIGH çıkartamaz. Bir Pullup direnci mutlaka bağlanmalıdır pine. Şema olmadığı çin yalnızca ikaz ediyorum.

Unutma mevcut kullandığın yöntem ile de bu program çalışır. Ancak kesme içindeki pause leri kaldırman gerekir.
Çalışır ama sorunlu çalışır en iyisi önerdiğim yöntemi dene sen.
SOnucu bildirirsin.

Ete




ete

#2
İllaki kendi yöntemini kullanmak istersen tuş kontrolünde kesmeden çıkmamanın bir çaresini bulman gerekir. Zira orada döngüde kursan anında döngü biter ve program kesmeden çıkar.
Çaresi şu, PORTB.0 pinini SET pini olarak kullanacaksın. Zaten bu pin LOW olunca program kesmeye girecek. Bu pin LOW olacak ve ayar için LOW da kalacak (bir nevi anahtar gibi düşün.) PORTB.0 LOW da iken SET ayarlarını yapacaksın ve PORTB.0 pinini tekrar HIGH yaptığın zaman sistem kesmeden çıkıp normal işine dönecek.
Tabiiki Kesme kısmındaki bir çok lüzümsuz satırıda silmek gerek.
Şöyle olmalı orası;
KESME:
        EKRANAYD=1
        WHILE PORTB.0=0
            IF ARTTIR=0 THEN
              SETONDA=SETONDA+1
              IF SETONDA=10 THEN
                SET=SET+1
                SETONDA=0
              ENDIF             
            ENDIF
            IF AZALT=0 THEN
              SETONDA=SETONDA-1
              IF SETONDA=255 THEN
                SETONDA=9
                SET=SET-1
              ENDIF
            ENDIF
            pause 100
            LCDOUT $FE,$C0,"SET:      ",DEC2 SET,".",DEC1 SETONDA,0,"C"               
        WEND
        INTCON.1=0
        EKRANAYD=0
        RESUME
        ENABLE
END

bu sistem işini görecektir. Zaten kesmeye girince PORTB.4 HIGH olacak çıkınca da tekrardan LOW olacak aynı pin.

Sıcaklık okuma kısmına şimdilik dokunma. Yalnızca hesap kısmını aşağıdaki şekilde değiştir
    Sign  = "+"
    IF SIGN_BITI = NEGAT_ISI THEN
       Sign   = "-" 
       ham=~(ham-2)
    endif                                   
    ISI = HAM*10/16     '
    FLOAT=ISI//10
    ISI=ISI/10

Aslında sıcaklık ile set değeri karşılaştırırken 10 ile çarpılmış hallerini kullansan hiç de fena olmaz.
Sıcaklık 10 ile çarpılmış şekilde okunuyor. Sonradan 10 a bölüyoruz. Bunu bölme ama ekrana yazdırırken bölerek yazdır.
Aynı şekilde set değeride 10 ile çapılmış şekilde tut hafızada ve karşılaştırıken
IF SET=ISI şeklinde karşılaştır bir çok sorununu ortadan kaldırır bu mantık.

Bir başka yöntem de PORTB (4-7) değişiklik kesmesi kullanmaktır. Bu durumda artır ve azalt tuşlarını PORTB.6 ve PORTB.7 ya bağlarsan ve INT kesmesi yerine değişiklik kesmesi kullanırsan direk verdiğim kesme kodundan while-wend kısmını çıkartarak yararlanabilirsin.

Ete

Celal Kızılırmak

#3
Ete hocam şemayı kısa zamanda paylaşacağım. Sensör bir türlü okumuyor hesaplama kısmını sizin söylediğiniz gibi yapsam düzelirmi.Tabiki bu söylediklerim simülasyon programı içinde oluyor.şemayı yükledikten sonra tekrar yardımcı olur ve yorumlrsınız. Teşekkürler.

ete

Sorun hesaplama kısmında değil muhtemelen devrende donanım hatası var. Yada aldığın DS18B20 bozuk.
Normalde okuması gerek ama tuş kontrolün çalışmıyor bu dediklerim programı verdiğin hali için geçerli.
Şema birebir yaptığın devre ile aynı olmalı bunada dikkat etmelisin.
Burada kritik nokta DS18B20 nin Data yada Out bacağı ile +5V arasında 4K7 direnç ile pullup yapılmış olması önemli.

Ete

. Kağan

Erol bey, Sensörün takılı olup olmadığını tespit edebilmek için A0 portunu yoklayıp sensörden "buradayım" şeklinde bir bilgi isteyebilirmiyiz. Bu bilgiyi kullanıp sensör yok alt menüsüne gitsin istiyorum.

Teşekkürler

ete

#6
Sensöre buradamısın diye soru yöneltemiyoruz. Çünki okuma yapacağım diye emir verdikten sonra okumanın tamamlandığını yada tamamlanmadığını kontrol edebiliyoruz.

Normal şartlarda okuma süresi 750 ms dir Bu süreyi Busy bitine bakarak bekliyor ve Busy=1 olduğunda okunan bilgileri alıp sensör okumadan çıkıyoruz. Şayet sensör var ise okuma peryodu içerisinde Busy=1 olacaktır mutlaka. Sensor yok ise bu değer 750 ms içinde sürekli sıfırda kalacaktır. Yada ne olduğu anlaşılamayacaktır. Beklerken birde sayaç çalıştırabilirseniz ve sayac süresi 750 ms aştığı halde okuma tamamlanmamış ise sensör yok yada kopukluk var demektir. O zaman istediğiniz yere gidebilirsiniz.
Bekle:     
           Sayac=0
           WHILE sayac<750
             OWIN    Datapin , 4 , [Busy]
             IF busy = 1 THEN exit
             Sayac=sayac+1
             PAUSE 1
           WEND
           IF TOPLAM=750 THEN SENSOR_YOK

              RETURN
            ENDIF 

şeklinde bir kod ile halledilebilir sanırım.

Ayrıca data sheet e bakılırsa okuma rutini sensör varlığı kontrol edilerek başlıyormuş. Bunun için
Sensör pini çıkış yapılıp LOW a çekiliyor ve 480uS bekleniyor. Ardından Aynı pin giriş yapılıyor ve hemen pullup direncinden dolyaı pin HIGH oluyor. Bu konumda yaklaşık 60-240us süre içinde Sensör pininin Sensör tarafından LOW a çekilmesi gerekiyor (sensör varsa tabiiki) çekilmemiş ise anlıyoruzki sensör mevcut değil.
Bunun için Sensör okumaya gitmeden önce;
  HIGH PORTA.0  'DATA PİNİ ÇIKIŞ YAPILDI VE HIGH UYGULANDI
       porta.0=0     'DATA PİNİ LOW YAPILDI
       pauseus 480   '480 uS LOW DA TUTULDU
       INPUT PORTA.0 'DATA PİNİ GİRİŞ YAPILDI VE PULLUP DAN DOLAYI PİN ANINDA HIGH OLACAK
       pauseus 20    '20uS BEKLİYORUZ SENSÖR DATA PİNİNİ low A ÇEKMESİ GEREKİYOR.
       DON=0
       if porta.0=0 then atla  'ŞAYET DATA PİNİ LOW OLMUŞ İSE SENSÖR VAR ÇIK GİT SENSÖRÜ OKU     
       WHILE PORTA.0=1 AND DON<50  'YAKLAŞIK 240uS İÇİNDE SENSÖR PİNİ LOW OLMASI GEREK
        DON=DON+1
        PAUSEUS 5                  'BİZ 250 uS BEKLEYELİM
'        IF PORTA.0=0 THEN EXIT
       WEND 
     
       IF PORTA.0=1 and DON=50 THEN SENSORYOK   'BU SÜRE İÇİNDE SENSÖR PİNİ HALA HIGH İSE SNSÖSENSÖR YOK DEMEKTİR
ATLA:       
       GOSUB SENSOROKU
şeklindeki bir kod ile de sensör varlığı veya yokluğu kontrol edilebilir.


Ete

. Kağan

Hocam tekrar merhaba,

bendeki sensörü okurken
OWIN  SENSOR_ORTAM, 4, [Busy]    ' Busy değerini oku
kodunu eklemesem de sensör çalışıyor ve okuma yapıyor. Bu kodu yazdığımda da bir sonuç çıkmıyor.

ete

#8
busy okumanın sıcaklık okuma ile bir alakası yok. Sadece okuma işleminin tamamlanıp tamamlanmadığını kontrol eder busy.
Sen onsuz da okuma yapabilirsin tabiiki.
Şayet o satır yok ise kodların arasında ikinci alternatifi dene o zaman.

Ete

Not: her iki alternatifi de denedim çalışıyorlar.

. Kağan

Bi sorum daha olacak.


OWIN    Datapin , 4 , [Busy]
OWOUT Datapin,1,[$CC,$BE] 'Sensöre okuduğu değeri göndermesini söyle.
OWIN  Datapin,2,[HAM.LOWBYTE,HAM.HIGHBYTE] 'Gelen 16 bitlik bilgiyi al.


Datapin den sonra gelen rakamlar her sensör için farklı mı olmalı? Yani farklı girişlerde farklı sensörler olduğunda bunlar değişmeli mi. Ve bu rakamlar farklı kod yazarlarında farklı verilmiş. Neye göre değişiyor. Yazıp geçiyoruz ama anlamak isterim.

ete

Bir komut ile ilgili bilgi almak istediğinizde kursörü komut üstüne getirip F1 tuşuna basın. Böylece komut açıklaması ekrana gelecektir. (Benim PC de Fn+F1 tuşları aynı işi yaptırıyor.)
Bu komut açıklamasına bakarsanız.
Mode bit number Effect
0  = send reset pulse before data
1  = send reset pulse after data
2  = byte-sized data, 1 = bit-sized data
0 verince data göndermeden önce bir reset puls'ı uyguluyor
1 verince data dan sonra reset pulsı veriliyor
2 verilince byte cinsinden data yollanıyormuş. 1 olursa bit cinsi data oluyormuş.

Bazı örneklerde burada 4 gibi açıklamda olmayan rakamlar görüyorum. Bir anlamı olduğunu sanmıyorum.
Doğru değerler 0-1-2 olmalı.
Ete



. Kağan

BASLA:

IF MOD_SEC=0 THEN
 
WHILE MOD_SEC=0 : WEND

TOGGLE DRM       
ENDIF

IF DRM=1 THEN
GOTO BTN_KNTRL
ENDIF

OWOUT SENSOR_ORTAM,1,[$CC,$44]   'ORTAM Sensöre sıcaklığı okumasını söyle.
GOSUB SENSOR_ORTAM_OKU

OWOUT SENSOR_DEFROST,1,[$CC,$44]   'DEFROST Sensöre sıcaklığı okumasını söyle.
GOSUB SENSOR_DEFROST_OKU

OWOUT SENSOR_MOTOR,1,[$CC,$44]   'MOTOR Sensöre sıcaklığı okumasını söyle.
GOSUB SENSOR_MOTOR_OKU

OWOUT SENSOR_SU_GIRIS,1,[$CC,$44]   'SU GIRIS Sensöre sıcaklığı okumasını söyle.
GOSUB SENSOR_SU_GIRIS_OKU

OWOUT SENSOR_SU_CIKIS,1,[$CC,$44]   'SU CIKIS Sensöre sıcaklığı okumasını söyle.
GOSUB SENSOR_SU_CIKIS_OKU


LCDOUT $FE,1   
LCDOUT $FE, $80, "   SISTEM ISILARI   "
LCDOUT $FE, $C0, "ORTAM   MOTOR   G.SU"
LCDOUT $FE, $94, DEC2 ORTAM, ",", DEC1 ONDA_ORTAM, Derece,"C  ", DEC3 MOTORISI, Derece,"C   "   , DEC2 GIRIS, Derece,"C"
LCDOUT $FE, $D4, "        Ayar        "
PAUSE 100

IF  EKRANISI<SET OR (EKRANISI=SET AND ONDA_EKRANISI<SET1) THEN :GOTO MOTOR_ISI       

     
Goto BASLA

'*************ALT PROGRAMLAR**********************
BTN_KNTRL:
  LCDOUT $FE,1
  LCDOut $FE,$80, "MOTOR ISI: ", DEC2 EKRANISI,  ",", DEC2 ONDA_EKRANISI, Derece,"C "
  LCDOUT $FE,$C0, "ISI   SET: ", DEC2 SET,    ",", DEC2 SET1, Derece,"C "
  LCDOUT $FE,$94, "--------------------"
  LCDOUT $FE,$D4, "Azal   KAYDET    Art"
  pause 100
  i=0
  BUTTON BUTON1, 0,254,255,i,1,ARTI
  i=0                                                       
  BUTTON BUTON2, 0,254,255,i,1,EKSI
  i=0
  BUTTON MOD_SEC, 0,254,0,i,1,CIK
  GOTO BTN_KNTRL
 
CIK:
WHILE MOD_SEC=0
       WEND
        TOGGLE DRM
        IF DRM=0 THEN BASLA

  ARTI:
  PAUSE 100
  SET1=SET1+1
IF SET1=10 THEN SET1=0:SET=SET+1
IF SET=100 THEN SET=0
  WRITE 0,SET
  WRITE 1,SET1
  pause 100
GOTO BTN_KNTRL:

EKSI:
PAUSE 100
SET1=SET1-1
IF SET1=255 THEN SET1=9:SET=SET-1
IF SET=255 THEN SET=100:SET1=0
  WRITE 0,SET
  WRITE 1,SET1
  pause 100 
GOTO BTN_KNTRL

END



Merhaba,

Yukarıdaki gibi 5 adet sensörden değer istediğimde menüye geç giriyor. Menü tuşuna sıra gelmesi uzun sürüyor. Çünkü hepsine gidip veri alıp dönmesi uzun sürüyor. Menüye girişin rahatlaması için ne yapabilirim?


ete

Verdiğiniz kod'a bakıyorum tamda lazım olacak olan kısmını buraya koymadığınızı görüyorum.
GOSUB SENSOR_ORTAM_OKU nerede bu alt program ve orada ne yapılıyor.????

Genelde yapılan hata şudur. Sensör okuması ortalama 750 ms tutmaktadır. Okuma emrini verdikten sonra busy kontrolü yapılarak okuma işleminin bitirilmesi alt program beklenilerek yapılmaktadır.

Peki yapılması gereken nedir.?
OWOUT SENSOR_ORTAM,1,[$CC,$44]  komut satırı ile okuma emri verilerek program içinde yapılacak diğer işlere bakılmalıdır. Bu işler için ortalama 750 ms vakit harcanıp daha sonra hazır olan sıcaklık bilgisi sensörden okunmalıdır.
Olaya sizin açınızdan bakacak olursak,

5 sensör için okuma emrini verip menü vs gibi diğer işlerle uğraştıktan sonra gidip teker teker hazır olan sıcaklık değerlerini sensörlerden okumak en güzeli olurdu. Hatta daha da güzeli, 250 ms lik dilimler halinde TMR1 sensörü kurularak zaman tutulmalı ve 3 defa bu dilimi çalıştırıp üçüncünün sonunda sırası ile gidip sıcaklıkları okumak gerekir.

Ete


. Kağan

#13


OWOUT SENSOR_ORTAM,    1, [$CC, $4E, 0, 0, DS18B20_10bit]  'SENSOR COZUNURLUGU AYARLAMA 
OWOUT SENSOR_DEFROST,  1, [$CC, $4E, 0, 0, DS18B20_10bit]  'SENSOR COZUNURLUGU AYARLAMA
OWOUT SENSOR_MOTOR,    1, [$CC, $4E, 0, 0, DS18B20_10bit]  'SENSOR COZUNURLUGU AYARLAMA
OWOUT SENSOR_SU_GIRIS, 1, [$CC, $4E, 0, 0, DS18B20_10bit]  'SENSOR COZUNURLUGU AYARLAMA
OWOUT SENSOR_SU_CIKIS, 1, [$CC, $4E, 0, 0, DS18B20_10bit]  'SENSOR COZUNURLUGU AYARLAMA
' 10 bitte okuma süresi yaklaşık 200 ms

BASLA:
BUZZ=0 'BUZZER KAPATMA BITI
HIGH FAN
HIGH MOTOR

IF MOD_SEC=0 THEN
 
WHILE MOD_SEC=0 : WEND

TOGGLE DRM       
ENDIF

IF DRM=1 THEN
GOTO BTN_KNTRL
ENDIF


OWOUT SENSOR_ORTAM,1,[$CC,$44]   'Sensöre sıcaklığı okumasını söyle.
OWOUT SENSOR_DEFROST,1,[$CC,$44]   'Sensöre sıcaklığı okumasını söyle.
OWOUT SENSOR_MOTOR,1,[$CC,$44]   'Sensöre sıcaklığı okumasını söyle.
OWOUT SENSOR_SU_GIRIS,1,[$CC,$44]   'Sensöre sıcaklığı okumasını söyle.
OWOUT SENSOR_SU_CIKIS,1,[$CC,$44]   'Sensöre sıcaklığı okumasını söyle.
GOSUB BEKLE
GOSUB SENSOR_ORTAM_OKU
GOSUB SENSOR_DEFROST_OKU
GOSUB SENSOR_MOTOR_OKU
GOSUB SENSOR_SU_GIRIS_OKU
GOSUB SENSOR_SU_CIKIS_OKU


LCDOUT $FE,1   
LCDOUT $FE, $80, "   SISTEM ISILARI   "
LCDOUT $FE, $C0, "ORTAM   MOTOR   C.SU"
LCDOUT $FE, $94, DEC2 ORTAM, ",", DEC1 ONDA_ORTAM, Derece,"C  ", DEC3 MOTORISI, Derece,"C   "   , DEC2 CIKIS, Derece,"C"
LCDOUT $FE, $D4, "        Ayar        "
PAUSE 100


'************GIRISLERIN DEGERLENDIRILMESI*********

IF  CIKIS > SET OR (CIKIS=SET AND ONDA_CIKIS>SET1) THEN : GOTO CIKIS_SU       

         
Goto BASLA


BTN_KNTRL:
  LCDOUT $FE,1
  LCDOut $FE,$80, "SU  ISI:", DEC3 CIKIS,  ",", DEC2 ONDA_CIKIS,"C "
  LCDOUT $FE,$C0, "ISI SET:", DEC3 SET,    ",", DEC2 SET1, Derece,"C "
  LCDOUT $FE,$94, "--------------------"
  LCDOUT $FE,$D4, "Azal   KAYDET    Art"
  pause 100
  i=0
  BUTTON BUTON1, 0,254,255,i,1,ARTI
  i=0                                                       
  BUTTON BUTON2, 0,254,255,i,1,EKSI
  i=0
  BUTTON MOD_SEC, 0,254,0,i,1,CIK
  GOTO BTN_KNTRL
 
CIK:
WHILE MOD_SEC=0
       WEND
        TOGGLE DRM
        IF DRM=0 THEN BASLA

  ARTI:
  PAUSE 100
  SET1=SET1+1
IF SET1=10 THEN SET1=0:SET=SET+1
IF SET=100 THEN SET=0
  WRITE 0,SET
  WRITE 1,SET1
  pause 100
GOTO BTN_KNTRL:

EKSI:
PAUSE 100
SET1=SET1-1
IF SET1=255 THEN SET1=9:SET=SET-1
IF SET=255 THEN SET=100:SET1=0
  WRITE 0,SET
  WRITE 1,SET1
  pause 100 
GOTO BTN_KNTRL

END
SENSOR_ORTAM_OKU:
HAM=0
'************ SENSOR TAKILI MI KONTROLU *********************
HIGH SENSOR_ORTAM  'DATA PİNİ ÇIKIŞ YAPILDI VE HIGH UYGULANDI
SENSOR_ORTAM=0     'DATA PİNİ LOW YAPILDI
pauseus 480        '480 uS LOW DA TUTULDU
INPUT SENSOR_ORTAM 'DATA PİNİ GİRİŞ YAPILDI VE PULLUP DAN DOLAYI PİN ANINDA HIGH OLACAK
pauseus 20         '20uS BEKLİYORUZ SENSÖR DATA PİNİNİ low A ÇEKMESİ GEREKİYOR.
DON = 0
if SENSOR_ORTAM=0 then SENSOR_ORTAM_OKU2  'ŞAYET DATA PİNİ LOW OLMUŞ İSE SENSÖR VAR ÇIK GİT SENSÖRÜ OKU     

WHILE SENSOR_ORTAM=1 AND DON<50  'YAKLAŞIK 240uS İÇİNDE SENSÖR PİNİ LOW OLMASI GEREK
DON=DON+1
PAUSEUS 5                  'BİZ 250 uS BEKLEYELİM
WEND 
     
IF SENSOR_ORTAM=1 and DON=50 THEN SENSOR_ORTAM_ARIZA   'BU SÜRE İÇİNDE SENSÖR PİNİ HALA HIGH İSE SNSÖSENSÖR YOK DEMEKTİR
'****************************
SENSOR_ORTAM_OKU2:
OWOUT SENSOR_ORTAM,1,[$CC,$44]   'Sensöre sıcaklığı okumasını söyle.
PAUSE 500
OWOUT SENSOR_ORTAM,1,[$CC,$BE] 'Sensöre okuduğu değeri göndermesini söyle.
OWIN  SENSOR_ORTAM,2,[HAM.LOWBYTE,HAM.HIGHBYTE] 'Gelen 16 bitlik bilgiyi al.

ISI=HAM*10/16  ' Ham değerden Santigrat derece hesabı
ORTAM=ISI/10 '12 bit hassasiyet kullandığımız için her değer 0.0625 santigrat dereceye denk geliyor.
ONDA_ORTAM=ISI//10
RETURN

BEKLE:
PAUSE 250
RETURN

ete

Süreleri kısaltabilmek için çözünürlüğü dolayısıyla ısı değeri oluşturma süresini kısaltmışsınız. Ama kullandığınız mantık aynı.
Sensörlere okuma emri ver ve hiç bir şey yapmadan bekle. İşte o hiçbirşey yapmadan bekle kısmında yapılacakları yapabilme imkanınız var iken neden değerlendirmiyorsunuz?
Bu program yalnızca sensör okuması yapıyor başka iş yapamıyor sanırım. Bu kısa kod parçasında bile buton kontrolleri var ama oraya ulaşım göremedim. Belliki programın başka uzantılarıda mevcut ve sistem benim mantığıma ters çalışıyor.
Benim mantığımla 12 bit çözünürlükle programın yapması gereken her şeyi yaptırır ve toplamda 750 ms içinde o sensörlerin hepsini okuyabilirdim. Temel mantık ise okuma emrini Gosub ile göndererek ver Return ile geri dön. Yapacaklarını yap ama zaman say 750 ms dolunca Gosub ile git hazır olan sıcaklık değerlerini sadece okuyup return ile geriye dön şeklindedir.

Ete


Powered by EzPortal