Jump to content
43oh

longhorn engineer

Members
  • Content Count

    17
  • Joined

  • Last visited

  • Days Won

    2

Reputation Activity

  1. Like
    longhorn engineer got a reaction from pine in MSP-EXP430 : Accelerometer and Servo Demo   
    Video uploaded.
     


  2. Like
    longhorn engineer got a reaction from pine in MSP-EXP430 : Accelerometer and Servo Demo   
    Just finished tweaking and streaming the code.
     
    This code also contains a twin servo routine. The servos are connected to P1.4 and P1.5. When the X-axis moves the servo on P1.4 moves and when the Y-axis moves the servo on P1.5. The Z-aixs is implemented but not used in the program.
     

    #include "msp430fr5739.h" #include "FR_EXP.h" #define SERVO_1 BIT4 #define SERVO_2 BIT5 #define scale 9 unsigned int servo_counter = 0; unsigned int servo1pos = 1500; unsigned int servo2pos = 1500; unsigned int ADC_counter = 0; unsigned int ADCResult_X, ADCResult_Y, ADCResult_Z; unsigned int CalValue_X, CalValue_Y, CalValue_Z; unsigned int temp; void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop the dog SystemInit(); //Setup the pins StartUpSequence(); //Copy Ti's fancy LED boot up trick SetupAccel(); //Setup the ADC and Accel CalibrateADC(); //Find zero points of all 3 axis ADC10CTL0 |= ADC10ENC | ADC10SC; //Start the first sample. If this is not done the ADC10 interupt will not trigger. while (1) { if (ADCResult_X > CalValue_X + 10) { servo1pos = 1500 + scale * (ADCResult_X - CalValue_X); if (servo1pos > 2500) { servo1pos = 2500; } } else if (ADCResult_X < CalValue_X - 10) { servo1pos = 1500 - scale * (CalValue_X - ADCResult_X); if (servo1pos < 500) { servo1pos = 500; } } else { servo1pos = 1500; } if (ADCResult_Y > CalValue_Y + 10) { servo2pos = 1500 + scale * (ADCResult_Y - CalValue_Y); if (servo2pos > 2500) { servo2pos = 2500; } } else if (ADCResult_Y < CalValue_Y - 10) { servo2pos = 1500 - scale * (CalValue_Y - ADCResult_Y); if (servo2pos < 500) { servo2pos = 500; } } else { servo2pos = 1500; } } } void SystemInit(void) //Sets up the Fraunch board for Accel reads and LED tricks { //Startup clock system in max. DCO setting ~8MHz // This value is closer to 10MHz on untrimmed parts CSCTL0_H = 0xA5; // Unlock register CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting CSCTL2 = SELA_1 + SELS_3 + SELM_3; // set ACLK = vlo; MCLK = DCO CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // set all dividers CSCTL0_H = 0x01; // Lock Register // Turn off temp. REFCTL0 |= REFTCOFF; REFCTL0 &= ~REFON; // Enable LEDs P3OUT &= ~(BIT6+BIT7+BIT5+BIT4); P3DIR |= BIT6+BIT7+BIT5+BIT4; PJOUT &= ~(BIT0+BIT1+BIT2+BIT3); PJDIR |= BIT0 +BIT1+BIT2+BIT3; // P3.0,P3.1 and P3.2 are accelerometer inputs P3OUT &= ~(BIT0 + BIT1 + BIT2); P3DIR &= ~(BIT0 + BIT1 + BIT2); P3REN |= BIT0 + BIT1 + BIT2; // Setup Servo ports P1OUT &= ~(SERVO_1 + SERVO_2); P1DIR |= SERVO_1 + SERVO_2; P1SEL0 &= ~(SERVO_1 + SERVO_2); P1SEL1 &= ~(SERVO_1 + SERVO_2); // Setup Servo Interrupt TA0CCTL0 = CCIE; TA0CCR0 = 1500; TA0CTL = TASSEL_2 + MC_1 + ID_3; } void CalibrateADC(void) //Sets the "zero" point of the accelerometer { unsigned char CalibCounter =0; unsigned int Value = 0; __disable_interrupt(); //Turn off any interupts just incase ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Sample the X-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_X = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Sample the Y-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Y = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Sampel the Z-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Z = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //We need to start at the X-axis first due to how the interupt routine works. __enable_interrupt(); //enable interupts } void SetupAccel(void) { //Setup accelerometer // ~20KHz sampling //Configure GPIO ACC_PORT_SEL0 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; //Enable A/D channel inputs ACC_PORT_SEL1 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; ACC_PORT_DIR &= ~(ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN); ACC_PWR_PORT_DIR |= ACC_PWR_PIN; //Enable ACC_POWER ACC_PWR_PORT_OUT |= ACC_PWR_PIN; // Allow the accelerometer to settle before sampling any data __delay_cycles(200000); //Setting up the ADC stuff ADC10CTL0 &= ~ADC10ENC; // Ensure ENC is clear ADC10CTL0 = ADC10ON + ADC10SHT_5; ADC10CTL1 = ADC10SHS_0 + ADC10SHP + ADC10CONSEQ_0 + ADC10SSEL_0; ADC10CTL2 = ADC10RES; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; ADC10IV = 0x00; //Clear all ADC12 channel int flags ADC10IE |= ADC10IE0; //Enable ADC10 interrupts __enable_interrupt(); } void StartUpSequence(void) //this is copied from the Ti Fraunch Pad experience. Only thing it does is make a fancy LED sequence on boot. { unsigned char flag=4,up=1,counter = 0; unsigned char LED_ArrayPJ[] = {0x01,0x02,0x04,0x08}; unsigned char LED_ArrayP3[] = {0x80,0x40,0x20,0x10}; while (counter <10) { counter++; PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); if(up) { while(flag) { P3OUT = LED_ArrayP3[flag-1]; PJOUT = LED_ArrayPJ[flag-1]; LongDelay(); flag--; } up=0; } else { while(flag<4) { P3OUT = LED_ArrayP3[flag]; PJOUT = LED_ArrayPJ[flag]; LongDelay(); flag++; } up = 1; } } PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); } void LongDelay() { __delay_cycles(250000); } //Servo Interrupt #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A (void) { if(servo_counter == 0) { P1OUT |= SERVO_1; P1OUT |= SERVO_2; if (servo1pos >= servo2pos) { TA0CCR0 = servo2pos; } else { TA0CCR0 = servo1pos; } servo_counter++; } else if(servo_counter == 1) { if (servo1pos >= servo2pos) { P1OUT &= ~(SERVO_2); TA0CCR0 = servo1pos - servo2pos; } else { P1OUT &= ~(SERVO_1); TA0CCR0 = servo2pos - servo1pos; } servo_counter++; } else { TA0CCR0 = 20000 - servo1pos; P1OUT &= ~(SERVO_1); P1OUT &= ~(SERVO_2); servo_counter = 0; } } //ADC10 interupt routine #pragma vector = ADC10_VECTOR __interrupt void ADC10_ISR(void) { if (ADC_counter == 0) //X-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Next channel is the Y-axis ADCResult_X = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else if (ADC_counter == 1) //Y-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Next channel is the Z-axis ADCResult_Y = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else //Z-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Next channel is the X-axis ADCResult_Z = ADC10MEM0; ADC_counter = 0; ADC10CTL0 |= ADC10ENC | ADC10SC; } }
     
    http://longhornengineer.com/projects/code/msp-exp430-accel-and-servo/
  3. Like
    longhorn engineer got a reaction from SirPatrick in MSP-EXP430 : Accelerometer and Servo Demo   
    Just finished tweaking and streaming the code.
     
    This code also contains a twin servo routine. The servos are connected to P1.4 and P1.5. When the X-axis moves the servo on P1.4 moves and when the Y-axis moves the servo on P1.5. The Z-aixs is implemented but not used in the program.
     

    #include "msp430fr5739.h" #include "FR_EXP.h" #define SERVO_1 BIT4 #define SERVO_2 BIT5 #define scale 9 unsigned int servo_counter = 0; unsigned int servo1pos = 1500; unsigned int servo2pos = 1500; unsigned int ADC_counter = 0; unsigned int ADCResult_X, ADCResult_Y, ADCResult_Z; unsigned int CalValue_X, CalValue_Y, CalValue_Z; unsigned int temp; void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop the dog SystemInit(); //Setup the pins StartUpSequence(); //Copy Ti's fancy LED boot up trick SetupAccel(); //Setup the ADC and Accel CalibrateADC(); //Find zero points of all 3 axis ADC10CTL0 |= ADC10ENC | ADC10SC; //Start the first sample. If this is not done the ADC10 interupt will not trigger. while (1) { if (ADCResult_X > CalValue_X + 10) { servo1pos = 1500 + scale * (ADCResult_X - CalValue_X); if (servo1pos > 2500) { servo1pos = 2500; } } else if (ADCResult_X < CalValue_X - 10) { servo1pos = 1500 - scale * (CalValue_X - ADCResult_X); if (servo1pos < 500) { servo1pos = 500; } } else { servo1pos = 1500; } if (ADCResult_Y > CalValue_Y + 10) { servo2pos = 1500 + scale * (ADCResult_Y - CalValue_Y); if (servo2pos > 2500) { servo2pos = 2500; } } else if (ADCResult_Y < CalValue_Y - 10) { servo2pos = 1500 - scale * (CalValue_Y - ADCResult_Y); if (servo2pos < 500) { servo2pos = 500; } } else { servo2pos = 1500; } } } void SystemInit(void) //Sets up the Fraunch board for Accel reads and LED tricks { //Startup clock system in max. DCO setting ~8MHz // This value is closer to 10MHz on untrimmed parts CSCTL0_H = 0xA5; // Unlock register CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting CSCTL2 = SELA_1 + SELS_3 + SELM_3; // set ACLK = vlo; MCLK = DCO CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // set all dividers CSCTL0_H = 0x01; // Lock Register // Turn off temp. REFCTL0 |= REFTCOFF; REFCTL0 &= ~REFON; // Enable LEDs P3OUT &= ~(BIT6+BIT7+BIT5+BIT4); P3DIR |= BIT6+BIT7+BIT5+BIT4; PJOUT &= ~(BIT0+BIT1+BIT2+BIT3); PJDIR |= BIT0 +BIT1+BIT2+BIT3; // P3.0,P3.1 and P3.2 are accelerometer inputs P3OUT &= ~(BIT0 + BIT1 + BIT2); P3DIR &= ~(BIT0 + BIT1 + BIT2); P3REN |= BIT0 + BIT1 + BIT2; // Setup Servo ports P1OUT &= ~(SERVO_1 + SERVO_2); P1DIR |= SERVO_1 + SERVO_2; P1SEL0 &= ~(SERVO_1 + SERVO_2); P1SEL1 &= ~(SERVO_1 + SERVO_2); // Setup Servo Interrupt TA0CCTL0 = CCIE; TA0CCR0 = 1500; TA0CTL = TASSEL_2 + MC_1 + ID_3; } void CalibrateADC(void) //Sets the "zero" point of the accelerometer { unsigned char CalibCounter =0; unsigned int Value = 0; __disable_interrupt(); //Turn off any interupts just incase ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Sample the X-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_X = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Sample the Y-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Y = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Sampel the Z-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Z = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //We need to start at the X-axis first due to how the interupt routine works. __enable_interrupt(); //enable interupts } void SetupAccel(void) { //Setup accelerometer // ~20KHz sampling //Configure GPIO ACC_PORT_SEL0 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; //Enable A/D channel inputs ACC_PORT_SEL1 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; ACC_PORT_DIR &= ~(ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN); ACC_PWR_PORT_DIR |= ACC_PWR_PIN; //Enable ACC_POWER ACC_PWR_PORT_OUT |= ACC_PWR_PIN; // Allow the accelerometer to settle before sampling any data __delay_cycles(200000); //Setting up the ADC stuff ADC10CTL0 &= ~ADC10ENC; // Ensure ENC is clear ADC10CTL0 = ADC10ON + ADC10SHT_5; ADC10CTL1 = ADC10SHS_0 + ADC10SHP + ADC10CONSEQ_0 + ADC10SSEL_0; ADC10CTL2 = ADC10RES; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; ADC10IV = 0x00; //Clear all ADC12 channel int flags ADC10IE |= ADC10IE0; //Enable ADC10 interrupts __enable_interrupt(); } void StartUpSequence(void) //this is copied from the Ti Fraunch Pad experience. Only thing it does is make a fancy LED sequence on boot. { unsigned char flag=4,up=1,counter = 0; unsigned char LED_ArrayPJ[] = {0x01,0x02,0x04,0x08}; unsigned char LED_ArrayP3[] = {0x80,0x40,0x20,0x10}; while (counter <10) { counter++; PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); if(up) { while(flag) { P3OUT = LED_ArrayP3[flag-1]; PJOUT = LED_ArrayPJ[flag-1]; LongDelay(); flag--; } up=0; } else { while(flag<4) { P3OUT = LED_ArrayP3[flag]; PJOUT = LED_ArrayPJ[flag]; LongDelay(); flag++; } up = 1; } } PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); } void LongDelay() { __delay_cycles(250000); } //Servo Interrupt #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A (void) { if(servo_counter == 0) { P1OUT |= SERVO_1; P1OUT |= SERVO_2; if (servo1pos >= servo2pos) { TA0CCR0 = servo2pos; } else { TA0CCR0 = servo1pos; } servo_counter++; } else if(servo_counter == 1) { if (servo1pos >= servo2pos) { P1OUT &= ~(SERVO_2); TA0CCR0 = servo1pos - servo2pos; } else { P1OUT &= ~(SERVO_1); TA0CCR0 = servo2pos - servo1pos; } servo_counter++; } else { TA0CCR0 = 20000 - servo1pos; P1OUT &= ~(SERVO_1); P1OUT &= ~(SERVO_2); servo_counter = 0; } } //ADC10 interupt routine #pragma vector = ADC10_VECTOR __interrupt void ADC10_ISR(void) { if (ADC_counter == 0) //X-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Next channel is the Y-axis ADCResult_X = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else if (ADC_counter == 1) //Y-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Next channel is the Z-axis ADCResult_Y = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else //Z-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Next channel is the X-axis ADCResult_Z = ADC10MEM0; ADC_counter = 0; ADC10CTL0 |= ADC10ENC | ADC10SC; } }
     
    http://longhornengineer.com/projects/code/msp-exp430-accel-and-servo/
  4. Like
    longhorn engineer got a reaction from jsolarski in MSP-EXP430 : Accelerometer and Servo Demo   
    Video uploaded.
     


  5. Like
    longhorn engineer got a reaction from AaronInSpace in Non-ADC-driven PWM servo control with Launchpad   
    I know this post is close to a week old but you need to make sure the grounds between the Launch pad and the servo are connected.
  6. Like
    longhorn engineer got a reaction from nuetron in MSP-EXP430 : Accelerometer and Servo Demo   
    Video uploaded.
     


  7. Like
    longhorn engineer got a reaction from bluehash in MSP-EXP430 : Accelerometer and Servo Demo   
    Video uploaded.
     


  8. Like
    longhorn engineer got a reaction from gwdeveloper in MSP-EXP430 : Accelerometer and Servo Demo   
    Video uploaded.
     


  9. Like
    longhorn engineer got a reaction from RobG in MSP-EXP430 : Accelerometer and Servo Demo   
    Just finished tweaking and streaming the code.
     
    This code also contains a twin servo routine. The servos are connected to P1.4 and P1.5. When the X-axis moves the servo on P1.4 moves and when the Y-axis moves the servo on P1.5. The Z-aixs is implemented but not used in the program.
     

    #include "msp430fr5739.h" #include "FR_EXP.h" #define SERVO_1 BIT4 #define SERVO_2 BIT5 #define scale 9 unsigned int servo_counter = 0; unsigned int servo1pos = 1500; unsigned int servo2pos = 1500; unsigned int ADC_counter = 0; unsigned int ADCResult_X, ADCResult_Y, ADCResult_Z; unsigned int CalValue_X, CalValue_Y, CalValue_Z; unsigned int temp; void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop the dog SystemInit(); //Setup the pins StartUpSequence(); //Copy Ti's fancy LED boot up trick SetupAccel(); //Setup the ADC and Accel CalibrateADC(); //Find zero points of all 3 axis ADC10CTL0 |= ADC10ENC | ADC10SC; //Start the first sample. If this is not done the ADC10 interupt will not trigger. while (1) { if (ADCResult_X > CalValue_X + 10) { servo1pos = 1500 + scale * (ADCResult_X - CalValue_X); if (servo1pos > 2500) { servo1pos = 2500; } } else if (ADCResult_X < CalValue_X - 10) { servo1pos = 1500 - scale * (CalValue_X - ADCResult_X); if (servo1pos < 500) { servo1pos = 500; } } else { servo1pos = 1500; } if (ADCResult_Y > CalValue_Y + 10) { servo2pos = 1500 + scale * (ADCResult_Y - CalValue_Y); if (servo2pos > 2500) { servo2pos = 2500; } } else if (ADCResult_Y < CalValue_Y - 10) { servo2pos = 1500 - scale * (CalValue_Y - ADCResult_Y); if (servo2pos < 500) { servo2pos = 500; } } else { servo2pos = 1500; } } } void SystemInit(void) //Sets up the Fraunch board for Accel reads and LED tricks { //Startup clock system in max. DCO setting ~8MHz // This value is closer to 10MHz on untrimmed parts CSCTL0_H = 0xA5; // Unlock register CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting CSCTL2 = SELA_1 + SELS_3 + SELM_3; // set ACLK = vlo; MCLK = DCO CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // set all dividers CSCTL0_H = 0x01; // Lock Register // Turn off temp. REFCTL0 |= REFTCOFF; REFCTL0 &= ~REFON; // Enable LEDs P3OUT &= ~(BIT6+BIT7+BIT5+BIT4); P3DIR |= BIT6+BIT7+BIT5+BIT4; PJOUT &= ~(BIT0+BIT1+BIT2+BIT3); PJDIR |= BIT0 +BIT1+BIT2+BIT3; // P3.0,P3.1 and P3.2 are accelerometer inputs P3OUT &= ~(BIT0 + BIT1 + BIT2); P3DIR &= ~(BIT0 + BIT1 + BIT2); P3REN |= BIT0 + BIT1 + BIT2; // Setup Servo ports P1OUT &= ~(SERVO_1 + SERVO_2); P1DIR |= SERVO_1 + SERVO_2; P1SEL0 &= ~(SERVO_1 + SERVO_2); P1SEL1 &= ~(SERVO_1 + SERVO_2); // Setup Servo Interrupt TA0CCTL0 = CCIE; TA0CCR0 = 1500; TA0CTL = TASSEL_2 + MC_1 + ID_3; } void CalibrateADC(void) //Sets the "zero" point of the accelerometer { unsigned char CalibCounter =0; unsigned int Value = 0; __disable_interrupt(); //Turn off any interupts just incase ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Sample the X-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_X = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Sample the Y-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Y = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Sampel the Z-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Z = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //We need to start at the X-axis first due to how the interupt routine works. __enable_interrupt(); //enable interupts } void SetupAccel(void) { //Setup accelerometer // ~20KHz sampling //Configure GPIO ACC_PORT_SEL0 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; //Enable A/D channel inputs ACC_PORT_SEL1 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; ACC_PORT_DIR &= ~(ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN); ACC_PWR_PORT_DIR |= ACC_PWR_PIN; //Enable ACC_POWER ACC_PWR_PORT_OUT |= ACC_PWR_PIN; // Allow the accelerometer to settle before sampling any data __delay_cycles(200000); //Setting up the ADC stuff ADC10CTL0 &= ~ADC10ENC; // Ensure ENC is clear ADC10CTL0 = ADC10ON + ADC10SHT_5; ADC10CTL1 = ADC10SHS_0 + ADC10SHP + ADC10CONSEQ_0 + ADC10SSEL_0; ADC10CTL2 = ADC10RES; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; ADC10IV = 0x00; //Clear all ADC12 channel int flags ADC10IE |= ADC10IE0; //Enable ADC10 interrupts __enable_interrupt(); } void StartUpSequence(void) //this is copied from the Ti Fraunch Pad experience. Only thing it does is make a fancy LED sequence on boot. { unsigned char flag=4,up=1,counter = 0; unsigned char LED_ArrayPJ[] = {0x01,0x02,0x04,0x08}; unsigned char LED_ArrayP3[] = {0x80,0x40,0x20,0x10}; while (counter <10) { counter++; PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); if(up) { while(flag) { P3OUT = LED_ArrayP3[flag-1]; PJOUT = LED_ArrayPJ[flag-1]; LongDelay(); flag--; } up=0; } else { while(flag<4) { P3OUT = LED_ArrayP3[flag]; PJOUT = LED_ArrayPJ[flag]; LongDelay(); flag++; } up = 1; } } PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); } void LongDelay() { __delay_cycles(250000); } //Servo Interrupt #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A (void) { if(servo_counter == 0) { P1OUT |= SERVO_1; P1OUT |= SERVO_2; if (servo1pos >= servo2pos) { TA0CCR0 = servo2pos; } else { TA0CCR0 = servo1pos; } servo_counter++; } else if(servo_counter == 1) { if (servo1pos >= servo2pos) { P1OUT &= ~(SERVO_2); TA0CCR0 = servo1pos - servo2pos; } else { P1OUT &= ~(SERVO_1); TA0CCR0 = servo2pos - servo1pos; } servo_counter++; } else { TA0CCR0 = 20000 - servo1pos; P1OUT &= ~(SERVO_1); P1OUT &= ~(SERVO_2); servo_counter = 0; } } //ADC10 interupt routine #pragma vector = ADC10_VECTOR __interrupt void ADC10_ISR(void) { if (ADC_counter == 0) //X-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Next channel is the Y-axis ADCResult_X = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else if (ADC_counter == 1) //Y-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Next channel is the Z-axis ADCResult_Y = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else //Z-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Next channel is the X-axis ADCResult_Z = ADC10MEM0; ADC_counter = 0; ADC10CTL0 |= ADC10ENC | ADC10SC; } }
     
    http://longhornengineer.com/projects/code/msp-exp430-accel-and-servo/
  10. Like
    longhorn engineer reacted to bluehash in MSP-EXP430 : Accelerometer and Servo Demo   
    Thanks! Much appreciated.
  11. Like
    longhorn engineer reacted to oPossum in 256 x 192 graphics display using Fraunchpad - preview   
    A frame buffer for 256x192 pixels requires 6k. That is more than will fit in RAM, so the frame buffer is in the FRAM memory. NTSC video generated using TimerA0 for sync, and SPI with DMA for video.
     
    Graphics library functions:


    [*:hf56qo2f]Pixel
    [*:hf56qo2f]Line
    [*:hf56qo2f]Box
    [*:hf56qo2f]Circle
    [*:hf56qo2f]Ellipse
    [*:hf56qo2f]Quadratic and cubic bezier curve
    [*:hf56qo2f]BitBlt up to 24 pixels wide
    [*:hf56qo2f]OR, AND, and XOR drawing modes
    [*:hf56qo2f]Text with 8 x 12 font
     


  12. Like
    longhorn engineer got a reaction from jsolarski in MSP-EXP430 : Accelerometer and Servo Demo   
    Just finished tweaking and streaming the code.
     
    This code also contains a twin servo routine. The servos are connected to P1.4 and P1.5. When the X-axis moves the servo on P1.4 moves and when the Y-axis moves the servo on P1.5. The Z-aixs is implemented but not used in the program.
     

    #include "msp430fr5739.h" #include "FR_EXP.h" #define SERVO_1 BIT4 #define SERVO_2 BIT5 #define scale 9 unsigned int servo_counter = 0; unsigned int servo1pos = 1500; unsigned int servo2pos = 1500; unsigned int ADC_counter = 0; unsigned int ADCResult_X, ADCResult_Y, ADCResult_Z; unsigned int CalValue_X, CalValue_Y, CalValue_Z; unsigned int temp; void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop the dog SystemInit(); //Setup the pins StartUpSequence(); //Copy Ti's fancy LED boot up trick SetupAccel(); //Setup the ADC and Accel CalibrateADC(); //Find zero points of all 3 axis ADC10CTL0 |= ADC10ENC | ADC10SC; //Start the first sample. If this is not done the ADC10 interupt will not trigger. while (1) { if (ADCResult_X > CalValue_X + 10) { servo1pos = 1500 + scale * (ADCResult_X - CalValue_X); if (servo1pos > 2500) { servo1pos = 2500; } } else if (ADCResult_X < CalValue_X - 10) { servo1pos = 1500 - scale * (CalValue_X - ADCResult_X); if (servo1pos < 500) { servo1pos = 500; } } else { servo1pos = 1500; } if (ADCResult_Y > CalValue_Y + 10) { servo2pos = 1500 + scale * (ADCResult_Y - CalValue_Y); if (servo2pos > 2500) { servo2pos = 2500; } } else if (ADCResult_Y < CalValue_Y - 10) { servo2pos = 1500 - scale * (CalValue_Y - ADCResult_Y); if (servo2pos < 500) { servo2pos = 500; } } else { servo2pos = 1500; } } } void SystemInit(void) //Sets up the Fraunch board for Accel reads and LED tricks { //Startup clock system in max. DCO setting ~8MHz // This value is closer to 10MHz on untrimmed parts CSCTL0_H = 0xA5; // Unlock register CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting CSCTL2 = SELA_1 + SELS_3 + SELM_3; // set ACLK = vlo; MCLK = DCO CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // set all dividers CSCTL0_H = 0x01; // Lock Register // Turn off temp. REFCTL0 |= REFTCOFF; REFCTL0 &= ~REFON; // Enable LEDs P3OUT &= ~(BIT6+BIT7+BIT5+BIT4); P3DIR |= BIT6+BIT7+BIT5+BIT4; PJOUT &= ~(BIT0+BIT1+BIT2+BIT3); PJDIR |= BIT0 +BIT1+BIT2+BIT3; // P3.0,P3.1 and P3.2 are accelerometer inputs P3OUT &= ~(BIT0 + BIT1 + BIT2); P3DIR &= ~(BIT0 + BIT1 + BIT2); P3REN |= BIT0 + BIT1 + BIT2; // Setup Servo ports P1OUT &= ~(SERVO_1 + SERVO_2); P1DIR |= SERVO_1 + SERVO_2; P1SEL0 &= ~(SERVO_1 + SERVO_2); P1SEL1 &= ~(SERVO_1 + SERVO_2); // Setup Servo Interrupt TA0CCTL0 = CCIE; TA0CCR0 = 1500; TA0CTL = TASSEL_2 + MC_1 + ID_3; } void CalibrateADC(void) //Sets the "zero" point of the accelerometer { unsigned char CalibCounter =0; unsigned int Value = 0; __disable_interrupt(); //Turn off any interupts just incase ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Sample the X-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_X = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Sample the Y-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Y = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Sampel the Z-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Z = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //We need to start at the X-axis first due to how the interupt routine works. __enable_interrupt(); //enable interupts } void SetupAccel(void) { //Setup accelerometer // ~20KHz sampling //Configure GPIO ACC_PORT_SEL0 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; //Enable A/D channel inputs ACC_PORT_SEL1 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; ACC_PORT_DIR &= ~(ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN); ACC_PWR_PORT_DIR |= ACC_PWR_PIN; //Enable ACC_POWER ACC_PWR_PORT_OUT |= ACC_PWR_PIN; // Allow the accelerometer to settle before sampling any data __delay_cycles(200000); //Setting up the ADC stuff ADC10CTL0 &= ~ADC10ENC; // Ensure ENC is clear ADC10CTL0 = ADC10ON + ADC10SHT_5; ADC10CTL1 = ADC10SHS_0 + ADC10SHP + ADC10CONSEQ_0 + ADC10SSEL_0; ADC10CTL2 = ADC10RES; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; ADC10IV = 0x00; //Clear all ADC12 channel int flags ADC10IE |= ADC10IE0; //Enable ADC10 interrupts __enable_interrupt(); } void StartUpSequence(void) //this is copied from the Ti Fraunch Pad experience. Only thing it does is make a fancy LED sequence on boot. { unsigned char flag=4,up=1,counter = 0; unsigned char LED_ArrayPJ[] = {0x01,0x02,0x04,0x08}; unsigned char LED_ArrayP3[] = {0x80,0x40,0x20,0x10}; while (counter <10) { counter++; PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); if(up) { while(flag) { P3OUT = LED_ArrayP3[flag-1]; PJOUT = LED_ArrayPJ[flag-1]; LongDelay(); flag--; } up=0; } else { while(flag<4) { P3OUT = LED_ArrayP3[flag]; PJOUT = LED_ArrayPJ[flag]; LongDelay(); flag++; } up = 1; } } PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); } void LongDelay() { __delay_cycles(250000); } //Servo Interrupt #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A (void) { if(servo_counter == 0) { P1OUT |= SERVO_1; P1OUT |= SERVO_2; if (servo1pos >= servo2pos) { TA0CCR0 = servo2pos; } else { TA0CCR0 = servo1pos; } servo_counter++; } else if(servo_counter == 1) { if (servo1pos >= servo2pos) { P1OUT &= ~(SERVO_2); TA0CCR0 = servo1pos - servo2pos; } else { P1OUT &= ~(SERVO_1); TA0CCR0 = servo2pos - servo1pos; } servo_counter++; } else { TA0CCR0 = 20000 - servo1pos; P1OUT &= ~(SERVO_1); P1OUT &= ~(SERVO_2); servo_counter = 0; } } //ADC10 interupt routine #pragma vector = ADC10_VECTOR __interrupt void ADC10_ISR(void) { if (ADC_counter == 0) //X-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Next channel is the Y-axis ADCResult_X = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else if (ADC_counter == 1) //Y-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Next channel is the Z-axis ADCResult_Y = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else //Z-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Next channel is the X-axis ADCResult_Z = ADC10MEM0; ADC_counter = 0; ADC10CTL0 |= ADC10ENC | ADC10SC; } }
     
    http://longhornengineer.com/projects/code/msp-exp430-accel-and-servo/
  13. Like
    longhorn engineer got a reaction from oPossum in MSP-EXP430 : Accelerometer and Servo Demo   
    Just finished tweaking and streaming the code.
     
    This code also contains a twin servo routine. The servos are connected to P1.4 and P1.5. When the X-axis moves the servo on P1.4 moves and when the Y-axis moves the servo on P1.5. The Z-aixs is implemented but not used in the program.
     

    #include "msp430fr5739.h" #include "FR_EXP.h" #define SERVO_1 BIT4 #define SERVO_2 BIT5 #define scale 9 unsigned int servo_counter = 0; unsigned int servo1pos = 1500; unsigned int servo2pos = 1500; unsigned int ADC_counter = 0; unsigned int ADCResult_X, ADCResult_Y, ADCResult_Z; unsigned int CalValue_X, CalValue_Y, CalValue_Z; unsigned int temp; void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop the dog SystemInit(); //Setup the pins StartUpSequence(); //Copy Ti's fancy LED boot up trick SetupAccel(); //Setup the ADC and Accel CalibrateADC(); //Find zero points of all 3 axis ADC10CTL0 |= ADC10ENC | ADC10SC; //Start the first sample. If this is not done the ADC10 interupt will not trigger. while (1) { if (ADCResult_X > CalValue_X + 10) { servo1pos = 1500 + scale * (ADCResult_X - CalValue_X); if (servo1pos > 2500) { servo1pos = 2500; } } else if (ADCResult_X < CalValue_X - 10) { servo1pos = 1500 - scale * (CalValue_X - ADCResult_X); if (servo1pos < 500) { servo1pos = 500; } } else { servo1pos = 1500; } if (ADCResult_Y > CalValue_Y + 10) { servo2pos = 1500 + scale * (ADCResult_Y - CalValue_Y); if (servo2pos > 2500) { servo2pos = 2500; } } else if (ADCResult_Y < CalValue_Y - 10) { servo2pos = 1500 - scale * (CalValue_Y - ADCResult_Y); if (servo2pos < 500) { servo2pos = 500; } } else { servo2pos = 1500; } } } void SystemInit(void) //Sets up the Fraunch board for Accel reads and LED tricks { //Startup clock system in max. DCO setting ~8MHz // This value is closer to 10MHz on untrimmed parts CSCTL0_H = 0xA5; // Unlock register CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting CSCTL2 = SELA_1 + SELS_3 + SELM_3; // set ACLK = vlo; MCLK = DCO CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // set all dividers CSCTL0_H = 0x01; // Lock Register // Turn off temp. REFCTL0 |= REFTCOFF; REFCTL0 &= ~REFON; // Enable LEDs P3OUT &= ~(BIT6+BIT7+BIT5+BIT4); P3DIR |= BIT6+BIT7+BIT5+BIT4; PJOUT &= ~(BIT0+BIT1+BIT2+BIT3); PJDIR |= BIT0 +BIT1+BIT2+BIT3; // P3.0,P3.1 and P3.2 are accelerometer inputs P3OUT &= ~(BIT0 + BIT1 + BIT2); P3DIR &= ~(BIT0 + BIT1 + BIT2); P3REN |= BIT0 + BIT1 + BIT2; // Setup Servo ports P1OUT &= ~(SERVO_1 + SERVO_2); P1DIR |= SERVO_1 + SERVO_2; P1SEL0 &= ~(SERVO_1 + SERVO_2); P1SEL1 &= ~(SERVO_1 + SERVO_2); // Setup Servo Interrupt TA0CCTL0 = CCIE; TA0CCR0 = 1500; TA0CTL = TASSEL_2 + MC_1 + ID_3; } void CalibrateADC(void) //Sets the "zero" point of the accelerometer { unsigned char CalibCounter =0; unsigned int Value = 0; __disable_interrupt(); //Turn off any interupts just incase ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Sample the X-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_X = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Sample the Y-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Y = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Sampel the Z-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Z = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //We need to start at the X-axis first due to how the interupt routine works. __enable_interrupt(); //enable interupts } void SetupAccel(void) { //Setup accelerometer // ~20KHz sampling //Configure GPIO ACC_PORT_SEL0 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; //Enable A/D channel inputs ACC_PORT_SEL1 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; ACC_PORT_DIR &= ~(ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN); ACC_PWR_PORT_DIR |= ACC_PWR_PIN; //Enable ACC_POWER ACC_PWR_PORT_OUT |= ACC_PWR_PIN; // Allow the accelerometer to settle before sampling any data __delay_cycles(200000); //Setting up the ADC stuff ADC10CTL0 &= ~ADC10ENC; // Ensure ENC is clear ADC10CTL0 = ADC10ON + ADC10SHT_5; ADC10CTL1 = ADC10SHS_0 + ADC10SHP + ADC10CONSEQ_0 + ADC10SSEL_0; ADC10CTL2 = ADC10RES; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; ADC10IV = 0x00; //Clear all ADC12 channel int flags ADC10IE |= ADC10IE0; //Enable ADC10 interrupts __enable_interrupt(); } void StartUpSequence(void) //this is copied from the Ti Fraunch Pad experience. Only thing it does is make a fancy LED sequence on boot. { unsigned char flag=4,up=1,counter = 0; unsigned char LED_ArrayPJ[] = {0x01,0x02,0x04,0x08}; unsigned char LED_ArrayP3[] = {0x80,0x40,0x20,0x10}; while (counter <10) { counter++; PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); if(up) { while(flag) { P3OUT = LED_ArrayP3[flag-1]; PJOUT = LED_ArrayPJ[flag-1]; LongDelay(); flag--; } up=0; } else { while(flag<4) { P3OUT = LED_ArrayP3[flag]; PJOUT = LED_ArrayPJ[flag]; LongDelay(); flag++; } up = 1; } } PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); } void LongDelay() { __delay_cycles(250000); } //Servo Interrupt #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A (void) { if(servo_counter == 0) { P1OUT |= SERVO_1; P1OUT |= SERVO_2; if (servo1pos >= servo2pos) { TA0CCR0 = servo2pos; } else { TA0CCR0 = servo1pos; } servo_counter++; } else if(servo_counter == 1) { if (servo1pos >= servo2pos) { P1OUT &= ~(SERVO_2); TA0CCR0 = servo1pos - servo2pos; } else { P1OUT &= ~(SERVO_1); TA0CCR0 = servo2pos - servo1pos; } servo_counter++; } else { TA0CCR0 = 20000 - servo1pos; P1OUT &= ~(SERVO_1); P1OUT &= ~(SERVO_2); servo_counter = 0; } } //ADC10 interupt routine #pragma vector = ADC10_VECTOR __interrupt void ADC10_ISR(void) { if (ADC_counter == 0) //X-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Next channel is the Y-axis ADCResult_X = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else if (ADC_counter == 1) //Y-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Next channel is the Z-axis ADCResult_Y = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else //Z-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Next channel is the X-axis ADCResult_Z = ADC10MEM0; ADC_counter = 0; ADC10CTL0 |= ADC10ENC | ADC10SC; } }
     
    http://longhornengineer.com/projects/code/msp-exp430-accel-and-servo/
  14. Like
    longhorn engineer got a reaction from bluehash in MSP-EXP430 : Accelerometer and Servo Demo   
    Just finished tweaking and streaming the code.
     
    This code also contains a twin servo routine. The servos are connected to P1.4 and P1.5. When the X-axis moves the servo on P1.4 moves and when the Y-axis moves the servo on P1.5. The Z-aixs is implemented but not used in the program.
     

    #include "msp430fr5739.h" #include "FR_EXP.h" #define SERVO_1 BIT4 #define SERVO_2 BIT5 #define scale 9 unsigned int servo_counter = 0; unsigned int servo1pos = 1500; unsigned int servo2pos = 1500; unsigned int ADC_counter = 0; unsigned int ADCResult_X, ADCResult_Y, ADCResult_Z; unsigned int CalValue_X, CalValue_Y, CalValue_Z; unsigned int temp; void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop the dog SystemInit(); //Setup the pins StartUpSequence(); //Copy Ti's fancy LED boot up trick SetupAccel(); //Setup the ADC and Accel CalibrateADC(); //Find zero points of all 3 axis ADC10CTL0 |= ADC10ENC | ADC10SC; //Start the first sample. If this is not done the ADC10 interupt will not trigger. while (1) { if (ADCResult_X > CalValue_X + 10) { servo1pos = 1500 + scale * (ADCResult_X - CalValue_X); if (servo1pos > 2500) { servo1pos = 2500; } } else if (ADCResult_X < CalValue_X - 10) { servo1pos = 1500 - scale * (CalValue_X - ADCResult_X); if (servo1pos < 500) { servo1pos = 500; } } else { servo1pos = 1500; } if (ADCResult_Y > CalValue_Y + 10) { servo2pos = 1500 + scale * (ADCResult_Y - CalValue_Y); if (servo2pos > 2500) { servo2pos = 2500; } } else if (ADCResult_Y < CalValue_Y - 10) { servo2pos = 1500 - scale * (CalValue_Y - ADCResult_Y); if (servo2pos < 500) { servo2pos = 500; } } else { servo2pos = 1500; } } } void SystemInit(void) //Sets up the Fraunch board for Accel reads and LED tricks { //Startup clock system in max. DCO setting ~8MHz // This value is closer to 10MHz on untrimmed parts CSCTL0_H = 0xA5; // Unlock register CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting CSCTL2 = SELA_1 + SELS_3 + SELM_3; // set ACLK = vlo; MCLK = DCO CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // set all dividers CSCTL0_H = 0x01; // Lock Register // Turn off temp. REFCTL0 |= REFTCOFF; REFCTL0 &= ~REFON; // Enable LEDs P3OUT &= ~(BIT6+BIT7+BIT5+BIT4); P3DIR |= BIT6+BIT7+BIT5+BIT4; PJOUT &= ~(BIT0+BIT1+BIT2+BIT3); PJDIR |= BIT0 +BIT1+BIT2+BIT3; // P3.0,P3.1 and P3.2 are accelerometer inputs P3OUT &= ~(BIT0 + BIT1 + BIT2); P3DIR &= ~(BIT0 + BIT1 + BIT2); P3REN |= BIT0 + BIT1 + BIT2; // Setup Servo ports P1OUT &= ~(SERVO_1 + SERVO_2); P1DIR |= SERVO_1 + SERVO_2; P1SEL0 &= ~(SERVO_1 + SERVO_2); P1SEL1 &= ~(SERVO_1 + SERVO_2); // Setup Servo Interrupt TA0CCTL0 = CCIE; TA0CCR0 = 1500; TA0CTL = TASSEL_2 + MC_1 + ID_3; } void CalibrateADC(void) //Sets the "zero" point of the accelerometer { unsigned char CalibCounter =0; unsigned int Value = 0; __disable_interrupt(); //Turn off any interupts just incase ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Sample the X-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_X = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Sample the Y-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Y = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Sampel the Z-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Z = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //We need to start at the X-axis first due to how the interupt routine works. __enable_interrupt(); //enable interupts } void SetupAccel(void) { //Setup accelerometer // ~20KHz sampling //Configure GPIO ACC_PORT_SEL0 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; //Enable A/D channel inputs ACC_PORT_SEL1 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; ACC_PORT_DIR &= ~(ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN); ACC_PWR_PORT_DIR |= ACC_PWR_PIN; //Enable ACC_POWER ACC_PWR_PORT_OUT |= ACC_PWR_PIN; // Allow the accelerometer to settle before sampling any data __delay_cycles(200000); //Setting up the ADC stuff ADC10CTL0 &= ~ADC10ENC; // Ensure ENC is clear ADC10CTL0 = ADC10ON + ADC10SHT_5; ADC10CTL1 = ADC10SHS_0 + ADC10SHP + ADC10CONSEQ_0 + ADC10SSEL_0; ADC10CTL2 = ADC10RES; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; ADC10IV = 0x00; //Clear all ADC12 channel int flags ADC10IE |= ADC10IE0; //Enable ADC10 interrupts __enable_interrupt(); } void StartUpSequence(void) //this is copied from the Ti Fraunch Pad experience. Only thing it does is make a fancy LED sequence on boot. { unsigned char flag=4,up=1,counter = 0; unsigned char LED_ArrayPJ[] = {0x01,0x02,0x04,0x08}; unsigned char LED_ArrayP3[] = {0x80,0x40,0x20,0x10}; while (counter <10) { counter++; PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); if(up) { while(flag) { P3OUT = LED_ArrayP3[flag-1]; PJOUT = LED_ArrayPJ[flag-1]; LongDelay(); flag--; } up=0; } else { while(flag<4) { P3OUT = LED_ArrayP3[flag]; PJOUT = LED_ArrayPJ[flag]; LongDelay(); flag++; } up = 1; } } PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); } void LongDelay() { __delay_cycles(250000); } //Servo Interrupt #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A (void) { if(servo_counter == 0) { P1OUT |= SERVO_1; P1OUT |= SERVO_2; if (servo1pos >= servo2pos) { TA0CCR0 = servo2pos; } else { TA0CCR0 = servo1pos; } servo_counter++; } else if(servo_counter == 1) { if (servo1pos >= servo2pos) { P1OUT &= ~(SERVO_2); TA0CCR0 = servo1pos - servo2pos; } else { P1OUT &= ~(SERVO_1); TA0CCR0 = servo2pos - servo1pos; } servo_counter++; } else { TA0CCR0 = 20000 - servo1pos; P1OUT &= ~(SERVO_1); P1OUT &= ~(SERVO_2); servo_counter = 0; } } //ADC10 interupt routine #pragma vector = ADC10_VECTOR __interrupt void ADC10_ISR(void) { if (ADC_counter == 0) //X-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Next channel is the Y-axis ADCResult_X = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else if (ADC_counter == 1) //Y-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Next channel is the Z-axis ADCResult_Y = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else //Z-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Next channel is the X-axis ADCResult_Z = ADC10MEM0; ADC_counter = 0; ADC10CTL0 |= ADC10ENC | ADC10SC; } }
     
    http://longhornengineer.com/projects/code/msp-exp430-accel-and-servo/
  15. Like
    longhorn engineer reacted to oPossum in Precision 12 MHz clock for Launchpad MCU   
    The MSP430F1612 on the Launchpad provides a 12 MHz clock to the TUSB3410 chip. This clock can also be used by the MSP430 in the 20 pin socket.
     
    Clock on pin 49 of F1612

     
    Mask off pin 49 with Kapton tape and solder a 1k resistor to the pin.
    Connect the other end of the resistor to the lower pad of C21 using a short wire.
     

     
    This test program will flash the red LED five times with the DCO at ~1 MHz and then switch to the 12 MHz external clock.
     

    #include "msp430g2231.h" void main(void) { unsigned i; volatile unsigned n = 0; WDTCTL = WDTPW | WDTHOLD; P1DIR = 0x01; P1SEL = 0x00; i = 10; do { P1OUT ^= 1; while(--n); } while(--i); BCSCTL3 = LFXT1S0 | LFXT1S1; // - Set XT1 clock type as external do { // - Wait for MSP430 to detect clock is stable IFG1 &= ~OFIFG; // Clear OFIFG n = 250; while(--n); // Wait a while } while(IFG1 & OFIFG); // Loop until OFIFG remains cleared BCSCTL2 = SELM1 | SELM0 | SELS; // - Use LFXT1CLK as clock source do { P1OUT ^= 1; while(--n); } while(1); }
  16. Like
    longhorn engineer got a reaction from oPossum in Fraunch Pad Accel ADC code   
    I worked a bit more and streamlined it a bit. Also added my Servo code.
     
    Samples X, Y, Z axis. Then based on the X and Y axis it moves the two servos.
     

    #include "msp430fr5739.h" #include "FR_EXP.h" #define SERVO_1 BIT4 #define SERVO_2 BIT5 #define scale 9 unsigned int servo_counter = 0; unsigned int servo1pos = 1500; unsigned int servo2pos = 1500; unsigned int ADC_counter = 0; unsigned int ADCResult_X, ADCResult_Y, ADCResult_Z; unsigned int CalValue_X, CalValue_Y, CalValue_Z; unsigned int temp; void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop the dog SystemInit(); //Setup the pins StartUpSequence(); //Copy Ti's fancy LED boot up trick SetupAccel(); //Setup the ADC and Accel CalibrateADC(); //Find zero points of all 3 axis ADC10CTL0 |= ADC10ENC | ADC10SC; //Start the first sample. If this is not done the ADC10 interupt will not trigger. while (1) { if (ADCResult_X > CalValue_X + 10) { servo1pos = 1500 + scale * (ADCResult_X - CalValue_X); if (servo1pos > 2500) { servo1pos = 2500; } } else if (ADCResult_X < CalValue_X - 10) { servo1pos = 1500 - scale * (CalValue_X - ADCResult_X); if (servo1pos < 500) { servo1pos = 500; } } else { servo1pos = 1500; } if (ADCResult_Y > CalValue_Y + 10) { servo2pos = 1500 + scale * (ADCResult_Y - CalValue_Y); if (servo2pos > 2500) { servo2pos = 2500; } } else if (ADCResult_Y < CalValue_Y - 10) { servo2pos = 1500 - scale * (CalValue_Y - ADCResult_Y); if (servo2pos < 500) { servo2pos = 500; } } else { servo2pos = 1500; } } } void SystemInit(void) //Sets up the Fraunch board for Accel reads and LED tricks { //Startup clock system in max. DCO setting ~8MHz // This value is closer to 10MHz on untrimmed parts CSCTL0_H = 0xA5; // Unlock register CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting CSCTL2 = SELA_1 + SELS_3 + SELM_3; // set ACLK = vlo; MCLK = DCO CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // set all dividers CSCTL0_H = 0x01; // Lock Register // Turn off temp. REFCTL0 |= REFTCOFF; REFCTL0 &= ~REFON; // Enable LEDs P3OUT &= ~(BIT6+BIT7+BIT5+BIT4); P3DIR |= BIT6+BIT7+BIT5+BIT4; PJOUT &= ~(BIT0+BIT1+BIT2+BIT3); PJDIR |= BIT0 +BIT1+BIT2+BIT3; // P3.0,P3.1 and P3.2 are accelerometer inputs P3OUT &= ~(BIT0 + BIT1 + BIT2); P3DIR &= ~(BIT0 + BIT1 + BIT2); P3REN |= BIT0 + BIT1 + BIT2; // Setup Servo ports P1OUT &= ~(SERVO_1 + SERVO_2); P1DIR |= SERVO_1 + SERVO_2; P1SEL0 &= ~(SERVO_1 + SERVO_2); P1SEL1 &= ~(SERVO_1 + SERVO_2); // Setup Servo Interrupt TA0CCTL0 = CCIE; TA0CCR0 = 1500; TA0CTL = TASSEL_2 + MC_1 + ID_3; } void CalibrateADC(void) //Sets the "zero" point of the accelerometer { unsigned char CalibCounter =0; unsigned int Value = 0; __disable_interrupt(); //Turn off any interupts just incase ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Sample the X-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_X = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Sample the Y-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Y = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Sampel the Z-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Z = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //We need to start at the X-axis first due to how the interupt routine works. __enable_interrupt(); //enable interupts } void SetupAccel(void) { //Setup accelerometer // ~20KHz sampling //Configure GPIO ACC_PORT_SEL0 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; //Enable A/D channel inputs ACC_PORT_SEL1 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; ACC_PORT_DIR &= ~(ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN); ACC_PWR_PORT_DIR |= ACC_PWR_PIN; //Enable ACC_POWER ACC_PWR_PORT_OUT |= ACC_PWR_PIN; // Allow the accelerometer to settle before sampling any data __delay_cycles(200000); //Setting up the ADC stuff ADC10CTL0 &= ~ADC10ENC; // Ensure ENC is clear ADC10CTL0 = ADC10ON + ADC10SHT_5; ADC10CTL1 = ADC10SHS_0 + ADC10SHP + ADC10CONSEQ_0 + ADC10SSEL_0; ADC10CTL2 = ADC10RES; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; ADC10IV = 0x00; //Clear all ADC12 channel int flags ADC10IE |= ADC10IE0; //Enable ADC10 interrupts __enable_interrupt(); } void StartUpSequence(void) //this is copied from the Ti Fraunch Pad experience. Only thing it does is make a fancy LED sequence on boot. { unsigned char flag=4,up=1,counter = 0; unsigned char LED_ArrayPJ[] = {0x01,0x02,0x04,0x08}; unsigned char LED_ArrayP3[] = {0x80,0x40,0x20,0x10}; while (counter <10) { counter++; PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); if(up) { while(flag) { P3OUT = LED_ArrayP3[flag-1]; PJOUT = LED_ArrayPJ[flag-1]; LongDelay(); flag--; } up=0; } else { while(flag<4) { P3OUT = LED_ArrayP3[flag]; PJOUT = LED_ArrayPJ[flag]; LongDelay(); flag++; } up = 1; } } PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); } void LongDelay() { __delay_cycles(250000); } //Servo Interrupt #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A (void) { if(servo_counter == 0) { P1OUT |= SERVO_1; P1OUT |= SERVO_2; if (servo1pos >= servo2pos) { TA0CCR0 = servo2pos; } else { TA0CCR0 = servo1pos; } servo_counter++; } else if(servo_counter == 1) { if (servo1pos >= servo2pos) { P1OUT &= ~(SERVO_2); TA0CCR0 = servo1pos - servo2pos; } else { P1OUT &= ~(SERVO_1); TA0CCR0 = servo2pos - servo1pos; } servo_counter++; } else { TA0CCR0 = 10000 - servo1pos; P1OUT &= ~(SERVO_1); P1OUT &= ~(SERVO_2); servo_counter = 0; } } //ADC10 interupt routine #pragma vector = ADC10_VECTOR __interrupt void ADC10_ISR(void) { if (ADC_counter == 0) //X-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Next channel is the Y-axis ADCResult_X = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else if (ADC_counter == 1) //Y-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Next channel is the Z-axis ADCResult_Y = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else //Z-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Next channel is the X-axis ADCResult_Z = ADC10MEM0; ADC_counter = 0; ADC10CTL0 |= ADC10ENC | ADC10SC; } }
  17. Like
    longhorn engineer got a reaction from oPossum in Fraunch Pad Accel ADC code   
    Thanks for the help! I looked into the sequential sampling already but as you said it samples from whatever ADC10INCHx you set and will go all the way down to ADC10INCH0 in sequence. This is a problem on the Fraunch Pad as the AXL335 outputs are wired to P3.0 - P3.2 which means when you set ADC10INCHx to ADC10INCH14 (P3.2) it will process more then half the pins as analog inputs!
     
    Solution was to change the ADC10INCHx between sampling so the ADC process became round robin style. Here is the working code to sample all the axises on the Fraunch board. Also included is the "zero" calibration routines.
     

    #include "msp430fr5739.h" #include "FR_EXP.h" unsigned int ADC_counter = 0; unsigned int ADCResult_X, ADCResult_Y, ADCResult_Z; unsigned int CalValue_X, CalValue_Y, CalValue_Z; unsigned int temp; void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop the dog SystemInit(); //Setup the pins StartUpSequence(); //Copy Ti's fancy LED boot up trick SetupAccel(); //Setup the ADC and Accel CalibrateADC(); //Find zero points of all 3 axis ADC10CTL0 |= ADC10ENC | ADC10SC; //Start the first sample. If this is not done the ADC10 interupt will not trigger. while (1) { //Code goes here } } void SystemInit(void) //Sets up the Fraunch board for Accel reads and LED tricks { //Startup clock system in max. DCO setting ~8MHz // This value is closer to 10MHz on untrimmed parts CSCTL0_H = 0xA5; // Unlock register CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting CSCTL2 = SELA_1 + SELS_3 + SELM_3; // set ACLK = vlo; MCLK = DCO CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // set all dividers CSCTL0_H = 0x01; // Lock Register // Turn off temp. REFCTL0 |= REFTCOFF; REFCTL0 &= ~REFON; // Enable LEDs P3OUT &= ~(BIT6+BIT7+BIT5+BIT4); P3DIR |= BIT6+BIT7+BIT5+BIT4; PJOUT &= ~(BIT0+BIT1+BIT2+BIT3); PJDIR |= BIT0 +BIT1+BIT2+BIT3; // P3.0,P3.1 and P3.2 are accelerometer inputs P3OUT &= ~(BIT0 + BIT1 + BIT2); P3DIR &= ~(BIT0 + BIT1 + BIT2); P3REN |= BIT0 + BIT1 + BIT2; } void CalibrateADC(void) //Sets the "zero" point of the accelerometer { unsigned char CalibCounter =0; unsigned int Value = 0; __disable_interrupt(); //Turn off any interupts just incase ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Sample the X-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_X = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Sample the Y-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Y = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Sampel the Z-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Z = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //We need to start at the X-axis first due to how the interupt routine works. __enable_interrupt(); //enable interupts } void SetupAccel(void) { //Setup accelerometer // ~20KHz sampling //Configure GPIO ACC_PORT_SEL0 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; //Enable A/D channel inputs ACC_PORT_SEL1 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; ACC_PORT_DIR &= ~(ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN); ACC_PWR_PORT_DIR |= ACC_PWR_PIN; //Enable ACC_POWER ACC_PWR_PORT_OUT |= ACC_PWR_PIN; // Allow the accelerometer to settle before sampling any data __delay_cycles(200000); //Setting up the ADC stuff ADC10CTL0 &= ~ADC10ENC; // Ensure ENC is clear ADC10CTL0 = ADC10ON + ADC10SHT_5; ADC10CTL1 = ADC10SHS_0 + ADC10SHP + ADC10CONSEQ_0 + ADC10SSEL_0; ADC10CTL2 = ADC10RES; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; ADC10IV = 0x00; //Clear all ADC12 channel int flags ADC10IE |= ADC10IE0; //Enable ADC10 interrupts __enable_interrupt(); } void StartUpSequence(void) //this is copied from the Ti Fraunch Pad experience. Only thing it does is make a fancy LED sequence on boot. { unsigned char flag=4,up=1,counter = 0; unsigned char LED_ArrayPJ[] = {0x01,0x02,0x04,0x08}; unsigned char LED_ArrayP3[] = {0x80,0x40,0x20,0x10}; while (counter <10) { counter++; PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); if(up) { while(flag) { P3OUT = LED_ArrayP3[flag-1]; PJOUT = LED_ArrayPJ[flag-1]; LongDelay(); flag--; } up=0; } else { while(flag<4) { P3OUT = LED_ArrayP3[flag]; PJOUT = LED_ArrayPJ[flag]; LongDelay(); flag++; } up = 1; } } PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); } void LongDelay() { __delay_cycles(250000); } //ADC10 interupt routine #pragma vector = ADC10_VECTOR __interrupt void ADC10_ISR(void) { if (ADC_counter == 0) //X-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Next channel is the Y-axis ADCResult_X = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else if (ADC_counter == 1) //Y-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Next channel is the Z-axis ADCResult_Y = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else if (ADC_counter == 2) //Z-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Next channel is the X-axis ADCResult_Z = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else //Reset { ADC_counter = 0; } }
     
    Hope this helps someone. Could easily make a quadcoptor :mrgreen:
  18. Like
    longhorn engineer reacted to DanAndDusty in Fraunch Pad Accel ADC code   
    As far as Im aware you can't actually sample 3 channels at the same time.. However you can tell the 430 to sample a sequence of channels one after the other and its pretty quick. If you look at page 403 of this document there is a chart showing how it works. Basically you set ADC10INCHx and it will sample channels x, x-1... CH0 in sequence. I think the sequence has to be consecutive channels and has to end at 0.
     
    Other 430s have a DMA controller that can automatically transfer readings into a section of ram and then interrupt when the conversions are all complete. From a brief scan of that document it doesn't look as though the fraunchpad has that capability but it was a brief scan so I may have missed it.
     
    Hope this helps. Good luck with your project.
     
    Dan
  19. Like
    longhorn engineer reacted to oPossum in Fraunch Pad Accel ADC code   
    The Fraunchpad supports ADC DMA using trigger #24.
  20. Like
    longhorn engineer reacted to bluehash in Replying to Questions   
    Hello Everyone,
     
    There has been a sudden influx of new members over the past month, resulting in many questions.
    You guys are doing a great job at replying to questions, this is just to motivate you more:
    If you see a question not answered for a day, with zero replies, try to answer it. If not, you may leave it alone. So far, you have had a very good record of answering questions. We could count 0 in the General forum. The posts that went unreplied were updates or ideas, not specifically needing a reply.
     
    Another huge thing, which is very surprising, is that you guys have created a fantastic ecosystem. There is no mockery, good understanding as well as sharing of ideas - impressive- so much so that the new users love this forum( literally here and here). The only trouble makers are the darn spammers. The only come when we are asleep.
     
    So big kudos to you and keep up the hard work.
  21. Like
    longhorn engineer reacted to bluehash in Hello from ATX!   
    Looked through your website. You got quite a few interesting posts there. Loving the sniffer?
    Welcome to the Forums! Glad you could join and don't forget to add your website to your signature.
     
    Which one? C2000? Picollo? I work on the C2000(F28335) to be specific.
×
×
  • Create New...