Shop OBEX P1 Docs P2 Docs Learn Events
BMP 180 Pressure sensor I²C on Propeller, strange behavior — Parallax Forums

BMP 180 Pressure sensor I²C on Propeller, strange behavior

saulosaulo Posts: 2
edited 2015-01-15 10:18 in Accessories
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.

photo-01.jpg


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

terminal.gif


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
800 x 623 - 119K
742 x 725 - 47K

Comments

  • saulosaulo Posts: 2
    edited 2015-01-15 10:18
    jazzed wrote: »
    Are you sure that a line like this is actually passing a buffer with the value to the driver (the driver expects a buffer) ?

    i2c_out(boosterpack, BMP , 0xE0 , 1, (char *) 0xB6 , 1); // Reset!

    Seems to me that you are telling the driver to use the buffer at address 0xB6.

    hmm, ok i got it!

    an i do the same on the others i2c_out() too! What a silly mistake... thank you jazzed!
Sign In or Register to comment.