Sayıcı devresi hatası

Başlatan HASAN48, 27 Aralık 2013, 10:46:05

HASAN48

Sayın ete hocam foruma daha yeni katıldım ve daha önce sizin hazırlamış olduğunuz pic derslerini indirdim ve çalıştım şu anda kandi çapımda küçük beni zorlamayacak programları yazabiliyorum fakat bi programda takılı kaldım yardımınızı istiyorum.
Program 0-999 sayıcı pic16f84 ile tasarladım fakat bu devreye ben lazerle fotodiyot koyup gelip geçenleri saymak istiyorum.Takıldığım nokta bikişi gelip lazerin önünde beklerse saymaması gerekiyo bunun için yardımcı olabilirmisiniz.

program kodları şu şekilde:

'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [DESİGNED BY HHK]                                 *
'*  Notice  : Copyright (c) 2013 [DESİGNED BY H.H.KIRCAĞIZ]     *
'*          : All Rights Reserved                               *
'*  Date    : 29.11.2013                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
DEFINE LCD_DREG PORTA 'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT 0 'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_RSREG PORTA 'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT 4 'LCD RS bacağı Hangi Bite bağlı ?
DEFINE LCD_EREG PORTB 'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT 0 '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

TRISA=0
TRISB=%11000010                               
SAYI  VAR WORD
SAYI1 VAR WORD
SAYI2 VAR WORD
SAYI3 VAR WORD
SAYI4 VAR WORD
SAYI=0
SAYI1=0
SAYI2=0
SAYI3=0
SAYI4=0
SYMBOL RESET=PORTB.6
SYMBOL LED1=PORTB.1
ANA:
    IF RESET=0 THEN   'RESET BUTONUNA 1 SANİYEDEN FAZLA BASılırsa SAYACI SIFIRLA
    PAUSE 1000
    SAYI4=0
    ENDIF
    LCDOUT $FE,$80,"BAGAJ SAYISI:",DEC3 SAYI4
    LCDOUT $FE,$C0,"BJV ATOLYE byHHK"
    PAUSE 200
    IF PORTB.7=1 THEN GOTO ANA
    SAYI4=SAYI4+1
    IF SAYI4>=1000 THEN   
    SAYI4=0
    SAYI3=SAYI3+1
    IF SAYI3>=1000 THEN
    SAYI3=0 
    SAYI2=SAYI2+1
    IF SAYI2>=1000 THEN
    SAYI2=0
    SAYI1=SAYI1+1
    IF SAYI1>=1000 THEN
    SAYI1=0
    SAYI=SAYI+1
    IF SAYI>=10 THEN
    SAYI=0
    IF PORTB.7=0 THEN
    LOW LED1
    ELSE
    HIGH LED1
    ENDIF
    ENDIF
    ENDIF 
    ENDIF     
    ENDIF
    ENDIF
    GOTO ANA
    END

şimdiden teşekkür ederim.

ete

Alt kısımda GOTO ANA satırından evvel şu satırları ilave et.
WHILE PORTB.7=0: WEND
PAUSE 50

Böylece sensör önüne birisi gelince bir kere sayacak kişi oradan çekilinceye kadar sayma yapmayacaktır.

Ete

İlyas KAYA

IF RESET=0 THEN   'RESET BUTONUNA 1 SANİYEDEN FAZLA BASılırsa SAYACI SIFIRLA
    PAUSE 1000
    SAYI4=0
    ENDIF

Bu satırda 1sn boyunca basılı tutmak değil her 1 sn 'de resetleme yapmaktır. Siz butona bastığınız andan 1 sn sonra sayı4'ü sıfır yapar.

Her 1sn sonra tekrar reset'in durumunu kontrol ederseniz o zaman olur.

IF RESET=0 THEN   'RESET BUTONUNA 1 SANİYEDEN FAZLA Basılırsa SAYACI SIFIRLA
    PAUSE 1000
IF RESET=0 THEN  SAYI4=0
    ENDIF


Olarak düzeltirseniz olacaktır.
Başka bir konu ise
'#######################
SAYI4=SAYI4+1
    IF SAYI4>=1000 THEN   
    SAYI4=0
    SAYI3=SAYI3+1
    IF SAYI3>=1000 THEN
    SAYI3=0 
    SAYI2=SAYI2+1
    IF SAYI2>=1000 THEN
    SAYI2=0
    SAYI1=SAYI1+1
    IF SAYI1>=1000 THEN
    SAYI1=0
    SAYI=SAYI+1
    IF SAYI>=10 THEN
    SAYI=0
    IF PORTB.7=0 THEN
    LOW LED1
    ELSE
    HIGH LED1
    ENDIF
    ENDIF
    ENDIF 
    ENDIF     
    ENDIF
    ENDIF
'###############################

Buraya kadar olan komutlar ne işe yarıyor ? Amaç nedir ?
Göz odur ki dağ ardını görsün,
Akıl odur ki başa geleceği bilsin.!

HASAN48

öncelikle heriki ustayada teşekkür ederim.Alttaki satırlar sayıcıyı 9999 ve daha ilerisine sayması için eklemiştim.Ama sonra değiştirdim 0-999 yaptım ve onları ellemedim onlarıda değiştireceğim.

İlyas KAYA

Gerek yok ki zaten word değişkeni 65535'e kadar çıkabilir ve siz bunu lcd ekranda gösterebilirsiniz.
sayı var word

SAYI=SAYI+1

lcdout $fe,1,#SAYI       

Bu şekilde zaten 0-65535'e kadar ekranda görünecek ve sayacaktır.

Sınırlamak isterseniz IF sayı>=999 then sayı=999 yapmanız yeterli.

onlar, birler ,yüzler basamaklarını sizin ayrı ayrı yapmanıza yapmanıza gerek yoktur.
Bu display dahi kullansanız yine yapmanıza gerek yoktur.

Mesela;


SAYI=SAYI+1

birler=SAYI DIG 0
onlar=SAYI DIG 1
yüzler=SAYI DIG 2

gibi...
Göz odur ki dağ ardını görsün,
Akıl odur ki başa geleceği bilsin.!

HASAN48

#5
Ete hocam ve ilyas hocam programı yaptığınız öneriler doğrultusunda değiştirdim.Programın son hali aşağıdaki şekildedir.Şimdi ben bu PORTB.7 ye fototransistör bağlayıp 1mt mesafeden lazer tutacağım.Bunun için programın içine herhangi bir kod eklememiz gerekecekmi.

program:

DEFINE LCD_DREG PORTA 'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT 0 'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_RSREG PORTA 'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT 4 'LCD RS bacağı Hangi Bite bağlı ?
DEFINE LCD_EREG PORTB 'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT 0 '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

TRISA=0
TRISB=%11000000                               
SAYI  VAR WORD
SAYI4 VAR WORD
SAYI=0
SAYI4=0
SYMBOL RESET=PORTB.6
SYMBOL LED1=PORTB.1
SYMBOL LED2=PORTB.2
ANA:
    IF RESET=0 THEN   'RESET BUTONUNA 1 SANİYEDEN FAZLA Basılırsa SAYACI SIFIRLA
    PAUSE 1000
    IF RESET=0 THEN  SAYI4=0
    ENDIF
    IF RESET=0 THEN
    HIGH LED2
    PAUSE 1000
    LOW LED2
    ENDIF
    LCDOUT $FE,$80,"TOPLAM BAGAJ:",DEC3 SAYI4
    LCDOUT $FE,$C0,"BJV ATOLYE byHHK"
    PAUSE 200
    IF PORTB.7=1 THEN GOTO ANA
    SAYI4=SAYI4+1
    HIGH LED2
    IF SAYI4>=1000 THEN   
    SAYI4=0
    IF PORTB.7=0 THEN
    HIGH LED1
    ELSE
    LOW LED1
    ENDIF
    ENDIF 
    WHILE PORTB.7=0: WEND
    PAUSE 50
    GOTO ANA
    END





ete


Bana kalırsa sen önce lazer+Fototransistör sistmeni kur bir yere ve çalıştır. Daha sonra sistemin ne çıkış veriyor ise onun tersi lojik seviyesinde portu bekletmeliyiz. Daha açık söylemek gerekirse önce sistemi izah edelim.
Bir Foto transistör olacak karşısında ise lazer ışığı olacak. Işık var olduğu sürece foto transistör iletimde olacak. İletimde derken ne çıkacak bilemiyorum şu anda. Ama muhtemelen LOW çıkacaktır. Işık bir kişi tarafından engellenir ise Foto Transistör kesime gidecek ve çıkışdan bir şey çıkmayacaktır. Bu seferde pullxxx direnci devreye girerek B.7 pinini kendi seviyesine çekecek. Şimdi ortada somut bir şema olmadığı için örneği bir adım öteye götürelim.
Foto transistörün Lazer görünce LOW veriyor olsun (yanlış hatırlamıyorsam sistem gerçekten NPN transistör gibi davranıyor idi). Bu durumda PORTB.7 ye Pullup direnci bağlamak veya dahili pullup ları aktive etmek gerekir.
Bu durumda foto transistör lazer'ışığını görürse Collectörden LOW çıkartacak ve PortB.7 LOW olacaktır.
O halde Sistem insan görmez ise PORTB.7=LOW oluyor demektir.
Araya bir engel girince lazer kesilecek ve fototransistör kesime gidecektir. Bu durumda Pullup direnci PortB.7'i HIGH yapacaktır. Bu durumda;
Sistem engel görürse PORTB.7=HIGH olacak demektir.

O halde programında yer alan,
WHILE PORTB.7=0: WEND
komutu amaca uygun çalışıyor demektir. Zira foto transistör insan görmedikçe LOW çıkış verecek ve program saymak için orada bekleyecektir. Araya engel girince çıkış HIGH olacak  ve program bu satırı atlayıp saydırma yapacak. Ancak belki bir şey daha eklemek gerekir çünki adam biraz yavaş geçerse geçerken iki defa sayabilir. Bu nedenle
WHILE PORTB.7=0: WEND
satırının altına şunuda ekle
WHILE PORTB.7=1:WEND
Böylece birinci satır adam gelinceye kadar programı bekletir. İkincisi ise adam sensörün önünden çekilinceye kadar bekletir. Sonrasında sistem bir sayar.

Ete


HASAN48

Allah razı olsun hocam mükemmel şekilde aydınlattınız beni dediğiniz gibi önce lazerle fototransistör devresini kurayım deneyeyim ve ona göre programda değişikliğe gidelim.

HASAN48

Syn.ETE hocam buralartda malzeme sıkıntısı olduğu için fototransistör bulamadım adamlar fototransistör yerine fotodiyot göndermişler oyüzden devreyi fotodiyot ile kuracağım.Sizinde dediği gibi fotodiyotu kurdum ve lazer tutulu iken 5v çıkış veriyo lazer kesildiğinde 0,5v civarı veriyor.Ozaman dediğiniz gibi adam yavaş geçip beklediğini düşündüğümüzde daha önceki mesajda yazdığınız gibi WHILE PORTB.7=1:WEND  satırınıda ekleyecekmiyiz.ve portb.7 ye pullup direnci bağlamamıza gerek kalmayacak diye düşünüyorum.


medes

HASAN48 malesef  WHILE PORTB.7=0: WEND komutunu koymak mecburiyeti var aksi halde önünde engel olduğundan dolayı
saymaya devam edecektir kanaatindeyim

ete

Lazer var iken çıkış HIGH ve yok iken (yani önünde engel var iken) çıkış LOW ise
WHILE PORTB.7=0:WEND  şeklinde komut koyman lazım. Bu komut engel geçinceye kadar programı orada bekletecektir.
Bununda başka mahsurları var. Birisi lazer önüne geçti sayıcı sayacak . WHILE PORTB.7=0:WEND Komutu engelin geçmesini beklerken ikinci kişi lazerin görüş alanına girerse sistem bu ikinici kişiyi görmeyecek ve bir kişi olarak sayacaktır.
Bunları en baştan düşünmek gerekir. Nasıl çözmek lazım bilemiyorum. Çünki mekanı tanımıyorum. Kişileri tek sıra geçiş yapmaya zorlayarak bu sorun çözülebilir belkide.

Pullup direnci meselesine devreye göre karar vermek lazım. Pullup yada pulldown her neyse takmadan sistem lazer varken HIGH yok iken LOW verebiliyor ise elbette bir direnç takmaya gerek olmaz.

Ete

HASAN48

Hocam ben size en başında anlatmam gerekliydi devreyi.Devreyi ben konveyör sistemi üzerinde kullanacağım bant üzerinden geçen bagajları sayacak bizde bagajları sıra sıra aralıklı atma şartı var.Devreyi bu koşulları gözönüne alıp yorumlarsanız çok çok sevinirim şimdiden çok teşekkür derim.

ete

Başka yoruma gerek yok.
While PORTB.7=0:WEND  komutunu (lazer engeli gördükten sonra ki satıra koyulacak) koyduktan sonra sistem çalışır.

Bu durumda bagajlar sıra sıra geleceklerse mutlaka aralarında bir kaç cm boşluk olmalı aksi halde bitişik iki bagajı 1 bagaj sayar bu sistem.

Ete

HASAN48

#13
Allah Razı olsun hocam sayenizde projede kullandığımız komutları daha iyi anladım.
O zaman programın son şekli budur.
@ DEVICE pic16F84A                      'işlemci 16F84                                
@ DEVICE pic16F84A, WDT_on              'Watch Dog timer açık
@ DEVICE pic16F84A, PWRT_ON             'Power on timer açık
@ DEVICE pic16F84A, PROTECT_OFF         'Kod Koruma kapalı

DEFINE OSC 4
OPTION_REG.7=0

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

TRISA=0
TRISB=%11000000
                             
SAYI  VAR WORD
SAYI=0
SAYI4=0

SYMBOL RESET=PORTB.6
SYMBOL LED1=PORTB.1
SYMBOL LED2=PORTB.2

PAUSE 300 '*****************************************
BASLA:
    IF RESET=0 THEN 
      SAYI4=0
      LED2=1
      PAUSE 300
      LED2=0
      PAUSE 300     
    ENDIF
   
    LCDOUT $FE,$80,"TOPLAM BAGAJ:",DEC3 SAYI4
    LCDOUT $FE,$C0,"BJV ATOLYE byHHK"
'    PAUSE 200
    WHILE PORTB.7=1
      IF RESET=0 THEN BASLA
    WEND
    HIGH LED1
    SAYI4=SAYI4+1
   
    IF SAYI4>=1000 THEN   
      SAYI4=0
      HIGH LED2
      PASUE 500
      LOW LED2
    ENDIF
   
    WHILE PORTB.7=0: WEND
    LOW LED1
   
    GOTO BASLA
    END


Edit-Ete:  Kod butonunu kullanman daha doğru olur. Ayrıca yazdıklarını olması gereken şekilde yeniden düzelttim.
Bu şekli daha doğru bence

HASAN48

Hocam çok sağolun teşekkür ederim.Çalışmalarıma devam edeceğim.

Powered by EzPortal