Jump to content
43oh

Accelerometer reading problem


Recommended Posts

Hi, I'm using msp430f2274 to program an accelerometer. The values of x,y,z I display on CCS does not seem to be related to the changes in accelerometer and the value is just jumping around to random numbers. I'm using http://coder-tronics.com/msp430-adc-tutorial/ example 3 as a reference for my code. Below are my codes, hardware connection, and result on the CCS: 

I connect battery to accelerometer and X,Y,Z output of accelerometer to P2.1, P2.2, P2.3 of the msp430. My codes are as follow :

#include <msp430.h>
#define BIT0 (0x0001)
#define BIT1 (0x0002)
#define BIT2 (0x0004)
#define BIT3 (0x0008)
#define BIT4 (0x0010)
#define BIT5 (0x0020)
#define BIT6 (0x0040)
#define BIT7 (0x0080)
#define BIT8 (0x0100)
#define BIT9 (0x0200)
#define BITA (0x0400)
#define BITB (0x0800)
#define BITC (0x1000)
#define BITD (0x2000)
#define BITE (0x4000)
#define BITF (0x8000)

// Global Variables
unsigned int adc[3] = {0};	// This will hold the x,y and z axis values
unsigned int X_Axis = 0;
unsigned int Y_Axis = 0;
unsigned int Z_Axis = 0;

//Function Prototypes
void Setup_HW(void);		// Setup watchdog timer, clockc, ADC ports
void Read_Acc(void);	// This function reads the ADC and stores the x, y and z values

int main(void)
{

	Setup_HW();			// Setup watchdog timer, clocks, ADC ports

	while (1)			// Code run continuously inside the while loop

		{
			Read_Acc();	// This function reads the ADC and stores the x, y and z values
		}
}

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
  __bic_SR_register_on_exit(CPUOFF);        // Clear CPUOFF bit from 0(SR)
}

void Setup_HW(void)
{
	  WDTCTL = WDTPW + WDTHOLD;
	  // Stop watch dog timer

	  BCSCTL1 = DIVA_0;     	// Set range
	  DCOCTL = CALDCO_1MHZ,		// Set DCO clock frequency

	  ADC10CTL1 = INCH_3 + CONSEQ_3;
	  // ADC10CTL1 control Register 1
	  // INCH_3 selects channel 3 as the highest channel for a sequence of conversions A3/A2/A1
	  // CONSEQ_1 conversion sequence mode 3 repeat sequence of channels
	  ADC10CTL0 = ADC10SHT_1 + MSC + ADC10ON + ADC10IE + REFON; // + ADC10SR;
	  // ADC10CTL0 control Register 0
	  // ADC10SHT_1 sample and hold time, 2 = 16 x ADC10CLK
	  // MSC multiple sample and conversions
	  // ADC10ON adc10 on
	  // ADC10IE adc10 interrupt enable
	  // REFON internal reference voltage is on and set to 1.5V
	  ADC10DTC1 = 0x03;
	  // Data Transfer Control register, defines the number of transfers in each block, 3 in this case

	  ADC10AE0 |= BIT3+ BIT2 + BIT1;
	  // ADC10 analog enable bits P2.3,P2.2 and P2.1 (bit1 = 0x02, bit2 = 0x04 and bit3 = 0x08 therefore 14 in hex = 0x0E)


}

void Read_Acc(void)
{
    ADC10CTL0 &= ~ENC;
    while (ADC10CTL1 & BUSY);               // Wait if ADC10 core is active
    ADC10SA = (unsigned int)adc;			// Copies data in ADC10SA to unsigned int adc array
    ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
    __bis_SR_register(CPUOFF + GIE);        // LPM0, ADC10_ISR will force exit


    X_Axis = adc[2];						// adc array 2 copied to the variable X_Axis
    Y_Axis = adc[1];						// adc array 1 copied to the variable Y_Axis
    Z_Axis = adc[0];						// adc array 0 copied to the variable Z_Axis
}

This is the result I got :

post-38537-0-68103400-1412738889_thumb.png

Link to post
Share on other sites
  • 2 weeks later...

Hi Pawnie,

 

Firstly sorry to hear you had trouble with my code!  I can see one thing I would change and this may help, but if not follow the further steps below.

 

 

Move the last 4 statements in the Read_adc() function around as below, so the CPU is sent to sleep after the readings from the array are assigned to the variables

 

X_Axis = adc[2];                        // adc array 2 copied to the variable X_Axis
Y_Axis = adc[1];                        // adc array 1 copied to the variable Y_Axis
Z_Axis = adc[0];                        // adc array 0 copied to the variable Z_Axis

 

__bis_SR_register(CPUOFF + GIE); // LPM0, ADC10_ISR will force exit

 

The next things I would do is confirm the code is working correctly on the MSP430F2274.  Your reading values as the adc[] array is initialised so those values are coming from somewhere, So what I propose is the following:

 

1) Connect the X ADC input reading to Gnd and you should get a 0 in CCS, then connect to 3.3V (I usually do this via a 1k resistor) to the ADC X input and you should then see something around 4095.  You can repeat these steps for the Y and Z ADC connections.  Assuming these read as expected pretty sure the code is working ok on the MSP430F2274.

2) What voltage ranges are you expecting from the Accelerometer?

3) Check the accelerometer voltage ranges by using a multimeter.  If you are unsure of the range the datasheet should tell you, you can also note what the level values are then as well.

4) Also remember CCS updates the data at a slower rate than the microcontroller, it's default settings is every 500mS, you can reduce this to 100mS

 

Pending on these test we can then see if we can solve this issue.

 

Cheers,

Ant

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...