STM32 ile BMP180 Basınç Sensörü Sorunları

Başlatan Rasim GÖKMEN, 11 Aralık 2020, 03:35:48

Rasim GÖKMEN

Merhaba değerli forum sakinleri,
Stm32f4 discovery kartımla I2C protokolünü öğrenmek üzere projeler yapıyorum. Geçenlerde BMP180 basınç sensörünü kullanmaya çalıştım. Haberleşmemi bir yandan lojik analizörle dinliyor, iletişimde bir hata olup olmadığına bakıyorum. Yazdığım I2C kütüphanesi çalışıyor hiç bir hata yok veri doğru bir şekilde gidip geliyor fakat basınç değeri yanlış hesaplanıyor. Amacım basınç değerinden deniz seviyesine göre yükseklik bulmak. Yükseklik bulma formülü doğru çalışıyor ancak basınç değeri yanlış olduğu için doğru değil tabii. Aşağıya yazmış olduğum kodları atıyorum. I2C ve delay için kurduğum timer doğru çalıştığı için onların konfigurasyonunu atmayacağım.


main fonksiyonu bu şekilde:
int main(void){

	
CLK_Config();
	
GPIO_Config();
	
I2C1_Config();
	
TIM14_Config();

	
int16_t calib_data[11];
	
long temp_data;
	
long pressure_data;
	
long altitude;

	
bmp_get_calib(&calib_data);
	
bmp_calc(&calib_data3, &temp_data, &pressure_data, &altitude);


	
while (
1)
	
{

	
}
}

Bmp180 C dosyası:

#include "Bmp180.h"
#include "math.h"

void bmp_get_calib(int16_t *data){

	
uint8_t calib_val[22];

	
multi_byte_read(bmp_addrbmp_calib, &calib_val22);

	
int16_t AC1  = (calib_val[0]<<8)  + calib_val[1];
	
int16_t AC2  = (calib_val[2]<<8)  + calib_val[3];
	
int16_t AC3  = (calib_val[4]<<8)  + calib_val[5];
	
int16_t AC4  = (calib_val[6]<<8)  + calib_val[7];
	
int16_t AC5  = (calib_val[8]<<8)  + calib_val[9];
	
int16_t AC6  = (calib_val[10]<<8) + calib_val[11];
	
int16_t B1   = (calib_val[12]<<8) + calib_val[13];
	
int16_t B2   = (calib_val[14]<<8) + calib_val[15];
	
int16_t MB   = (calib_val[16]<<8) + calib_val[17];
	
int16_t MC   = (calib_val[18]<<8) + calib_val[19];
	
int16_t MD   = (calib_val[20]<<8) + calib_val[21];

	
data[0]  = AC1;
	
data[1]  = AC2;
	
data[2]  = AC3;
	
data[3]  = AC4;
	
data[4]  = AC5;
	
data[5]  = AC6;
	
data[6]  = B1;
	
data[7]  = B2;
	
data[8]  = MB;
	
data[9]  = MC;
	
data[10] = MD;
}

void bmp_calc(int16_t *calib_datauint8_t osslong *temp_datalong *pressure_datalong *altitude){

	
uint8_t raw_temp_data[2];
	
	
	
	
	
	
	
	
	
	
//raw temp data
	
uint8_t raw_pressure_data[3];
	
	
	
	
	
	
	
	
	
//raw pressure data
	
long pre_pressure_data;
	
float sea_level_press 1013.25;

	
write_byte(bmp_addrbmp_configbmp_config_temp);
	
	
	
	
//setup reading for temp
	
delay_us(5);
	
	
	
	
	
	
	
	
	
	
	
	
	
//wait 4.5ms

	
multi_byte_read(bmp_addrbmp_out_msb, &raw_temp_data2);
	
	
//reading temp values
	
long UT = ((raw_temp_data[0]<<8) + raw_temp_data[1]); 
	
	
	
//converting UT val

	
switch (
oss) {
	
	
	
	
	
	
	
	
	
	
	
	
	
//switch case depended by over sampling settings
	
	
case 
0:
	
	
	
write_byte(bmp_addrbmp_configbmp_config_pres0);
	
	
//ultra low power mode and setup for pressure
	
	
	
delay_us(5);
	
	
	
break;
	
	
case 
1:
	
	
	
write_byte(bmp_addrbmp_configbmp_config_pres1);
	
	
//standard mode and setup for pressure
	
	
	
delay_us(8);
	
	
	
break;
	
	
case 
2:
	
	
	
write_byte(bmp_addrbmp_configbmp_config_pres2);
	
	
//high resolution mode and setup for pressure
	
	
	
delay_us(15);
	
	
	
break;
	
	
case 
3:
	
	
	
write_byte(bmp_addrbmp_configbmp_config_pres3);
	
	
//ultra high resolution mode and setup for pressure
	
	
	
delay_us(30);
	
	
	
break;
	
	
default:
	
	
	
while(
1);
	
	
	
break;
	
}

	
multi_byte_read(bmp_addrbmp_out_msb, &raw_pressure_data3);
	
//reading raw pressure values
	
long UP = ((raw_pressure_data[0]<<16) + (raw_pressure_data[1]<<8) + (raw_pressure_data[2])) >> (8-oss);
	
//converting raw to UP val

	
long X1 = (UT-(uint16_t)calib_data[5]) * (uint16_t)calib_data[4]/pow(2,15);
	
//
	
long X2 calib_data[9] * pow(2,11) / (X1 calib_data[10]);
	
	
	
	
//
	
	
All 4 lines for calculating true temperature value
	
long B5 X1 X2;
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
//
	
*
temp_data = (B5 8) / pow(2,4);
	
	
	
	
	
	
	
	
	
	
	
//

	
long B6 B5 4000;
	
	
	
	
	
	
	
	
	
	
	
	
	
	
//
	
X1 = (calib_data[7] * (B6 B6 pow(2,12))) / pow(2,11); 
	
	
	
	
	
//
	
X2 calib_data[1] * B6 pow(2,11);
	
	
	
	
	
	
	
	
	
	
//
	
long X3 X1 X2;
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
//
	
long B3 = (((calib_data[0] * X3) << oss) + 2) / 4;
	
	
	
	
	
	
//
	
X1 calib_data[2] * B6 pow(2,13);
	
	
	
	
	
	
	
	
	
	
//
	
X2 = (calib_data[6] * (B6 B6 pow(2,12))) / pow(2,16);
	
	
	
	
	
//
	
X3 = ((X1 X2) + 2) / pow(2,2);
	
	
	
	
	
	
	
	
	
	
	
//
	
unsigned long B4 = (uint16_t)calib_data[3] * (unsigned long)(X3 32768) / pow(2,15);
	
//
	
unsigned long B7 = ((unsigned longUP B3) * (50000 >> oss);
	
	
	
	
//
	
	
All those lines for calculating true pressure value
	
if(
B7 0x80000000){
	
	
	
	
	
	
	
	
	
	
	
	
	
	
//
	
	
pre_pressure_data = (B7 2) / B4;
	
	
	
	
	
	
	
	
	
	
//
	
}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
//
	
else{
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
//
	
	
pre_pressure_data = (B7 B4) * 2;
	
	
	
	
	
	
	
	
	
	
//
	
}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
//
	
X1 = (pre_pressure_data pow(2,8)) * (pre_pressure_data pow(2,8));
	
	
//
	
X1 = (X1 3038) / pow(2,16);
	
	
	
	
	
	
	
	
	
	
	
	
//
	
X2 = (-7357 pre_pressure_data) / pow(2,16);
	
	
	
	
	
	
	
	
//
	
pre_pressure_data pre_pressure_data + (X1 X2 3791) / pow(2,4);
	
	
//

	
*
pressure_data pre_pressure_data;
	
	
	
	
	
	
	
	
	
	
	
//pressure in Pa

	
*
altitude 44330 * (1-pow(((pre_pressure_data/100) / sea_level_press),5.255));

}

Bmp180 H dosyası

#include "stm32f4xx.h"

#define bmp_addr
	
 0xEE
	
//Bmp180 device address without Read Bit

#define bmp_out_xlsb 0xF8
	
//This bit field using by 19 bit pressure measurement
#define bmp_out_lsb  0xF7
	
//This bit field using by temperature and pressure measurement
#define bmp_out_msb  0xF6
	
//This bit field using by temperature and pressure measurement

#define bmp_config   0xF4
	
//This bit field used for configure Bmp180

#define bmp_soft_rst 0xE0
	
//This bit field used for software reset to Bmp180 write to 0xB6

#define bmp_id
	
	
 0xD0
	
//This bit field contains Bmp180 id

#define bmp_calib    0xAA
	
//This bit field going until address reach 0xBF and contains calibration value

#define bmp_config_temp 0x2E
#define bmp_config_pres0 0x34
#define bmp_config_pres1 0x74
#define bmp_config_pres2 0xB4
#define bmp_config_pres3 0xF4

void bmp_get_calib(int16_t *data);
void bmp_calc(int16_t *calib_datauint8_t osslong *temp_datalong *pressure_datalong *altitude);

Bu resim ise ham sıcaklık ve basınç değerlerinin nasıl doğru değerlere çevrilmesi gerektiğini gösteriyor. Doğru basınç hesaplama son kutucukta anlatılıyor. Şimdiden herkese teşekkürler.


Yasal Uyarı: Picproje.org sitemizde 5651 sayılı kanunun 8. maddesine ve T.C.Knın 125. maddesine göre tüm üyelerimiz yaptıkları paylaşımlardan kendileri sorumludur. Picproje.org hakkında yapılacak tüm hukuksal şikayetleri İletişim sayfamızdan bize bildirdikten en geç 3 (üç) iş günü içerisinde ilgili kanunlar ve yönetmelikler çerçevesinde tarafımızca incelenerek gereken işlemler yapılacak ve site yöneticilerimiz tarafından bilgi verilecektir.