Gönderen Konu: Takometre  (Okunma sayısı 959 defa)

Çevrimdışı 3L3CTRO

  • SsEeRrCcAaNn
  • Üye
  • **
  • İleti: 18
  • .:: SsEeRrCcAaNn ::.
Ynt: Takometre
« Yanıtla #15 : 16 Kasım 2011, 22:11:12 »
Merhabalar Boş zamanım oldu ve bir önceki mesajımda geçen algoritmaya göre programı yazdım. İsiste istediğim gibi çalışmakta gerçekte henüz denemedim ama sorun çıkacağını sanmıyorum.. algoritmayı anlaman için aşağıdaki kodu inceleyebilirsin..

 pragma target clock 4_000_000 kodundaki değeri 20_000_000 yaptığında kesmeyi ona göre oluşturmaktadır. Saygılar..

Kod: [Seç]
-- ------------------------------------------------------------
 -- Programın Adı : Temel Takometre Uygulaması
 -- Programcı : SsEeRrCcAaNn -- Sercan TEK --
 -- Tarih : 16.11.2011
 -- Kütüphaneler : 16F877
 -- Compiler : Jalv2 2.4o
 -- ------------------------------------------------------------
 
include 16f877A

pragma target clock 4_000_000
pragma target OSC  HS
pragma target WDT  disabled
pragma target LVP  disabled

enable_digital_io()

include delay
include print

const serial_hw_baudrate = 9_600 -- Seri İletişim Hızı
include serial_hardware
serial_hw_init()                 -- Seri iletişimi Hazırla

var word pals  = 0
var byte sayac,kesme_adeti
var byte s1[] = " Saniyede "
var byte s2[] = " Devir - "
var byte s3[] = " Rpm"

_usec_Delay(150000)               --  Stabil Çalışması için Gecikme 150ms
--------------------------------------------------------------------------------
-- Kristal Değerine Göre Tmr0 Kesme Ayarı
--------------------------------------------------------------------------------
if target_clock == 4_000_000 Then  -- 4 Mhz Kristal için Gerekli Ayarlar
  kesme_adeti = 61                 -- 1sn için olması Gereken Kesme Adeti
  OPTION_REG = 0b_0000_0101        -- Bölme Oranı 64
end if

if target_clock == 20_000_000 Then -- 20 Mhz Kristal için Gerekli Ayarlar
  kesme_adeti = 76                 -- 1sn için olması Gereken Kesme Adeti
  OPTION_REG = 0b_0000_0111        -- Bölme Oranı 256
end if

--------------------------------------------------------------------------------

INTCON_TMR0IE = true                    -- TMR0 Kesmesi Aktif
INTCON_INTE = true                      -- RB0 Kesmesi Aktif
INTCON_GIE = true                       -- Tüm Kesmeler Aktif

procedure Takometre is
 pragma interrupt                       -- Kesme Alt Programları

 if (INTCON_TMR0IF) then                -- TMR0 Kesmesi İse
   sayac = sayac + 1                    -- Sayacı Arttır
    if sayac == kesme_adeti then        -- Kesme adetine Ulaştı mı ?
     sayac = 0                          -- Ulaştı İse 1 sn geçti Demektir

     print_string(serial_hw_Data,s1)
     print_word_dec(serial_hw_data,pals)
     print_string(serial_hw_Data,s2)
     print_word_dec(serial_hw_Data,pals*60)
     print_string(serial_hw_Data,s3)
     print_crlf(serial_hw_Data)
     
     
     pals = 0                             -- pals Değerini Sıfırla
    end if
   INTCON_TMR0IF = false                  -- TMR0 Kesmesinin Bayrağını
 end if                                   -- sıfırla
     
 if (INTCON_INTF) Then                    -- RB0 Kesmesi İse
   pals = pals  + 1                       -- Pals değerini Arttır
   INTCON_INTF = low                      -- RB0 Kesmesinin Bayrağını Sıfırla
 end if
 
end procedure

forever loop
  -- TMR0 olduğu için sonsuz döngüye sokuldu. uyku moduna geçince TMR0 saymıyor.
  -- pals Değişkeni saniyedeki devir sayısını verir
  -- pals*60 ise dakikadaki devir sayısını verir
