Takometre

Başlatan Retona, 29 Ekim 2011, 15:39:18

Retona

Selamün aleyküm.Jal kullanarak bir takometre yapmaya çalışıyorum ancak net sonuc alamadım.tmr0 değerini bölemedim.Bununla beraber.240 a kadar her pulseyi 1 devir alıyor ve 60 arıyor.Küsüratlı ölçüm yapmak için bir zamanlama yapmak istediğimde saniye ve salise değerlerini bir alıp çarpma işlemi yapamadım.Yaptığım çapma işlemlerinide doğru yazdıramadım.Yani  :o
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
pragma target MCLR external        -- reset externally
-- These configuration bit settings are only a selection, sufficient for
-- this program, but other programs may need more or different settings.
--
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_a0      -- data trigger
alias     lcd_rs       is pin_a1      -- command/data select.
pin_a0_direction       = output
pin_a1_direction       = output
--
alias     lcd_d4       is pin_b2
alias     lcd_d5       is pin_b3
alias     lcd_d6       is pin_b4
alias     lcd_d7       is pin_b5
--
pin_b2_direction       = output
pin_b3_direction       = output
pin_b4_direction       = output
pin_b5_direction       = output
pin_a2_direction       = input
pin_a3_direction       = output
include lcd_hd44780_4
include delay
include print
lcd_init()
var byte sonuc
forever loop
sonuc =   (1/tmr0 * 60 )
print_byte_dec(lcd , sonuc )
lcd_cursor_position(1,0)
end loop

Retona

Jal ile alakalı kimseler yok anlaşılan ? Peki küsüratlı sayıları nasıl çarptırabiliriz ? iki farklı değer var biri saniye biri salise bilgisi.Tam devir ölçümü için ikisini işlemem gerekiyor ama saniye ve salise değerkerini yan yana koyamadım ? bana algoritmasını söyleyebilecek birileri yokmu ? İllede jal ile açıklamanıza gerek yok iki ayrı değerin birini küsürat olarak alıp işlemem gerekiyoru sadece ?


3L3CTRO

#3
Merhabalar gördüğüm kadarıyla jalv2 kullanıyorsunuz.. Jalv2 güzel bir dil ama virgüllü sayılar ile işlem yapılamıyor. Nedeni ise geliştiricisinin dediğine göre derlendikten sonra çok yer kaplamış olmasıymış..

Eğer virgüllü sayı sabit sayı ise işimiz daha kolay..ama sürekli değişen bir sayı ise zor diyebilirim..

örneğin : 3,14 x 5 / 2  gibi bir işlemimiz var bunu jalda yazmak için extra bir fonksiyon kullanmamız gerekmekte.

http://www.casadeyork.com/jalv2/cmul.cgi adresine girip value değerine virgüllü sayıyı gireceğiz ve hemen altında bulunan Error % değerini yüzde cinsinden hata payını yazacaksınız. Eğer hata payı büyük ise üretilen kod daha küçüktür.

Value  = 3,14
error % = 0 ise

üretilen kod aşağıdaki gibi olacaktır.

tmp = x
x = x - tmp
x = x >> 4
x = x + tmp
x = x >> 3
x = x + tmp
x = x >> 2
x = x + tmp
x = x >> 5
x = x - tmp
x = x >> 3
x = x + tmp
x = x >> 1
x = x + tmp
x = x >> 2
x = x - tmp
x = x >> 4
x = x + tmp
x = x >> 3
x = x + tmp
x = x >> 3
x = x + tmp
tmp = tmp << 1
x = x + tmp

Biz bunu fonksiyon olarak yazalım



function pi return word is
 var word tmp,x = 1
 x = x * 100  --  virgülden sonra iki basamak çıksın diye biz ekledik
 tmp = x
