|
Forum Index : Microcontroller and PC projects : BME280
| Author | Message | ||||
palcal![]() Guru Joined: 12/10/2011 Location: AustraliaPosts: 2039 |
Here it is again.... I am trying to use a BME280 for Temperature and Humidity with this code from Peter.. option explicit option default none ' ' BME280 routines and test harness ' const BME280_ADDRESS = &H77 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 'used to store accurate temp reading from temp conversion for use in pressure and humidity conversions ' ' Test program ' bme280_init do print bme280_read_temp() 'must be run before pressure or humidity print bme280_read_pressure() print bme280_read_humidity() pause 2000 loop ' end ' '*************************************************************************************************** ' function bme280_read_temp() as float local integer var1,var2,adc_T local adc%(2) 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 end function function bme280_read_pressure() as float local integer var1, var2, adc_P, p local adc%(2) 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 end function ' function bme280_read_humidity() as float local integer v_x1,adc_H local adc%(1) 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 end function sub bme280_init local i%,cal%(17) 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 ' end sub ' function q(x as integer) as integer 'returns 2 raised to the power q=(1<<x) End CFunction I had to comment out the last line "End Cfunction" The program runs but at first I get an error "BME280 not found" at line 98. The program continues to run after this with correct Temperature and Pressure values but Humidity is 0. The value of i% in line 98 is 88. Edited 2026-02-16 15:54 by palcal "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 3013 |
It's just a typo. Delete just the "C" from CFunction. Function q(x as integer) as integer 'returns 2 raised to the power q=(1<<x) End Function The humidity function uses the q() function but without an End Function it never returns to the humidity function, hence you get zero. Your original post is in "Windmills" Here it is with indenting restored to make it more readable. Also added a debug message to the error message in Sub bme280_init. option explicit option default none ' ' BME280 routines and test harness ' const BME280_ADDRESS = &H77 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 'used to store accurate temp reading from temp conversion for use in pressure and humidity conversions ' ' Test program ' bme280_init Do print bme280_read_temp() 'must be run before pressure or humidity print bme280_read_pressure() print bme280_read_humidity() pause 2000 Loop ' end ' '*************************************************************************************************** ' Function bme280_read_temp() as float local integer var1,var2,adc_T local adc%(2) 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 End Function ' Function bme280_read_pressure() as float local integer var1, var2, adc_P, p local adc%(2) 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 End Function ' Function bme280_read_humidity() as float local integer v_x1,adc_H local adc%(1) 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 End Function ' Sub bme280_init local i%,cal%(17) 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, i% should be $H60 but was &H";Hex%(i%,2) ' 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 ' End Sub ' Function q(x as integer) as integer 'returns 2 raised to the power q=(1<<x) End Function Edited 2026-02-16 17:59 by phil99 |
||||
palcal![]() Guru Joined: 12/10/2011 Location: AustraliaPosts: 2039 |
Thanks Phil. "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 3013 |
There is a typo in my addition to the error message in Sub bme280_init. Hex%(i%,2) should be Hex$(i%,2). Corrected line is the last one here:- Sub bme280_init local i%,cal%(17) 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, i% should be $H60 but was &H";Hex$(i%,2) |
||||
palcal![]() Guru Joined: 12/10/2011 Location: AustraliaPosts: 2039 |
Can't understand what you mean "Hex%(i%,2) should be Hex$(i%,2). Corrected line is the last one here:-" I can't find Hex%(i%,2) or Hex$(i%,2) is Hex$ a typo. I used the code you posted but same result, I still get ERROR BME280 not found and humidity is zero "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
| JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 4241 |
After the line Sub bme280_init is an If and very near its end is Hex% which should be Hex$ John |
||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 3013 |
Hex$(i%,2) just formats the printout of i% in hexadecimal to correspond with the format in the program. eg. > i%=15 > ? "&H";Hex$(i%,2) &H0F > Sub bme280_init reads the value of i% from the BME280 and expects to see a value of &H60. i2c read BME280_ADDRESS,0,1,i% If it does not get that it gives the error message. if i%<>&H60 then print "Error BME280 not found, i% should be $H60 but was &H";Hex$(i%,2) The bit I added shows what the actual value of i% is. I don't have a BME280 so can't test it myself. If you run it again and post the value of i% I will have a look at the datasheet to see what it means. Edit. The datasheet is 60 pages! It will take me several days to work through it, perhaps Peter can produce an answer quicker. Edited 2026-02-17 07:06 by phil99 |
||||
TassyJim![]() Guru Joined: 07/08/2011 Location: AustraliaPosts: 6455 |
You have a BMP280 not a BME280 Chip ID for the BMP280 is 88 decimal = &h58 The BMP280 uses the same registers for temperature and pressure which is why you are getting readings for those. Jim ![]() Edited 2026-02-17 07:14 by TassyJim VK7JH MMedit |
||||
palcal![]() Guru Joined: 12/10/2011 Location: AustraliaPosts: 2039 |
That is the value I get in the error message. I still don't know what to do to fix it. I bought the sensors as BME280, I can't take a picture because I can't find the memory card for my camera but the markings in the module are... GY-BM E/P 280 "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
TassyJim![]() Guru Joined: 07/08/2011 Location: AustraliaPosts: 6455 |
The same board is used for both chips. If you are lucky, there will be a mark crossing out the E or the P. The question is then, does crossing it out mean it is a P an E. The actual chip do look different. search for "bmp280 vs bme280" VK7JH MMedit |
||||
palcal![]() Guru Joined: 12/10/2011 Location: AustraliaPosts: 2039 |
OK it says BMP280 does not measure humidity. so look for BME280. "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 3013 |
The type number should be engraved on the tiny metal box. |
||||
TassyJim![]() Guru Joined: 07/08/2011 Location: AustraliaPosts: 6455 |
![]() Or with batch markings: Jim VK7JH MMedit |
||||
palcal![]() Guru Joined: 12/10/2011 Location: AustraliaPosts: 2039 |
Thanks for that. Mine is KU so it is a BMP280. Edited 2026-02-17 10:53 by palcal "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2026 |