end loop

Çevrimdışı Retona

  • Üye
  • **
  • İleti: 22
Ynt: Takometre
« Yanıtla #16 : 17 Kasım 2011, 13:03:33 »
Selamün aleyküm.

Hocam bu doğru sonuç vermiyor.Seri iletişim devreye girdiğinde bir gecikme meydana geliyor. Bir saniye de geçen süreyi saniye bazında alınca sadece 60 - 120 ve katlayarak gider buda 60 devir fark verir.Bunların hepsini denedim.Nano saniye olmasada us bazında sayıp değer alıyorum oda fark veriyor.Ben size yaptığımı göstereyim deneyin.En basitinden lcd üzerinden saniye takibi yaparsanız lcd kütüphanesindeki gecikmeler sayamaya etki eder aynı şekilde seri port kütüphanesindekiler de gecikmeye etki eder.Sonuc olarak net sayı vermiyor.Bundan dolayı kod çalıştırma süresine göre saydırma yapıp çıkan sonucu bölerek gerçek devir sonucuna ulaşabiliz.Daha önce seri portta delay derdinden kurtulmak için while ile bir kesme uygulamıştım aynısını burada uyguluyorum bu sayede lcd kütüphanesinin gecikmeleri sonuca etki etmiyor ama genede fark çıkıyor.fark sebebi ise bölmede net sonuc alınamaması yani 4 mhz i 1/2 yaptığınızda 65 us eder ama bunun aslı 65536 dır bu katlandıkca fark veriyor

Kod: [Seç]

include 16f628a                  -- target PICmicro
pragma target clock 4_000_000     -- oscillator frequency
pragma target OSC      HS               -- HS crystal or resonator
pragma target WDT      disabled     -- no watchdog
pragma target LVP      disabled     -- no Low Voltage Programming


enable_digital_io()                -- make all pins digital I/O


const byte LCD_ROWS    =  2           -- LCD with 2 lines
const byte LCD_CHARS   =  16          -- and 16 characters per line

alias     lcd_en       is pin_b2      -- data trigger
alias     lcd_rs       is pin_b3      -- command/data select.
pin_b2_direction       = output
pin_b3_direction       = output

alias     lcd_d4       is pin_b4
alias     lcd_d5       is pin_b5
alias     lcd_d6       is pin_b6
alias     lcd_d7       is pin_b7

pin_b4_direction       = output
pin_b5_direction       = output
pin_b6_direction       = output
pin_b7_direction       = output


include delay
include print
include lcd_hd44780_4                -- LCD library with 4 data lines
lcd_init()


pin_b0_direction = input
pin_b1_direction = input

var sdword  sonuc  ,s1 = 1 ,c = 0 ,sayi =0


INTCON_TMR0IE = true
OPTION_REG = 0b_0000_0000     -- 1/2

procedure say is                         -- 1 us'lik gecikme
tmr0 = 0
while tmr0 < 250 loop  sayi = (sayi + 1)      end loop
end procedure


procedure yaz is                         -- Tıklandığı anda saymayı keser sayaç sıfırlanır bekler.
if pin_b1 == high then
sonuc = 600000/sayi
print_sdword_dec(lcd,sonuc)
lcd_cursor_position(2,5)
sayi = 0
s1 = s1 + 1
while s1 > c loop
if pin_b1 == low then
lcd_clear_screen()
s1=s1-1
end if
end loop
end if

end procedure


forever loop
say
yaz
if pin_b0 == high then
print_sdword_dec(lcd , sayi)                  - isis de 950 salise ye gelince butonu aktif edin ve lcd den asıl sayma oranına bakın
lcd_cursor_position(2,0)
end if
end loop



yukarıda 1 mikro saniyede bir saydırıyorum. gerçek manada devir ölçümü için mikro saniye bazında ölçüm yapmak gerekyor.Uzun lafın kısası hocam benim kapasite bu  :o 1 saniye içerisinde 1000000 us saymalı ki bölüp hakiki deviri alayım .mesela 10 mhz kıristal ile değeri 11 yaparak bölme 1/2 de bir saniye sonunda 1054320 gibi bir değer alıyorum ama başlangıçta aynı oran ile artmadığı için 3-5 bazende 30 devir hata ile ölçüyor.Bunu düzletmenin yolu nedir ?