x = x - tmp
x = x >> 4
x = x + tmp
x = x >> 3
x = x + tmp
x = x >> 2
x = x + tmp
x = x >> 5
x = x - tmp
x = x >> 3
x = x + tmp
x = x >> 1
x = x + tmp
x = x >> 2
x = x - tmp
x = x >> 4
x = x + tmp
x = x >> 3
x = x + tmp
x = x >> 3
x = x + tmp
tmp = tmp << 1
x = x + tmp
 return x
end function


şimdi yukarıdaki kodumuzu kullanarak çıkış alalım..



include 16f877  -- kullanılacak Chip
include print   -- Yazdırma Formatı

-- CİHAZ TANIMLAMALARI--------------------
pragma target OSC HS             -- Yüksek Hızlı Kristal
pragma target clock 20_000_000   -- Kristal Hızı
pragma target WDT  disabled      -- WatchDogTimer Kapalı
pragma target LVP  disabled      -- Düşük güç programalama Kapalı


pragma target  pwrte       enabled  ; PowerUpTimer
pragma target  CP          disabled ; code protection
pragma target  BROWNOUT    enabled


enable_digital_io()              -- dijital giriş çıkışlar etkin


const serial_hw_baudrate = 9_600 -- Seri İletişim Hızı
include serial_hardware          -- Donanımsal Seri İletişim
serial_hw_init()



include format  -- format kütüphanesi

function pi return word is
 var word tmp,x = 1
 x = x * 100  --  virgülden sonra iki basamak çıksın diye biz ekledik
 tmp = x
x = x - tmp
x = x >> 4
x = x + tmp
x = x >> 3
x = x + tmp
x = x >> 2
x = x + tmp
x = x >> 5
x = x - tmp
x = x >> 3
x = x + tmp
x = x >> 1
x = x + tmp
x = x >> 2
x = x - tmp
x = x >> 4
x = x + tmp
x = x >> 3
x = x + tmp
x = x >> 3
x = x + tmp
tmp = tmp << 1
x = x + tmp
 return x
 end function

format_word_dec(serial_hw_data, pi*5/2, 6, 2)



Sonuç 7.87 olarak çıkacaktır. azıcık hata payı var ama bence yeterli :):)

Retona

3L3CTRO Kardeşim, Teşşekkür ederim.Ancak jalv2 bu işi böyle yapamıyor.Harici pals girip onu bölmek gerekiyor anladığım kadarı ile.Son çare olarak alınan saniye ve salise değerini birleştirdim.Seri port üzerinden pc ye yollayıp pc de bölme ve çarpma işlemini yapacağım.Zaten kontrol edilecek olan cihazın başka bölümleride pc ye muhtaçtı ne yapalım Jal gene küstürdü.Tekrar teşekkürler.

3L3CTRO

Rica ederim.. 1/TMR0 ifadesinde TRM0 > 1 olduğunda derleyici onun sonucunu 0 olarak alacaktır. Bildiğim kadarıyla diğer pic derleyicilerinde de durum aynı... CCS C de denedim oda 0 verdi.. öyle bir formül kullan ki sana istediği sonucu versin. ? iyi düşünmek gerek. daha önce bende hassas terazi için program yazmıştım orada okunan adc değerini bilgisayara gönderip bilgisayar üzerinde işlem yapıyordum daha da  hassas veri elde etmiştim :)

Kolay gelsin..

Retona

saniye ve salise değerlerini birleştirip 60 la çarpmak yerine 60000 ve katına bölerek küsürat olmasada pc ye göndermeden 1 yada 2 devir fark ile okutabilirim yeni fark ettim.C ile yapılmış projeler de kat sayıyı artırmışlar. 60000000 / darbe gibi.Bitirince paylaşacağım İnşallah.Tekrar teşekkürler.

3L3CTRO

Tebrik ederim gelişme var.. Sonuçlarını bekliyorum.. Kolay gelsin.. Birde Kendinizi Jalv2\'siz bırakmayın :):) 8) 8)

Retona

Tek sorun zamanlama direk lcd ye yazdırıyorum.Zamanı mikro bazında almak gerekiyor ama mili\'den aşşağı alamadım nasıl yapabiliriz ? 20 mhz 16f877 emektarı kullanıyorum.jalın eski sürümünde option ile yapıyorlardı bu işi v2 de nasıl bölebiliriz ?

