Ynt: bmp085 ile variometre yapımı

Başlatan homer380, 15 Aralık 2013, 15:28:50

homer380

kendim için hazırladığım henüz kullanamadığım variometre. (variometre : açık hava basıncından yararlanarak yerden yüksekliğinizi ölçer.)
çalışma mantığı kısaca söyle referans bir basınc alınır. referans alınan basınç ile cıktığınız yüksekliğin basıncı ölçülerek size yüksekliğinizi verir. beni bu projede en çok zorlayan kısım herhangibir sayının n. dereceden kök alma işi oldu onuda newton rapshon kök alma metodu ile çözdüm. suan herhangibir sayınız 5.25 dereceden kökünü alabiliyorum. aslında 5.255 olması gerekiyordu ama virgülden sonraki kısmına erindim. filtre olarak kalman filtresi kullanacaktım ama hata az olduğu için gerek görmedim. biraz kodlar fazla görünebilir oda pic basic ve protonda işaretli sayı olmamasından.

kodlar da yeterince acıklama olmayabilir çünkü kodlar üzerinde sürekli değişiklik yapmak zorunda kaldım. geliştirmek adına.

buda videosu bazı yerlerde beklemediğim (yükseklik değerlerinde anlık ani değişimler) değişimler oldu ama 0-12 kata cıktığımda yüksekliği 36 metre civarı gösteriyordu.

http://youtu.be/_issl26EHvY

kaynak kodlar:

        Device 16F877A		'Proğramlanacak cihaz 16F877
@ CONFIG_REQ 
@ __config CP_ALL & CPD_ON & WDT_OFF & HS_OSC & PWRTE_OFF & BODEN_OFF & WRT_1FOURTH & LVP_OFF & DEBUG_OFF
        Xtal 20			'Osilatör Hızı 4 Mhz
         All_Digital TRUE
        'Output PORTB		'PortB çıkış
        'PORTB=$00			'Portb ye 00 hexadecimal sayısını at.
        TRISD=0
        
Declare LCD_DTPort  =PORTB      'GLCD DATA PORTLARI PORTB'YE BAĞLI
Declare LCD_RSPin  =PORTA.0      'GLCD RS PİNİ PORTC.5 BAĞLI bende d/i
Declare LCD_ENPin  =PORTA.2      'GLCD ENABLE PİNİ PORTC.1 BAĞLI
Declare LCD_RWPin  =PORTA.1     'GLCD RW PİNİ PORTC.4 BAĞLI
Declare LCD_CS1Pin =PORTD.7    'GLCD CS1 PİNİ PORTC.2 BAĞLI
Declare LCD_CS2Pin =PORTD.6    'GLCD CS2 PİNİ PORTC.3 BAĞLI
Declare GLCD_CS_Invert On
'declare glcd_strobe_delay = 100
Declare LCD_Type =  GRAPHIC      'GLCD TİPİ GRAFİK KS0108 128*64B WİNSTAR
Declare Internal_Font=  On                 
Declare Font_Addr =0


Declare SDA_Pin PORTD.3 
Declare SCL_Pin PORTD.2
'**********kökalma değişkenleri***************
Dim fx As Float
Dim x As Float
Dim bn1 As Float
Dim tfx As Float
Dim xn1 As Float
Dim xn As Float
'*********************
Dim gfx As Float
Dim gx As Float
Dim gbn1 As Float
Dim gtfx As Float
Dim gxn1 As Float
Dim gxn As Float
Dim sifirmi As Float
Dim sifirmi1 As Float

'****************basınc ve sıcaklık hesaplama değişkenleri**********************
Dim ac1 As Word
Dim ac2 As Word
Dim ac3 As Word
Dim ac4 As Word
Dim ac5 As Word
Dim ac6 As Word
Dim b1 As Word
Dim b2 As Word
Dim b3 As Dword
Dim b4 As Dword
Dim mb As Word
Dim mc As Word
Dim md As Word
Dim ut As Dword
Dim up As Dword
Dim oss As Byte
Dim b5 As Dword
Dim b6 As Dword
Dim b7 As Dword
Dim b As Dword
Dim msb As Byte
Dim lsb As Byte
Dim xlsb As Byte
Dim b5_pn As Byte
Dim b6_pn As Byte
Dim x1 As Dword
Dim x2 As Dword
Dim x3 As Dword
Dim basinc As Float
Dim sicaklk As Float
Dim ref_basinc As Float
ac1=7367:ac2=1190:ac3=14433
ac4=33574:ac5=23949:ac6=23315
b1=5498:b2=64
mb=32768:mc=11075:md=2432