Çevrimdışı 3L3CTRO

  • SsEeRrCcAaNn
  • Üye
  • **
  • İleti: 18
  • .:: SsEeRrCcAaNn ::.
Ynt: Takometre
« Yanıtla #17 : 17 Kasım 2011, 18:04:54 »
İyi ama genellikle yapılanların hepsi 1 saniyedeki ölçümleri baz alarak 60 ile çarpılır. Niçin ns bazında ölçüm yapacaksınız anlamadım ? 4 Mhz ile çalışan bir işlemci komut işleme süresi 1 mikrosaniyedir... 20 Mhz ile çalışan bir işlemci ise 0.2 mikrosaniye olmaktadır. 4 Mhz ile nasıl nanosaniye bazında gecikme üretebilirsin ?

Seriport evet gecikme yaratıyor ama örnek olması için bu şekilde yazdım.. değiştirilebilir yani :)

Birde 1 saniyede alınan 10 devir sayısı dakikada 600 devir olduğunu gösterir 60 devir fark demişsin. Ama zaten 1 sn de 10 devir alındı ise dakikada 600 deviri okuman gayet normal bir durum. Ama tek sorun şu olabilir çok yavaş bir motorda yani 1 devri 1 saniyenin altında olan bir motorda bu kod devri 0 olarak gösterecektir. min ve max devir sayısına göre bir algoritma kullanılabilir..

Çevrimdışı Retona

  • Üye
  • **
  • İleti: 22
Ynt: Takometre
« Yanıtla #18 : 17 Kasım 2011, 19:02:33 »
Selamün Aleyküm.

Hesap şöyle: 2 pulse arasındaki zaman /  60 ve katı yani ;
bir teker bir turu 0.600 sn içerisinde tamamlarsa = 0.600 / 60 =  100 /dd eder olaki bu teker bir deviri 0.0128 saniyede ala
0.0100 / 60000= 468 d/d eder. Yani 1/(0.128)*60 = 486.8 yapıp küsürat ile boğuşmak yerine net devir değerini alıyoruz.Hassas devir ölçümü hesabı benim bildiğim böyle.

Ben komut işleme süresini yanlış okumuşumdur.
Program :


Resim kucultulmustur. Buyultmek icin  Resim uzerine tiklayiniz.


Peki 1 mikro saniye de  bir komut çalıştırıyor ise pic 1 saniye sonunda sayıcıda doğal olarak 1000000 değerini alması gerekmezmi ? 1 sn =1000000 ms ediyor. ben verdiğim kodda 1 ms bir sayıcıyı arttırdım ancak alakasız değerler elde ediyorum .Saat gibi çalıştırdığımda ise daha alakasız değerler elde ediyorum.

Şöyle söyleyeyim en ideal ölçüm için saniye ve milisaniye değeri ve mikro saniye değerinin başlığı alınırsa net sonuç verir.Yani :

1-1000-1 beş hane bunu 110001 olarak saydıracağımki bölme işlemi sonucum bana deviri versin yani :


 60 / 1(saniye)1000(mili saniye)1(mikro saniye başı) = 54 /dd gibi ölçü düşürüldükçe sonuç hassaslaşır.bunu yapınca 300-500 liralık makineye 20 liraya sahip oluyorsunuz  :P ben düşük devirlerde çalıştığım için bana düşük devirlerde net sonuç verecek bir cihaz lazım.Derdim bu.Hem başkalarıda faydalanacakdır.Kimse bu tarz projelerini paylaşmaz.Ben hariç  ???
« Son Düzenleme: 17 Kasım 2011, 21:08:27 Gönderen: gevv »

Çevrimdışı 3L3CTRO

  • SsEeRrCcAaNn
  • Üye
  • **
  • İleti: 18
  • .:: SsEeRrCcAaNn ::.
Ynt: Takometre
« Yanıtla #19 : 17 Kasım 2011, 21:34:00 »
Merhaba Retona..