Düşük devirlerde gayet iyi sonuç veriyor 2 yada 4 devir fark ile ama mikro saniye olarak alınırsa hesaba süper olacak o zaman rahatlıkla 6000 d/d\' ya kadar hatta dahada yüksek devirlerde 1-2 d/d hata ile ölçer. Mikro bazında nasıl saydırabiliriz ?

3L3CTRO

dostum tam anlayamadım.. gecikme zamanını diyorsan jalv2 de _usec_delay() komutu var..parantez içine girdiğin kadar bir komut işleme süresi bekleme yapar...benim yazdığım temel jalv2 kavramları dokümanında açıklamıştım... eğer eski jalda oluyorsa v2 de mutlaka olur.. option isimleri için 16f877.jal dosyasını inceleyebilirsin ... daha fazla yardımcı olmak için programın kodlarını incelemem gerek...

3L3CTRO

Şuan evde değilim.. yarın kaynak kodları görürsem daha yardımcı olabilirim zira Şuanda kafam pek toplamiyor.. hayırlı geceler...

Retona

zamanlama meselesi var sadece.Yapamadığım iş şu : saniye ve salise değerleri bir sayıyor.Yani :
procedure say is
delay_1ms()
sayi1 = (sayi1 + 1 ) % 101
if sayi1 == 100 then
sayi2= (sayi2 + 1)
if sayi2 == 1000 then
sayi2 = 0
end if
end if
end procedure

böyle yaptığımda sayıyor, ancak tam zamanlı saydırma yaptıramıyorum.100 mili saniyeyi birer birer delay ile arttırmak istediğimde dengesiz oluyor.Fırekansı böldüğümdede aynı lcd üzerinden tam olarak zamanı okuyamıyorum .seri port üzerinden saniye bilgisini gönderdiğimde , 10 dan 50 ye atladığı esnada seri portta ara değerler gözüküyor.Acaba isisin azizliğine mi uğruyoruz gene ?
 
jalv2\'de üzerinde timer tam olarak nasıl kullanılıyor,Onun örneğini bulamadım sayıcıyı kullanabilsem güzel olacak ama jal işte ne diyeyim.Kaynak yok :)

3L3CTRO

#12
Merhabalar..

Açıkçası Yapmak istediğiniz Takometre devresini ve yazılımını bilmediğim için kafamdaki taşlar pek yerine oturmuyor. Kusuruma bakmayın daha önce takometre üzerine çalışmadım. Jalv2 ile timer kullanmak kolay aslında size örnek kodlar vereyim bir inceleyin ona göre istediğinize uygun bir algoritma geliştirebilirsiniz..

Timer0 ile süre kütüphanesi
http://code.google.com/p/jallib/source/browse/trunk/include/peripheral/timer/timer0_isr_interval.jal
Örnek  :
http://code.google.com/p/jallib/source/browse/trunk/sample/16f648a_timer0_interval.jal


http://code.google.com/p/jallib/source/browse/trunk/include/peripheral/timer/timer0_poll_interval.jal
Örnek :
http://code.google.com/p/jallib/source/browse/trunk/sample/18f14k50_tmr0_poll_interval.jal

Kronometre kütüphanesi :
http://code.google.com/p/jallib/source/browse/trunk/include/peripheral/timer/stopwatch.jal
Örnek Kod :
http://code.google.com/p/jallib/source/browse/trunk/sample/16f877_stopwatch.jal





Retona

Selamün aleyküm.

procedure say is
sayi  = (sayi + 1)
_usec_delay(5)
end procedure

Bu şekilde yaptığımda veya serbest bıraktığımda yanı komut işle süresi ile sayma yaptırdığımda fark çıkıyor. sayi değerini ise şu şekilde :
if pin_d1 == high then
sonuc = 6000000/sayi
print_sdword_dec(lcd,sonuc)
lcd_cursor_position(2,5)
end if
bölüp değer okumak istediğimde lcd ye yazıyorum.

