pwm dc motor hız kontrolü devresi çalışmıyor

Başlatan dgkn, 30 Ocak 2024, 18:04:18

dgkn

sayın ete verdiğiniz bu koda kızılötesi hız sensörü bağlamak istiyorum ve sizin kodunuzun üzerine yardımlarla birlikte bu güncellemeleri yaptım. sizin bu konuda ne kadar profesyonel olduğunuzu bildiğim için size kodu göstermek istiyorum. yaptığım yanlışlar ve eksikleri bana söyler misiniz?
@ete

#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 PORTB 'LCD data port 
DEFINE LCD_DBIT 4 'LCD data starting bit 0 or 4 
DEFINE LCD_RSREG PORTB 'LCD register select port 
DEFINE LCD_RSBIT 1 'LCD register select bit 
DEFINE LCD_EREG PORTB 'LCD enable port 
DEFINE LCD_EBIT 0 'LCD enable bit 
DEFINE LCD_RWREG PORTB '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 
'DEFINE LCD_COMMANDUS 2000 'Command delay time in us 
'DEFINE LCD_DATAUS 50 'Data delay time in us  

CMCON=7
ADCON0=%01000000
ADCON1=%10000000
TRISA=%11111111 
TRISB=%00000000
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 ' Motor hızı için değişken

SYMBOL IN1=PORTC.3
SYMBOL IN2=PORTC.4
SYMBOL SENSOR_PIN = PORTC.0 ' Kızılötesi sensörün çıkış pini
SYMBOL POT = 4 ' Potansiyometre bağlantısı (Analog giriş RA4)

portb.2=0
lcdout $fe,1
pause 200
lcdout $FE,$80,"LUTFEN  BEKLEYIN"
LCDOUT $FE,$C0,"SISTEM  ACILIYOR" 
PAUSE 500
 
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" 

' Kesme (Interrupt) Rutini Tanımı
INCLUDE "modedefs.bas"
INCLUDE "intdefs.bas"

' Kesme Rutini Tanımları
ASM
INT_LIST  macro         ; IntSource,         Label,  Type, ResetFlag?
        INT_Handler    RB_INT,    _RB_INT,   PBP,   yes
    endm
    INT_CREATE
ENDASM

ENABLE RB_INT ; Kesme (Interrupt) Aktif Edilir

BASLA:
    GOTO BASLA ' Ana döngüye geri dön

' Kesme (Interrupt) Rutini
RB_INT:
    ' Kızılötesi hız sensöründen okuma
    HIZ = HIZ + 1 ' Sensör her algılandığında hızı bir arttır
    INTCON.0 = 0 ' Kesmeyi temizle
RETURN

DUTY_VER:
    IF CCP1CON=0 THEN CCP1CON=%00001100
    X=DUTY
    CCP1CON.4=X.0
    CCP1CON.5=X.1
    CCPR1L=(X>>2)
RETURN

dgkn

evet öyle. kusuruma bakmayın benim yanlış söylediğim fakat bir türlü düzeltemediğim bir konu. alışkanlık haline getirdim bu yanlışı. arkadaşlarımla aramızda geçen bir muhabbet sonucu ağzıma yanlış yer etmiş bir durum.

ete

İnfrared sensör ile ilgili yazılanlara baktım. Bana göre pek çok yanlış şey var.

Birincisi normal kesme yerine DarrelTaylor'un ASM kesmeleri sistemini kullanmışsın.
Kesme PORTB de INT kesmesi yani PORTB.0 dan sensörün giriş yapması gerekir.
Buradan sensör girince o pinin Giriş olarak ayarlanmasıda gerekecektir.
Bu konuda hiç bir hazırlık göremedim.
Önceki şemadaa PORTB.0 pini LCD tarafından kullanılıyor idi ve halada kullanılmaya devam ediyor.
Bu durumda bu kesmeyi kullanamazsın. Ya PORTB.0 daki işlevi boşta olan başka bir pine vereceksin yada başka bir çare düşüneceksin.
Muhtemel çareleri açıklamadan önce bir noktaya parmak basmak isterim.
Pic İşlemcilerde PORTB çok özel bir port dur. Bu port genelde hariçten gelen bağlantılar için ayrılmıştır. İçeriden Pullup dirençleri vardır yazılımla aktif pasif yapılabilirler. Bu nedenle bu özel portu LCD gibi lüzumsuz bir işe kullanmakla yazık etmiş oluyorsun. Bu hatayı nedense pek çok kişi yapıyor.
Gelelim muhtemel alternatiflere
1) LCD yi başka bir porta geçirirsen PORTB.0 da boşa çıkar ve sende bu pini INT kesmesi için kullanabilirsin.
2. Benzer şekilde PORTB nin diğer bir özelliğide PORT değişiklik kesmesine müsaade etmesidir. Bu işlemcide PORTB.4 ile PortB.7 pinleri port daki değişiklik kesmesi için kullanılabilmektedir. Bu pinlerden birisini kullanarak yine sensör sayımı yaptırabilirsin.
3. Yada Timer-1 sayacını kullanarak belirli bir süre içinde kaç tane sensör palsi sayıldığına bakabilirsin.

