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.

Using MLX90614 with MSP430g2553

Hello,

I am trying to interface MLX90614

my code gets trapped in the while loops of the tempRead() function

any thoughts why would that happen?

#include <msp430g2553.h>

#ifndef TIMER0_A1_VECTOR
#define TIMER0_A1_VECTOR    TIMERA1_VECTOR
#define TIMER0_A0_VECTOR    TIMERA0_VECTOR
#endif

void FaultRoutine(void);
void ConfigWDT(void);
void ConfigClocks(void);
void ConfigLED(void);
void ConfigI2C(void);
int tempRead(void);
void ConfigTimerA2(void);

#define SLAVEAD 0x00

int TRead=0;
int temp;
int temp_high;
int temp_low;
unsigned int PEC;



int main(void) {
	volatile unsigned int i;

	ConfigWDT();
	ConfigClocks();
	ConfigLED();
	ConfigI2C();
	ConfigTimerA2();
	
	_BIS_SR(LPM0_bits+GIE);			//Enable global interrupts
	while(1){
	}
}

void ConfigWDT(void)
 {
 WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
 }

void ConfigClocks(void)
 {
 if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
   FaultRoutine();		                    // If calibration data is erased
 				                            // run FaultRoutine()
  BCSCTL1 = CALBC1_1MHZ; 					// Set range
  DCOCTL = CALDCO_1MHZ;  					// Set DCO step + modulation
  BCSCTL3 |= LFXT1S_2;                      // LFXT1 = VLO
  IFG1 &= ~OFIFG;                           // Clear OSCFault flag
  BCSCTL2 |= SELM_0 + DIVM_2 + DIVS_2;      // MCLK = DCO/4, SMCLK = DCO/4
 }

void FaultRoutine(void)
 {
   P1OUT = BIT0;                            // P1.0 on (red LED)
   while(1); 			                    // TRAP
 }

void ConfigLED(void){
  P1DIR = BIT0+BIT6;                             // P1.0 (red) output
  P1OUT = 0;                                // LED off
}

void ConfigI2C(void){
	P1SEL |= BIT6 + BIT7;				 	// Assign I2C pins to USCI_B0
	P1SEL2|= BIT6 + BIT7; 					// Assign I2C pins to USCI_B0

	UCB0CTL1 |= UCSWRST;					// Reset I2C to configure

	IE2 |= UCB0TXIE + UCB0RXIE;				// enable TX and RX interrupts

	/* Configurign I2C */
	UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;	// Master, I2C mode, Synchronous
	UCB0CTL1 = UCSSEL_2 + UCSWRST;			// SMCLK, and keep as reset
	UCB0BR0 = 5;							// SMCLK/5 = 100 KHz
	UCB0BR1 = 0;
	UCB0I2CSA = SLAVEAD;					// Set Slave address

	UCB0CTL1 &= ~UCSWRST;					// Enable I2C
}



int tempRead(void){
	UCB0CTL1 |= UCTR+UCTXSTT;			// Start transmission
	while (!(IFG2 & UCB0TXIFG));
	UCB0TXBUF = 0x07;					// Access RAM, object Temperature 1
	//while(UCB0CTL1 & UCTXSTT);			// wait until start condition is sent
	while (!(IFG2 & UCB0TXIFG));
	UCB0CTL1 &= ~UCTR;				  // Change to RX

	while (UCB0CTL1 & UCTXSTT);
	UCB0CTL1 |= UCTXSTT;				// Start

	while(!(IFG2 & UCB0RXIFG));
	temp_low=UCB0RXBUF;					// Get low byte

	while(!(IFG2 & UCB0RXIFG));
	temp_high=UCB0RXBUF;				// Get high byte

	while(!(IFG2 & UCB0RXIFG));
	PEC=UCB0RXBUF;						// Read packet error code

	UCB0CTL1 |= UCTXSTP;				// Stop
	temp = temp_low | (temp_high << 8);	// Concatinate MSB and LSB
	temp = (temp*2 - 27315)/100;			// temperature in degree celceues
	return temp;
}


void ConfigTimerA2(void){
	CCTL0 = CCIE;							// Allow periodic interrupt
	CCR0 = 12000;							// Enable interrupts every 1 second
	TACTL = TASSEL_1 + MC_1;
}

#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A_ISR (void){
	TRead = tempRead();
	CCR0 +=12000;
}

I am new to MSP430 so I don't know much

I have been reading the manuals, I don't understand them very well though

  • Hello Hasan Alkhater,

    Let me be the first to welcome you to the world of MSP430!  I hope you find it to be an enjoyable experience.

    The very first thing I've noticed is that your slave address is set at 0 hex whereas the MLX90614 datasheet specifies that the slave address is 5A hex.  You will need to change this value or else communication between the two devices will never commence.

    Second, in which while loop does your code hang?  You can find this out by pausing operation inside of your debugger interface and seeing in which loop the code is stopped.  This will help determine where and how your code is trapped.

    You mention being new to MSP430 and not understanding the manuals.  Is this code sampled from existing examples?  It is important to know what your code is trying to do in order to debug it properly.

    Regards,

    Ryan

  • Thank you Ryan, I am enjoying it and feeling appreciation toward the MSP430!

    I am hating communicating with MLX90614 thought :P

    Yeah when I posted this I didn't know what to do

    I figured out recently that the address for MLX90614 has to be 5Ah, and I know a little more now :P

    I copied this function from another thread that was posted in the forum and was fixed as far as I know, the original code is found here:

    http://e2e.ti.com/support/microcontrollers/msp430/f/166/t/227655.aspx

    but I think it is working for its owner after it was fixed

    I used it first as it is without changing the address he is using but communication never commences for me

    What I am trying to do is to read the temperature

    Yeah I did go through the debugger and used some breaking points and stepped around.

    the code gets trapped in all the loops

    you notice that I have commented the loop that checks for if UCTXSTT was cleared, if I use that loop, my software gets trapped.

    I also checked for UCNACKIFG, but it never gets set, which means the MLX90614 acknowledges?

    anyways, I commented that loop, but the program gets trapped into the next loop checking for UCB0TXIFG,

    I commented the loops one by one, and the communication always fails

    In my code I removed a function that was in the original code, which is the setslaveaddress

    from my understanding, this function just erases the older SMBus address and creates a new one?

    but I suppose it is not necessary, and even if I use it, I get trapped when I wait for the UCB0TXIFG to be set (the very first loop)

     

    I hope my explanation was clear

     

    Regards,

    Hasan

  • First of all, I would delete line 74 since your code does not use tx and rx interrupts, only polls the interrupt flags.  Then I would do as JMG suggested in the other thread:  comment back in line 92 to make sure that the start condition is sent.  If this traps your code, something is wrong with the initialization.  Also place the line

    if(UCB0STAT & UCNACKIFG);

    to make sure that acknowledgement was received.  Something could also be wrong with your initialization if the start condition is never acknowledged by the slave device.  In the end, your best resource will be Matthew Mertzlufft since he is working on the same project.  He never does say in the other thread if he was able to begin communication correctly.

    Regards,

    Ryan

**Attention** This is a public forum