Açıklamanı okuyunca atladığım bir konu olduğunun farkına vardım.. 4 Mhz 4 e bölünüyor ve timer için tekrar bölücü değerine göre hesaplayınca(1/2 ise)  ~2 ns gibi bir zaman çıkıyor. Eğer iki puls arasındaki zaman farkını net olarak hesaplayabilirsek sanırım gerisi çok kolay olacak..


---------------------------------

CCP birimi kullanılarak daha hassas ölçüm yapılabilir herhalde.. Örnek olarak tübidak kendimiz yapalım kısmındaki frekansmetre devresi incelenip jalv2 de istenilen algoritma oluşturulabilir..
« Son Düzenleme: 17 Kasım 2011, 22:06:20 Gönderen: 3L3CTRO »

Çevrimdışı Retona

  • Üye
  • **
  • İleti: 22
Ynt: Takometre
« Yanıtla #20 : 18 Kasım 2011, 09:16:57 »
Selamün aleyküm.

Bildiğiniz bir saat'den farksız aslında.Sadece hesaplayamadığım için doğru sonuç vermiyor.Olmaz ise işi eski yöntemler ile halledeceğiz artık.

Çevrimdışı Retona

  • Üye
  • **
  • İleti: 22
Ynt: Takometre
« Yanıtla #21 : 19 Kasım 2011, 20:08:57 »
Selamün aleyküm.

Hesaplama konusunda hata yapıp yapmadığımdan emin değilim inat ile fark vermeye devam ediyor.

kesme süresi hesaplaması :

Fosc = oslilatör frekansı / 4  =    4_000_000/ 4 = 1_000_000 yani 1 mikro saniyede bir komut çalıştırıyor.

Kesme süresi hesabı :

Tosc x (Bölme oranı) x ( 256 - tmr0 başlangıç değeri) = (1/1)x16x(256-6) = 4000 us ediyor.

Şimdi tmr1 kullanarak net sabit sayı hesaplıyorum

aynı işlemler 4 mhz pic bölme oranı 1:2

(1/1)x2x(65536 - 15536) = 100000 us buda = 100 milisaniye eder.Bu durumda tmr1 her 100 milisaniyede bir artacak doğal olarak 1 saniye sonra 10 kere kesme yapmış olacak.Ama yapmıyor ? Anlamadım gitti neden ? 1 saniye sonunda 5 kere kesme yapıyor.zaman uzadıkça zaman birbirine giriyor.Neden oluyor bu bulamadım.isis bize şakamı yapıyor nedir anlamadım artık.Hesaplamada başka bir şey varmı ?


Çevrimdışı Retona

  • Üye
  • **
  • İleti: 22
Ynt: Takometre
« Yanıtla #22 : 03 Aralık 2011, 13:17:47 »
Selamün aleyküm.

Sorun çözüldü.Seri lcd kullanarak hallettim tam sayma yapıyor ancak sensörün kılığından 3-5 devir arasında kararsız çalışıyor.Bunuda hallettimmi 500 tl lik cihaz 30tl oluyor.Ampüller bedava yanıyor.İnsanlar mutlu oluyor  ;D

Çevrimdışı 3L3CTRO

  • SsEeRrCcAaNn
  • Üye
  • **
  • İleti: 18
  • .:: SsEeRrCcAaNn ::.
Ynt: Takometre
« Yanıtla #23 : 03 Aralık 2011, 13:24:42 »
Tebrikler.. !! bende müsait olunca bir çalışma yapacağım.. eğer iki puls arası 0.0128 saniye ise bunu 10000 ile çarparsak 128 eder ve 60000 / 128 = 486 eder virgüller ile uğraşmazsın.. aradaki süreyi tmr0 ile hesaplayabiliriz herhalde.. algoritma ona göre kurulur ve virgülsüz işlem halledilir.. siz nasıl yol izlediniz.. ?

Çevrimdışı Retona

  • Üye
  • **
  • İleti: 22
Ynt: Takometre
« Yanıtla #24 : 03 Aralık 2011, 14:53:01 »
Selamün aleyküm.

Sayıyı doğrudan 600000  e bölünce net devri veriyor.Yöntem bu :

 ben 10000 mili saniye aldım. bunu 600000  e bölüp lcd ye yazdırdım.Bu kadar.kod  yukardaki aynı kod. tmr1'i kullandım.biraz zahmetli oldu ama işimi görüyor.şimdi ana projeme devam edeceğim.

Tamamen bitirince tüm projeyi paylaşacağım.Böylesi daha güzel olur İnşallah.

Çevrimdışı 3L3CTRO

  • SsEeRrCcAaNn
  • Üye
  • **
  • İleti: 18
  • .:: SsEeRrCcAaNn ::.
Ynt: Takometre
« Yanıtla #25 : 03 Aralık 2011, 15:06:57 »
Peki öyle olsun :) ortaya bir takometre çıktığında pdf açıklaması örnek kodu ve videoları paylaşırsanız 320voltta ve http://code.google.com/p/jalv2-kaynak/downloads/list 'ta paylaşırız böylelikle jalv2 üzerine proje geliştirmek isteyenler faydalanabilir.. Kolay gelsin..

Çevrimdışı gareven

  • Elektronik Bakkal
  • Yeni Üye
  • *
  • İleti: 9
    • Elektronik Bakkal
Ynt: Takometre
« Yanıtla #26 : 22 Mayıs 2012, 13:41:32 »
merhaba arkadaşlar
basic te yazılmış bu programı Jalv2 de nasıl yazarız yine takometre yapımı için?

Kod: [Seç]
define lcd_dreg portb
define lcd_dbit 4
define lcd_bits 4
define lcd_rsreg portb
define lcd_rsbit 2
define lcd_ereg portb
define lcd_ebit 3
define lcd_lines 2
define lcd_commandus 2000
define lcd_dataus 40
a var word
son_deger var word
deger var word
hiz var word
hiz_dev var word
devir_sayisi var word
input porta.0
input porta.1

                   

'***********************ANA PROGRM*******************************
PAUSE 100
son_deger = 0
main:

count porta.0,1000,deger

son_deger = son_deger + deger
devir_sayisi = son_deger
hiz = deger * 60
                           
if porta.1=0 then son_deger=0
lcdout $fe,1
lcdout $fe,2
lcdout, "hiz:",dec hiz
lcdout $fe,136," dev/dk"
lcdout $fe,$c0,"dev say:",dec devir_sayisi
 

GoTo main

Çevrimdışı 3L3CTRO

  • SsEeRrCcAaNn
  • Üye
  • **
  • İleti: 18
  • .:: SsEeRrCcAaNn ::.
Ynt: Takometre
« Yanıtla #27 : 22 Mayıs 2012, 17:30:32 »
merhaba arkadaşlar
basic te yazılmış bu programı Jalv2 de nasıl yazarız yine takometre yapımı için?

Kod: [Seç]
define lcd_dreg portb
define lcd_dbit 4
define lcd_bits 4
define lcd_rsreg portb
define lcd_rsbit 2
define lcd_ereg portb
define lcd_ebit 3
define lcd_lines 2
define lcd_commandus 2000
define lcd_dataus 40
a var word
son_deger var word
deger var word
hiz var word
hiz_dev var word
devir_sayisi var word
input porta.0
input porta.1

                   

'***********************ANA PROGRM*******************************
PAUSE 100
son_deger = 0
main:

count porta.0,1000,deger

son_deger = son_deger + deger
devir_sayisi = son_deger
hiz = deger * 60
                           
if porta.1=0 then son_deger=0
lcdout $fe,1
lcdout $fe,2
lcdout, "hiz:",dec hiz
lcdout $fe,136," dev/dk"
lcdout $fe,$c0,"dev say:",dec devir_sayisi
 

GoTo main

Burada count porta.0,1000,deger komutunun işleyişini bilmemiz gerekiyor. Kesme ilemi Çalışıyor yoksa başka bir algoritması mı Var ?

Eğer Kesme ile Çalışıyorsa Önceki Sayfada yayımladığım kod aynı işlevi Yapıyor..

Kod: [Seç]
-- ------------------------------------------------------------
 -- Programın Adı : Temel Takometre Uygulaması
 -- Programcı : SsEeRrCcAaNn -- Sercan TEK --
 -- Tarih : 16.11.2011
 -- Kütüphaneler : 16F877
 -- Compiler : Jalv2 2.4o
 -- ------------------------------------------------------------
 