Asıl önemli olan bir şeyide atlamışsın. Hız nasıl ölçülür? bunu bildiğini sanmıyorum. Özellikle Kızılötesi sensör kullanarak bu nasıl yapılacak acaba?.
Kızılötesi sensör dediğin sadece bir ışık sensörü ve kızıl ötesi yani infrared ışığı algılıyor.
O halde motor miline en azından bir çark bağlaman ve o çarkın üzerinde tam kızılötesi sensörün ışık veren tarafına denk gelecek bir delik olması gerekir. Böylece çark döndüğü zaman delik sensör önüne geldiğinde senin kesmen oluşur ve hız=hız+1 olur.
Peki sürekli hız kesmelerini toplamak bir işe yarayacakmı? elbette yaramayacak. Bu hız bilgisi değildir. Çarkında tek delik var ise senin sistemin tur başına 1 kesme oluşturur. Bu durumda en azından 1 sn lik bir zaman tutup o esnada hız sayacının kaç adet saydığına bakman işini böyük ölçüde halledecektir. Döner cisimlerin hızı devir/dakika ile ölçülür.
O halde aldığın Hız ölçüsünü 1 sn den 1dakikaya çevirmen gerekecektir. Saydığın değeri 60 ile çarparsan sana 1 dakikadaki devir sayısını verecektir. Böylece motorun hızını ölçmüş olursun.

Bu kadar teorik bilginin ardından artık seninde bir şeyleri anlayıp yapmanı beklemek gerekecek.
Devir hızı ölçecek isen ne yapacağını söyleyeyim.

Öncelikle yukarıda açıkladığım hataları düzelt eksiklikleri tamamla.
Sonra 1 sn lik bir zaman tutabilmenin yolunu araştır.
Zira Basic kullanacak isen Pause 1000 sana 1 sn lik gecikmeyi verir ama bu esnada hiçbir kesme çalışmaz. Yalnız Darrel'in kesme rutini belki çalışabilir emin değilim. Denemek lazım.
Bu nedenle zamanı Timer-1 sayacı ile tutmakta yarar var.
Oda nasıl yapılır anlatayım.
4 Mhz OSC frekansında Timer1 sayacı bileşenleri olan TMR1H ve TMR1L değişkenlerine aşağıdaki ön yükleme değerlerini verirsen;
TMR1H=$0B ve TMR1L=$DC  sayac bu değer (3036) den başlayarak sayar ve sayac değeri 65535 i aştığı anda PIR1.0 register bitini set eder. Buda sana 500ms lik bir süre verir.
O halde bu sayma işlemini 2 defa yaparsan 1 sn lik süreyi geçirmiş olursun.
Önce PIR1.0=0 şeklinde kesme bayrağını sıfırlarsın. Ardından saydırmaya başlarsın
While PIR1.0=0:Wend
burda aynı işlemi bir kez daha yaptırırsın böylece 1 sn geçmiş olur.
Yada sistemi 500 ms içinde sayacak şekilde çalıştırır ve saydığın rakamı 2 ile çarparsın buda bir yoldur.
Bir karşık anlatım gibi oldu ama bana göre her şey açık. Anlamadığın yeri sorarsın.

Ete

dgkn

Sayın ete anlattıklarınız doğrultusunda bir şeyler yapmaya çalıştım. emin olmamakla beraber galiba oldu. sizin yorumlarınız benim için çok değerli. eğer başarabilmişsem bir yanlışım yok ise pid kontrol için olan kısma geçmek istiyorum. (motora yük bindiğinde duty değerini arttırarak pot ile girilen hıza tekrar sabitlenmesi.) (kodda motor miline bağlı olan çarkta toplam 20 delik var.) (rpm kısmı HIZ*3 mü yoksa HIZ/3 mü olacak emin değlim şuan)
@ete

#CONFIG
 __CONFIG _CP_ALL & _WRT_256 & _CPD_ON & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
#ENDCONFIG
 
' Kristal osilatör frekansı
DEFINE OSC 4
 
' ADC özellikleri
DEFINE ADC_BITS 10     ' ADCIN çözünürlüğü (bit)
DEFINE ADC_CLOCK 1     ' ADC saat kaynağı (Fosc/8)
DEFINE ADC_SAMPLEUS 20 ' ADC örnekleme zamanı (μs)
 
' LCD bağlantıları
DEFINE LCD_DREG PORTD ' LCD veri portu
DEFINE LCD_DBIT 4      ' LCD veri başlangıç biti 0 veya 4
DEFINE LCD_RSREG PORTD ' LCD kayıt seçim portu
DEFINE LCD_RSBIT 1     ' LCD kayıt seçim biti
DEFINE LCD_EREG PORTD  ' LCD etkinleştirme portu
DEFINE LCD_EBIT 0      ' LCD etkinleştirme biti
DEFINE LCD_RWREG PORTD ' LCD oku/yaz portu
DEFINE LCD_RWBIT 2     ' LCD oku/yaz biti
DEFINE LCD_BITS 4      ' LCD veri yolu boyutu 4 veya 8
DEFINE LCD_LINES 2     ' LCD üzerindeki satır sayısı
'DEFINE LCD_COMMANDUS 2000 ' Komut gecikme süresi (μs)
'DEFINE LCD_DATAUS 50     ' Veri gecikme süresi (μs)

' Analog-Dijital Dönüşüm için giriş/çıkış tanımlamaları
CMCON = 7
ADCON0 = %01000000
ADCON1 = %10000000
TRISA = %11111111 
TRISB = %00000001 ' sensör pini giriş olarak ayarla 
TRISC = %00000000
TRISD = 0          ' D portunu tamamen çıkış olarak ayarla
TRISE = %00000000
 
' Portları sıfırla
PORTA = 0
PORTB = 0
PORTC = 0
PORTD = 0
PORTE = 0
 
' Değişken tanımlamaları
HAM   VAR WORD 56
VOLT  VAR WORD 58
DUTY  VAR WORD 60
X     VAR WORD
ESKI  VAR WORD
YUZDE VAR BYTE
HIZ   VAR WORD ' Motor hızı için değişken
RPM   VAR WORD ' RPM değeri için değişken

' Simge tanımlamaları
SYMBOL IN1 = PORTC.3
SYMBOL IN2 = PORTC.4
SYMBOL SENSOR_PIN = PORTB.0 ' Kızılötesi sensörün çıkış pini
SYMBOL POT = 4               ' Potansiyometre bağlantısı (Analog giriş RA4)

' Başlangıç mesajlarını göster
LCDOUT $FE,1
LCDOUT $FE,$80,"LUTFEN  BEKLEYIN"
LCDOUT $FE,$C0,"SISTEM  ACILIYOR" 
PAUSE 500

' PWM ayarları
PR2 = 249
T2CON = %00000101 ' İLK İKİ BİT %00=1/1  %01=1/4   %10=1/16
DUTY = 0
GOSUB DUTY_VER ' PWM Duty Cycle Ayarlama Rutini

' Sistem açıldı mesajını göster
LCDOUT $FE,1
LCDOUT $FE,$C0,"SISTEM ACILDI"

' Ana döngü
BASLA:
    ' ADC okuma
    GOSUB ADC_OKU
    
    ' IN1 ve IN2 sinyallerini ayarla
    IN1 = 1
    IN2 = 0
    
    ' Eğer eski değer duty değeriyle aynıysa, döngüyü tekrarla
    IF ESKI = DUTY THEN BASLA
    
    ' Duty Cycle'ı ayarla ve eski değeri güncelle
    GOSUB DUTY_VER
    ESKI = DUTY
    
    ' LCD'ye gerilim, duty cycle ve RPM değerlerini yazdır
    LCDOUT $FE,$80,"DUTY=",DEC(DUTY),"  %=",DEC YUZDE,"  "
    LCDOUT $FE,$C0,"RPM=",DEC RPM
    
    ' Ana döngüye geri dön
    GOTO BASLA

