Anyone used the Bosch BMP085 I2C baro sensor yet ?


Closed Thread
Results 1 to 40 of 52

Hybrid View

  1. #1


    Did you find this post helpful? Yes | No

    Default LONGs with the Bosch sensor

    I have read the Bosch datasheet which is very similar to the Intersema MS5540 family. With the exception of absolute altitude, LONGs and a PIC18F part will handle those formulae easily.

    The mathematical gymnastics of handling the Bosch 19 bit variables with 16 bit PBP will consume much code space thus ruling out the 12F series. You will get it into a 16F part on code space grounds but you will have to invent your own way to extend WORD variables up to 19 bits. Why bother?

    The 18F series costs hardly any more, at least at hobby volumes, so cut your losses and go for a PIC18F part and take advantage of LONGs. This will automatically take care of negative temperatures which your altimeter will certainly need.

    Absolute Altitude needs LOG functions to handle the power 1/5.255 so avoid that by using a lookup table which you can make as accurate as you want by adjusting the size of the table and the interpolation method.

    HTH
    BrianT
    Last edited by BrianT; - 19th May 2010 at 01:31. Reason: math error

  2. #2
    Join Date
    Nov 2008
    Posts
    96


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by BrianT View Post
    I have read the Bosch datasheet which is very similar to the Intersema MS5540 family. With the exception of absolute altitude, LONGs and a PIC18F part will handle those formulae easily.
    HTH
    BrianT
    Hi Brian, yes that helps me, a good confidence boost at the very least.
    Can I bother you a moment longer ? About two things in the datasheet that you may well understand without looking at it again.

    First is that the equations for the temp and pressure conversions have in there a couple of times the value called 'oss', used with a binary shift I think. Do you know what that 'oss' means ?

    Lastly, I've been reading the raw pressure value with my code as a 16 bit Word, but it occurred to me now that even if I don't specify the hi-res mode, that I should be reading the full 19bits (LSB being 000 I guess) not just 16. The data sheet doesn't make it clear either way (to me).

    TIA,
    Martin

  3. #3


    Did you find this post helpful? Yes | No

    Default oss = over sampling setting

    Looks to me the number of places you left or right shift is related to how many samples you take per reading. try and get hold of the C code and see if you can nut it out. In my Intersema code, I do the averaging by a simple sum of n readings divided by n at the end. Again, LONGs take the pain out of needing to know if the sum of 8 samples overflowed a 16 bit variable.

    I have failed to find a copy of their C source code on the net. Seems you have to genuflect for one of their distributors to get it.

    HTH
    BrianT

  4. #4
    Join Date
    Nov 2008
    Posts
    96


    Did you find this post helpful? Yes | No

    Default

    Thanks Brian. Did I fail to RTFM :-) I hope not.

    I studied a nicely done vario project here using the BMP085 and C30 compiler.
    http://www.pixelproc.net/pic24bmp085lcd.html
    Didn't mean much to me unfortunately as it's a very busy bit of work.

    Yes, I like the simpler add many then divide way of averaging too, it always works well.
    Martin

  5. #5
    Join Date
    Nov 2008
    Posts
    96


    Did you find this post helpful? Yes | No

    Default Moving along slowly

    For anyone interested in the BMP085 barometric sensor I am now a little more sure that I've got a good set of calibration coefficients read out my BMP085, and also got the UT and UP raw values reading correctly.
    I've set the BMP085 to it's highest resolution and over-sampling now (oss=3), and can use the 19bit size result in the Excel spreadsheet and get sensible results.
    I did a test from the top of the building I work in, to the bottom, some 12 floors, and I get a altitude change of 63 meters which is about right. Then did one from the bottom to the top of the hill I live on and got a good result again.

    While the code looks simple it turned out that it really needed to be using Longs and therefore a 18FXXXX micro. I had 18F1220 parts in my box so that's what I've used.
    To display whats going on inside the PIC I use a PIC serial display, which I built many years ago (great bit of gear that). Mine has 20x4 LCD display rather than the usual 16x2 line.

    I'll attach the Excel XLS file that my friend Andrew T made up using the calculations from the BMP085 datasheet. It processes the calibration data, temperature and pressure data the same way as I need my PIC too. So it's a good test comparison to see if my code is work right in each stage and has helped me greatly.

    Code:
    'PIC 18F1220 port/pin allocations
    '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    'PortA.0/Pin 1 = Serial TX
    'PortA.1/Pin 2 = LED
    'PortB.0/Pin 8 = I2C SCL clock
    'PortB.1/Pin 9 = I2C SDA data
     
    ' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    'Config Directive settings for MPASM (fuses)
     
    @    __CONFIG  _CONFIG1H, _IESO_OFF_1H & _FSCM_OFF_1H & _INTIO2_OSC_1H
    @    __CONFIG  _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L & _BORV_27_2L
    @    __CONFIG  _CONFIG2H, _WDT_ON_2H & _WDTPS_32K_2H
    @    __CONFIG  _CONFIG3H, _MCLRE_OFF_3H
    @    __CONFIG  _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVR_OFF_4L
    @    __CONFIG  _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L
    @    __CONFIG  _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
    @    __CONFIG  _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L
    @    __CONFIG  _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
    @    __CONFIG  _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L
    @    __CONFIG  _CONFIG7H, _EBTRB_OFF_7H   
     
        DEFINE OSC 8 '8Mhz clock used.
         
    ' Define some constants if needed
            
    ' Software Defines (variables and pins)
        Cal_table   var word[11]         '11 word array to store calibration data
        lUpres      var long             'Long variable for Uncompensated Pressure
        lTemp_Var   var Long             'Long temporary variable
        Temp_Var    var byte             'Byte temp variable 
        Temp_Var2   var Word	         'Word temp variable
        Temp_Var3   var word             'Word temp variable
        UTemp       var word             'uncompensated temp reading
    '    UPres       var word             'uncompensated pressure reading
        i2c_Reg     var Byte             'variable for target i2c register address
    
        CPIN        var     PortB.0       ' I2C clock pin 
        DPIN        var     PortB.1       ' I2C data pin
        SO          Var     PortA.0        'Serial out pin
        LED         var     PortA.1        'Indicator LED, via 500ohm to +3.3V
        
    'Alias's for calibration data in the sensor to match the Bosch parameter list names
        AC1     var     Cal_table[0]      '
        AC2     var     Cal_table[1]     'BMP085 has 11 16bit values stored in EEPROM
        AC3     var     Cal_table[2]     'First byte is at $AA last at $BF, two bytes per cal value
        AC4     var     Cal_table[3]     'Lowbyte is MSB (e.g $AA), Highbyte is LSB (e.g. $AB)
        AC5     var     Cal_table[4]     'some values are signed (not AC4, AC5, AC6)
        AC6     var     Cal_table[5]    
        B1      var     Cal_table[6]
        B2      var     Cal_table[7]
        MB      var     Cal_table[8]
        MC      var     Cal_table[9]    
        MD      var     Cal_table[10]    
        
    ' Initialize Processor - check for each PIC type 
    ' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        ADCON1 = %11111111              'Turn off all AD's     
    '    OSCCON =  %01100111     'set INTRC to 4 MHZ    
        OSCCON = %01110111     'set INTRC to 8 MHZ
    '    OSCTUNE = 0                      'OSC trim set to Null 
    
    '    Include "modedefs.bas"          ' Include serial modes    
    
    ' Set initial state of port pins as Input or Output
    
        TRISA = %11111100    'Input(0 = output, 1 = Input)
        TRISB = %11111100    '
        
    ' PIC initialization code
            Low So      'Must start low, or you get rubbish on the LCD at PIC boot up.
            Low LED     'LED on
            pause 5000  'led on for x seconds
            High LED    'LED off
            
            Serout2 SO,16780,[$FE,$01]               ' Clear LCD & home LCD cursor.
            pause 10                                ' wait for LCD to catch up
            Serout2 SO,16780,["   FrSky Vario    "]  ' Serial print 
            Serout2 SO,16780,[$FE,$C0]               ' Shift cursor to line2
            Serout2 SO,16780,[" Development Jig  "]  ' Serial print 
            Pause 3000                               'wait three seconds
            
            i2c_Reg =$AA                            'Start address of the BMP085 calibration data
            I2CREAD DPIN,CPIN,$EF,I2C_REG,[STR Cal_table\11],cal_error  'Read 11 reversed words out of sensor
    
            AC1 = (AC1.lowbyte<<8) + AC1.highbyte   'swap MSB and LSB of each to use in PBP (un-reverse then)    
            AC2 = (AC2.lowbyte<<8) + AC2.highbyte   'device stores the MSB in the Low byte, LSB in the High byte
            AC3 = (AC3.lowbyte<<8) + AC3.highbyte   
            AC4 = (AC4.lowbyte<<8) + AC4.highbyte          
            AC5 = (AC5.lowbyte<<8) + AC5.highbyte
            AC6 = (AC6.lowbyte<<8) + AC6.highbyte
            B1 = (B1.lowbyte<<8) + B1.highbyte
            B2 = (B2.lowbyte<<8) + B2.highbyte
            MB = (MB.lowbyte<<8) + MB.highbyte
            MC = (MC.lowbyte<<8) + MC.highbyte
            MD = (MD.lowbyte<<8) + MD.highbyte 
                                   
            Serout2 SO,16780,[$FE,$01]             ' Clear LCD & home LCD cursor. 
            Pause 10                              ' wait for LCD to catch up
    'Main loop -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    Main:  
            Serout2 SO,16780,[$FE,$02]             'home LCD cursor, not cleared.                           
             
            Gosub Read_temp                        'get Temp via I2C
    
            lTemp_var = 0                          'Clear the last pressure reading
            For Temp_var = 0 to 9                  'start of 10x averaging routine
            Gosub Read_pres                        'get Long uncompensated pressure via I2C
            lTemp_var = ltemp_var + lUpres
            Next Temp_var
            lUpres = lTemp_Var / 10               'finish of 10x Averaging routine
            
            Serout2 SO,16780,["UT=",DEC utemp," "]       'Send Word size number to LCD
            Serout2 SO,16780,["UP=",DEC luPres," "]      'Send Word size number to LCD
                    
    'lets see whats in the cal data array for a checking math in Excel - Rem out Utemp and lUpres above 
    '        Serout2 SO,16780,[$FE,$2]               ' Shift cursor to line_1 (128+addr) Note-Rem out Utemp and lUpres above
    '        Serout2 SO,16780,[SDEC AC1," ",SDEC AC2," ",SDEC AC3]   'display three signed cal values
            Serout2 SO,16780,[$FE,$C0]               ' Shift cursor to line_2
            Serout2 SO,16780,[DEC AC4," ",DEC AC5," ",DEC AC6]   'display three unsigned cal values
            Serout2 SO,16780,[$FE,$94]               ' Shift cursor to line_3  
            Serout2 SO,16780,[SDEC B1," ",SDEC B2]   'display two signed cal values
            Serout2 SO,16780,[$FE,$D4]               ' Shift cursor to line_4          
            Serout2 SO,16780,[SDEC MB," ",SDEC MC," ",SDEC MD]  'display three signed cal values
     '        pause 100
            Toggle LED                                'flash the 'im alive' LED
            Goto main
            
    'SUBROUTINES -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-      
    Read_pres: 
            i2c_Reg = $F4                         '$F4 is the control register address
            I2CWRITE DPIN,CPIN,$EE,I2C_REG,[$F4]  ' Write $34+(oss << 6) to set pressure conversion 
            Pause 30                              ' Delay 10ms after each write (30mS for HiRes results (oss=3))
            i2c_Reg = $F6                         '$F6 is the result register MSB
            I2CREAD DPIN,CPIN,$EF,I2C_REG,[lUpres],I2C_error  'Read pressure MSB, LSB, XLSB, $F9(not needed).
            lUpres = lUpres >> 13                 'remove result from $F9 (>>8) + left shift result back to 19bits (>>5)
                                                  'it's because PBP reads four bytes if [Var] is a long...
            return                                'we only want top 19bits of the result.
                  
    Read_temp:
            i2c_Reg = $F4                         '$F4 is the control register address
            I2CWRITE DPIN,CPIN,$EE,I2C_REG,[$2E]  ' Write $2E to set temperature conversion 
            Pause 10                              ' Delay 10ms after each write
            i2c_Reg = $F6                         '$F6 is the result register MSB
            I2CREAD DPIN,CPIN,$EF,I2C_REG,[Utemp],I2C_error  'Read temperature MSB, LSB.
            return
    
    'trap and display I2C problems        
    I2C_error:     
            Serout2 SO,16780,[$FE,$01]             ' Clear LCD & home LCD cursor. 
            Pause 10                              ' wait for LCD to catch up
            Serout2 SO,16780,["i2c bus read error"]       'no ACK from I2C device        
            pause 2000        
            Toggle LED
            Goto main
             
    Cal_error:
            Serout2 SO,16780,[$FE,$01]             ' Clear LCD & home LCD cursor. 
            Pause 10 
            Serout2 SO,16780,["i2c cal read error "]       '        
            
    End
    Now I have to convert this code below to PBPL and get a 'compensated' reading of the temperature and pressure.... Quite a few intermediate variables are needed.

    //calculate the temperature
    x1 = (ut - ac6) * ac5 >> 15;
    x2 = ((int32_t) mc << 11) / (x1 + md);
    b5 = x1 + x2;
    temperature = (b5 + 8) >> 4;

    //calculate the pressure
    b6 = b5 - 4000;
    x1 = (b2 * (b6 * b6 >> 12)) >> 11;
    x2 = ac2 * b6 >> 11;
    x3 = x1 + x2;
    b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 2;
    x1 = ac3 * b6 >> 13;
    x2 = (b1 * (b6 * b6 >> 12)) >> 16;
    x3 = ((x1 + x2) + 2) >> 2;
    b4 = (ac4 * (uint32_t) (x3 + 32768)) >> 15;
    b7 = ((uint32_t) up - b3) * 50000;
    p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;

    x1 = (p >> 8) * (p >> 8);
    x1 = (x1 * 3038) >> 16;
    x2 = (-7357 * p) >> 16;
    pressure = p + ((x1 + x2 + 3791) >> 4);

    I found this above C code elsewhere on the Web, it's in the datasheet more or less. I've also had PBP code help from a few forum members. Thank you all for the help so far

    The journey continues...
    Attached Files Attached Files
    Last edited by mr.sneezy; - 26th May 2010 at 11:39.

  6. #6
    Join Date
    Nov 2008
    Posts
    96


    Did you find this post helpful? Yes | No

    Default Bigger PIC's....

    Hmm...
    I've written all the 32Bit calculation code now using PBPL and Longs, where they are needed (well nearly everywhere).
    Right away I got a list of very strange compiler errors like this
    c:/pbp/pbppi18l.lib 695 : Argument out of range ( 4168 not between 0 and 4095)

    After having a look at line 695 of that file I still had no clue. So I took a punt that I might have run out of PIC code space, and yes that seems to be right. If I select a PIC in the same sub family with more code space the code complies error free....
    Longs sure burn code space like it was endless resource.
    Off to find a another bigger PIC again. This will be the 4th PIC tried for this project.


    Onward and upwards !!

    PS. Is there a simple to use utility, MCS add-on or method that will show me the amount of RAM space my code is using when compiled (as well as program space) ?
    Last edited by mr.sneezy; - 28th May 2010 at 14:02.

  7. #7
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,653


    Did you find this post helpful? Yes | No

    Lightbulb

    Quote Originally Posted by mr.sneezy View Post
    Hmm...
    I've written all the 32Bit calculation code now using PBPL and Longs, where they are needed (well nearly everywhere).
    Right away I got a list of very strange compiler errors like this
    c:/pbp/pbppi18l.lib 695 : Argument out of range ( 4168 not between 0 and 4095)

    After having a look at line 695 of that file I still had no clue. So I took a punt that I might have run out of PIC code space, and yes that seems to be right. If I select a PIC in the same sub family with more code space the code complies error free....
    Longs sure burn code space like it was endless resource.
    Off to find a another bigger PIC again. This will be the 4th PIC tried for this project.


    Onward and upwards !!
    Hi,

    Looks linked to too small a program memory ... in 18 pins ... the 1320 exists in 8k ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  8. #8
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mr.sneezy View Post

    PS. Is there a simple to use utility, MCS add-on or method that will show me the amount of RAM space my code is using when compiled (as well as program space) ?
    Nice work on the sensor code!

    MCS shows you how much code is being used at the bottom of the page after compliling. (Note it does need a successful compile to be able to tell you this.)

    Name:  size.png
Views: 4302
Size:  17.1 KB

    You can also peek in the .lst file, and find code used vs left.

    Code:
    MEMORY USAGE MAP ('X' = Used,  '-' = Unused)
    
    
    0000 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
    0040 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
    0080 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
    00C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
    0100 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
    0140 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
    0180 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXX-------
    0200 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
    0240 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
    0280 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
    02C0 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX ---------------- ----------------
    2000 : -------X-------- ---------------- ---------------- ----------------
    
    All other memory blocks unused.
    
    Program Memory Words Used:   665
    Program Memory Words Free:   359
    Then there is also Darrel's CodeSpace utility here:
    http://www.picbasic.co.uk/forum/showthread.php?t=2418
    Last edited by ScaleRobotics; - 28th May 2010 at 15:21.

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts