BMP 180 Pressure sensor I²C on Propeller, strange behavior
saulo
Posts: 2
Hi there!
I have the TivaC Launchpad and the Sensorhub Boosterpack working fine. I dont knew nothing about the propeller and the multicore feature really impressed me! The lack of power was the main reason to choose a ARM to my project at first time instead a 8bit controller, like the msp430. So i bought a activity board and start to code something in C .
The sensorhub has a i²c bus with several sensors hooked up. Using the example of accessing the eeprom memory, i start to read the BMP180 pressure sensor in the sensorhub.
I'm using some hobo datalogger has reference value to check consistences.
I can read the device ID constant value correctly (0x55), but when i try to read temperature and pressure, something happens that i can't read nothing feasible..
read a temperature using the Pressure oss0 (0x34) value on the measurement register (0xF4), the uncompensated value of pressure are always the double of temperature sensor..
Really don't understand why this is happening, can someone give me some hint? I see that spin is the most popular language for propeller but i really want to stay in C, just to make my code better to port between mcu's.
My code:
Already check the math with the datasheet example, according with the schematic of sensorhub, there is not a external pull-up resistors, but changing this on i2c_newbus() function dont affect nothing.
Best regards,
Saulo Barbosa
I have the TivaC Launchpad and the Sensorhub Boosterpack working fine. I dont knew nothing about the propeller and the multicore feature really impressed me! The lack of power was the main reason to choose a ARM to my project at first time instead a 8bit controller, like the msp430. So i bought a activity board and start to code something in C .
The sensorhub has a i²c bus with several sensors hooked up. Using the example of accessing the eeprom memory, i start to read the BMP180 pressure sensor in the sensorhub.
I'm using some hobo datalogger has reference value to check consistences.
I can read the device ID constant value correctly (0x55), but when i try to read temperature and pressure, something happens that i can't read nothing feasible..
read a temperature using the Pressure oss0 (0x34) value on the measurement register (0xF4), the uncompensated value of pressure are always the double of temperature sensor..
Really don't understand why this is happening, can someone give me some hint? I see that spin is the most popular language for propeller but i really want to stay in C, just to make my code better to port between mcu's.
My code:
#include "string.h" #include "simpletools.h" // Include simpletools header #include "math.h" //Activity Board to Sensorhub Boosterpack // GND ------------> J2.1 // Pin 14 (CLK) ---> J2.6 // Pin 15 (SDA) ---> J2.7 // 3.3v -----------> J1.1 i2c *boosterpack; // I2C bus ID const int BMP = 0x77; // BMP180 address const int BMP_meas = 0xF4; // Measurement control register address const int BMP_buffer = 0xF6; // Buffer address const int BMP_temp = 0x2E; // Control register to read temperature const int BMP_oss0 = 0x34; // Control register to read pressure with Oversampling=0 (Low Power) const int BMP_oss1 = 0x74; // Control register to read pressure with Oversampling=1 (Standard) const int BMP_oss2 = 0xB4; // Control register to read pressure with Oversampling=2 (High resolution) const int BMP_oss3 = 0xF4; // Control register to read pressure with Oversampling=3 (Ultra High resolution) int OSS; short AC1, AC2, AC3, B1, B2, MB, MC, MD; // Calibration Constants (nenhuma pode dar 0 ou xffff)! unsigned short AC4, AC5, AC6; // Calibration Constants (nenhuma pode dar 0 ou xffff)! long X1, X2, X3, B3, B5, B6; unsigned long B4, B7; float T,P,Altitude; long bmp_pressao(long UP); //Read pressure long bmp_temperatura(long UT); //Read Temperature void bmp_calibracao(void); // Read calibration coef int main() // Main function { char buffer16[]={0,0}, buffer19[]={0,0,0}; long UT,UP; char BMP_ID[]={0}; int i=0; boosterpack = i2c_newbus(14, 15, 0); // Set up I2C bus, get bus ID (pin CLK, pin SDA, Driver (pull-up or not) i2c_out(boosterpack, BMP , 0xE0 , 1, (char *) 0xB6 , 1); // Reset! pause(100); i2c_in(boosterpack, BMP,0xD0,1,&BMP_ID[0],1); print("Device ID = 0x%x\n",BMP_ID[0]); bmp_calibracao(); // Function to read the calibration constants while(1){ //Temperature OSS=0; i2c_out(boosterpack, BMP , BMP_meas , 1,(char *) BMP_oss0 , 1); pause(5); i2c_in(boosterpack, BMP , BMP_buffer , 1 , &buffer16[0] , 1); i2c_in(boosterpack, BMP , BMP_buffer+1 , 1 , &buffer16[1] , 1); UT=(buffer16[0]<<8)|buffer16[1]; T=bmp_temperatura(UT); buffer16[0]=0; buffer16[1]=0; //Pressure OSS=1; // Oversampling used i2c_out(boosterpack, BMP , BMP_meas , 1, (char *) BMP_oss1 , 1); pause(26); i2c_in(boosterpack, BMP , BMP_buffer , 1 , &buffer19[0] , 1); i2c_in(boosterpack, BMP , BMP_buffer+1 , 1 , &buffer19[1] , 1); i2c_in(boosterpack, BMP , BMP_buffer+2 , 1 , &buffer19[2] , 1); UP=(buffer19[0]<<16|buffer19[1]<<8|buffer19[2])>>(8-OSS); P=bmp_pressao(UP); buffer19[0]=0; buffer19[1]=0; buffer19[2]=0; Altitude = 44330*(1-pow((P/(1013.25*100)),(0.19029496))); // Altitude Calculation print("UT= %d, UP = %d, T = %2.1f C, %4.2f hPa, %3.2f m\n",UT, UP, T/10,P/100, Altitude); pause(15); i=i+1; if(i>50){ // Reset after 50 readings i2c_out(boosterpack, BMP , 0xE0 , 1, (char *) 0xB6 , 1); pause(50); i=1; i2c_in(boosterpack,BMP,0xD0,1,&BMP_ID[0],1); print("Resetado, ID = 0x%x\n",BMP_ID[0]); } } } long bmp_temperatura(long UT){ X1 = ((UT-AC6)*AC5) >> 15; X2 = (MC << 11)/(X1+MD); B5 = X1+X2; T = (B5+8) >> 4; return(T); } long bmp_pressao(long UP){ long P; B6 = B5-4000; X1 = (B2 * (B6 * B6 >> 12 ) ) >> 11; X2 = (AC2 * B6 ) >> 11 ; X3 = X1+X2; B3 = (((AC1*4+X3) << OSS)+2)/4; X1 = ( AC3 * B6 ) >> 13; X2 = (B1 * (B6 * B6 >> 12)) >> 16; X3 = ((X1 + X2 ) + 2) >> 2; B4 = AC4*(unsigned long)( ( X3 + 32768) >> 15 ); B7 = ((unsigned long)UP - B3 )*(50000 >> OSS); if(B7<0x80000000){P=(B7 * 2)/B4;}else{P=( B7 / B4 ) * 2;} X1 = (P >>8) * (P >> 8); X1 = (X1 * 3038) >> 16; X2 = (-7357 * P) >> 16; P = P + ( ( X1 + X2 + 3791) >> 4 ); return(P); } void bmp_calibracao(void){ char buffer16[]={0,0}; i2c_in(boosterpack, BMP, 0xAA, 1,&buffer16[0], 1); i2c_in(boosterpack, BMP, 0xAB, 1,&buffer16[1], 1); AC1=(buffer16[0]<<8)+buffer16[1]; i2c_in(boosterpack, BMP, 0xAC, 1,&buffer16[0], 1); i2c_in(boosterpack, BMP, 0xAD, 1,&buffer16[1], 1); AC2=(buffer16[0]<<8)+buffer16[1]; i2c_in(boosterpack, BMP, 0xAE, 1,&buffer16[0], 1); i2c_in(boosterpack, BMP, 0xAF, 1,&buffer16[1], 1); AC3=(buffer16[0]<<8)+buffer16[1]; i2c_in(boosterpack, BMP, 0xB0, 1,&buffer16[0], 1); i2c_in(boosterpack, BMP, 0xB1, 1,&buffer16[1], 1); AC4=(buffer16[0]<<8)+buffer16[1]; i2c_in(boosterpack, BMP, 0xB2, 1,&buffer16[0], 1); i2c_in(boosterpack, BMP, 0xB3, 1,&buffer16[1], 1); AC5=(buffer16[0]<<8)+buffer16[1]; i2c_in(boosterpack, BMP, 0xB4, 1,&buffer16[0], 1); i2c_in(boosterpack, BMP, 0xB5, 1,&buffer16[1], 1); AC6=(buffer16[0]<<8)+buffer16[1]; i2c_in(boosterpack, BMP, 0xB6, 1,&buffer16[0], 1); i2c_in(boosterpack, BMP, 0xB7, 1,&buffer16[1], 1); B1=(buffer16[0]<<8)+buffer16[1]; i2c_in(boosterpack, BMP, 0xB8, 1,&buffer16[0], 1); i2c_in(boosterpack, BMP, 0xB9, 1,&buffer16[1], 1); B2=(buffer16[0]<<8)+buffer16[1]; i2c_in(boosterpack, BMP, 0xBA, 1,&buffer16[0], 1); i2c_in(boosterpack, BMP, 0xBB, 1,&buffer16[1], 1); MB=(buffer16[0]<<8)+buffer16[1]; i2c_in(boosterpack, BMP, 0xBC, 1,&buffer16[0], 1); i2c_in(boosterpack, BMP, 0xBD, 1,&buffer16[1], 1); MC=(buffer16[0]<<8)+buffer16[1]; i2c_in(boosterpack, BMP, 0xBE, 1,&buffer16[0], 1); i2c_in(boosterpack, BMP, 0xBF, 1,&buffer16[1], 1); MD=(buffer16[0]<<8)+buffer16[1]; }
Already check the math with the datasheet example, according with the schematic of sensorhub, there is not a external pull-up resistors, but changing this on i2c_newbus() function dont affect nothing.
Best regards,
Saulo Barbosa
Comments
hmm, ok i got it!
an i do the same on the others i2c_out() too! What a silly mistake... thank you jazzed!