Her halukarda tam bir sayma yapmıyor 20 mhz lik 877 pic kullanıyorum.mesela yukarıdaki procedure deki delay süresine göre sayi değerini 1 arttırdığımda 1 saniyenin sonunda 99755 değeri çıkıyor 500 ms de ise 45409 kere saymış oluyor.Fark çıktığı için yannış devir değeri veriyor.4 - 10 - 20 mhz lik kıristallerde de denedim hep fark var.Komut çalıştırma süresi 20 mhz bölünme kapalı iken 50nano saniye  her halukarda tam sayma yapmıyor.Nedenini bulamadım. Amacım ise  1 saniye içerisinde  mikro saniye değeri almak.Tam bir saydırma yapamadım.Nasıl yapılabilir bulamadım.

3L3CTRO

#14
Kodunuzun çalışmaması gayet normal.. çünkü 1 sn içindeki pals leri saymak için trm0 sayıcısını 1sn sayacak şekilde ayarlamanız ve bu süre içinde RB0/int kesmesi yada timer1 kesmesini saydırmanız gerekmektedir. Böylece gerçek devir sayısını hesaplayabilirsiniz.

Algoritma olarak :
- TMR0 1sn\'de kesme üretecek şekilde ayarla
- Harici kesme kullanacaksan rb0 ile dışarıdan gelecek pals leri sayması için ayarla
- Rb0 kesmesi geldiğinde palsi 1 arttır ve kesme ayarlarını yeniden yap
- TMR0 kesmesi geldiğinde pals değerini al ve pals değerini sıfırla
- TMR0 kesmesini yeniden kur ve ayarla


-RB0 yerine timer1 kullanacaksanız onu ayarlamalı ve dışarıdan clock ile sayacak şekilde kurmalısınız.
-TMR0 kesmesi oluştuğunda TMR1 içeriği alınır ve sıfırlanıp kesme tekrar ayarlanır


Eğer Jalv2 ile TMR0 ve RB0 yada TMR1 kesmelerini kullanabilirseniz dediğim algoritma ile 1sn deki palsleri sayabilirsiniz.. ve 60 ile çarpıp dakikadaki devir sayısını bulursun.. Bu aralar müsait olmadığım için örnek yapamayacağım ilerleyen zamanda çalışan bir uygulama yapıp yayımlayacağım.. Kolay gelsin..

NOT : _usec_Delay() komutu bir komut süresi kadar bekleme yapacaktır. MCU nın çalısma hızı ne ise bir saykıl süresince bekleme yapar.. Bundan dolayı farklı kristallerde farklı sonuçlar alırsınız..

3L3CTRO

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..

-- ------------------------------------------------------------
 -- 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

Retona

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


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 ?

3L3CTRO

İ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..

Retona

#18
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 :




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ç  ???

3L3CTRO

#19
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..

Retona

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.

Retona

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ı ?


Retona

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

3L3CTRO

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.. ?

Retona

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.

3L3CTRO

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..

gareven

merhaba arkadaşlar
basic te yazılmış bu programı Jalv2 de nasıl yazarız yine takometre yapımı için?

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

3L3CTRO

Alıntı yapılan: gareven - 22 Mayıs 2012, 15:41:32merhaba arkadaşlar
basic te yazılmış bu programı Jalv2 de nasıl yazarız yine takometre yapımı için?

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..

-- ------------------------------------------------------------
 -- 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..


3L3CTRO

Alıntı yapılan: gareven - 22 Mayıs 2012, 20:40:27peki lcd ye nasıl göndeririz bu veriyi?

     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..


Hızlı Yanıt

Not: Bu konu bir moderatör tarafından onaylanmadan görüntülenmeyecektir.

Adı:
E-Posta:
Doğrulama:
Lütfen bu kutuyu boş bırakın:
IRFP250 Nedir:
kısayollar: göndermek için alt+s veya önizleme yapmak için alt+p'ye basın