Seri iletişimde hız sorunu

Başlatan erdemefe, 25 Ocak 2012, 02:19:42

erdemefe

Arkadaşlar iki tane 12f675 i seri haberleştirerek bir picde okuduğum sıcaklıgı diğer pice iletip ordada 3 tane 74HC595 ile ekrana yazdırdım -9.9 derece ile 99.9 derece arası ölçüm yapabiliyor. fakat bir sorunum var hem gerçekte hemde simulasyonda sıcaklık çok geç değişiyor gözlemlediğim kadarı ile ekran her 1.5 yada 2 snyede bir yenileniyor piclerin dahili osilatörlerini kullandım bilgiyi TRM0 kesmesi kullarak gönderdim ve aldım. ve 433MHZ alıcı ve verici modül kullanıyorum.

İkinci bir sorun ise simulasyonda programda belirlediğim min. sıcaklık değerinin altında (-9.9) ve maximum sıcaklık değerinin üstündeyken (99.9) bir yanlışlık oluyor atıyorum 99.9 yazarken 99.4 yazıp bida 99.9a dönüyor bu gerçekde de olurmu?

Birde sorum var verici kapsama alanından çıktığı zaman ekranda en son alınan sıcaklık bilgisi kalıyor. Nasıl vericinin kapsama alanından çıktığını anlayıp da ekrana özel birşeyler yazdırabilirim?

Kodları ve simulasyonu ekledim bakarsanız memnun olurum.

Mucit23

@erdemefe;
Ben programı biraz inceledim. Bazı ufak hataların var onları düzelteyim dedim.
Haberleşmede baund modları 4 adettir bunlar
Mode=813 , Haberleşme hızı 1200 Baud
Mode=396 , Haberleşme hızı 2400 Baud
Mode=188 , Haberleşme Hızı 4800 Baud
Mode= 84 , Haberleşme Hızı 9600 Baud

Sen burada 369 gibi bir değer yazmıştın. Bu yanlıştır. Ben bunu 396 olarak değiştirdim. 2400 baundta çalışıyor.

Ben programda ufak tefek değişiklikler yaptım.  Bi incele aklına takılan yerleri sor. Bu şekilde birazdaha iyi oldu gibi. Aslında senin yerinde olsaydım USART olan bir picle denerdim.
Verici
@ DEVICE PIC12F675                      'işlemci 16F628                                
@ DEVICE PIC12F675, WDT_ON              'Watch Dog timer açık
@ DEVICE PIC12F675, PWRT_ON             'Power on timer açık
@ DEVICE PIC12F675, PROTECT_OFF         'Kod Protek kapalı
@ DEVICE PIC12F675, MCLR_off            'MCLR pini kullanılMIYOR.
@ DEVICE PIC12F675, INTRC_OSC_NOCLKOUT  'Dahili osilatör kullanılacak
'-----------------------------------------------------------------
ON INTERRUPT GOTO KESME
'-----------------------------------------------------------------
TRISIO=%00000001   
CMCON=7
ANSEL=0
OPTION_REG=%10000101
INTCON=%00100000
'-----------------------------------------------------------------
DEFINE OSC 4
DEFINE OSCCAL_1K 1
INCLUDE "modedefs.bas"
'-----------------------------------------------------------------
symbol OUT=GPIO.1
SYMBOL DQ=GPIO.0
'-----------------------------------------------------------------
    Busy        VAR BIT         ' Busy Status-Bit
    HATA        VAR BIT
    HAM         VAR WORD
    ISI         VAR WORD        ' Sensör HAM okuma değeri
    Float       VAR WORD        ' Holds remainder for + temp C display       
    ISARET_BITI VAR HAM.11'Bit11   '   +/- sıcaklık İşaret biti,  1 = olursa eksi sıcaklık     
    ISARET      VAR BYTE       
    A           VAR BYTE
'-----------------------------------------------------------------
GPIO=0
GOSUB SENSOR_YAZ
GOSUB SENSOR_OKU
INTCON.7=1
BASLA:
    GOSUB SENSOR_OKU
    IF ISI>1000 AND ISARET=0 THEN
    ISI=999
    ENDIF
   
    IF ISI>100 AND  ISARET=1 THEN
    ISI=99
    ENDIF