'**************************************
Dim i As Byte
Dim j As Byte
Dim topla_h As Dword
Dim topla_l As Dword
Dim topla_xlsb As Dword
Dim h As Float
Dim h_kayit As Float
oss=3


GoSub basinc_sicaklik_hesaplama
ref_basinc=basinc
Cls
Print At 1,0,"referans basinc"
Print At 2,0,@ref_basinc
DelayMS 3000
Cls


yukseklik_hesapla:
        'KESME VARDI BURADA
        
   
GoSub basinc_sicaklik_hesaplama
            x=(basinc*1000)/ref_basinc          '5,25 alınacak sayı
            x=x/100
            GoSub kok_1
            If ref_basinc>basinc Then           'yükseliyormu alcalıyormu kısım onun için
               
                h=1000000-bn1                       'x'in 5,25 kökü xn1
                h=h*44330
                h=h/1000000
                
                Else 
                
                h=bn1-1000000                       'x'in 5,25 kökü xn1
                h=h*44330
                h=h/1000000 
                
            EndIf
            Cls
            Print At 1,0,"h:",@h,"m"
'********************
'h_kayit=ref_basinc-basinc       'referans basınc ile ölçulen basınc arasındaki fark bilgisayarda ölçümleri doğrulamak için
'Print At 1,12,@h_kayit          'silinebilir.


h=ut/10                         'sıcaklık ondalık olarak gösterilebilir.

Print At 2,0,"P:",@basinc,"hPa"            ' 1 anlamsız
Print At 3,0,"T:",@h,26           'sıcaklık ondalık olarak gösteriliyor.26 derece işareti




DelayMS 1



GoTo yukseklik_hesapla

 
basinc_sicaklik_hesaplama:
topla_h=0
topla_l=0

        For i=0 To 4
        BusOut $ee,$f4,[$2e]            'ultra hasas ölçüm 25 cm
        DelayMS 5
        BusIn $ef,$f6,[msb]
        BusIn $ef,$f7,[lsb]
        
        topla_h=topla_h+msb
        topla_l=topla_l+lsb
       
        Next
topla_h=topla_h/5
topla_l=topla_l/5

topla_h=topla_h<<8

ut=topla_h+topla_l          '8-3 oss 3


'Print At 2,1,Hex ut
'DelayMS 3000
x1=ut-ac6
x1=x1*ac5
x1=x1/32768
b=x1+md
x2=mc*2048
x2=x2/b 'x2 hep negatif


If x1>x2 Then 
b5=x1-x2    'sonuc pozitifdir
b5_pn=1
ut=b5+8 
ut=ut/16

Else
b5=x2-x1    'sonuc negatifdir.
b5_pn=0
ut=b5+8 
ut=ut/16
EndIf
'sicaklk=ut/10



 'GoTo basinc_hesaplama
 
 'basinc_hesaplama:
topla_h=0:topla_l=0:topla_xlsb=0
For i=0 To 4
 BusOut $ee,$f4,[$f4]
 DelayMS 30
 BusIn $ef,$f6,[msb]
 BusIn $ef,$f7,[lsb]
 BusIn $ef,$f8,[xlsb]
topla_h=topla_h+msb
topla_l=topla_l+lsb
topla_xlsb=topla_xlsb+xlsb
Next
topla_h=topla_h/5
topla_l=topla_l/5
topla_xlsb=topla_xlsb/5


topla_h=topla_h<<16
topla_l=topla_l<<8
up=(topla_h+topla_l+topla_xlsb)>>5




'*****************************************************************************

If b5_pn=1 Then               'sıcaklık pozitif,b5 pozitif  
                If b5>4000 Then         'b6=b5-4000
                
                b6=b5-4000    '*********b6 pozitif *************
                b6_pn=1         'b6 pozitif
                Else
                b6=4000-b5      'b6 negatifdir.
                b6_pn=0         'b6 negatifdir.
                 
                EndIf
            Else                'b5 negatifse 
            b6=4000+b5          'b6 negatifdir.b6=-b5-4000 anlamında
           
            EndIf
'******************************************************************************
x1=b6*b6                'x1 her zaman pozitifdir.
x1=x1/4096
x1=x1*b2
x1=x1/2048

'*****************************************************************************
x2=AC2*b6               'ac2 negatif değerlikli x2 b6 ya bağlı p yada n dir.
x2=x2/2048

'******************************************************************************
If b6_pn=0 Then                         'b6 negatif => x2 pozitif
x3=x1+x2
b5_pn=1         'x3 pozitifdir.
                                                                                                                   
Else        'b6 pozitifse => x2 negatifdir.
    If x2>x1 Then
    x3=x2-x1
  
    b5_pn=0
    Else 
    x3=x1-x2

    EndIf
    
   
EndIf

'*****************************************************************************
If b5_pn=0 Then                  'x3 negatif
b3=ac1*4        '******x3 negatif değerliklil
b3=b3-x3
b3=b3<<oss          'oss dikkat
b3=b3+2
b3=b3/4

Else
b3=ac1*4     '******x3 pozitif değerlikli
b3=b3+x3
b3=b3<<oss
b3=b3+2
b3=b3/4

EndIf

'*****************************************************************************


If b6_pn=1 Then 
x1=ac3*b6                      'ac3 negatif ve b6 pozitif olduğu iççin sonuc negatifdir.
x1=x1/8192
b5_pn=0                           'x1 negatif

Else
x1=ac3*b6                      'ac3 ve b6 negatif olduğu iççin sonuc negatifdir.
x1=x1/8192
b5_pn=1                           'x1 pozitif

EndIf
'*****************************************************************************

'burdaki x2 hep pozitif
x2=b6*b6
x2=x2/4096
x2=x2*b1
x2=x2/65536

'*****************************************************************************
If b5_pn=0 Then              'x1 negatif p_n=0 yani sonuc negatif 
x3=x1-x2        'x3 negatif
x3=x3/4


Else
x3=x1+x2        'x3 pozitif
 x3=x3/4

EndIf

'*****************************************************************************
If  b5_pn=0 Then
b4=32768-x3             'x3 negatif olduğundan cıkarılır.  
b4=ac4*b4
b4=b4 /32768


Else
b4=32768+x3
b4=b4*ac4
b4= b4/32768


EndIf

'*****************************************************************************
b7=up-b3
b7=b7*(50000>>oss)         'b7=b7*(50000<<oss) olmalı. oss =0 olduğu için gerek yok

'*****************************************************************************
If b7<$80000000 Then 
up=b7*2
up=up/b4


Else 
up=b7/b4
up=up*2
EndIf
 
 
'*****************************************************************************
x1=up/256
x1=x1*x1
x1=x1*3038
x1=x1/65536


'*****************************************************************************
 
x2=7357*up          'x2 hep neggatif -7357 den dolayı
x2=x2/65536

'******************************************************************************

up=up*16
up=up+x1
up=up+3791
up=up-x2
up=up/16
basinc=up/100
'*****************************************************************************

'GoTo sicaklik
Return
'##################################################################################
'###########################KOK ALMA###############################################
'##################################################################################
'##################################################################################
kok_1:
'basınc değerini 1000 ile genişletiyorum. sonra 1000 in 5,25 dereeceden kökünü alıyorum
'oda 6.44946677 cıkıyor. bu sayı ilede oynuyorum.(genişletiyorum)


bn1=x+2        'x istenen değer
Repeat
gx=bn1  
    GoSub kok_2                  ' gbn1  rastgele bir başlama noktası
    fx=bn1*bn1*bn1*bn1*bn1*gxn1-x  'gx istenen kök değeri
    tfx=(21*bn1*bn1*bn1*bn1*gxn1)/4
    sifirmi1=(fx*10)/tfx
    xn1=bn1-(sifirmi1/10)
    bn1=xn1
    
Until sifirmi1<0.001
bn1=644946.677*bn1      'bn1 sonucu 10^7 cıkarılır . 44330 carp yükseklik bul. 10^7 ye böl sonucu
 Return         'yukseklik hesaplamaya geri don


kok_2:

gbn1=gx+2
Repeat  
                      ' gbn1  rastgele bir başlama noktası
    gfx=gbn1*gbn1*gbn1*gbn1-gx  'gx istenen kök değeri
    gtfx=4*gbn1*gbn1*gbn1
    sifirmi=(gfx*10)/gtfx
    gxn1=gbn1-(sifirmi/10)
    gbn1=gxn1
    
   
Until sifirmi<0.001
Return



Include "font.inc"


mesaj birleştirme:: 15 Aralık 2013, 15:29:59

