Code:
' PicBasic Pro Code to Read Pressure, Temperature, and Humidity from BME280
' Define I2C pins
DEFINE I2C_SCL PORTC.3 ' Define SCL pin (use appropriate pin)
DEFINE I2C_SDA PORTC.4 ' Define SDA pin (use appropriate pin)
' Define BME280 I2C address
Symbol BME280_Address = $EC ' BME280 I2C address (write mode, default 0x76)
Symbol BME280_Read = $ED ' BME280 I2C address (read mode)
' Define BME280 registers
Symbol BME280_Reg_Control_Hum = $F2 ' Humidity control register
Symbol BME280_Reg_Control_Meas = $F4 ' Measurement control register
Symbol BME280_Reg_Config = $F5 ' Configuration register
Symbol BME280_Reg_Pressure_MSB = $F7 ' Pressure MSB register
' Variables for raw sensor data
Dim dig_T1 As Word, dig_P1 As Word, dig_H1 As Byte, dig_H2 As Integer
Dim dig_T2 As Integer, dig_T3 As Integer
Dim dig_P2 As Integer, dig_P3 As Integer, dig_P4 As Integer, dig_P5 As Integer
Dim dig_P6 As Integer, dig_P7 As Integer, dig_P8 As Integer, dig_P9 As Integer
Dim dig_H3 As Byte, dig_H4 As Integer, dig_H5 As Integer, dig_H6 As Integer
Dim adc_T As Long, adc_P As Long, adc_H As Word
Dim t_fine As Long
' Subroutine to read an unsigned 16-bit value from a register
Sub ReadUInt16(ByVal Reg As Byte, Dim ByRef Result As Word)
Dim MSB As Byte
Dim LSB As Byte
I2CWRITE BME280_Address, Reg ' Send register address
I2CREAD BME280_Read, MSB, [LSB] ' Read MSB and LSB
Result = (MSB << 8) + LSB ' Combine MSB and LSB into a 16-bit word
End Sub
' Subroutine to read a signed 16-bit value from a register
Sub ReadInt16(ByVal Reg As Byte, Dim ByRef Result As Integer)
Dim MSB As Byte
Dim LSB As Byte
I2CWRITE BME280_Address, Reg ' Send register address
I2CREAD BME280_Read, MSB, [LSB] ' Read MSB and LSB
Result = (MSB << 8) + LSB ' Combine MSB and LSB into a 16-bit integer
End Sub
' Subroutine to read an 8-bit value from a register
Sub ReadUInt8(ByVal Reg As Byte, Dim ByRef Result As Byte)
I2CWRITE BME280_Address, Reg ' Send register address
I2CREAD BME280_Read, Result ' Read 8-bit value
End Sub
' Subroutine to read calibration data
Sub ReadCalibrationData()
ReadUInt16($88, dig_T1)
ReadInt16($8A, dig_T2)
ReadInt16($8C, dig_T3)
ReadUInt16($8E, dig_P1)
ReadInt16($90, dig_P2)
ReadInt16($92, dig_P3)
ReadInt16($94, dig_P4)
ReadInt16($96, dig_P5)
ReadInt16($98, dig_P6)
ReadInt16($9A, dig_P7)
ReadInt16($9C, dig_P8)
ReadInt16($9E, dig_P9)
ReadUInt8($A1, dig_H1)
ReadInt16($E1, dig_H2)
ReadUInt8($E3, dig_H3)
dig_H4 = (ReadUInt8($E4) << 4) + (ReadUInt8($E5) & $0F)
dig_H5 = (ReadUInt8($E6) << 4) + (ReadUInt8($E5) >> 4)
ReadInt8($E7, dig_H6)
End Sub
' Subroutine to start the BME280 measurement
Sub StartMeasurement()
I2CWRITE BME280_Address, BME280_Reg_Control_Hum, [$01] ' Set humidity oversampling to x1
I2CWRITE BME280_Address, BME280_Reg_Control_Meas, [$27] ' Set temp and pressure oversampling to x1, mode to normal
I2CWRITE BME280_Address, BME280_Reg_Config, [$A0] ' Set standby time to 1000ms
End Sub
' Subroutine to read raw data from the sensor
Sub ReadRawData()
Dim data(8) As Byte
I2CWRITE BME280_Address, BME280_Reg_Pressure_MSB ' Set register pointer to pressure MSB
I2CREAD BME280_Read, data[0], [data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]] ' Read 8 bytes of data
adc_P = (data[0] << 12) + (data[1] << 4) + (data[2] >> 4) ' Pressure raw
adc_T = (data[3] << 12) + (data[4] << 4) + (data[5] >> 4) ' Temperature raw
adc_H = (data[6] << 8) + data[7] ' Humidity raw
End Sub
' Subroutine to calculate true temperature
Function CalculateTemperature() As Long
Dim var1 As Long, var2 As Long, T As Long
var1 = (((adc_T >> 3) - (dig_T1 << 1)) * dig_T2) >> 11
var2 = (((((adc_T >> 4) - dig_T1) * ((adc_T >> 4) - dig_T1)) >> 12) * dig_T3) >> 14
t_fine = var1 + var2
T = (t_fine * 5 + 128) >> 8
CalculateTemperature = T
End Function
' Subroutine to calculate true pressure
Function CalculatePressure() As Long
Dim var1 As Long, var2 As Long
Dim P As Long
var1 = (t_fine >> 1) - 64000
var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * dig_P6
var2 = var2 + ((var1 * dig_P5) << 1)
var2 = (var2 >> 2) + (dig_P4 << 16)
var1 = (((dig_P3 * (((var1 >> 2) * (var1 >> 2)) >> 13)) >> 3) + ((dig_P2 * var1) >> 1)) >> 18
var1 = ((32768 + var1) * dig_P1) >> 15
If var1 = 0 Then
CalculatePressure = 0 ' Avoid division by zero
Else
P = (((1048576 - adc_P) - (var2 >> 12))) * 3125
If P < $80000000 Then
P = (P << 1) / var1
Else
P = (P / var1) * 2
End If
var1 = (dig_P9 * (((P >> 3) * (P >> 3)) >> 13)) >> 12
var2 = (((P >> 2)) * dig_P8) >> 13
P = P + ((var1 + var2 + dig_P7) >> 4)
CalculatePressure = P
End If
End Function
' Subroutine to calculate true humidity
Function CalculateHumidity() As Long
Dim H As Long
H = (t_fine - 76800)
H = (((((adc_H << 14) - (dig_H4 << 20) - (dig_H5 * H)) + 16384) >> 15) * (((((((H * dig_H6) >> 10) * (((H * dig_H3) >> 11) + 32768)) >> 10) + 2097152) * dig_H2 + 8192) >> 14))
H = H - (((((H >> 15) * (H >> 15)) >> 7) * dig_H1) >> 4)
H = (H < 0) ? 0 : H
H = (H > 419430400) ? 419430400 : H
CalculateHumidity = (H >> 12)
End Function
' Main program
Start:
' Initialize the BME280 sensor
ReadCalibrationData() ' Read calibration coefficients
StartMeasurement() ' Start measurement
' Read raw data from the sensor
ReadRawData()
' Calculate temperature, pressure,
Bookmarks