DC MOTORUN HIZINI HIZ SENSÖRÜ İLE ÖLÇME

Başlatan dgkn, 03 Şubat 2024, 02:59:05

dgkn

Merhabalar. dc motorun miline 20 delikli çark bağlayıp kızılötesi sensör kullanarak bu sayede motorun hızını ölçüp lcd ekrana yazdıracağım.
bir kod yazdım ve kod genel olarak bakıldığında doğru.
bu kodu hex olarak 16f877a mikrodenetleyicime atıyorum ve devremde çalıştırıyorum. sonuç olarak ilk satırda bulunan rpm değeri sabit ve 3 değerini gösteriyor (RPM=3) yani demek oluyor ki kodda hız=0 dediğimde bunu timer 1 ile iki kez 500ms lik sayma işleminin üzerine eklemiyor. yani hız değeri en başta 0 sonrasında ise timer1 ile ölçülen 1 saniyelik impuls sayısını hız değerine yazmıyor böylece hız değeri 0 olarak kalıyor ve 2 kez sayma döngüsü yaşanıyor sonrasında hız=hız+1 den hız değeri 1 oluyor ve rpm hesabında rpm=(1*60)/20 den rpm=3 oluyor.
eğer ki baştaki hız=0 değerini silip kodu yüklersem bu sefer ekranda rpm değeri sonsuza kadar saymaya başlıyor (motor dönmediği halde)

yanlışlarım beni daha da geliştirecektir. yardımlarınız için şimdiden teşekkürler.

#CONFIG
 __CONFIG _CP_ALL & _WRT_256 & _CPD_ON & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
#ENDCONFIG

DEFINE OSC 4

DEFINE ADC_BITS 10     ' ADCIN resolution  (Bits)
DEFINE ADC_CLOCK 1     ' ADC clock source  (Fosc/8)
DEFINE ADC_SAMPLEUS 20 ' ADC sampling time (uSec)

DEFINE LCD_DREG PORTD 'LCD data port 
DEFINE LCD_DBIT 4 'LCD data starting bit 0 or 4 
DEFINE LCD_RSREG PORTD 'LCD register select port 
DEFINE LCD_RSBIT 1 'LCD register select bit 
DEFINE LCD_EREG PORTD 'LCD enable port 
DEFINE LCD_EBIT 0 'LCD enable bit 
DEFINE LCD_RWREG PORTD 'LCD read/write port 
DEFINE LCD_RWBIT 2 'LCD read/write bit 
DEFINE LCD_BITS 4 'LCD bus size 4 or 8 
DEFINE LCD_LINES 2 'Number lines on LCD 

CMCON=7
ADCON0=%01000000
ADCON1=%10000000
TRISA=%11111111 
TRISB=%00000001 ' IR_SENSOR portunu input olarak ayarla
TRISC=%00000000
TRISD=%00000000
TRISE=%00000000

PORTA=0
PORTB=0
PORTC=0
PORTD=0
PORTE=0

HAM   VAR WORD 56
VOLT  VAR WORD 58
DUTY  VAR WORD 60
X     VAR WORD
ESKI  VAR WORD
YUZDE VAR BYTE
HIZ VAR WORD
RPM VAR WORD
KES VAR BYTE

SYMBOL IN1=PORTC.3
SYMBOL IN2=PORTC.4
SYMBOL IR_SENSOR=PORTB.0 ' Kızılötesi sensörün bağlı olduğu pin

portd.2=0
lcdout $fe,1
pause 200
lcdout $FE,$80,"LUTFEN  BEKLEYIN"
LCDOUT $FE,$C0,"SISTEM  ACILIYOR" 
PAUSE 2000
PR2=249
T2CON=%00000101 'İLK İKİ BİT %00=1/1  %01=1/4   %10=1/16
DUTY=0:GOSUB DUTY_VER
LCDOUT $FE,1
LCDOUT $FE,$C0,"SISTEM ACILDI"
pause 1000 


BASLA:
      
      GOSUB ADC_OKU            
      IN1=1:IN2=0
      IF ESKI=DUTY THEN BASLA
      GOSUB DUTY_VER:ESKI=DUTY
      LCDOUT $FE,$C0,"DUTY=",DEC DUTY,"  %=",DEC YUZDE,"  "
      GOSUB HIZ_OLC
      LCDOUT $FE,$80,"RPM=",DEC RPM
      GOTO BASLA


ADC_OKU:
        ADCIN 4,HAM
        DUTY=(HAM*/2503)/10
        VOLT=(HAM*/1252)/10
        YUZDE=DUTY/10
        RETURN      
DUTY_VER:
        IF CCP1CON=0 THEN CCP1CON=%00001100
        X=DUTY
        CCP1CON.4=X.0
        CCP1CON.5=X.1
        CCPR1L=(X>>2)
        RETURN

HIZ_OLC:    
        HIZ = 0
        T1CON = %00000001
        TMR1H = $0B
        TMR1L = $DC
        PIR1.0 = 0
        T1CON.0 = 1
        WHILE PIR1.0 = 0
        WEND
        PIR1.0 = 0
        T1CON.0 = 1
        WHILE PIR1.0 = 0
        WEND
        HIZ = HIZ + 1
        RPM = (HIZ * 60) / 20
        RETURN

alisumer

