BME280 accuracy using Micromite


Author Message
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6546
Posted: 04:44am 17 Sep 2019      

OK Lew,
I have had a play.
The following program needs to be run on your PI as well as a micromite using the same BME280 module.
You can then compare the registers and see where there are differences.
The cal%(x), Tx Px and Hx values should be the same for the same module but differ between modules.

The adc%(x) values depend on the temperature etc so will be different for each run.

If you need further investigation, we can take dig into the maths further and see where the figures diverge.

  Quote    ' BME280 test program to compare Pi-cromite to micromite basic
 OPTION BASE 0
 
OPTION EXPLICIT
 
 
'  BME280 constants
 '
 CONST BME280_ADDRESS                    = &H76
 
CONST BME280_REGISTER_T1                = &H88
 
CONST BME280_REGISTER_P1                = &H8E
 
CONST BME280_REGISTER_H1                = &HA1
 
CONST BME280_REGISTER_H2                = &HE1
 
CONST BME280_REGISTER_CHIPID            = &HD0
 
CONST BME280_REGISTER_CONTROLHUMID      = &HF2
 
CONST BME280_REGISTER_CONTROL           = &HF4
 
CONST BME280_REGISTER_PRESSUREDATA      = &HF7
 
CONST BME280_REGISTER_TEMPDATA          = &HFA
 
CONST BME280_REGISTER_HUMIDDATA         = &HFD
 
'
 DIM INTEGER s16=&HFFFFFFFFFFFF0000 , s16b=&H8000
 
DIM INTEGER s12=&HFFFFFFFFFFFFF000 , s12b=&H800
 
DIM INTEGER s8= &HFFFFFFFFFFFFFF00 , s8b=&H80
 
'
 DIM INTEGER T1,T2,T3     'uint16_t, int16_t, int16_t
 DIM INTEGER P1,P2,P3,P4,P5,P6,P7,P8,P9    'uint16_t, 8 x int16_t
 DIM INTEGER H1,H2,H3,H4,H5,H6     'uint8_t, int16_t , uint8_t, int16_t, int16_t, int8_t
 DIM INTEGER t_fine
 
DIM FLOAT t_bme, p_bme, h_bme, alt = 235    ' your altitude in metres
 
 
I2C OPEN 400, 200       ' Enable I2C. use slow speeds for long leads
 PAUSE 20
 
PRINT "Device = ";MM.DEVICE$
 bme280_init
 t_bme = bme280_read_temp()
 p_bme = bme280_read_pressure()
 p_bme = Psl(p_bme,alt)
 h_bme = bme280_read_humidity()
 
PRINT "T= ";t_bme;" P= ";p_bme;" H= ";h_bme
 
I2C CLOSE
 
END
 
 
FUNCTION Psl(p AS FLOAT, alt AS FLOAT) AS FLOAT
 
'given local pressure and altitude, returns pressure at sea level
 Psl= p/(1- alt/44330.77)^5.25588
END FUNCTION
 
 
'
FUNCTION bme280_read_temp() AS FLOAT
 
LOCAL INTEGER var1,var2,adc_T
 
LOCAL adc%(2),n!
 
I2C WRITE BME280_ADDRESS,1,1,BME280_REGISTER_TEMPDATA
 
I2C READ BME280_ADDRESS,0,3,adc%()
 adc_T=((adc%(
0)<<16) OR (adc%(1)<<8) OR adc%(2))>>4
 var1  = ((((adc_T>>
3) - (T1 <<1))) * T2) \ q(11)
 var2  = (((((adc_T>>
4) - (T1)) * ((adc_T\ q(4)) - (T1))) \ q(12)) * (T3)) \ q(14)
 t_fine = var1 + var2
 bme280_read_temp = ((t_fine *
5 + 128) \ q(8))/100.0
 
PRINT "bme280_read_temp()"
 
FOR n! = 0 TO 2
   
PRINT "adc%(";n!;"), ";adc%(n!)
 
NEXT n!
END FUNCTION
 
FUNCTION bme280_read_pressure() AS FLOAT
 
LOCAL INTEGER var1, var2, adc_P, p
 
LOCAL adc%(2),n!
 
I2C WRITE BME280_ADDRESS,1,1,BME280_REGISTER_PRESSUREDATA
 
I2C READ BME280_ADDRESS,0,3,adc%()
 adc_P=((adc%(
0)<<16) OR (adc%(1)<<8) OR adc%(2))>>4
 var1 = t_fine -
128000
 var2 = var1 * var1 * P6
 var2 = var2 + ((var1 * P5)<<
17)
 var2 = var2 + (P4 <<
35)
 var1 = ((var1 * var1 * P3)\ q(
8)) +    ((var1 * P2)<<12)
 var1 = ((
1<<47)+var1)*P1\ q(33)
 
IF var1 = 0 THEN
   bme280_read_pressure =  
0' avoid exception caused by division by zero
   EXIT FUNCTION
 
