BME280 via I2C?


+ Reply to Thread
Results 1 to 7 of 7

Thread: BME280 via I2C?

Hybrid View

  1. #1
    Join Date
    Feb 2013
    Posts
    1,124


    Did you find this post helpful? Yes | No

    Default Re: BME280 via I2C?

    I asked to make corrections and he(or it?) created new code, this time with SWORD type variables
    when I asked what kind is SWORD variables is, it answered that these are variables not supported by PBP

    After some discussion, it finally generated more "normal" looking code, but this needs PBPL, I never used it, can microcode studio modified to launch PBPL automatically?

    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 calibration and raw sensor data
    dig_T1 VAR WORD
    dig_P1 VAR WORD
    dig_H1 VAR BYTE
    dig_H2 VAR WORD
    dig_T2 VAR WORD
    dig_T3 VAR WORD
    dig_P2 VAR WORD
    dig_P3 VAR WORD
    dig_P4 VAR WORD
    dig_P5 VAR WORD
    dig_P6 VAR WORD
    dig_P7 VAR WORD
    dig_P8 VAR WORD
    dig_P9 VAR WORD
    dig_H3 VAR BYTE
    dig_H4 VAR WORD
    dig_H5 VAR WORD
    dig_H6 VAR BYTE
    
    
    adc_T VAR LONG
    adc_P VAR LONG
    adc_H VAR WORD
    t_fine VAR LONG
    
    
    ' Temporary variables for handling read data
    MSB VAR BYTE
    LSB VAR BYTE
    Result VAR WORD
    data0 VAR BYTE
    data1 VAR BYTE
    data2 VAR BYTE
    data3 VAR BYTE
    data4 VAR BYTE
    data5 VAR BYTE
    data6 VAR BYTE
    data7 VAR BYTE
    data8 VAR BYTE
    
    
    ' Subroutine to read an unsigned 16-bit value from a register
    ReadUInt16:
        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
    RETURN
    
    
    ' Subroutine to read a signed 16-bit value from a register
    ReadInt16:
        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
    
    
        ' Handle signed 16-bit conversion
        IF Result > 32767 THEN
            Result = Result - 65536
        ENDIF
    RETURN
    
    
    ' Subroutine to read an 8-bit value from a register
    ReadUInt8:
        I2CWRITE BME280_Address, [Reg]          ' Send register address
        I2CREAD BME280_Read, [Result]           ' Read 8-bit value
    RETURN
    
    
    ' Subroutine to read calibration data
    ReadCalibrationData:
        Reg = $88 : GOSUB ReadUInt16 : dig_T1 = Result
        Reg = $8A : GOSUB ReadInt16 : dig_T2 = Result
        Reg = $8C : GOSUB ReadInt16 : dig_T3 = Result
        Reg = $8E : GOSUB ReadUInt16 : dig_P1 = Result
        Reg = $90 : GOSUB ReadInt16 : dig_P2 = Result
        Reg = $92 : GOSUB ReadInt16 : dig_P3 = Result
        Reg = $94 : GOSUB ReadInt16 : dig_P4 = Result
        Reg = $96 : GOSUB ReadInt16 : dig_P5 = Result
        Reg = $98 : GOSUB ReadInt16 : dig_P6 = Result
        Reg = $9A : GOSUB ReadInt16 : dig_P7 = Result
        Reg = $9C : GOSUB ReadInt16 : dig_P8 = Result
        Reg = $9E : GOSUB ReadInt16 : dig_P9 = Result
        Reg = $A1 : GOSUB ReadUInt8 : dig_H1 = Result
        Reg = $E1 : GOSUB ReadInt16 : dig_H2 = Result
        Reg = $E3 : GOSUB ReadUInt8 : dig_H3 = Result
        Reg = $E4 : GOSUB ReadUInt8 : MSB = Result
        Reg = $E5 : GOSUB ReadUInt8 : LSB = Result
        dig_H4 = (MSB << 4) + (LSB & $0F)
        Reg = $E6 : GOSUB ReadUInt8 : MSB = Result
        dig_H5 = (MSB << 4) + (LSB >> 4)
        Reg = $E7 : GOSUB ReadUInt8 : dig_H6 = Result
    RETURN
    
    
    ' Subroutine to start the BME280 measurement
    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
    RETURN
    
    
    ' Subroutine to read raw data from the sensor
    ReadRawData:
        I2CWRITE BME280_Address, [BME280_Reg_Pressure_MSB]         ' Set register pointer to pressure MSB
        I2CREAD BME280_Read, [data0, data1, data2, data3, data4, data5, data6, data7, data8] ' Read 8 bytes of data
    
    
        adc_P = (data0 << 12) + (data1 << 4) + (data2 >> 4) ' Pressure raw
        adc_T = (data3 << 12) + (data4 << 4) + (data5 >> 4) ' Temperature raw
        adc_H = (data6 << 8) + data7                        ' Humidity raw
    RETURN
    
    
    ' Subroutine to calculate true temperature
    CalculateTemperature:
        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
    RETURN T
    
    
    ' Subroutine to calculate true pressure
    CalculatePressure:
        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
            P = 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
            ENDIF
            var1 = (dig_P9 * (((P >> 3) * (P >> 3)) >> 13)) >> 12
            var2 = (((P >> 2)) * dig_P8) >> 13
            P = P + ((var1 + var2 + dig_P7) >> 4)
        ENDIF
    RETURN P
    
    
    ' Subroutine to calculate true humidity
    CalculateHumidity:
        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
    RETURN (H >> 12)
    
    
    ' Main program
    Start:
        ' Initialize the BME280 sensor
        GOSUB ReadCalibrationData  ' Read calibration coefficients
        GOSUB StartMeasurement     ' Start measurement
    
    
        ' Main loop: read data continuously
    MainLoop:
        GOSUB ReadRawData          ' Read raw data
        GOSUB CalculateTemperature ' Calculate true temperature
        GOSUB CalculatePressure    ' Calculate true pressure
        GOSUB CalculateHumidity    ' Calculate true humidity
    
    
        ' Display results (you can modify this to fit your output method)
        DEBUG "Temperature: ", DEC T, " C", 13, 10
        DEBUG "Pressure: ", DEC P, " Pa", 13, 10
        DEBUG "Humidity: ", DEC H, " %", 13, 10
    
    
        PAUSE 1000  ' Wait 1 second before the next reading
        GOTO MainLoop

  2. #2
    Join Date
    May 2013
    Location
    australia
    Posts
    2,643


    Did you find this post helpful? Yes | No

    Default Re: BME280 via I2C?

    H = (H > 419430400) ? 419430400 : H
    good luck getting the ternary operator to work with pbp

    RETURN (H >> 12)
    good luck getting pbp subroutines to return a value

    can microcode studio modified to launch PBPL
    just tick the box in the compile options
    Warning I'm not a teacher

  3. #3
    Join Date
    Feb 2013
    Posts
    1,124


    Did you find this post helpful? Yes | No

    Default Re: BME280 via I2C?

    Thanks, I'll squeeze every drop out of it

    It's just matter of curiosity, rather than actual need...

  4. #4
    Join Date
    Dec 2010
    Location
    Melbourne Australia
    Posts
    169


    Did you find this post helpful? Yes | No

    Default Re: BME280 via I2C?

    I've worked with the BMP180 with PBP, but not the BME280 IIRC.

    Troy

Similar Threads

  1. BME280 sensor.
    By HenrikOlsson in forum PBP3
    Replies: 19
    Last Post: - 18th October 2020, 06:46
  2. I2C two master on one I2C display
    By Kmt in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 22nd September 2014, 20:44
  3. I2C help Please
    By snuff28 in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 29th December 2011, 16:12
  4. I2C help!
    By linoko in forum mel PIC BASIC
    Replies: 1
    Last Post: - 24th December 2005, 09:13

Members who have read this thread : 9

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