#1
kodu tamamen okumadım ama en sonunda hız=hız+1 :rpm=hız*60/20 sana zaten hızın 0 olması halinde 3 sonucunu vermesi normal ve hızın motor dönmüyorkende sürekli artması normal çünki hız=hız+1 demişsiniz. kodda hız ile ilgili tek işlem bu ne anlama geldiğini anlamadım.yapmak istediğiniz 1 saniye içinde ir sensörden okuduğun her puls için hız değişkenini 1 artırmak ve sonrasında 20 ye bölmek ise hız değişkenini gelen ir okuması ile arttırmadığını görüyorum .ayrıca adc ile ölçüm yapmışsın nerde kullanmışsın onu da anlamadım.bir saniyelik bir timer1 kesmesi kullanmanız kesmeye girdiğinizde ana programda her bir ir puls darbesinde artan hız değişkenini formulunuze koyup hesaplamanız ekrana yazdımanız sonra timer 1 i tekrar bir saniyeye kurup çıkmanız çalışan bir senaryo olabilir
Hep meraktan

alisumer

#2
sanırım kodlamaya yeni başlıyorsunuz.naçizane bir tavsiye olarak ilk önce yapmak istediğiniz cihazın çalışma şeklini girişlerini ve çıkışlarını en sade hali ile kafanızda bir senaryoya oturtmaya çalışın orada çalışmayacak senaryo gerçek hayatta da çalışmayacaktır(tabi bazen tersi de olur :))ama bana çok yardımı oluyor.tabi birde vazgeçmeyin
Hep meraktan

ete

HIZ_OLC:    
	        HIZ = 0
	        T1CON = %00000001
	        TMR1H = $0B
	        TMR1L = $DC
	        PIR1.0 = 0
	        T1CON.0 = 1  yukarıda zaten 1 yapmıştın ama bölme oranı 1/1 yapılmış. Bu şekilde süre kesme oluncaya kadar 500 ms olmuyor. 
	        WHILE PIR1.0 = 0
	        WEND
	        PIR1.0 = 0 
	        T1CON.0 = 1 sürekli bunu vermek de yanlış zaten 1 durumda
	        WHILE PIR1.0 = 0
	        WEND 
Buraya kadar kısmen doğru kabul edeceğimiz bu kodda eksik olan şey Hız pulsleri nasıl sayılacak. 
iki yolu var. Yak PORTB.0 kesmesini While-wend döngüsüne girmeden önce aktif edeceksin ve her gelen encoder palsi kesme oluşturacak ve sende kesme içinde Hız=Hız+1 komutunu vererek gelen pulsleri sayacaksın.
Yada While wend döngüsü içinde PORTB.0=1 olduğunda HIZ=HIZ+1 yapıp girişin tekrar LOW olmasını bekleyeceksin. Beklemezsen Hız=Hız+1 sayacı sürekli artar ve yanlış değer hesaplar. Aşağıda bu verdiğim örnekte bu seçeneği kullandım.

	        HIZ = HIZ + 1  'bu satırda yanlış yerde ve anlamsız bir konumda sadece bir kereliğine Hız değerini bir artırır biz ise böyle bir şey istemiyoruz. Yanlış komut satırı.
	        RPM = (HIZ * 60) / 20
	        RETURN

Bu kodlarıolması gerektiği gibi aşağıda düzelteceğim.

HIZ_OLC:    
         T1CON=%00110001 'bölme oranı 1/8 olması gerekiyor yoksa 500ms lik süre çalışmaz.
         KES=2:HIZ=0	 'kes değişkeni 2 defa aynı kodu çalıştırmak için kullnıldı
'         (değişken tanımlama kısmına KES VAR BYTE eklemesini yapman gerekiyor)       
	        
HIZ_BIR:
        TMR1H=$0B:TMR1L=$DC:PIR1.0=0 'tmr1 ön yükleme değerini verdik kesme bayrağını sıfırladık	        
'	    Hız artışları PORTB.0 yani INT kesmesi ile yapılmayacak ise aşağıdaki gibi olmalı  
        WHILE PIR1.0=0        'kesme bayrağı set edilinceye kadar (500ms süre ile)
        IF PORTB.0=1 THEN     'portb.0=1 ise yani puls gelmiş ise
          HIZ=HIZ+1           'Hız değerini 1 artır
          WHILE PORTB.0=1:WEND' Portb.0 girişinin yeniden LOW olmasını bekle
        ENDIF 
        WEND 'süre doluncaya kadar aynı şeyleri tekrarla
        KES=KES-1:IF KES=1 THEN HIZ_BIR 'ilk 500 ms lik süreden sonra ikincisini yapmak üzere HIZ_BIRe git
        T1CON=0  'timer çalışmasını durdur süre doldu artık
        HIZ=HIZ-(HIZ DIG 0)'sayması gerekende bir fazla sayıyor birler hanesini sıfırla
        RPM=HIZ*3         'hız*60/20 işelmini uyguladık                  '
        RETURN	
Yanlarına açıklamaları yazdım.
Basla satırından sonra GOSUB HIZ_OLC satırı altındaki LCD ye yazdırma satınıda aşağıdaki ile değiştir.

LCDOUT $FE,$80,"HIZ =",DEC HIZ," rpm  "

Görülüeceği üzere yapman gereken KES isimli bir Byte değişkeni tanımlayıp verdiğim kodlarla seninkileri yer değiştireceksin.

Ete

Powered by EzPortal