This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430G2553: getting wrong raw value for temperature in bme280 sensor

Part Number: MSP430G2553


i have interface bme280 with msp430 with spi communication.I have used algorithm defined by Bosch for calculating the temperature.But it showing me wrong value.

 whether i have to send command to start conversion or not? i did't find any command to start the conversion .

here is my code below.  

#include <msp430.h>

#define DLY 8000
long int data,reset,con_hum,cont_meas,status,pressure[4],temp[4];
unsigned short int tem_dig1[2],Tem_Dig1;
short int tem_dig2[2],tem_dig3[2],Tem_Dig2,Tem_Dig3;
long int Raw_Temp,real_temp;
long int var1, var2, T,t_fine;
/**
* main.c
*/
void clockConfig(void);
void uart_init(void);
void spi_init(void);
void uart_put(char byte);
int sensor_read(char data);
void spi_write(char byte);
char spi_read(void);
void calibrated_temp_values()
{
tem_dig1[0]=sensor_read(0x89);
tem_dig1[1]=sensor_read(0x88);
tem_dig2[0]=sensor_read(0x8B);
tem_dig2[1]=sensor_read(0x8A);
tem_dig3[0]=sensor_read(0x8D);
tem_dig3[1]=sensor_read(0x8C);
}

void get_actual_values()
{
Tem_Dig1=(tem_dig1[0]<<8)+tem_dig1[1];
Tem_Dig2=(tem_dig2[0]<<8)+tem_dig2[1];
Tem_Dig3=(tem_dig3[0]<<8)+tem_dig3[1];

}

void get_raw_values_temp()
{
temp[0]=sensor_read(0xFA);
temp[1]=sensor_read(0xFB);
temp[2]=sensor_read(0xFC);
Raw_Temp=(temp[0]<<12)+(temp[1]<<4)+temp[2];
}

long int actual_temp()
{
var1 = (((Raw_Temp>>3)-(Tem_Dig1<<1))*Tem_Dig2) >> 11;
var2 = (((((Raw_Temp>>4)-(Tem_Dig1))*((Raw_Temp>>4)-(Tem_Dig1))) >> 12)*(Tem_Dig3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}


int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
clockConfig();


uart_init();


spi_init();


P1DIR |= BIT0;


P1OUT |= BIT0;


uart_put('A');


data=sensor_read(0xD0);


reset=sensor_read(0xE0);


con_hum=sensor_read(0xF2);

status=sensor_read(0xF3);

cont_meas=sensor_read(0xF4);


calibrated_temp_values();


get_actual_values();


get_raw_values_temp();


real_temp=actual_temp();


__no_operation();
}


void clockConfig(void)
{
// configure the CPU clock (MCLK)
// to run from DCO @ 8MHz and SMCLK = DCO / 2
BCSCTL1 = CALBC1_8MHZ; // Set DCO
DCOCTL = CALDCO_8MHZ;
BCSCTL2= DIVS_1 + DIVM_0; // divider=2 for SMCLK and 1 for MCLK
}


void uart_init(void)
{
P1SEL |= BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD
P1SEL2 |=BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD

UCA0CTL1 = UCSWRST; // reset
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 0xA0; // 9600 baud rate // 0x08; // 1MHz 115200
UCA0BR1 = 0x01; // 1MHz 9600
UCA0MCTL = UCBRS2 | UCBRS1; //UCBRF_1 | UCOS16; // 9600
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
//UC0IE |= UCA0RXIE; // Enable USCI_A0 RX interrupt
}

void spi_init(void)
{
// set the pin mode 3 for pins 5,6 & 7 of port 1 (USCI mode)
P1SEL |= BIT5 + BIT6 + BIT7; // low bit = 1 for pins 5,6 and 7 BIT 3 is 0 (CS via GPIO)
P1SEL2 |= BIT5 + BIT6 + BIT7; // high bit = 1 for pins 5,6 and 7 BIT 3 is 0 (CS via GPIO)

P1DIR |= BIT4; // p1.4 set to output to drive CS
P1OUT |= BIT4; // pull p1.4 to high - CS high -> chip is disabled

UCB0CTL1 = UCSWRST;

// synchronous (=SPI) master 3 wire SPI, clock polarity Low at idle
// SPI mode 0
UCB0CTL0 |= UCCKPH | UCMST | UCSYNC | UCMSB | UCMODE_0;

UCB0CTL1 |= UCSSEL_2; //use SCLK : 4MHz

// set baud rate = SMCLK, divide by 4, SPI Clock Freq : 1 MHz
UCB0BR0 = 0x04;
UCB0BR1 = 0;
UCB0CTL1 &= ~UCSWRST; // ** Initialize USCI **
}


void uart_put(char byte)
{
UCA0TXBUF = byte;
while (!( IFG2 & UCA0TXIFG));
}

int sensor_read(char data)
{
int ch = 1;

P1OUT &= ~BIT4; // Enable Device
_delay_cycles(DLY);
spi_write(data);
spi_write(0xFF);
while((UCB0STAT & UCBUSY)); // Wait if Transmit process is busy

ch = spi_read();

_delay_cycles(DLY);
P1OUT |= BIT4; // Disable Device

return(ch);
}

void spi_write(char byte)
{
UCB0TXBUF = byte;
while (!( IFG2 & UCB0TXIFG));
}

char spi_read(void)
{
while (!(IFG2 & UCB0RXIFG)); // USCI_b0 RX Received?
return(UCB0RXBUF);
}

  • > whether i have to send command to start conversion or not?
    As I read BST-BME280-DS001-10, you have to set ctrl_meas for "Normal" mode (it resets in "Sleep" mode) to get it going. This would be a write to address 0x74 with value 0x03 (Table 18, sec 5.4.5). You'll need a sensor_write() but that should be a simple change to sensor_read().

    > Raw_Temp=(temp[0]<<12)+(temp[1]<<4)+temp[2];
    The significant bits in 0xFC are the high 4, not the low 4 (Table 18). Try:
    > Raw_Temp=(temp[0]<<12)+(temp[1]<<4)+(temp[2] >> 4);

    I haven't been through your arithmetic in actual_temp(), though shifting signed values usually makes me a little nervous. What I suggest is that, once you start getting data, you go through the arithmetic with a calculator or on paper to see if you get what Bosch says you should. Save a few of your code's intermediate values to help you narrow down any discrepancies.

**Attention** This is a public forum