GOTO BASLA

SENSOR_YAZ:       
  OWOUT   DQ, 1, [$CC,$4E, $FF, $FF, $7F]  ;Hassasiyet 12 bit olarak ayarlanıyor
  OWOUT   DQ, 1, [$CC,$48]         
  OWOUT   DQ, 1, [$CC,$B8]         
  OWOUT   DQ, 1, [$CC,$BE]         
return

SENSOR_OKU:
          OWOUT   DQ, 1, [$CC, $44]' ISI değerini oku
Bekle:
          OWIN    DQ, 4, [Busy]    ' Busy değerini oku
          IF      Busy = 0 THEN Bekle    ' hala meşgulmü? , evet ise goto Bekle..!
          OWOUT   DQ, 1, [$CC, $BE]' scratchpad memory oku
          OWIN    DQ, 2, [HAM.Lowbyte, HAM.Highbyte]' İki byte oku ve okumayı bitir.
          GOSUB   Hesapla
RETURN

Hesapla:  ' Ham değerden Santigrat derece hesabı
    IF ISARET_BITI = 1 THEN
       ISARET = 1 ;İşaret negatif,Nokta pasif..
       ham=~ham+2
       GOTO CIK
    endif
    ISARET  = 0   ;İşaret pozitif,Nokta aktif..
CIK:
    float = (HAM*10)/16
    ISI=FLOAT/10
RETURN 
   
    DISABLE
    KESME:
    serout2 out,396,[REP$AA\5,REP$00\5,REP$FF\5]
    SEROUT2 OUT,396,["E","F","E",FLOAT.LOWBYTE,FLOAT.HIGHBYTE,ISARET]
    SEROUT2 OUT,396,["E","F","E",FLOAT.LOWBYTE,FLOAT.HIGHBYTE,ISARET]
    SEROUT2 OUT,396,["E","F","E",FLOAT.LOWBYTE,FLOAT.HIGHBYTE,ISARET]
    RESUME
    ENABLE
    END


Alıcı
@ DEVICE PIC12F675                      'işlemci 16F628                                
@ DEVICE PIC12F675, WDT_ON              'Watch Dog timer açık
@ DEVICE PIC12F675, PWRT_ON             'Power on timer açık
@ DEVICE PIC12F675, PROTECT_OFF         'Kod Protek kapalı
@ DEVICE PIC12F675, MCLR_off            'MCLR pini kullanılMIYOR.
@ DEVICE PIC12F675, INTRC_OSC_NOCLKOUT  'Dahili osilatör kullanılacak
'-----------------------------------------------------------------
ON INTERRUPT GOTO KESME
'-----------------------------------------------------------------
TRISIO=%00001000   
CMCON=7
ANSEL=0
OPTION_REG=%10000101
INTCON=%00100000
'-----------------------------------------------------------------
DEFINE OSC 4
DEFINE OSCCAL_1K 1
INCLUDE "modedefs.bas"
'-----------------------------------------------------------------
symbol CLK=GPIO.2
SYMBOL DT=GPIO.1
SYMBOL LD=GPIO.0
SYMBOL IN=GPIO.3
'-----------------------------------------------------------------
SAYI    VAR WORD
X       VAR BYTE
ISI     var WORD
ISARET  VAR BIT
'-----------------------------------------------------------------
GPIO=0
INTCON.7=1
BASLA:


x=ISI dig 0 : gosub al : GOSUB YAZ


x=ISI dig 1 : gosub al : SAYI.BIT7=1: GOSUB YAZ

IF ISARET=0 AND ISI>99 THEN
X=ISI DIG 2 : GOSUB AL : GOSUB YAZ
ENDIF

IF ISARET=0 AND ISI<100 THEN
SAYI=0 : GOSUB YAZ
ENDIF

IF ISARET=1 THEN
SAYI=64 : GOSUB YAZ
ENDIF

PULSOUT LD,1
goto basla

'-------------------------------------------------------------------------
AL:    LOOKUP X,[63,6,91,79,102,109,125,7,127,111,99,57,64,0],SAYI :RETURN     
'-------------------------------------------------------------------------
YAZ:
  shiftout dt,clk,1,[sayi]