vakit bulursam gps, gyro, ivmeölçer pusula da ekleyecem. ekranıda tft cevirecem.

Maxim

merhaba teşekkürler
Başlığı proton bölümüne taşıdım zira bu proton kodu, picbasic değil

birde burada ne demek istediniz
biraz kodlar fazla görünebilir oda pic basic ve protonda işaretli sayı olmamasından.

homer380

kusura bakmayın ilk başta picbasic ile yazmıştım kafam ona gitmiş o yüzden picbasic'e açmışım siz diyince fark ettim.
derlenen kelime sayısı fazla onu demek istemiştim.değişken olarak negatif sayı tanımlı değil. o yüzden kendim negatif sayılar için düzenleme yapmak zorunda kalmıştım.

engerex

 Sorun işaretli sayı kullanan açısından olabilir. MikroBasic destekliyor. Yada Proton un destekleyen sürümü var.

Maxim

negatif sayi protonda var.
ayrica gordugum kadariyla kare kok almak icin 55 takla atmissiniz. protonda onun icin hazir komut olmasi lazim.

homer380

#5
negatif sayı için yaptığımda hata veriyordu. verileri önce bilgisayardaki yükseklik ve basınç hesaplaması için kullandığımda pic'in değeri yanlış hesapladığını fark ettim.mecburen değiştirmek zorunda kaldım. Kök işlemi için internette aradım ama bulamadım türkçe kaynak.
virgüllü sayının n. dereceden hangi kod ile kök alınıyor bilmiyorum öğretirseniz iyi olur. a sayısının 2.dereceden karekökü değil, a sayısının 5,255 dereceden kökünü alacak.

z

#6
Eger komut kumesinde log ve 10^x fonksiyonlari varsa herhangi bir dereceden kok alma islemini su sekilde yapabilirsin.

y=x^n olsun.   n burada tam sayi değil.

n.log(x) degerini hesaplarsin. Ardindan y=10^(n.log(x)) den aradigin y degerini bulmus olursun.

log yerine ln, 10^x yerine e^x de kullanabilirsin.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

homer380

anladığım kadarıyla excel'de söyle olması gerekiyor.

istenen kök değeri=10^(A2*(LOG(B2)))               ;a2 kök derecesi, b2 kökü istenen sayı

ama sonuc hatalı cıktı

z

Alıntı yapılan: homer380 - 15 Aralık 2013, 18:10:45
anladığım kadarıyla excel'de söyle olması gerekiyor.

istenen kök değeri=10^(A2*(LOG(B2)))               ;a2 kök derecesi, b2 kökü istenen sayı

ama sonuc hatalı cıktı

a2=5.255 olsun. Mesela sen 3 un 5.255nci dereceden kokunu hesaplayacaksan

10^((1/5.255)*log(3)) den 1.2325 buluruz.

Ilk mesajim dogru da anlam karmasasi olmus. Verdigim hesap kuvvet almayi gosteriyor. Kok alirken 1/kuvvet yapacaktin.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

engerex

Yani Kuvvet(KöküAlınacakSayı, 1/5,255);

homer380

logaritma fonksiyonu var ama 10 ^ x fonksiyonunu bulamadım bi ara buna göre'de düzenlerim.  kısa yöntemler her zaman tercihimdir.

muhittin_kaplan

Bu sensörü bende Aldım. Hala Gelmedi. geldiğinde STM ile Çalışma Yapacağım.
Bu Çalışma iyi oldu benim için.
Kolay Gelsin.

Maxim

#12
ben önemli bir detayı atlamışım
protondaki matematik fonksiyonları 18F serisi işlemcilerde çalışıyor
16F877A da çoğu çalışmayacaktır

mesaj birleştirme:: 16 Aralık 2013, 09:06:37

bir soru
bu sensörün işe yaraması için başlangıçtaki örneği alıp tutmamızmı lazım doğrumu anlamışım?
mesela bir dağa çıkıcaz,
aşağıda devreyi çalıştırdık ve yukarıya çıktıkça bilgi doğrulanacak?
yukarıda devreyi çalıştırırsak bir işe yaramazmı ?

X-Fi

maxim hocam sensör içerisine üretici kalibrasyon verilerini gömüyor. bu veriler her sensör için değişir bir kereye mahsus okuyup işlemlerde kullanıyorsunuz. böylece her zaman doğru değerlerde ölçüm yapıyorsunuz. bunun dışında bir kalibrasyon yok.
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)