Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    BME280 Raw Temp data never changes

    BME280 Raw Temp data never changes

    Kenny22
    New Poster

    As the title states my raw temperature data never changes even as the room's temperature fluctuates. I'm connected to the device via SPI and can read the device ID and change the mode of the sensors but the raw data never updates. This device is connected to a PIC32CMMC, any help would be appreciated. I have posted the code below this paragraph. Main issue right now is readTemp but if you notice something else as well feel free to let me know.

    #include <stddef.h>                     // Defines NULL
    #include <stdbool.h>                    // Defines true
    #include <stdlib.h>                     // Defines EXIT_FAILURE
    #include "definitions.h"                // SYS function prototypes
    //#include "bme280def.h"                  //bme280 defs
    #include <stdio.h>
    #include <xc.h>
    #include <string.h>
    #include <math.h>
    
    //definitions
    #define BME280_REG_CHIP_ID             0xD0
    #define BME280_REG_RESET               0xE0
    #define BME280_REG_STATUS              0xF3
    #define BME280_REG_CTRL_MEAS           0xF4
    #define BME280_REG_CTRL_HUMIDITY       0xF2
    #define BME280_REG_CONFIG              0xF5
    #define BME280_REG_PRESSURE_MSB        0xF7
    #define BME280_REG_PRESSURE_LSB        0xF8
    #define BME280_REG_PRESSURE_XLSB       0xF9
    #define BME280_REG_TEMPERATURE_MSB     0xFA
    #define BME280_REG_TEMPERATURE_LSB     0xFB
    #define BME280_REG_TEMPERATURE_XLSB    0xFC
    #define BME280_REG_HUMIDITY_MSB        0xFD
    #define BME280_REG_HUMIDITY_LSB        0xFE
    
    
    #define CTRL_HUM 0xF2  // BME280 humidity register settings
    #define CONTROL 0xF4 //BME280 control register
    #define TEMP_REG 0xFA // BME280 temperature reg
    #define HUM_REG 0xFD // BME280 humidity reg
    #define PRESS_REG 0xF7 // BME280 pressure reg
    #define reset_REG 0xE0 // BME280 reset register, write 0xB6 to it
    #define dig_T1_REG 0x88 // BME280 temp calibration coefficients...
    #define dig_T2_REG 0x8A
    #define dig_T3_REG 0x8C
    #define dig_H1_REG 0xA1 // BME280 humidity calibration coefficients...
    #define dig_H2_REG 0xE1
    #define dig_H3_REG 0xE3
    #define dig_H4_REG 0xE4
    #define dig_H5_REG 0xE5
    #define dig_H6_REG 0xE7
    #define dig_P1_REG 0x8E // BME280 pressure calibration coefficients...
    #define dig_P2_REG 0x90
    #define dig_P3_REG 0x92
    #define dig_P4_REG 0x94
    #define dig_P5_REG 0x96
    #define dig_P6_REG 0x98
    #define dig_P7_REG 0x9A
    #define dig_P8_REG 0x9C
    #define dig_P9_REG 0x9E
    
    //Declarations
    signed long int t_fine; // global variable 
    
    float temperature, humidity, pressure; //variables for each data. 
    float temperatures[240];//array for all temps stored in an hour
    
    uint8_t deviceID;
    
    //Forces a sample of the BME280. Also sets oversampling for humidity, temp and press = 1.
    //Consult the BME280 Datasheet to change these options. 
    void BME280_init();
    
    //Write a byte to a register via SPI 
    void writeSPI(char, char);
    
    // return a unsigned 16-bit value 
    unsigned int readSPI16bit(char);
    
    // return a unsigned 8-bit value
    unsigned char readSPI8bit(char);
    // returns a unsigned 16-bit (little endian) 
    unsigned int readSPI16bit_u_LE(char);
    
    // returns a unsigned 16-bit (little endian)
    signed int readSPI16bit_s_LE(char); 
    
    // get temperature and returns it in Celsius
    float readTemp(); 
    
    // gets RH humidity and returns it as a percentage
    float readHumidity();
    
    // gets pressure and returns it in kPa.
    float readPressure(); 
    // *****************************************************************************
    // *****************************************************************************
    // Section: Main Entry Point
    // *****************************************************************************
    // *****************************************************************************
    
    int main ( void )
    { 
        char *formattedTemp;
        /* Initialize all modules */
        SYS_Initialize ( NULL );
        deviceID = 0x00;
        
        CS0_Set();
        
        CS0_Clear();
        BME280_init(); // starts a new sample 
        CS0_Set();
        
        while ( true ){
            CS0_Clear();
            writeSPI(reset_REG, 0xB6); //reset the BME280
            CS0_Set();
            
            CS0_Clear();
            BME280_init(); // starts a new sample 
            CS0_Set();
            
            deviceID = 0x00;
            CS0_Clear();
            deviceID = readSPI8bit(BME280_REG_CHIP_ID);
            CS0_Set();
            printf("ID = %X\n",deviceID);
            
            CS0_Clear();
            temperature = readTemp(); // reads temp sample 
            CS0_Set();
            printf("Celsius Temp: %f\n",temperature);
            
            
            temperature = temperature*9/5 + 32; // convert to Fahrenheit
              
            printf("F temp: %f\n",temperature);
            
            CS0_Clear();
            humidity = readHumidity(); // reads temp sample 
            CS0_Set();
            DelaySec(10);
        }
    
        /* Execution should not come here during normal operation */
    
        return ( EXIT_FAILURE );
    }
    
    unsigned char readSPI8bit(char reg){
        unsigned char regData;
        SERCOM3_SPI_Write(&reg,1);
        while(SERCOM3_SPI_IsBusy()){
            WDT_Clear();
        } 
        SERCOM3_SPI_Read(&regData,1);
        while(SERCOM3_SPI_IsBusy()){
            WDT_Clear();
        } 
        return regData; 
    }
    
    unsigned int readSPI16bit(char reg){
        unsigned int val;
        val = readSPI8bit(reg); // shift in MSB
        val = val << 8 | readSPI8bit(reg+1); // shift in LSB
        return val;
    }
    
    signed int readSPI16bit_s(char reg){
    return (signed int) readSPI16bit(reg);
    }
    
    unsigned int readSPI16bit_u_LE(char reg){ // read 16-bits unsigned little endian
        unsigned int val;
        val = readSPI16bit(reg); 
        return (val >> 😎 | (val << 8); // swap upper and lower regs
    }
    
    signed int readSPI16bit_s_LE(char reg) { // read 16-bit signed little endian
        return (signed int) readSPI16bit_u_LE(reg);
    }
    
    void writeSPI(char reg, char data){
        reg = reg & 0x7F; //mask off first bit to specify a write. 
        
        SERCOM3_SPI_Write(&reg,1);
        while(SERCOM3_SPI_IsBusy()){
            WDT_Clear();
        } 
        SERCOM3_SPI_Write(&data,1);
        while(SERCOM3_SPI_IsBusy()){
            WDT_Clear();
        } 
    }
    
    void BME280_init(){
        writeSPI(BME280_REG_CTRL_HUMIDITY, 0x03); // 1Forced, 3normal mode, Humidity oversampling = 1
        writeSPI(BME280_REG_CTRL_MEAS, 0x27); // 25Forced mode,27normal mode, Temp/Press oversampling = 1
    }
    
    float readTemp(void){
        // Calibration Coefficients:
        unsigned long int dig_T1 = readSPI16bit_u_LE(dig_T1_REG); 
        signed long int dig_T2 = readSPI16bit_s_LE(dig_T2_REG);
        signed long int dig_T3 = readSPI16bit_s_LE(dig_T3_REG);
        
        // Temperature Raw ADC:
        unsigned long int adc_T = 0;
        adc_T = readSPI16bit_u_LE(TEMP_REG);
        adc_T <<= 8; // move in XLSB register
        adc_T |= readSPI8bit(TEMP_REG + 2);
        adc_T >>= 4; // Only uses top 4 bits of XLSB register 
    
        // From BME280 data sheet: 
        signed long int var1  = ((((adc_T>>3) - (dig_T1 <<1))) *
    	   (dig_T2)) >> 11;
      
        signed long int var2  = (((((adc_T>>4) - (dig_T1)) *
    	     ((adc_T>>4) - (dig_T1))) >> 12) *
    	     (dig_T3)) >> 14;
    
        t_fine = var1 + var2;
     
        float T = (t_fine * 5 + 128) >> 8;
        return T/100;
    }
    
    float readHumidity(void){
        // Calibration Coefficients
        unsigned int dig_H1 = readSPI8bit(dig_H1_REG);
        signed long int dig_H2 = readSPI16bit_s_LE(dig_H2_REG);
        unsigned int dig_H3 = readSPI8bit(dig_H3_REG);
        signed long int dig_H4 = (readSPI8bit(dig_H4_REG)<<4)|(readSPI8bit(dig_H4_REG+1) & 0xF);
        signed long int dig_H5 = (readSPI8bit(dig_H5_REG+1)<<4)|(readSPI8bit(dig_H5_REG)>>4);
        signed int dig_H6 = (signed int) readSPI8bit(dig_H6_REG);
        
        //Humidity raw ADC
        unsigned long int adc_H = readSPI16bit(HUM_REG);
        
        //compensate
        unsigned long int v_x1_u32r;
        v_x1_u32r = t_fine - 76800;
        
        v_x1_u32r = (((((adc_H << 14) - ((dig_H4) << 20) - ((dig_H5) * v_x1_u32r))
                + (16384)) >> 15) * (((((((v_x1_u32r * (dig_H6)) >> 10) *
    		    (((v_x1_u32r * (dig_H3)) >> 11) + (32768))) >> 10) +
                (2097152)) * (dig_H2) + 8192) >> 14));
        
        v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) *
    			    (dig_H1)) >> 4));
        
        v_x1_u32r = (v_x1_u32r <0 )? 0: v_x1_u32r;
        v_x1_u32r = (v_x1_u32r > 419430400)?419430400:v_x1_u32r;
        float humidity = (v_x1_u32r>>12);
        return humidity/1024.0;
    }
    
    // second delay user chooses how many seconds
    void DelaySec(uint8_t time){
        int seconds = 0;
        while(seconds < time){
            TC0_TimerStart();
            while(!TC0_TimerPeriodHasExpired());
            WDT_Clear();
            seconds++;
        }
        return;
    }
    
    
    
    //1 minute delays used for sensors to gather readings every minute
    void DelayminuteT0(){
        int seconds = 0;
        while(seconds <60){
            TC0_TimerStart();
            while(!TC0_TimerPeriodHasExpired()){
                WDT_Clear();
            };
            WDT_Clear();
            seconds++;
        }
        return;
    }
    
    //main time function to call function on designated time frames
    void onTimeT0(){
        while(true){
            int seconds = 0;
            int minutes = 0;
            while(minutes < 60){
                while(seconds < 60){
                    TC0_TimerStart();
                    while(!TC0_TimerPeriodHasExpired());
                    seconds++;
                }
                minutes++;
                seconds = 0;
                readTemp();
                if(minutes%5 == 0){
                    adjustDampers();
                }
            }
            avgSensors();
        }
        return;
    }
    
    
    
    //open or close damper based on most recent temperature in the room
    void adjustDampers(){
        return;
    }
    
    //averages sensor readings for storage
    void avgSensors(){
        float avg;
        for(int i = 0; i < 240; i++){
            avg += temperatures[i];
        }
        avg = avg/240;
        
        //empty temp array to make ready for new temperatures
        for(int i = 0; i < 240; i++){
            temperatures[i] = 0;
        }
        return;
    }
    
    
    /*******************************************************************************
     End of File
    */



    1 REPLY 1

    BSTRobin
    Community Moderator
    Community Moderator

    Hi Kenny22,

    We are not familiar with your hardware platform and software environment. You can refer to the official BME280 sensor API and example code https://github.com/boschsensortec/BME280_SensorAPI to check for any differences between your code and the reference code.

    Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist