BMP085 bir türlü tutturamıyorum.

Başlatan omereliusuk, 23 Ağustos 2013, 19:13:02

omereliusuk

bulunduğumuz yerin yüksekliği 1034m.
bmp085 ile ben bir türlü bu değeri tutturamıyorum.
sıcaklık arttıkça bizim rakım alıp başını gidiyor(en son ölçümüm 1056m).
bir de ölçüm değerini milibar olarak almam lazım ingilizcemiz malum kötü olunca neyin ne olduğu tam anlaşılamıyor.
daha sonra bu yazı düzenlenir tekrardan ya neyse...:(((

homer380

hangi yükseklik formulunu kullanıyorsunuz.

omereliusuk

#2
//************************************************ 
//  BMP085 Barometric Pressure Sensor 
// 
//  - Datasheet: http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf 
// 
//  - Written in CCS PCH C using floating point math 
//  - Several integer math versions of this driver exist but the speed improvement is 
//    not warranted in typical weather station type applications 
//  
//  - Based on a paper posted to thebackshed.com by DuinoMiteMegaAn 
//    http://www.thebackshed.com/forum/forum_posts.asp?TID=4768&PN=9  
// 
//  - Usage: 
//     Call once: bmp085Calibration(); 
//     P_mBar_float = BMP085Pressure(true);  //  calls for temperature first 
//     P_mBar_float = BMP085Pressure(false);  // skips temperature reading, assumes done previously 
//     T_Cent_float = BMP085Temperature(); 
//     t_reading = _Temp;  _Temp set on every temperature reading 
//        Note:   pressure reading is temp compensated so call for temp reading prior to pressure reading periodically or on each reading 
// 

//    Revision - integer algotihm 
//    Fatih GENC 
//    07/30/2013 
// 
//  Al Testani 
//  08/17/12 
//************************************************ 

// place a #use i2c statement in the main program and comment this out if not applicable 
//#use i2c(MASTER, fast=400000, I2C1, RESTART_WDT) 
int32 UP;
#include <math.h> 
#ifndef OVS_S
#define  OVS_S  3 // Oversampling Setting (0,1,2,3 from ultra low power, to ultra hi-resolution) 
#endif
#define BMP085_ADDRESS 0xEE          // I2C address of BMP085 
// Calibration values 
static signed int32 ac1; 
static signed int16 ac2; 
static signed int16 ac3; 
static int16 ac4; 
static int16 ac5; 
static int16 ac6; 
static signed int16 b1; 
static signed int16 b2; 
static signed int16 mb; 
static signed int16 mc; 
static signed int16 md; 


static float b5; 

static float _Temp;  // set after every temperature or temperature/pressure reading 


//---------------------------------------------- 
int8 BMP085ReadByte(int8 address) 
//---------------------------------------------- 
{ 
int8 data; 

   i2c_start(bir); 
   i2c_write(bir,BMP085_ADDRESS); 
   i2c_write(bir,address); 
   i2c_start(bir); 
   i2c_write(bir,BMP085_ADDRESS | 0x01 ); 
   data=i2c_read(bir,0); 
   i2c_stop(bir); 
   return(data); 
} 


//---------------------------------------------- 
int16 BMP085ReadInt(int8 address) 
//---------------------------------------------- 
{ 
int8 msb, lsb; 
int16 temp; 

   i2c_start(bir); 
   i2c_write(bir,BMP085_ADDRESS); 
   i2c_write(bir,address); 
/*#ifdef eoc 
//i2c_stop(bir);
 //  while(!input(eoc_pin));
#endif*/
   i2c_start(bir); 
   i2c_write(bir,BMP085_ADDRESS | 0x01 ); 
   msb = i2c_read(bir,1); 
   lsb = i2c_read(bir,0); 
   i2c_stop(bir); 
   temp = make16(msb, lsb); 
   return ( temp ); 
} 


//---------------------------------------------- 
void BMP085WriteByte(int8 address, int8 data) 
//---------------------------------------------- 
{ 
   i2c_start(bir); 
   i2c_write(bir,BMP085_ADDRESS); 
   i2c_write(bir,address); 
   i2c_write(bir,data); 
   i2c_stop(bir); 
} 


//---------------------------------------------- 
void bmp085Calibration() 
//---------------------------------------------- 
{ 
   // read BMP085 EEPROM cal factors 
   ac1 = bmp085ReadInt(0xAA); //read wrong value 
   ac2 = bmp085ReadInt(0xAC); 
   ac3 = bmp085ReadInt(0xAE); 
   ac4 = bmp085ReadInt(0xB0); 
   ac5 = bmp085ReadInt(0xB2); 
   ac6 = bmp085ReadInt(0xB4); 
   b1  = bmp085ReadInt(0xB6); 
   b2  = bmp085ReadInt(0xB8); 
   mb  = bmp085ReadInt(0xBA); 
   mc  = bmp085ReadInt(0xBC); 
   md  = bmp085ReadInt(0xBE); 
   ac1 = bmp085ReadInt(0xAA); // read ac1 again. comes true value this time 
    
   //fprintf(debug,"b1:%5Ld,b2:%5Ld,ac1:%5Ld,ac2:%5Ld,ac3:%5Ld,ac4:%5Ld,ac5:%5Ld,ac6:%5Ld,\r\n",b1,b2,ac1,ac2,ac3,ac4,ac5,ac6); 
   //fprintf(debug,"mb:%5Ld,mc:%5Ld,md:%5Ld\r\n",mb,mc,md); 

  
} 


// Read the uncompensated temperature value 
//---------------------------------------------- 
int16 BMP085ReadUT() 
//---------------------------------------------- 
{ 
int16 ut; 
  
  // Write 0x2E into Register 0xF4 
  BMP085WriteByte(0xF4, 0x2E); 
 // delay_ms(5); // Wait at least 4.5ms 
 // Read two bytes from registers 0xF6 and 0xF7 
  ut = BMP085ReadInt(0xF6); 
  
  
  
  return(ut); 
} 


// Read the uncompensated pressure value 
//---------------------------------------------- 
int32 bmp085ReadUP() 
//---------------------------------------------- 
{ 
int8 msb, lsb, xlsb; 
//int32 UP;  
  // Write 0x34+(OSS<<6) into register 0xF4 
  // Request a pressure reading w/ oversampling setting 
  BMP085WriteByte(0xF4, 0x34+(OVS_S<<6) ); 
  
  switch (OVS_S) 
  { 
     case 0: delay_ms(5);  break; 
     case 1: delay_ms(8);  break; 
     case 2: delay_ms(14); break; 
     case 3: delay_ms(26); break; 
  }  
      
      i2c_start(bir); 
      i2c_write(bir,BMP085_ADDRESS); 
      i2c_write(bir,0xF6); 
      
      i2c_start(bir); 
      i2c_write(bir,BMP085_ADDRESS | 0x01); 
      
      // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB) 
      
      msb = i2c_read(bir,1); 
      lsb = i2c_read(bir,1); 
      xlsb = i2c_read(bir,0); // NACK on last read 
      i2c_stop(bir); //*/ 
      
      UP = make32(0,msb,lsb,xlsb); 
      UP >>=(8-OVS_S); 
      

    //fprintf(debug,"UP:%5Lu,msb: %02x,lsb: %02x,xlsb: %02x\r\n",UP,msb,lsb,xlsb); 
    
   return(UP); 
} 


//---------------------------------------------- 
signed int32 BMP085GetTemp(signed int32 ut) 
//---------------------------------------------- 
{ 
signed int32 X1,X2, T; 
    
   X1 = (ut - ac6)* ac5 / 32768; 
   X2 = mc; 
   X2 *= 2048; 
   X2 /= (X1 + md); 
    
   b5 = X1+X2; 
    
   T = (b5+8)/16; 
    
   //fprintf(debug,"X1:%5Ld,X2:%5Ld,mc:%5Ld,md:%5Ld,ut:%5Ld\r\n",X1,X2,mc,md,ut); 
    
   return(T); 
}    


//---------------------------------------------- 
int32 BMP085GetPressure(signed int32 up) 
//---------------------------------------------- 
{ 
signed int32 B3,B6,X1,X2,X3,a; 
signed int32 P; 
int32 B4,B7,P2; 
    
   switch (OVS_S) 
  { 
     case 0: a=1;  break; 
     case 1: a=2;  break; 
     case 2: a=4; break; 
     case 3: a=8; break; 
  }  
    
   //CCS C gives wrong values when shifting bits in signed integers 
   //so, we need arithmetic operation for signed integer variables 
    
   B6 = (signed int32)b5-4000; 
   X1 = ((B6*B6)/4096)*b2/2048; 
   X2 = B6*ac2 / 2048; 
   X3 = X1 + X2; 
   B3 = ((X3 +(ac1*4))*a + 2)/4; // sint32 
    
   //fprintf(debug,"UP:%5Ld,X1:%5Ld,X2:%5Ld,X3:%5Ld,b5:%5Ld,B3:%5Ld,B6:%5Ld,\r\n",up,X1,X2,X3,(signed int32)b5,B3,B6); 
    
    
    
   X1 = (ac3)*B6/8192; 
   X2 = ((B6*B6)/4096)*b1/65536; 
   X3 = (X1 + X2 + 2) / 4; 
   B4 = (int32)(X3+32768)*(ac4)/32768; 
    
   B7 = (int32)(up-B3); 
    
   B7 *=50000>>OVS_S; //unsigned 
    
   //fprintf(debug,"X1:%5Ld,X2:%5Ld,X3:%5Ld,B4:%5Lu,B7:%5Lu,\r\n",X1,X2,X3,B4,B7); 
   //fprintf(debug,"b1:%5Ld,b2:%5Ld,ac1:%5Ld,ac2:%5Ld,ac3:%5Ld,ac4:%5Ld,\r\n",b1,b2,ac1,ac2,ac3,ac4); 

   P2 =(b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2);// (B7/B4)<<1; //unsigned 

    
   X1 = (P2>>8)*(P2>>8); //unsigned 
   X1 = (X1*3038)>>16;   //unsigned 
   P=P2; 
   X2 = (-7357*P)/65536; 
    
   //fprintf(debug,"X1:%5Ld,X2:%5Ld,p:%5Lu,\r\n",X1,X2,P2); 
    
   P = P + (X1+X2+3791)/16; 
    
   return(P); 
} 


//---------------------------------------------- 
float BMP085Pressure(boolean getTemp) 
//---------------------------------------------- 
{ 
   if (getTemp) 
      _Temp = BMP085GetTemp(BMP085ReadUT());  
   return(BMP085GetPressure(BMP085ReadUP())); 
} 


//---------------------------------------------- 
float BMP085Temperature(void) 
//---------------------------------------------- 
{ 
   _Temp = BMP085GetTemp(BMP085ReadUT()); 
   return(_Temp); 
}


metre= altitude = (float)44330 * (1 - pow(((float) basinc_dereceli/p0), 0.190295));

formül burada:)

mistek

Alıntı yapılan: omereliusuk - 23 Ağustos 2013, 19:13:02
bulunduğumuz yerin yüksekliği 1034m.
bmp085 ile ben bir türlü bu değeri tutturamıyorum.
sıcaklık arttıkça bizim rakım alıp başını gidiyor(en son ölçümüm 1056m).
bir de ölçüm değerini milibar olarak almam lazım ingilizcemiz malum kötü olunca neyin ne olduğu tam anlaşılamıyor.
daha sonra bu yazı düzenlenir tekrardan ya neyse...:(((

Ölçümü açık havadamı yapıyorsunuz ?
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

omereliusuk

açık hava değil. pencere açık ama bu bir şey değiştirir mi. malum çok da fazla değişim olmaması gerekir diye düşünüyorum.

homer380

#5
css den cok anlamam ama yükseklik formulu doğru bende uğraşmıştım bmp085 ile picbasic'de üst alma işi olmadığı için n dereceden kök alıyordum sıkıntı  olmuyordu.siz nerenin yüksekliğini ölçüyorsunuz yani yükseklik değeri kesin mi ? anladığım kadarıyla 1034 rakım değeri.( rüzgar etki ediyor basınca onun için rüzgardan korumanız gerekli senserü  )

mesaj birleştirme:: 23 Ağustos 2013, 21:49:59

https://disk.yandex.com.tr/public/?hash=ZKg7i2NS0PBC%2BHgdWqd3ks3Mtz8SqfYyEGarinIvCgc%3D excelde kendim için oluşturduğum yükseklik hesaplama var ölçtüğünüz basınc değerini girip hata nerde ise bulabilirsiniz.

mistek

BMP085 ile bende çalıştım doğru değerler alıyordum.

Formül:
float altitude(float pressure)
{
float A = pressure/101325;
float B = 1/5.25588;
float C = pow(A,B);
C = 1 - C;
C = C /0.0000225577;

return C;
}


Mesela bir noktayı referans alın ölçün sonrasında 1 metre yukarı kaldırın tekrar ölçün.

Ben kapalı ortamda çok fazla bi değişim görmemiştim ancak açık havada sonuçlar istediğim gibiydi. Rüzgarı engelleyin tabi ki.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

alper06

#7
Şimdi hocam ortam basıncını ölçerek irtifa ölçmek çok hassas olmayacaktır.
Çünkü gün içerisinde hava basıncı sürekli değişmektedir.
Hassas ölçüm, hava şartlarından etkilenmeyen ölçüm istiyorsan gps kullanmalısın.

Yada şöyle bir deneme yapabilirisin.
Şu an Konya' dasın galiba.
Konya Havalimanı için her 30 dakikada METAR denilen hava tahmin raporları yayınlanır.
Bu raporarın içerisinde meydanın deniz seviyesine indirgenmiş hava basınçları milibar cinsinden
QNH başlığı ile verilir. İnişteki uçaklar altimetrelerine bu QNH değerini girerler.
Uçak piste teker koyduğuna altimetre aşağı yukarı tam meydan irtifasını gösterir.

Sen kendi ölçümlerin ile konya meydanının QNH değerlerini karşılaştırabilirisn.
Yalnız QNH değeri deniz seviyesine indirgenmiştir değerlerdir.
Konya meydanı irtifası 3392 feet.
Her 27 feet 1 milibar eder.
QNH değerinden 3392/27  değeri kadar düşük değer ölçmeyi beklemelisin...

Konya meydanının kodu LTAN dır.
Metar raporlarına buradan ulaşabilirsin.

http://aviationweather.gov/adds/metars/?station_ids=ltan&std_trans=standard&chk_metars=on&hoursStr=most+recent+only&submitmet=Submit

şu an Q1013

omereliusuk

#8
aslında amacım yükselti ölçmek değildi. ama bu da hesaplanabiliyorsa neden olmasın dedim. asıl amacım bulunduğu yerdeki havanın basıncını milibar olarak ölçebilmek. fakat bu da sıkıntı. Pa=Paskal (hektopaskal-->milibar) ise kolay dedim bir de sıcaklık verileri bir türlü santigrat olarak tutturamıyorum.
işin garip tarafı ben bu çipte bir türlü net rakamlar ile buluşamıyorum.

@mistek verdiğiniz formül ile benim kullandığım formül aynı sonuçları veriyor. eğer ölçtüğünüz değerler kesinlikle doğru ise bunu doğru olarak değerlendirmek istiyorum.

mistek

Alıntı yapılan: omereliusuk - 24 Ağustos 2013, 00:43:52
@mistek verdiğiniz formül ile benim kullandığım formül aynı sonuçları veriyor. eğer ölçtüğünüz değerler kesinlikle doğru ise bunu doğru olarak değerlendirmek istiyorum.

Ben değeri bilinen noktalarda ölçüm yaptım 1 metre farkla hep aynı sonuçları aldım.
Ancak sensörden gelen değerler sabit olmadığı için 20 örnek ortalama almıştım.

http://bildr.org/2011/06/bmp085-arduino/
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R