include 16f877A

pragma target clock 4_000_000
pragma target OSC  HS
pragma target WDT  disabled
pragma target LVP  disabled

enable_digital_io()

include delay
include print

const serial_hw_baudrate = 9_600 -- Seri İletişim Hızı
include serial_hardware
serial_hw_init()                 -- Seri iletişimi Hazırla

var word pals  = 0
var byte sayac,kesme_adeti
var byte s1[] = " Saniyede "
var byte s2[] = " Devir - "
var byte s3[] = " Rpm"

_usec_Delay(150000)               --  Stabil Çalışması için Gecikme 150ms
--------------------------------------------------------------------------------
-- Kristal Değerine Göre Tmr0 Kesme Ayarı
--------------------------------------------------------------------------------
if target_clock == 4_000_000 Then  -- 4 Mhz Kristal için Gerekli Ayarlar
  kesme_adeti = 61                 -- 1sn için olması Gereken Kesme Adeti
  OPTION_REG = 0b_0000_0101        -- Bölme Oranı 64
end if

if target_clock == 20_000_000 Then -- 20 Mhz Kristal için Gerekli Ayarlar
  kesme_adeti = 76                 -- 1sn için olması Gereken Kesme Adeti
  OPTION_REG = 0b_0000_0111        -- Bölme Oranı 256
end if

--------------------------------------------------------------------------------

INTCON_TMR0IE = true                    -- TMR0 Kesmesi Aktif
INTCON_INTE = true                      -- RB0 Kesmesi Aktif
INTCON_GIE = true                       -- Tüm Kesmeler Aktif

procedure Takometre is
 pragma interrupt                       -- Kesme Alt Programları

 if (INTCON_TMR0IF) then                -- TMR0 Kesmesi İse
   sayac = sayac + 1                    -- Sayacı Arttır
    if sayac == kesme_adeti then        -- Kesme adetine Ulaştı mı ?
     sayac = 0                          -- Ulaştı İse 1 sn geçti Demektir

     print_string(serial_hw_Data,s1)
     print_word_dec(serial_hw_data,pals)
     print_string(serial_hw_Data,s2)
     print_word_dec(serial_hw_Data,pals*60)
     print_string(serial_hw_Data,s3)
     print_crlf(serial_hw_Data)
     
     
     pals = 0                             -- pals Değerini Sıfırla
    end if
   INTCON_TMR0IF = false                  -- TMR0 Kesmesinin Bayrağını
 end if                                   -- sıfırla
     
 if (INTCON_INTF) Then                    -- RB0 Kesmesi İse
   pals = pals  + 1                       -- Pals değerini Arttır
   INTCON_INTF = low                      -- RB0 Kesmesinin Bayrağını Sıfırla
 end if
 
end procedure

forever loop
  -- TMR0 olduğu için sonsuz döngüye sokuldu. uyku moduna geçince TMR0 saymıyor.
  -- pals Değişkeni saniyedeki devir sayısını verir
  -- pals*60 ise dakikadaki devir sayısını verir
end loop


Bir Kaç değişiklik Yaparak senin verdiğin kod haline gelebilir..

Çevrimdışı gareven

  • Elektronik Bakkal
  • Yeni Üye
  • *
  • İleti: 9
    • Elektronik Bakkal
Ynt: Takometre
« Yanıtla #28 : 22 Mayıs 2012, 18:40:27 »
peki lcd ye nasıl göndeririz bu veriyi?

Çevrimdışı 3L3CTRO

  • SsEeRrCcAaNn
  • Üye
  • **
  • İleti: 18
  • .:: SsEeRrCcAaNn ::.
Ynt: Takometre
« Yanıtla #29 : 22 Mayıs 2012, 21:03:08 »
peki lcd ye nasıl göndeririz bu veriyi?

Kod: [Seç]
     print_string(serial_hw_Data,s1)
     print_word_dec(serial_hw_data,pals)
     print_string(serial_hw_Data,s2)
     print_word_dec(serial_hw_Data,pals*60)
     print_string(serial_hw_Data,s3)
     print_crlf(serial_hw_Data)
Bu Bölümde gerekli düzenlemeyi yaparsanız istediğiniz lcd de gösterirsiniz..