Anyone used the Bosch BMP085 I2C baro sensor yet ? - Page 2


Closed Thread
Page 2 of 2 FirstFirst 12
Results 41 to 52 of 52
  1. #41
    Join Date
    Nov 2008
    Posts
    96


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by rore85 View Post
    Thanks for answer...
    I wonder if the calibration coefficients of BMP085 depend on something ... as either light, or are the same constants for all?
    And another thing, the uncompensated temperature varies a lot ... in the order of thousands or hundreds
    Thanks
    Mainly temperature dependant. I've not been able to show much sensitivity to light yet (indoors).
    Yes, the pressure reading is very 'active' so I used the maximum OSS and then 10x averaging as well. It could do with even more...

  2. #42
    Join Date
    Nov 2008
    Posts
    96


    Did you find this post helpful? Yes | No

    Default The complete opus in Longs

    Here it is. This works, and give you a corrected temperature and pressure reading from a Bosch BMP085 barometric pressure sensor.

    It requires a PIC18FXXXX MCU and use of PBPL compiler option. You'll need to change the configs for whatever PIC you choose and change the Serout2 statements to LCDOUT or whatever you want to display data on.

    The main point of this post is really to show the calculations and variable casting and manipulation required.

    Code:
    '******************************************************************************
    'MR.SNEEZY - test code for FrSky using Bosch BMP085 baro sensor.
    'This version is for PIC 18F4620 
    '
    'ADD/Do
    '
    'NOTES - 
    '
    'LAST ACTION - scratch my head...
    '
    'PIC 18F1220 port/pin alocations
    '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    'PortA.0/Pin 2 = Serial TX
    'PortA.1/Pin 3 = LED
    'PortB.0/Pin 33 = I2C SCL clock
    'PortB.1/Pin 34 = I2C SDA data
     
    ' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    'Config Directive settings for MPASM (fuses) for 18F4620
     
    @    __CONFIG  _CONFIG1H, _IESO_OFF_1H & _FCMEN_OFF_1H & _OSC_INTIO7_1H
    @    __CONFIG  _CONFIG2L, _PWRT_ON_2L & _BOREN_OFF_2L 
    @    __CONFIG  _CONFIG2H, _WDT_OFF_2H & _WDTPS_512_2H
    @    __CONFIG  _CONFIG3H, _MCLRE_OFF_3H & _PBADEN_OFF_3H
    @    __CONFIG  _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVREN_OFF_4L & _XINST_OFF_4L
    @    __CONFIG  _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L
    @    __CONFIG  _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
    @    __CONFIG  _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L
    @    __CONFIG  _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
    @    __CONFIG  _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_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
        lPres       var Long             'Long variable for Compensated Pressure
        lTemp_Var1  Var long             'Long temporary variable
        X1          var Long
        X2          var Long
        X3          var Long
        B3          var long
        B4          var long
        B5          var long
        B6          var Long
        B7          var long
        
        lAC1        var Long            'Long variables for cal values actually negative in my sensor
        lAC2        var long            'These are 'cast' from the Word vars into Long vars in code below
        lAC3        var Long 
        lAC4        var Long 
        lMB         var Long
        lMC         var Long
     
        bTemp_Var1  var byte             'Byte temp variable 
        wTemp_Var1  var Word	         'Word temp variable
        wTemp_Var2  var word             'Word temp variable
        lUTemp      var long             'Uncompensated temperature reading from sensor
        lCTemp      var Long             'Compensated (real) temperature x10 (1/10th of C) from sensor
        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
        
        OSS         con     $3          'This value is the Over Sampling Setting for the BMP085
                                        '0 = minimum, 3 = maximum. Also change value in Read_pres if you alter OSS 
    
    '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]        '
        AC6     var     Cal_table[5]    
        B1      var     Cal_table[6]        'Warning - AC4, AC5, AC6 are UNSIGNED values, the rest are SIGNED
        B2      var     Cal_table[7]
        MB      var     Cal_table[8]
        MC      var     Cal_table[9]    
        MD      var     Cal_table[10]    
        
    ' Initialise Processor - check for each PIC type 
    ' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
        ADCON1 = %00001111              '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 
    
    ' Set initial state of port pins as Input or Output if needed
    '    TRISA = %11111100    'Input(0 = output, 1 = Input)
    '    TRISB = %11111100    '
    '    TRISC = %11111111
    '    TRISD = %11111110
    '    TRISE = %11111111
        
    ' PIC initialization code
    '        Low So      'Start low, or you get rubbish on the LCD at PIC boot up.
            Gosub Alive                             'Go prove the PIC is running via LED
                       
            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   2000
            
            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 
    
    'Cast (convert) signed PBP Word vars to signed PBP Long vars where needed by math routines below
            lAC1 = AC1                           'copy word to long   
            if AC1.15 then lAC1.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true 
    
            lAC2 = AC2                           'copy word to long   
            if AC2.15 then lAC2.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true 
    
            lAC3 = AC3                           'copy word to long
            if AC3.15 then lAC3.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true
    
            lMB = MB                            'copy word to long
            if MB.15 then lMB.HIGHWORD = $FFFF  'Check for negative, set top 16bits to all 1's if true
    
            lMC = MC                            'copy word to long
            if MC.15 then lMC.HIGHWORD = $FFFF  'Check for negative, set top 16bits to all 1's if true
    
    'Cast (convert) UN-signed PBP Word var to UN-signed PBP Long var for math routines below
            lAC4 = AC4                          'copy word to long, both unsigned
                                    
            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, LCD not cleared.                           
             
            Gosub Read_temp                        'get Temp via I2C
            
            Serout2 SO,16780,["UT=",SDEC lUtemp," "]       'Send Word size number to LCD
            
            lTemp_Var1 = 0                          'Clear the last pressure reading
            For bTemp_Var1 = 0 to 9                 'Start of 10x averaging routine
            Gosub Read_pres                         'get Long uncompensated pressure via I2C
            lTemp_Var1 = lTemp_Var1 + lUpres
            Next bTemp_Var1
            lUpres = lTemp_Var1 / 10                'finish of the 10x Averaging routine   
    
            Serout2 SO,16780,["UP=",SDEC lUpres," "]       'Send Word size number to LCD
    
    'Calculate temperature in 1/10ths of Deg C  from lUTemp     ' Note 2^15 = 32768 Dec or $8000
            X1 = ((lUtemp - AC6) * AC5) / $8000     'find X1. 
            X2 = (lMC * $800) / (X1 + MD)           'Find X2.  Note:- math rounding results in X2 being in error by 1 ?
            B5 =  X1 + X2                           'Find B5 from X1 and X2.
            lCTemp = (B5 + 8) / 16                  'Hey presto, lCTemp appears... 
    
    'DISPLAY true temperature in C 
            X1 = lCTemp / 10                         'find value above decimal point
            Serout2 SO,16780,[$FE,$C0]               ' Shift cursor to line_2
            Serout2 SO,16780,["Temp= ",DEC X1,"."]   'Send Word size number to LCD        
            X1 = lCTemp // 10                        'Find decimal value
            Serout2 SO,16780,[DEC X1,"  "]           'Send Word size number to LCD 
             
    'Calculate pressure in Pascals from uncompensated pressure lUpres (1/100th's of hPa's)        
            B6 = b5 - 4000
    
            x1 = (b2 * (B6 * B6 / $1000)) / $800 
            x2 = (lac2 * B6) / $800
            x3 = x1 + x2
            B3 = ((lac1 * 4 + x3) << OSS + 2) / 4     'OSS = Over Sampling constant set above  
     
            x1 = (lac3 * b6) / $2000
            x2 = (b1 * (b6 * b6 / $1000)) / $10000
            x3 = ((x1 + x2) + 2) / 4
            B4 = (lac4 * (x3 + 32768)) / $8000        'Find B4, note lAC4 is an unsigned Long
    
            B7 = (lUPres - B3) * (50000 >> OSS)       'OSS = Over Sampling constant set above
     
            If B7 < $80000000 then                    'branch if value is above or below range
                lPres = (B7 * 2) / B4
                Else
                lPres = (B7 / B4) * 2
            Endif
    
            X1 = (lPres / 256) * (lPres / 256)
            X1 = (X1 * 3038) / $10000                 '$10000 = 2^16
            X2 = (-7357 * lPres) / $10000
            lPres = lPres + (X1 + X2 + 3791) / 16     'lPres is the true pressure in Pa
    
    'DISPLAY true pressure in hPa
            X1 = lPres / 100                          'find value above decimal point
            Serout2 SO,16780,[$FE,$94]                'Shift cursor to line_3   
            Serout2 SO,16780,["hPa= ",DEC X1,"."]     'Send Word size number to LCD        
            X1 = lPres // 100                         'find value below decimal point
            Serout2 SO,16780,[DEC X1,"  "]            'Send Word size number to LCD         
    
            pause 1000
            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 ($F9 not actually wanted).
            lUpres = lUpres >> (16 - oss)               'remove $F9 from result (>>8), and left shift result back to 16 to 19 Bits (OSS value dependant)
                                                        '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,[wTemp_Var1],I2C_error  'Read temperature MSB, LSB.
            lUTemp = wTemp_Var1                          'copy word to long. Note BMP085 UT is NOT a signed value   
            return
    
    'Prove it's alive
    Alive:
            High LED                                     'flash LED routine
            For btemp_var1 = 10 to 110 step 10
            Low LED
            Pause bTemp_Var1
            High LED
            Pause bTemp_Var1
            Next bTemp_Var1
            
            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

  3. #43
    Join Date
    May 2010
    Posts
    3


    Did you find this post helpful? Yes | No

    Default Problems with decimal point

    Quote Originally Posted by rore85 View Post
    Thanks for answer...
    I wonder if the calibration coefficients of BMP085 depend on something ... as either light, or are the same constants for all?
    And another thing, the uncompensated temperature varies a lot ... in the order of thousands or hundreds
    Thanks
    Hi everybody...
    The program in assembler works but I have problems generated in a division ratio, ie, it is rounded to an integer and the final value of the temperature goes too far in the real value, almost 80 degrees more ...
    Someone had the same problem?
    Thanks in advance!

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


    Did you find this post helpful? Yes | No

    Default

    Here are some multi byte division functions for assembly: http://avtanski.net/projects/math/

  5. #45
    Join Date
    Aug 2010
    Posts
    2


    Did you find this post helpful? Yes | No

    Default Compile problems

    Hi Martin-
    Thanks for sharing the Bosch code with us- some undertaking.
    I'm just about to start a small project that could use this device and thought I'd just check I can compile it correctly using your posted code for the 18F4620 before proceeding further.

    Unfortunately I'm getting compile errors ("overwriting previous address contents 0000 to 0007 locations") and just wondering if you could give me the versions of Microstudio and PBP you are running- I'm running Microstudio 3.0.0.5 and PBP 2.50L (with the pbpl box checked!)
    Thanks for your time.
    Edward

  6. #46
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    You need to set the configs correctly
    http://www.picbasic.co.uk/forum/showthread.php?t=543
    Dave
    Always wear safety glasses while programming.

  7. #47
    Join Date
    Aug 2010
    Posts
    2


    Did you find this post helpful? Yes | No

    Default

    Thanks- all ok now.

  8. #48
    Join Date
    Nov 2008
    Posts
    96


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by eab123 View Post
    just wondering if you could give me the versions of Microstudio and PBP you are running- I'm running Microstudio 3.0.0.5 and PBP 2.50L (with the pbpl box checked!)
    Thanks for your time.
    Edward
    PBP 2.60 and MCS 4.0.0.0

    Martin
    PS. If you do something interesting with the code please let us in on it :-)

  9. #49
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default Re: Anyone used the Bosch BMP085 I2C baro sensor yet ?

    Hello,

    I was wondering if someone did make a piece of PB code for converting the pressure to altitude?

    I'm far too bad in maths......
    Roger

  10. #50
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default What result precision shall I expect from the module - sampling methods

    Hi there,

    I have played around with mr.sneezy's code and came up with that one hereunder. Appart from the temperature,I use only raw data for my tests (makes the code a little smaller).

    The serial comm settings have been changed to connect to a pc-terminal (i.e. Serial Communicator in MCS) instead of a serial LCD display to make it more handy to store data into an EXCEL sheet for analysis.

    I'm using three sampling methods:
    1.- all measured values added and divided by the number of measurements ("16/16")
    2.- keep 8 middle measurements out of sixteen and average them ("Mid8/16")
    3.- keep 4 lowest (Bottom) and 4 highest (Top) measurements out of sixteen and average them ("B4+T4/16")

    The "Diff" shows the variation +/- with the previous value to have a rought idea about the result of each sampling method.

    Question: I'm wondering what precision I can expect from the BOSCH sensor. I'm not used to what one can expect from that type of sensor. While my sensor is "sitting" on my table,the values are bouncing up and down. I this correct?

    As a parglider pilot, I use an alti-variometer from FlyTec 4010 and the ascent/descent speed (precision is up to 0,1m per second) does not vary if the instruments isn't moved up or down. How can I reach the same behaviour from my sensor (no "bouncing" or no wrong ascent/descent indication)?

    Name:  results.jpg
Views: 969
Size:  50.3 KB

    Code:
    '******************************************************************************
    'MR.SNEEZY - test code for FrSky using Bosch BMP085 baro sensor.
    'This version is for PIC 18F4620 
    '
    'PIC 18F4620 port/pin alocations
    '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    'PortA.0/Pin 2 = Serial TX
    'PortA.1/Pin 3 = LED
    'PortB.0/Pin 33 = I2C SCL clock
    'PortB.1/Pin 34 = I2C SDA data
     
     
    'Config Directive settings for MPASM (fuses) for 18F4620
    @    __CONFIG  _CONFIG1H, _IESO_OFF_1H & _FCMEN_OFF_1H & _OSC_INTIO7_1H
    @    __CONFIG  _CONFIG2L, _PWRT_ON_2L & _BOREN_OFF_2L 
    @    __CONFIG  _CONFIG2H, _WDT_OFF_2H & _WDTPS_512_2H
    @    __CONFIG  _CONFIG3H, _MCLRE_OFF_3H & _PBADEN_OFF_3H
    @    __CONFIG  _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVREN_OFF_4L & _XINST_OFF_4L
    @    __CONFIG  _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L
    @    __CONFIG  _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
    @    __CONFIG  _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L
    @    __CONFIG  _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
    @    __CONFIG  _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
    @    __CONFIG  _CONFIG7H, _EBTRB_OFF_7H   
     
    'Registers
    ADCON1 = 001111    'Turn off all AD's     
    OSCCON = 110111    'set INTRC to 8 MHZ
     
    DEFINE OSC 8 '8Mhz clock used.
         
    ' SO_pinftware Defines (variables and pins)
    Cal_table   VAR WORD[11]  '11 word array to store calibration data
    lUpres      VAR LONG      'Uncompensated Pressure
    lPres       VAR LONG      'Compensated Pressure
    DataA       VAR LONG      'or WORD - as needed
    ArraySize   CON 16
    RawData     VAR LONG[ArraySize] 'or WORD - as needed
    X1          VAR LONG
    X01         VAR LONG
    X2          VAR LONG
    X3          VAR LONG
    B3          VAR LONG
    B4          VAR LONG
    B5          VAR LONG
    B6          VAR LONG
    B7          VAR LONG
    lAC1        VAR LONG  'cal values actually negative in my sensor
    lAC2        VAR LONG  'These are 'cast' from the Word vars into Long vars in code below
    lAC3        VAR LONG
    lAC4        VAR LONG
    lMB         VAR LONG
    lMC         VAR LONG
    bTemp_Var1  VAR BYTE  'temp variable 
    wTemp_Var1  VAR WORD  'temp variable
    wTemp_Var2  VAR WORD  'temp variable
    lUTemp      VAR LONG  'Uncompensated temperature reading from sensor
    lCTemp      VAR LONG  'Compensated (real) temperature x10 (1/10th of C) from sensor
    lTemp_Var1  VAR LONG
    lTemp_Var2  VAR LONG
    lTemp_Var3  VAR LONG
    Tempo1      VAR LONG
    Tempo2      VAR LONG
    Tempo3      VAR LONG
    I2C_Reg     VAR BYTE  'target i2c register address
    Counter     VAR WORD  'loop counter to show on display
    Counter     = 0
    S_Bd_Rate   VAR WORD        
    S_Bd_Rate   =   84    '9600DTN
    LF          CON 10    'Line Feed (for use with Serial Terminal like Hyperterminal)
    CR          CON 13    'Carriage Return (for use with Serial Terminal like Hyperterminal)
    OSS_Res     CON $3    'Over Sampling Setting for the BMP085
    OSS_Time    CON 30    'in ms for OSS_Res 0 = 10ms, ..., 3 = 25ms (see BMP085 datasheet)
     
    I2C_SCL     VAR PortB.0 'I2C clock pin 
    I2C_SDA     VAR PortB.1 'I2C data pin
    S_TX        VAR PortA.0 'Serial Tx) out pin
    LED         VAR PortA.1 'Indicator LED, via 500ohm to +3.3V
     
     
    'Aliases for calibration data in the senS_TXr 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]  '
    AC6 VAR Cal_table[5]
    B1  VAR Cal_table[6]  'Warning - AC4, AC5, AC6 are UNSIGNED values, the rest are SIGNED
    B2  VAR Cal_table[7]
    MB  VAR Cal_table[8]
    MC  VAR Cal_table[9]
    MD  VAR Cal_table[10]
     
     
    I2C_Reg =$AA                            'Start address of the BMP085 calibration data
    I2CREAD I2C_SDA,I2C_SCL,$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 
     
    'Cast (convert) signed PBP Word vars to signed PBP Long vars where needed by math routines below
    lAC1 = AC1                           'copy word to long   
    IF AC1.15 THEN lAC1.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true 
     
    lAC2 = AC2                           'copy word to long   
    IF AC2.15 THEN lAC2.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true 
     
    lAC3 = AC3                           'copy word to long
    IF AC3.15 THEN lAC3.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true
     
    lMB = MB                            'copy word to long
    IF MB.15 THEN lMB.HIGHWORD = $FFFF  'Check for negative, set top 16bits to all 1's if true
     
    lMC = MC                            'copy word to long
    IF MC.15 THEN lMC.HIGHWORD = $FFFF  'Check for negative, set top 16bits to all 1's if true
     
    'Cast (convert) UN-signed PBP Word var to UN-signed PBP Long var for math routines below
    lAC4 = AC4                          'copy word to long, both unsigned
                    
     
    'Main loop
    '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    MAIN:  
     
    'Get Temp via I2C
    I2C_Reg = $F4                                       '$F4 is the control register address
    I2CWRITE I2C_SDA,I2C_SCL,$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 I2C_SDA,I2C_SCL,$EF,I2C_Reg,[wTemp_Var1],I2C_error'Read temperature MSB, LSB.
    lUTemp = wTemp_Var1                                 'copy word to long. Note BMP085 UT is NOT a signed value   
     
    'Calculate temperature in 1/10ths of Deg °C from lUTemp    ' Note 2^15 = 32768 Dec or $8000
    X1 = ((lUTemp - AC6) * AC5) / $8000     'Find X1. 
    X2 = (lMC * $800) / (X1 + MD)           'Find X2.  Note:- math rounding results in X2 being in error by 1 ?
    B5 = X1 + X2                            'Find B5 from X1 and X2.
    lCTemp = (B5 + 8) / 16                  'Hey presto, lCTemp appears... 
     
    'Assign true temperature in °C in "x.x" format
    X1  = lCTemp / 10                       'find value above decimal point
    X01 = lCTemp // 10                      'Find decimal value
     
     
    'Take 16 measures from the BMP085
    lTemp_Var1 = 0                                'Clear the last pressure reading
    FOR bTemp_Var1 = 0 TO 15                      'Start of 16x averaging routine
      I2C_Reg = $F4                               '$F4 is the control register address
      I2CWRITE I2C_SDA,I2C_SCL,$EE,I2C_Reg,[$F4]  'Write $34+(oss << 6) to set pressure conversion 
      PAUSE OSS_Time                              'Delay 10ms after each write (30mS for HiRes results (oss=3))
      I2C_Reg = $F6                               '$F6 is the result register MSB
      I2CREAD I2C_SDA,I2C_SCL,$EF,I2C_Reg,[lUpres],I2C_error  'Read pressure MSB, LSB, XLSB, $F9 ($F9 not actually wanted).
      lUpres = lUpres >> (16 - OSS_Res)           'remove $F9 from result (>>8), and left shift result back to 16 to 19 Bits (OSS value dependant)
      lTemp_Var1 = lTemp_Var1 + lUpres
      RawData(bTemp_Var1) = lUpres                'fill-up array for sorting & averaging
    NEXT bTemp_Var1
    lUpres = lTemp_Var1 / 16                      'finish of the 10x Averaging routine   
     
     
    'Melanie's "sorting number" algorythm - ordonate data
    bTemp_Var1 = 0
    SortLoop:
    IF RawData(bTemp_Var1 + 1) < RawData(bTemp_Var1) THEN
        DataA = RawData(bTemp_Var1)
        RawData(bTemp_Var1) = RawData(bTemp_Var1 + 1)
        RawData(bTemp_Var1 + 1) = DataA
        IF bTemp_Var1 > 0 THEN bTemp_Var1 = bTemp_Var1-2
    ENDIF
    bTemp_Var1 = bTemp_Var1 + 1
    IF bTemp_Var1 < (ArraySize -1) THEN GOTO SortLoop
    'display data array
    'for bTemp_Var1 = 0 to (ArraySize -1)
    '  Serout2 S_TX,S_Bd_Rate,[dec2 bTemp_Var1, "  ", dec rawdata(bTemp_Var1),LF]
    'next   
     
     
    '**** Additional SAMPLING METHODS ****
     
    'keep the eight middle values and average them
    lTemp_Var2 = 0
    FOR bTemp_Var1 = 4 TO 11
      lTemp_Var2 = lTemp_Var2 + RawData(bTemp_Var1)
    NEXT bTemp_Var1
    lTemp_Var2 = lTemp_Var2 / 8
     
     
    'keep Bottom 4 (B4) and top 4 (T4) and average them
    lTemp_Var3 = 0
    FOR bTemp_Var1 = 0 TO 3
      lTemp_Var3 = lTemp_Var3 + RawData(bTemp_Var1)
    NEXT bTemp_Var1
    FOR bTemp_Var1 = 12 TO 15
      lTemp_Var3 = lTemp_Var3 + RawData(bTemp_Var1)
    NEXT bTemp_Var1
    lTemp_Var3 = lTemp_Var3 / 8
     
     
    'find the differences with the previous values
    IF lUpres > Tempo1 THEN
      Tempo1 = lUpres - Tempo1
    ELSE
      Tempo1 = Tempo1 - lUpres
    ENDIF
     
    IF lTemp_Var2 > Tempo2 THEN
      Tempo2 = lTemp_Var2 - Tempo2
    ELSE
      Tempo2 = Tempo2 - lTemp_Var2
    ENDIF
     
    IF lTemp_Var3 > Tempo3 THEN
      Tempo3 = lTemp_Var3 - Tempo3
    ELSE
      Tempo3 = Tempo3 - lTemp_Var3
    ENDIF
     
     
    'Display all data
    SEROUT2 S_TX,S_Bd_Rate,["16/16     = ",DEC lUpres,"  Diff = ",DEC Tempo1, LF]
    SEROUT2 S_TX,S_Bd_Rate,["Mid8/16   = ",DEC lTemp_Var2,"  Diff = ",DEC Tempo2, LF]
    SEROUT2 S_TX,S_Bd_Rate,["B4+T4/16 = ",DEC lTemp_Var3,"  Diff = ",DEC Tempo3, LF]
    SEROUT2 S_TX,S_Bd_Rate,["Temp     = ",DEC X1,".",DEC X01,"°C",LF]
    SEROUT2 S_TX,S_Bd_Rate,["Counter  = ",DEC Counter,LF,CR]
    PAUSE 1000
     
    Tempo1 = lUpres
    Tempo2 = lTemp_Var2
    Tempo3 = lTemp_Var3
    Counter = Counter + 1
    TOGGLE LED            'flash the 'im alive' LED
    GOTO MAIN
     
     
    'Trap and display I2C problems        
    I2C_error:     
    SEROUT2 S_TX,S_Bd_Rate,["i2c bus read error",LF,CR]
    PAUSE 2000
    TOGGLE LED
    GOTO MAIN:
     
    Cal_error:
    SEROUT2 S_TX,S_Bd_Rate,["i2c cal read error ",LF,CR]
    PAUSE 2000
    TOGGLE LED
    GOTO MAIN:
     
    END

    ...yes, it's quite cold in my lab
    Roger

  11. #51
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default "Resolution" or "precision" or whatever....

    Here is the latest BMP085's datasheet (rev 1.3 - August 22nd 2011).

    I need to understand how one can use this sensor and have a stable 0,1m reading. I just don't get it

    Furthermore, what's the "rms noise" meaning?
    Name:  precision.jpg
Views: 1115
Size:  35.4 KB
    Last edited by flotulopex; - 11th January 2012 at 06:17.
    Roger

  12. #52
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default Re: "Resolution" or "precision" or whatever....

    ...really nobody can help?
    Roger

Members who have read this thread : 3

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