' ADC okuma rutini
ADC_OKU:
    ADCIN 4, HAM
    DUTY = (HAM * 2503) / 10
    VOLT = (HAM * 1252) / 10
    YUZDE = DUTY / 10
    
    ' Sensörden gelen impulsları kullanarak RPM hesapla
    RPM = HIZ * 3 ' Bir dakikada ölçülen impulsların sayısı (dakikadaki devir sayısı)
RETURN

' PWM Duty Cycle Ayarlama Rutini
DUTY_VER:
    IF CCP1CON = 0 THEN CCP1CON = %00001100
    X = DUTY
    CCP1CON.4 = X.0
    CCP1CON.5 = X.1
    CCPR1L = (X >> 2)
RETURN


ete

Alıntı Yapkodda motor miline bağlı olan çarkta toplam 20 delik var.) (rpm kısmı HIZ*3 mü yoksa HIZ/3 mü olacak emin değlim şuan)

Motor miline bağlı çarkta 20 delik var. Senin motorun tam bir devir yaptığında senin hız ölçerin kaç adet puls okuyacak düşündünmü? Elbette 20 puls okuyacak.
1dak içinde toplam 20 puls okunmuş ise senin motorun kaç dev/dak ile dönüyordur sence?
Formül şöyle idi;
Hız (Dev/dak)=1 dak içinde sayılan Puls sayısı/çarktaki delik sayısı
Bu durumda hız=20/20=1 dev/dak ile dönüyor demektir.

Bence pek kafanı çalıştırmıyorsun ve sürekli bir şeyleri kopyala yapıştır yapıyorsun. Öncelikle bu tutumunu değiştir. İşin içine aklını kat.

Bir basic programı satır takip eder.Bir satırdaki emrileri yerine getirdikten sonra bir sonraki satıra otomatik geçer. Şimdi bu mantık üzerinden düşünelim.!!!!
senin program;
- ADC den değer okuyup bunu DUTY değeri olarak çevirip kullanacak O halde ADC okumaya gidip gelmeli bunu GISUB ADC_OKU komutu ile yaptırdık.
- ADC okumadan elde ettiği Duty değerini PWM sinyalinin Duty değeri olarak atayacak ohalde DUTY_VER isimli etikete gidip bu işi yapacak ve bunuda GOSUB DUTY_VER komutu ile yaptırdık.
- Motoru hareket ettirecek. Bunuda IN1 ve IN2 pinlerine gereken lojik durumları vererek hallettik
- LCD de yapılan işleri göstermek gerekecek bunları da LCDOUT komutları ile yaptık.
- Son iş devir ölçülecek Buna ait bir komut verdinmi.? hayır. Öncelikle buna ait bir alt program yaratman gerekiyor.BU alt programa HIZ_OLC ismini verelim. Bu alt programda;
a) Öncelikle her biri 500 ms olan bir Timer-1 kesme döngüsü yaratacaksın
b) Bu döngüyü 2 defa çalıştırırsan 1 sn lik zamanı geçirmiş olacaksın. Bu nedenle KES=2 şeklinde bir Byte değişkeni ayarla. Sonra döngüye girmeden önce HIZ=0 yap ki hız ölçümü zaman sayacı çalışmaya başladıktan sonra saymaya başlasın.
Tabiiki HIZ ölçme için bir de giriş pini ayarlaman gerekiyordu ki bunu PORTB.0 olarak yapmışsın.
c) Döngüye girmeden önce TMR1H=$0B:TMR1L=$DC ve PIR1.0=0 komutlarını vererek sayacı hazır hale getiriceksin ve önceden de T1CON=%00xx0001 komutunu vereceksin. Dikkat edersen binary sayının içinde XX harfleri var. Bu ikisi TMR1 sayacının bölme oranını ayarlar. XX=00 olursa bölme yok 1/1 , XX=01 olursa 1/2 bölme, XX=10 olursa 1/4 bölme, XX=11 olursa 1/8 bölme oranın olur.
Şimdi kendi kendimize soralım hangi bölme oranını kullanalım?. Bunun için bir mantık hesabı yapmamız gerekecek.
Motorun ortalama 500 dev/dak. hızla döner ise motor çarkı 500*20=10.000 puls üretir.  1 dakikada HIZ sayacın 10.000 puls sayacak demektir. Peki o motor 1000 dev/dak hızla dönerse senin HIZ sayacın HIZ=1000 *20=20.000 saaycak demektir. Bütün bu değerler WORD değişkenin taşıyabileceği 65535 rakamından küçük olacağı için 1/1 bölme oranını kullanabilirsin demektir bu sonuçlar.
O halde T1CON=%00000001 komutunu vererek işi başlatman gerekir.
Önceki mesajımda buranın detayını vermiş idim.
1 sn zaman tuttun. Sonuçta HIZ sayacın bri değer saydı ve bunu 60 ile çarparak 1dak. içinde kaç puls üretildiğini bulacaksın Bunuda 20 ye bölersen motorunun RPM değerini bulmuş olacak ve RETURN ile geri döneceksin.
Sende eksik olan bu son bölümde anlattıklarım.
Gidip ADC okumanın içine hiç alakası olmamasına rağmen,
"       ' Sensörden gelen impulsları kullanarak RPM hesapla
       RPM = HIZ * 3 ' Bir dakikada ölçülen impulsların sayısı (dakikadaki devir sayısı)"
satırlarını eklemişsin. Bunları buradan sil ve anlattığım şekilde yeniden toparla.
HIZ nasıl hesaplanır iyice öğren anlattım burada.
Hangi akıla dayanarak RPM=HIZ*3 formülünü yazdın çok merak ediyorum. Mantığın neydi acaba?
3 rakamı özellikle nereden çıktı?.
Mantıksız işler yapma lütfen. Araştırma yap ve Kafanı çalıştır!!!!!.

Ete


dgkn

3 rakamına bayağı gerilmişsiniz sayın ete RPM = (HIZ * 60) / 20  o da eşittir HIZ*3
basit matematik...
şu şekilde düzenledim. kod yazma gibi işleri hiçbir şekilde bilmediğim için çok fazla hatalarım oluyor. daha birkaç gün önce başladım çünkü

umarım bu şekilde doğru bir sona ulaşmışımdır. yeniden teşekkür ederim @ete


yeni kod şöyle
#CONFIG
 __CONFIG _CP_ALL & _WRT_256 & _CPD_ON & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
#ENDCONFIG
 
' Kristal osilatör frekansı
DEFINE OSC 4
 
' ADC özellikleri
DEFINE ADC_BITS 10     ' ADCIN çözünürlüğü (bit)
DEFINE ADC_CLOCK 1     ' ADC saat kaynağı (Fosc/8)
DEFINE ADC_SAMPLEUS 20 ' ADC örnekleme zamanı (μs)
 
' LCD bağlantıları
DEFINE LCD_DREG PORTD ' LCD veri portu
DEFINE LCD_DBIT 4      ' LCD veri başlangıç biti 0 veya 4
DEFINE LCD_RSREG PORTD ' LCD kayıt seçim portu
DEFINE LCD_RSBIT 1     ' LCD kayıt seçim biti
DEFINE LCD_EREG PORTD  ' LCD etkinleştirme portu
DEFINE LCD_EBIT 0      ' LCD etkinleştirme biti
DEFINE LCD_RWREG PORTD ' LCD oku/yaz portu
DEFINE LCD_RWBIT 2     ' LCD oku/yaz biti
DEFINE LCD_BITS 4      ' LCD veri yolu boyutu 4 veya 8
DEFINE LCD_LINES 2     ' LCD üzerindeki satır sayısı
'DEFINE LCD_COMMANDUS 2000 ' Komut gecikme süresi (μs)
'DEFINE LCD_DATAUS 50     ' Veri gecikme süresi (μs)
 
' Analog-Dijital Dönüşüm için giriş/çıkış tanımlamaları
CMCON = 7
ADCON0 = %01000000
ADCON1 = %10000000
TRISA = %11111111 
TRISB = %00000001 ' sensör pini giriş olarak ayarla 
TRISC = %00000000
TRISD = 0          ' D portunu tamamen çıkış olarak ayarla
TRISE = %00000000
 
' Portları sıfırla
PORTA = 0
PORTB = 0
PORTC = 0
PORTD = 0
PORTE = 0
 
' Değişken tanımlamaları
HAM   VAR WORD 56
VOLT  VAR WORD 58
DUTY  VAR WORD 60
X     VAR WORD
ESKI  VAR WORD
YUZDE VAR BYTE
HIZ   VAR WORD ' Motor hızı için değişken
RPM   VAR WORD ' RPM değeri için değişken
 
