'**************************************************************** '* Name : BME280.BAS * '* Author : Bob Marshall * '* Date : 26/07/2016 * '* Version : 1.0 * '* Notes : This program uses a BME280 sensor to measure * '* : current pressure, temperature, humidity and * '* : altitude. * '**************************************************************** Include "Amicus18_mk2.inc" Declare FLOAT_DISPLAY_TYPE = Fast Declare HBUS_BITRATE 400 Symbol BME280 = $EC 'BME280 I2C address Symbol CalDatStAd = $88 'Start address for cal. data. Symbol HumCalDatAd = $E1 'Start address for MAIN humidity cal. data. Symbol BME280HumCtrlReg = $F2 'BME280 humidity control register Symbol BME280ContReg = $F4 'BME280 control Register Symbol BME280ConfigReg = $F5 'BME280 configuration register Symbol BME280DataReg = $F7 'Uncompensated Data start register 'Values of 0-3 acceptable but see data sheet. 3 = Normal Mode Symbol PowerMode = 3 'Values of 0-5 acceptable but see data sheet. 5 = 20 bit res. Symbol TempRes = 5 'Values of 0-5 acceptable but see data sheet. 5 = 20 bit res. Symbol PresRes = 5 'Values of 0-7 acceptable. See data sheet before changing. Symbol Filter = 4 'Values of 0-7 acceptable but see data sheet. 4 = 500ms. Symbol Standby = 4 'Values of 0-5 acceptable but see data sheet. Symbol BME280CtrlHum = 5 'Temperature related variables. Dim T1 As Word Dim T2 As SWord Dim T3 As SWord Dim UT As Word 'Uncompensated temperature Dim XLSB_t As Byte Dim UTLong As SDword Dim Temperature As Float Dim T_fine As Float 'Pressure related variables Dim P1 As Word Dim P2 As SWord Dim P3 As SWord Dim P4 As SWord Dim P5 As SWord Dim P6 As SWord Dim P7 As SWord Dim P8 As SWord Dim P9 As SWord Dim UP As Word 'Uncompensated pressure. Dim UPLong As SDword Dim XLSB_p As Byte Dim P As Float 'Humidity related variables. Dim H1 As Byte Dim H2 As SWord Dim H3 As Byte Dim H4 As SWord Dim H5 As SWord Dim H6 As Byte Dim H4p1 As Byte 'H4 high bits Dim H4p2H5p2 As Byte 'H4 & H5 low bits Dim H5p1 As Byte 'H5 high bits Dim UH As Word 'Uncompensated Humidity Dim H As Float 'BME280 related variables. Dim BME280Config As Byte Dim BME280Control As Byte 'General variables Dim var1 As Float Dim var2 As Float Dim Altitude As Float Dim SeaLevel As DWord Main: DelayMS 500 'Let things settle down. Clear 'Setup BME280 Control and configuration registers. HBusOut BME280,BME280HumCtrlReg,[BME280CtrlHum] BME280Config = (Standby <<5) + (Filter <<2) ' Combine configuration bits HBusOut BME280,BME280ConfigReg,[BME280Config] BME280Control = (TempRes <<5) + (PresRes <<2) + PowerMode ' Combine BME280Control bits. HBusOut BME280,BME280ContReg,[BME280Control] ' Read calibration data HBusIn BME280,CalDatStAd,[T1,T2,T3,P1,P2,P3,P4,P5,P6,P7,P8,P9] HBusIn BME280, $A1,[H1]'First byte of humdity comp. data held in $A1 HBusIn BME280,HumCalDatAd,[H2,H3,H4p1,H4p2H5p2,H5p1,H6] H4 = (H4p1 << 4)|(H4p2H5p2 & $0F) H5 = (H5p1 << 4)|(H4p2H5p2 >> 4) Swap T1.BYTE0,T1.BYTE1 : Swap T2.BYTE0,T2.BYTE1 : Swap T3.BYTE0,T3.BYTE1 Swap P1.BYTE0,P1.BYTE1 : Swap P2.BYTE0,P2.BYTE1 : Swap P3.BYTE0,P3.BYTE1 Swap P4.BYTE0,P4.BYTE1 : Swap P5.BYTE0,P5.BYTE1 : Swap P6.BYTE0,P6.BYTE1 Swap P7.BYTE0,P7.BYTE1 : Swap P8.BYTE0,P8.BYTE1 : Swap P9.BYTE0,P9.BYTE1 Swap H2.BYTE0,H2.BYTE1 While 'Read the uncompensated temperature and pressure values. HBusIn BME280,BME280DataReg,[UP,XLSB_p,UT,XLSB_t,UH] UTLong = UT * 16 + (XLSB_t >> 4) UPLong = UP * 16 + (XLSB_p >> 4) ' Test data from the Bosch datasheet. Used to check calculations. ' T1=27504 : T2=26435 : T3=-1000 ' P1=36477 : P2=-10685 : P3=3024 ' P4=2855 : P5=140 : P6=-7 ' P7=15500 : P8=-14600 : P9=6000 ' UTlong=519888 : UPlong=415148 ' Expected results: Temperature = 25.08, Pressure = 100656.26 var1=(UTLong/16384-T1/1024)*T2 var2=(UTLong/131072-T1/8192)*(UTLong/131072-T1/8192)*T3 Temperature=(var1+var2)/5120 T_fine=(var1+var2) ' $B0 is the hex value for the degree symbol. Not correctly displayed on some terminals. HSerOut ["Current temperature is: ",DEC2 Temperature,$B0,"C",13] ' Pressure calculations start here. var1=T_fine/2-64000 var2=var1*var1*P6/32768 var2=var2+var1*P5 * 2 var2=(var2/4)+ P4 * 65536 var1=(P3*var1*var1/524288+P2*var1)/524288 var1=(1+var1/32768)*P1 P=1048576-UPLong P=(P-var2/4096)*6250/var1 ' The *-1 is needed here to negate the value of var1 ' See p23 of the Bosch data sheet (example calculation). var1=(P9*P*P/2147483648)*-1 var2=P*P8/32768 P=P+(var1+var2+P7)/16 HSerOut ["Current pressure: ",DEC2 P,"Pa",13] ' Note: The altitude calculation takes about 1.5k of program memory. ' : Remove if not needed! ' Altitude = 44330*((1-(p/101325)) ^ (1/5.255)) ' 101325 represents the 'standard' pressure at sea level. Adjust to suit. SeaLevel = 101200 ' Air pressure in pascals at sea level var1 = Pow((P/SeaLevel),0.190295) Altitude = 44330 *(1-var1) HSerOut ["Current altitude: ",DEC2 Altitude ,"m",13] 'Humidity Calculations. H = T_fine - 76800 H = (UH - (H4 * 64 + H5 / 16384 * H)) * (H2 / 65536 * (1 + H6 / 67108864 * H * (1.0 + H3 / 67108864 * H))) H = H * (1 - H1 * H / 524288) If H > 100 Then H = 100 Else If H < 0 Then H = 0 EndIf HSerOut ["Current humidity: ",DEC2 H ,"%",13,10,13] DelayMS 2000 Wend ' End of program