return

DISABLE
KESME:
SERIN2 IN,396,[WAIT ("EFE"),ISI.LOWBYTE,ISI.HIGHBYTE,ISARET]
RESUME
ENABLE   
end


Verici kısımda Sesoryaz gibi bir bölüm ekledim. Bu sensörün ilk başta set edilmesini sağlıyor. Genelde 12 Bit ölçüm  yaklaşık 750ms civarı sürer. Bunun seri olarak gönderilmesi simülasyon koşulları vs ele alındığında bi iki sn sürebilir. Tabi bilgisayar hızınada bağlı. Bana kalırsa RF modül kullanmadan bi board üzerine kur data hatlarını birleştir öyle test et.

Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

erdemefe

Hocam cevabiniz icin tesekkur ederim mode gozumden kacmis 6 ile 9un yerini karistirmisim :) aslinda benimde aklima bu baud hizlari takiliyordu inceledigim tum programlarda baud hizi 2400 secilmis neden 9600 secilmiyor mesela bu baud nasil bir olcu birimidir? usartin avantaji ne olur ben ayni isi gorur diye 16f628e gore daha ucuz olan 12f675i secmistim

Mucit23

@erdemefe. Malesef benimde seri iletişim hakkında fazla deneyimim yok.
Usartın avantajı söyle olabilir. Sen veri gönderme ve alma kısmıyla uğraşmazsın. Alıcı kısımda TMR0 ile 74595 ler yerine multiplex display tarama yapabilirsin.
Benimde pek fazla bir bilgim yok açıkçası
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

greatgonzo

Dostum kodlarını incelemedim ama usart ile ilgili sana kabaca şöyle bir bilgi vereyim. Tamamen donanımsal bir aksesuar olduğundan dolayı usart kesmesini kullanma gibi bir avantajın olacak. Bunun anlamı preambl aldığında ve byte byte veriler geldiğinde herşeyi durdurup verileri sıhatli  olarak almaya başlayacak. Verileri sorunsuz alınca senin istedğin bir noktaya sıcrayacak ve bir sonraki veri alma ve kesme için hazır olacak. Bana göre kablosuz iletişimdeki en güvenilir yöntem.

Bir diğer avantajında sleep komutlarını kullanabilmen. Kodlarını incelemediğim için mantık yürütüyorum yanlışım varsa affola. Senin vericin belli periyodlarda ölçüm yapıp yolluyor. Alıcında belli periyodlarda tımer kesmesi olusturuyor ve lcd ye güncel veriyi yolluyor.
usart kesmesinde timer kesmesine ihtiyacın kalmayabilir. Zira verici modulde belli periyodlarda (-ki zaman guncellemede zaman kaybetmene rağmen sleep komutuyla işlemciyi uyutabilirsin vs vs ) guncel değeri yollarsın alıcıda aldığında usart kesmesi ile uyanır, güncel veriyi lcdye gonderir ve diğer veri gelene kadar uyku moduna geçer. Hem veride değişim olduğunda sadece pic in calışır hemde ciddi enerji tasarufu sağlarsın. Hatta vericidede (sanırım boyle birşey vardı araştırırsan iyi olur) ısı sensorunun değişikliklerine gore kesme uretip sadece gelen veri değiştiğinde pic i uyandırıp guncel veriyi yollarsın sonra tekrar uyutursun. Hem pic i gereksiz program yukunden kurtarırsın hemde daha az enerji harcayan bir devren olur.

İkinci paragrafta değişik bir noktaya değinmek isterim. Genel olarak lcd ye bir veri yazdırdığımızda okunaklı olması acısından bir pause komutu ve makul bir zaman değeri kullanırız. İsis simülasyonunda benzer bir kodda ben sleep kullandım ve en az pause komutu kadar dengeli çalıştığını gordum. Program lcdye güncel veriyi yolluyor ve uyku moduna geciyor. Baska bir veri gelmediği için lcd de hafızasındakı son veriyi kırpıştırma olmadan yazıyor. Multiplex tarama yapıyorsanda onuda kesmelerle aradan cıkaracaksın. Tabii iki kesmen olduğu için bu durumda biraz daha dikkatli olmalısın.

