fan devir sayıcı

Başlatan AVARE, 20 Mayıs 2016, 16:10:55

AVARE

herkese kolay gelsin.
pic e yeni başladım ve pc için basit bi fan devir göstergesi yapmak istiyorum nette örneklere bakarak bişey yapmaya çalıştım ama fan tam devirdeyken atıyorum 1500  gösteriyor yavaşlatıyorum 2000 devir gösteriyor devreyi hall sensörle yapıyorum bana hızlanınca atlama yapıyor gibi geldi ama acaba kodda bi sıkıntımı var bakabilirmisiniz?
@ __config _XT_OSC & _WDT_ON & _PWRTE_ON & _LVP_OFF & _CP_OFF & _MCLRE_ON
define OSC 4

  ON INTERRUPT GoTo KESME   'kesme oluşursa KESME adlı etikete git.

OPTION_REG=%10000101    'Pull up dirençleri İPTAL- Bölme oranı 1/64.
INTCON=%10100000         'Kesmeler aktif ve TMR0 kesmesi aktif
TMR0=0



     
DEFINE LCD_DREG PORTB 'LCD data bacakları PortB de bağlı
DEFINE LCD_DBIT 4 'LCD data bacakları 4. bitten başlıyor
DEFINE LCD_EREG PORTB 'LCD Enable Bacağı PortB de bağlı
DEFINE LCD_EBIT 3 'LCD Enable Bacağı 3. bite bağlı
DEFINE LCD_RWREG PORTB 'LCD RW Bacağı PortB de bağlı
DEFINE LCD_RWBIT 2 'LCD RW Bacağı 2. bite bağlı
DEFINE LCD_RSREG PORTB 'LCD RS Bacağı PortB de bağlı
DEFINE LCD_RSBIT 1 'LCD RS bacağı 1. Bite bağlı
DEFINE LCD_BITS 4 'LCD 4 bit olarak bağlı
DEFINE LCD_LINES 2 'LCD 2 sıra olarak çalışıyor.

CMCON=7
TRISA=255
TRISB=0
PORTA=0
PORTB=0

Devir var word
Devir2 var word
Sure var word
RPM var word
FAN var bit


devir = 0
Devir2 = 0
sure = 0
RPM = 0
FAN = 0

LCDOUT $FE,1,"  DEVIR SAYICI  "

  pause 1200
LCDOUT $FE,1," BASLAT BUTONUNA"
LCDOUT $FE,$C0,"      BASIN"

start:
PAUSE 50
if porta.1 = 0 then
FAN=1
devir=0
devir2=0
rpm=0
sure=0

if FAN=1 then portb.0 = 1

  goto basla
endif



GOTO START

basla:
if porta.2 = 0 then
FAN=0
if FAN=0 then portb.0 = 0
LCDOUT $FE,1,"DEVIR = ",#devir
LCDOUT $FE,$C0,"RPM = ",#RPM," DURDU"
goto start
endif

LCDOUT $FE,1,"DEVIR = ",#devir
LCDOUT $FE,$C0,"RPM = ",#RPM
pause 50

if porta.0 = 0 then
goto biraktimi
birakti:

devir = devir+1

devir2 = devir2+1
endif


goto basla

biraktimi:
if porta.0 = 1 then
goto birakti
else
goto biraktimi
endif

              DISABLE
KESME:
       sure=sure+1     'kesme sayacı  1 sn= 61(sayac) x 256 (Tmr0) x 64 (bölme)
      if sure=61 then      '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
          sure=0      'sayaç sıfırlanıyor
             
           rpm=devir2*60
      devir2=0
               
                         endif
       

       
     
    INTCON.2=0        'TMR0 Kesme bayrağı sıfırlanıyor
RESUME
ENABLE

end 

BGAA

Kardesim uzerinde bende calısıyorum proteusta calıstırdım
yardımım dokunursa ne mutlu


not:proteus 8 de cizdim devreyi altta link vericem hem proteus hemde proje

ete

Kodda çok fazla sıkıntı yok. Olanları aşağıda açıklayacağım.
Sensör sisteine iyi bakman gerek. Çok stabil çalışmadığı kesin bence.
Aşağıdaki kodda yer alan;
if FAN=1 then portb.0 = 1 ifadesi orada lüzumsuz. Zira aynı şart komutunun içinde FAN=1 diye değeri 1 yapıyorsun zaten.
Bu durumda oraya direk PORTB.0=1 yazman gerekir. If'e gerek yok çünki hiç bir zaman orada FAN=0 olmayacaktır.
if porta.1 = 0 then 
    FAN=1
    devir=0
    devir2=0
    rpm=0
    sure=0
    if FAN=1 then portb.0 = 1
    goto basla
endif


Devir sayacı PORTA.0 pininin HIGH olması durumunda sayıyor. Bu sanırım sensörün konum değiştirmesi olarak açıklanabilir. Aynı geçiş için birden fazla saymasın diye olmalı. Bu durumda aşağıdaki kodu düzenlemek lazım;
if porta.0 = 0 then
goto biraktimi
birakti:

devir = devir+1

devir2 = devir2+1
endif
goto basla

biraktimi:
if porta.0 = 1 then
goto birakti
else
goto biraktimi
endif

Bu satırları silip yerine şunu yazabilirsin.
 if porta.0 = 0 then
    while porta.0=0:wend
    devir = devir+1
    devir2 = devir2+1
endif

goto basla


Ancak gerek senin yazdığın gerekse benim kısalttığım kodun da bir dezavantajı var. Her ikiside sayma için sensörün HIGH olmasını bekliyor.
Ancak High olduktan sonra low olmasını beklemiyor.
Bu nedenle kodu şöyle düzenlemek belkide daha doğru. Zira sensör HIGH olunca sayacak sonra tekrar başa gidecek ama hala high ise yeniden sayma yapabilecektir. Buda zaman zaman yüksek sayac değeri çıkmasının açıklaması olabilir.

While PORTA.0=0:WEND 'önce sensörün HIGH olmasını bekleyelim
    devir = devir+1
    devir2 = devir2+1  'sayacları saydıralım
WHILE PORTA.0=1:WEND 'sonra tekrar LOW olmasını bekleyelim
Goto basla 'diyerek bir sonraki sayma işlemine geçelim.
Bu şekilde if lere gerek olamadan sistem sensörün her high olması konumunda yalnızca bir kere sayarak işini yapmış olur.

Ete

AVARE

cevabınız için teşekkür ederim
dediğiniz gibi while  wend komutlarını kullandım sanırım 0 olduğu sürece işlem yapıyor 1 ise 0 ı bekliyor. bu şekilde benim yaptığından daha dengeli sayıyor devir değişiminde eskiden neredeyse her yavaşlatmada değerler saçmalıyodu şimdi daha dengeli ama  max 1500 devir okumuşken yavaşlatınca hala 2000 gösterdiği oluyo. hall sensörü out bacağını pulup yapıp direk birde opamp üzerinden çıkış alıp bağladım aynı devreyi yazıcının optik  spot sensörüylede (beyaz bant ile) denedim yine aynı aslında devreden beklediğim hassasiyet değil  tutarlı değerler okuması birde  yavaşlattığımda okunan yüksek değer olması gereken gibi geliyor sanki hızlandığında ya sensör yavaş yada pic yanılıyormuyum?

Powered by EzPortal