' Simge tanımlamaları
SYMBOL IN1 = PORTC.3
SYMBOL IN2 = PORTC.4
SYMBOL SENSOR_PIN = PORTB.0 ' Kızılötesi sensörün çıkış pini
SYMBOL POT = 4               ' Potansiyometre bağlantısı (Analog giriş RA4)
 
' Başlangıç mesajlarını göster
LCDOUT $FE,1
LCDOUT $FE,$80,"LUTFEN  BEKLEYIN"
LCDOUT $FE,$C0,"SISTEM  ACILIYOR" 
PAUSE 500
 
' PWM ayarları
PR2 = 249
T2CON = %00000101 ' İLK İKİ BİT %00=1/1  %01=1/4   %10=1/16
DUTY = 0
GOSUB DUTY_VER ' PWM Duty Cycle Ayarlama Rutini
 
' Sistem açıldı mesajını göster
LCDOUT $FE,1
LCDOUT $FE,$C0,"SISTEM ACILDI"
 
' Ana döngü
BASLA:
    ' ADC okuma
    GOSUB ADC_OKU
    
    ' IN1 ve IN2 sinyallerini ayarla
    IN1 = 1
    IN2 = 0
    
    ' Eğer eski değer duty değeriyle aynıysa, döngüyü tekrarla
    IF ESKI = DUTY THEN BASLA
    
    ' Duty Cycle'ı ayarla ve eski değeri güncelle
    GOSUB DUTY_VER
    ESKI = DUTY
    
    ' LCD'ye gerilim, duty cycle ve RPM değerlerini yazdır
    LCDOUT $FE,$80,"DUTY=",DEC(DUTY),"  %=",DEC YUZDE,"  "
    LCDOUT $FE,$C0,"RPM=",DEC RPM
    
    ' Ana döngüye geri dön
    GOTO BASLA
 
' ADC okuma rutini
ADC_OKU:
    ADCIN 4, HAM
    DUTY = (HAM * 2503) / 10
    VOLT = (HAM * 1252) / 10
    YUZDE = DUTY / 10
    
    ' Sensörden gelen impulsları kullanarak RPM hesapla
    GOSUB HIZ_OLC
RETURN
 
' RPM hesaplama rutini
HIZ_OLC:
    ' Timer1'in bölme oranını ayarla
    T1CON = %00000001 ' 1/1 bölme oranı
    
    ' Timer1'i sıfırla
    TMR1H = $0B
    TMR1L = $DC
    
    ' Kesme (interrupt) bayrağını temizle
    PIR1.0 = 0
    
    ' Timer1'i başlat
    T1CON.0 = 1
    
    ' Impuls sayacını sıfırla
    HIZ = 0
    
    ' Timer1 kesme (interrupt) bayrağı 20 kez tetiklendiğinde, 1 devir tamamlanmış olacak
    KES = 20

    ' Hızı hesapla: 1 dakika içinde kaç pulse olduğunu hesapla
    ' HIZ değişkeni 1 dakikadaki impulsları içerir
    ' HIZ değerini 60 ile çarparak dakikadaki pulse sayısını elde ederiz
    ' Ardından bu değeri çarktaki delik sayısına bölerek RPM değerini buluruz
    RPM = (HIZ * 60) / 20
    
    ' Ana döngüye geri dön
    RETURN

' PWM Duty Cycle Ayarlama Rutini
DUTY_VER:
    IF CCP1CON = 0 THEN CCP1CON = %00001100
    X = DUTY
    CCP1CON.4 = X.0
    CCP1CON.5 = X.1
    CCPR1L = (X >> 2)
RETURN

*(KES   VAR BYTE ' Impuls sayısı şeklinde KES sembolünü de tanımladım bu kodda yok şuan )
**(SYMBOL POT_PIN = 4 değeri de düzletildi)

dgkn

kodu denedim pot ayarı 0 iken bile motor dönüyor ve sistem kafayı yedi duty değeri bazen %1xx gibi değerler veriyor ve rpm değeri sabit 0 görünüyor ayrıca sistem açıldı yazısı ve rpm iç içe gömülmüş şekilde görünüyor. nerede hata yaptım iyice kafam çorba oldu. kod yazma işini bilmemek çok zorluklar getiriyor bana

Powered by EzPortal