Kapsama alanı ile pratık olarak 2 cozum aklıma geliyor.
1) her pic te bir alıcı ve verici modul kullanacaksın ve bilgisayarlardakine benzer bi ping protoku yazacaksın. Böylece alıcı verici 2 yonlu haberlesecek. İletişim tamaman koptuysa bariz bicimde menzilden cıkmıs demektir. Bu yontem pahalı olacak çunku modul adedini iki ile çarpacaksın.
2) Alıcı modulde tımer kesmesi ile belli periyodlarda gelen veriyi kontrol edeceksin. Verici moduldede yine timer kesmesi ile veri değişikliği haricindede veri yollayacaksın. Önemli nokta alıcı modulde gelen veriyi her kullanımda/kontrolde sıfırlayacaksın. Sonrasında rutin kontrolunde eger  sıfır cıkarsa (ki vericiden veri geliyorsa oyle olmaması lazım)  anlakı kapsama alanından çıkmıstır.

Bana göre bu enstrumanlarda daha profosyonel bir sistem kurulabilir.

Önemli not 1: Daha evvelde yazdım. 16f628 "2 byte" veri almadan sleep durumundan cıkmaz. Diğer piclerdede klavuzlarını kontrol edilmesi gerekir. Modeline göre böyle garip huyları olabiliyor.

Önemli not 1:Özellikle extereme low power olmayan eski kuşak picler uyku modunda timer modullerini kapatırlar. Yani timer kesmesi için uyanmazlar cunku timer durur. Bu özellikte kılavuzdan kontrol edilmesi gerekir. Çoğunluklada sleep modundan cıkaran 3 timer sayacından sadece 1 tanesidir. Doğru picte doğru timer kullanılmalı.

est32

#5
Bu kadar büyütmeye gerek yok, devre yine 3 adet 595 ile çalışsın önemli değil, sadece tek yönlü iletişim biraz daha güvensiz oluyor.
DS18B20 normalde 750mS gibi bir sürede okunur zaten.
Alıcı kısmında ise hata etiketi olacak ve belli bir süre veri alınamadıysa hata etiketine gidilip ekrana gerekli bilgi verilecek. Daha önce denediğimde yaklaşık 1 dakika boyunca bilgi bekledim ve 1 dk içinde bilgi gelmeyince istediğim etikete atladım.

Kendi denememde dışarıya bir verici cihaz koydum, Bu cihaz her 5 dakikada bir dışarının ısısını HAM değer olarak birkaç kez yolluyor ve alıcı pic de her 5 dakikada alıcı cihazı devreye sokuyor(pil tasarrufu) ve bu şekilde 1 dakika boyunca bekliyor. Eğer veri gelmazse 6 dk beklemiş oluyor ve ölçüm alınamadığına dair ekrana bilgi veriyor. Eğer veri alınırsa ham değer alıcı kısmında hesaplanıp ekrana veriliyor ve alıcı pic rf alıcının beslemesini kesiyor.
Alıcı kısmın biraz erken uyanması gerek ben tolerans olarak 20-30sn bırakmıştım ve alıcı veriyi alınca, verici de veriyi gönderince her iki cihaz da kendisini kapatıyor böylelikle her iki cihaz da senkronize gibi çalışıyor. Eğer alıcı veriyi kaçırırsa o zmaan 1 dk fazladan beklemiş oluyor.

Alıcı veriyi kaçırsa, senkron bozulsa bile bir süre sonra mutlaka yine karşılaşıyorlar(biri 5dk diğeri 6dk), matematik problemlerindeki sorular gibi.
Alıcı kısma da bir önlem alınır ham değerin durumuna göre 99.9 ve -9.9 aşılınca hata bilgisi ekrana verilebilir.
proton açıklamalarını ekliyeyim;

For example, to receive a value through bit-0 of PortA at 9600 baud, 8N, inverted and abort
Serin after 2 seconds (2000 ms) if no data arrives: -

Serin PORTA.0, 16468, 2000, TimeoutError, [SerData]
Print Cls, Dec Result
Stop
TimeoutError:
Print Cls, "Timed Out"
Stop

If no serial data arrives within 2 seconds, Serin aborts and continues at the label to_ERROR

Powered by EzPortal