ENDIF
 p =
1048576 - adc_P
 p = (((p<<
31) - var2)*3125) \ var1
 var1 = (P9 * (p\ q(
13)) * (p\ q(13))) \ q(25)
 var2 = (P8 * p) \ q(
19)
 p = ((p + var1 + var2) \ q(
8)) + (P7<<4)
 bme280_read_pressure = p/
25600.0
 
PRINT "bme280_read_pressure()"
 
FOR n! = 0 TO 2
   
PRINT "adc%(";n!;"), ";adc%(n!)
 
NEXT n!
END FUNCTION
 
'
FUNCTION bme280_read_humidity() AS FLOAT
 
LOCAL INTEGER v_x1,adc_H
 
LOCAL adc%(1),n!
 
I2C WRITE BME280_ADDRESS,1,1,BME280_REGISTER_HUMIDDATA
 
I2C READ BME280_ADDRESS,0,2,adc%()
 adc_H=(adc%(
0)<<8) OR adc%(1)
 v_x1 = t_fine -
76800
 v_x1=(((((adc_H<<
14)-((H4)<<20)-(H5*v_x1))+16384)\ q(15))*(((((((v_x1*H6)\ q(10))*(((v_x1*H3)\ q(11))+32768))\ q(10))+2097152)*H2+8192)\ q(14)))
 v_x1 = (v_x1 - (((((v_x1 \ q(
15)) * (v_x1 \ q(15))) \ q(7)) * (H1)) \ q(4)))
 
IF v_x1< 0 THEN v_x1 = 0
 
IF v_x1 > 419430400 THEN v_x1= 419430400
 bme280_read_humidity = (v_x1\ q(
12)) / 1024.0
 
PRINT "bme280_read_pressure()"
 
FOR n! = 0 TO 1
   
PRINT "adc%(";n!;"), ";adc%(n!)
 
NEXT n!
END FUNCTION
 
SUB bme280_init
 
LOCAL i%,cal%(17),n!
 
' i2c open 400,1000 '400KHz bus speed
 I2C WRITE BME280_ADDRESS,1,1,BME280_REGISTER_CHIPID
 
I2C READ BME280_ADDRESS,0,1,i%
 
IF i%<>&H60 THEN PRINT "Error BME280 not found"
 
'
 I2C WRITE BME280_ADDRESS,1,1,BME280_REGISTER_T1
 
I2C READ BME280_ADDRESS,0,6,cal%()
 T1=cal%(
0) OR (cal%(1)<< 8)
 T2=cal%(
2) OR (cal%(3)<< 8):   IF T2 AND s16b THEN T2=T2 OR s16 'sign extend if required
 T3=cal%(4) OR (cal%(5)<< 8):   IF T3 AND s16b THEN T3=T3 OR s16
 
'
 I2C WRITE BME280_ADDRESS,1,1,BME280_REGISTER_P1
 
I2C READ BME280_ADDRESS,0,18,cal%()
 P1=cal%(
0) OR (cal%(1)<<8)
 P2=cal%(
2) OR (cal%(3)<<8):   IF P2 AND s16b THEN P2=P2 OR s16 'sign extend if required
 P3=cal%(4) OR (cal%(5)<<8):   IF P3 AND s16b THEN P3=P3 OR s16
 P4=cal%(
6) OR (cal%(7)<<8):   IF P4 AND s16b THEN P4=P4 OR s16
 P5=cal%(
8) OR (cal%(9)<<8):   IF P5 AND s16b THEN P5=P5 OR s16
 P6=cal%(
10) OR (cal%(11)<<8):   IF P6 AND s16b THEN P6=P6 OR s16
 P7=cal%(
12) OR (cal%(13)<<8):   IF P7 AND s16b THEN P7=P7 OR s16
 P8=cal%(
14) OR (cal%(15)<<8):   IF P8 AND s16b THEN P8=P8 OR s16
 P9=cal%(
16) OR (cal%(17)<<8):   IF P9 AND s16b THEN P9=P9 OR s16
 
'
 I2C WRITE BME280_ADDRESS,1,1,BME280_REGISTER_H1
 
I2C READ BME280_ADDRESS,0,1,H1
 
I2C WRITE BME280_ADDRESS,1,1,BME280_REGISTER_H2
 
I2C READ BME280_ADDRESS,0,7,cal%()
 H2=cal%(
0) OR (cal%(1)<< 8):   IF H2 AND s16b THEN H2=H2 OR s16 'sign extend if required
 H3=cal%(2)
 H6=cal%(
6):   IF H6 AND s8b THEN H6=H6 OR s8 'sign extend if required
 H4=(cal%(3)<<4) OR (cal%(4) AND &H0F): IF H4 AND s12b THEN H4=H4 OR s12 'sign extend if required
 H5=(cal%(5)<<4) OR (cal%(4)>>4):  IF H5 AND s12b THEN H5=H5 OR s12
 
'
 I2C WRITE BME280_ADDRESS,0,2,BME280_REGISTER_CONTROLHUMID,&H05 '16x oversampling humidity
 I2C WRITE BME280_ADDRESS,0,2,BME280_REGISTER_CONTROL,&HB7      '16x oversampling pressure/temp, normal mode
 '
 FOR n! = 0 TO 17
   
PRINT "cal%(";n!;"), &h";HEX$(cal%(n!),2)
 
NEXT n!
 
PRINT
 
PRINT "T1 , &h";HEX$(T1,4)
 
PRINT "T2 , &h";HEX$(T2,4)
 
PRINT "T3 , &h";HEX$(T3,4)
 
PRINT
 
PRINT "P1 , &h";HEX$(P1,4)
 
PRINT "P2 , &h";HEX$(P2,4)
 
PRINT "P3 , &h";HEX$(P3,4)
 
PRINT "P4 , &h";HEX$(P4,4)
 
PRINT "P5 , &h";HEX$(P5,4)
 
PRINT "P6 , &h";HEX$(P6,4)
 
PRINT "P7 , &h";HEX$(P7,4)
 
PRINT "P8 , &h";HEX$(P8,4)
 
PRINT "P9 , &h";HEX$(P9,4)
 
PRINT
 
PRINT "H1 , &h";HEX$(H1,4)
 
PRINT "H2 , &h";HEX$(H2,4)
 
PRINT "H3 , &h";HEX$(H3,4)
 
PRINT "H4 , &h";HEX$(H4,4)
 
PRINT "H5 , &h";HEX$(H5,4)
 
PRINT "H6 , &h";HEX$(H6,4)
 
PRINT
END SUB
 
'
FUNCTION q(x AS INTEGER) AS INTEGER  'returns 2 raised to the power
 q=(1<<x)
END FUNCTION


Results form a RPi and micromite:

  Quote  > RUN
Device = Micromite MkII
cal%( 0), &h6D
cal%( 1), &h01
cal%( 2), &h00
cal%( 3), &h13
cal%( 4), &h27
cal%( 5), &h03
cal%( 6), &h1E
cal%( 7), &h26
cal%( 8), &h37
cal%( 9), &hFF
cal%( 10), &hF9
cal%( 11), &hFF
cal%( 12), &hAC
cal%( 13), &h26
cal%( 14), &h0A
cal%( 15), &hD8
cal%( 16), &hBD
cal%( 17), &h10

T1 , &h6D04
T2 , &h663A
T3 , &h0032

P1 , &h9613
P2 , &hFFFFFFFFFFFFD5D0
P3 , &h0BD0
P4 , &h26AE
P5 , &hFFFFFFFFFFFFFF37
P6 , &hFFFFFFFFFFFFFFF9
P7 , &h26AC
P8 , &hFFFFFFFFFFFFD80A
P9 , &h10BD

H1 , &h004B
H2 , &h016D
H3 , &h0000
H4 , &h0137
H5 , &h0032
H6 , &h001E

bme280_read_temp()
adc%( 0),  125
adc%( 1),  97
adc%( 2),  160
bme280_read_pressure()
adc%( 0),  66
adc%( 1),  52
adc%( 2),  240
bme280_read_pressure()
adc%( 0),  108
adc%( 1),  72
T=  20.91 P=  1027.35 H=  43.3281
>

> RUN
Device = Pi-cromite running on H/W version: A02082
cal%( 0), &h6D
cal%( 1), &h01
cal%( 2), &h00
cal%( 3), &h13
cal%( 4), &h27
cal%( 5), &h03
cal%( 6), &h1E
cal%( 7), &h26
cal%( 8), &h37
cal%( 9), &hFF
cal%( 10), &hF9
cal%( 11), &hFF
cal%( 12), &hAC
cal%( 13), &h26
cal%( 14), &h0A
cal%( 15), &hD8
cal%( 16), &hBD
cal%( 17), &h10

T1 , &h6D04
T2 , &h663A
T3 , &h0032

P1 , &h9613
P2 , &hFFFFFFFFFFFFD5D0
P3 , &h0BD0
P4 , &h26AE
P5 , &hFFFFFFFFFFFFFF37
P6 , &hFFFFFFFFFFFFFFF9
P7 , &h26AC
P8 , &hFFFFFFFFFFFFD80A
P9 , &h10BD

H1 , &h004B
H2 , &h016D
H3 , &h0000
H4 , &h0137
H5 , &h0032
H6 , &h001E

bme280_read_temp()
adc%( 0),  126
adc%( 1),  87
adc%( 2),  112
bme280_read_pressure()
adc%( 0),  66
adc%( 1),  134
adc%( 2),  128
bme280_read_pressure()
adc%( 0),  107
adc%( 1),  206
T=  22.14 P=  1027.339211 H=  42.65429687
>


Jim
VK7JH
MMedit