Things used in this project

Hardware components:
Msp exp430f5529lp 5529 lp angle%5b1%5d
TI LaunchPad MSP-EXP430F5529LP MSP430 LaunchPad
×2
Hand tools and fabrication machines:
09507 01
Soldering iron (generic)

Schematics

Block Diagram
System Block diagram
Embedded final project zmlbmcz380

Code

Transmit Code for Infrared LEDC/C++
Code used to convert flex sensor analog voltage into data to control the infrared LED.
//This program is the transmission portion of Jackson Love's final project.
//The program will read in a analog voltage from two flex sensors
//and control an infrared LED and two servo motors based on the threshold values.
//This program uses a motor driver to step up the current to operate the infrared LED.
#include <msp430.h>
#define Motor BIT2 //P1.2 is designated for the two motors
#define RedLED BIT4 // P1.4 designated for the test LED
#define InfLED BIT3 // P1.3 for the infrared LED
#define Button BIT1
#define Flex1  BIT0
#define Flex2  BIT1
volatile unsigned int ADCresults[2];
const float VCC = 5.08; // 5V pin
const float R1_Divisor = 46120; //Flex sensor 1 divisor
const float R2_Divisor = 46520; //Flex sensor 2 divisor
const float R1StraightResistance = 28190; //Flex sensor 1 straight resistance
const float R2StraightResistance = 30770; //Flex sensor 2 straight resistance
const float R1BendResistance = 120000; //Max resistance value for R1
const float R2BendResistance = 125000; //Max resistance value for R2
int Angle = 1500;	//initial position.
int degree90 = 1600; //90 degrees. Neutral position
int degree45 = 2200;//45 degrees. Position 1
int motorOn = 1;//variable that tracks whether motor is on or off
int state = 0; //state machine variable that tells if at position 0 or 1
//position 0: neutral
//position 1: rotates right

void main(void)
{
	  WDTCTL = WDTPW+WDTHOLD;                   // Stop watchdog timer
	  P6SEL = Flex1 + Flex2;                             // Enable A/D channel inputs
	  ADC12CTL0 = ADC12ON+ADC12MSC+ADC12SHT0_2; // Turn on ADC12, set sampling time
	  ADC12CTL1 = ADC12SHP+ADC12CONSEQ_1;       // Use sampling timer, single sequence
	  ADC12MCTL0 = ADC12INCH_0;                 // ref+=AVcc, channel = A0
	  ADC12MCTL1 = ADC12INCH_1;                 // ref+=AVcc, channel = A1
	  ADC12MCTL2 = ADC12INCH_2;                 // ref+=AVcc, channel = A2
	  ADC12MCTL3 = ADC12INCH_3+ADC12EOS;        // ref+=AVcc, channel = A3, end seq.
	  ADC12CTL0 |= ADC12ENC;                    // Enable conversions
                                                                                                                                                                                                                                                                                               WDTCTL = WDTPW + WDTHOLD;    // Stop watchdog timer
  P1DIR |= BIT2 + RedLED+ InfLED; //Motors, Red LED, and Infrared set as outputs
  P2REN |= Button;
  P2OUT |= Button;
  P1REN |= Button;            // enable pull-up resistor for switch
  P1OUT |= Button;            // enable pull-up resistor for S2 (P1.3)
  P1IE = Button;              // enable P1.3 interrupt
  P1IES= Button;
  P1IFG = 0x00;                // clears interrupt flag
  TA0CCTL0 = CCIE;             // CCR0 interrupt enabled
  TA0CCR0  = 5000;            // Set count threshold
  TA0CTL    = TASSEL_1 + MC_0;  // SMCLK, up mode (starts timer!)
  TA1CCTL0 = CCIE;             // CCR0 interrupt enabled
  TA1CCR0  = 1500;            // Set count threshold
  TA1CTL    = TASSEL_2 + MC_1;  // SMCLK, up mode (starts timer!)
  __enable_interrupt();        // enables selected interupts


  while(1) // infinitely loop
  {
	  ADC12CTL0 |= ADC12SC;   //begins ADC sampling conversion
	  ADCresults[1]= ADC12MEM1;  //assigns results buffer to memory 1
	  ADCresults[0] = ADC12MEM0; //assigns results buffer to memory 1

	  if(ADCresults[1] < 2500) // if flex sensor 1 analog reading is less than 2500
	  {
 	 P1OUT ^= RedLED; //turn on the Red LED as long as sensor is bent
 	 P1OUT ^= InfLED; //turn on the infrared LED as long as sensor is bent
	  }
	  else
	  {
		  P1OUT &= ~InfLED; //turns off the red LED
	  	  P1OUT	&= ~RedLED; //turns off the infrared LED
	  }

  if (ADCresults[0] < 2500) // if flex sensor 2 analog reading is less than 2500
  	  {
       Angle = degree45;//move motor to angle of 90
       state = 1;//change state
       }
       else
       {
       Angle = degree90;//rotate motor 45 degrees

       }




  }
}

#pragma vector=TIMER1_A0_VECTOR
__interrupt void Timer_A1 (void) // Timer A0 interrupt service routine
{   // the TACCR0 CCIFG flag is automatically reset
    if (motorOn == 1)//statement for motor on
       {
       P1OUT |= BIT2;//sets P1.2 as output, turns motor on
       TA1CCR0  = Angle;   // Sets max counter to Angle
       motorOn = 0;//set to 0 for motor off state
       }
       else
       {
           motorOn = 1;
           P1OUT &= ~BIT2; //turns motor off
           TA1CCR0  = 20000;//delay for 20 millisecond
       }
}
//code from ADC example
//reads the analog values and assigns them to the results buffer
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR (void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch(__even_in_range(ADC12IV,34))
  {
  case  0: break;                           // Vector  0:  No interrupt
  case  2: break;                           // Vector  2:  ADC overflow
  case  4: break;                           // Vector  4:  ADC timing overflow
  case  6: break;                           // Vector  6:  ADC12IFG0
  case  8: break;                           // Vector  8:  ADC12IFG1
  case 10: break;                           // Vector 10:  ADC12IFG2
  case 12:                                  // Vector 12:  ADC12IFG3
    ADCresults[0] = ADC12MEM0;                 // Move results, IFG is cleared
    ADCresults[1] = ADC12MEM1;                 // Move results, IFG is cleared
  case 14: break;                           // Vector 14:  ADC12IFG4
  case 16: break;                           // Vector 16:  ADC12IFG5
  case 18: break;                           // Vector 18:  ADC12IFG6
  case 20: break;                           // Vector 20:  ADC12IFG7
  case 22: break;                           // Vector 22:  ADC12IFG8
  case 24: break;                           // Vector 24:  ADC12IFG9
  case 26: break;                           // Vector 26:  ADC12IFG10
  case 28: break;                           // Vector 28:  ADC12IFG11
  case 30: break;                           // Vector 30:  ADC12IFG12
  case 32: break;                           // Vector 32:  ADC12IFG13
  case 34: break;                           // Vector 34:  ADC12IFG14
  default: break;
  }
}
Receiving Circuit CodeC/C++
Code used with an Infrared Receiver and passive buzzer.
#include  <msp430.h>
#define RedLED BIT0
#define GreenLED BIT6
#define Button BIT3 // output of infrared receiver
#define SPEAKERLOW BIT4 //negative piezzo
#define SPEAKERHIGH BIT5 //positive piezzo
int enableBuzzer = 0;
void playNote(unsigned char pitch);
void playNoteForDuration(unsigned char pitch, unsigned char duration);

void main(void) {
	WDTCTL = WDTPW + WDTHOLD;       // Stop watchdog timer
	P1DIR |= SPEAKERLOW | SPEAKERHIGH;		//sets the two LEDs to output
	P1REN |= Button;
	P1IE = Button;	//enable interrupt for Button
	P1IES = Button;	//initializes the interrupt on the clock edge select
	P1OUT |= Button;			//sets Button as an output
	TA0CCR0 = 3000;              // Upper limit of 3000 cycles
	TA0CCTL0 = CCIE;             // enable the interrupts from TimerA0 CC0
	_enable_interrupts();
//note that TACTL is not initialized. It will be called in the PORT1 interrupt

	while (1)
	{
		if (enableBuzzer==1)
		{

 			playNoteForDuration('c',1);
			enableBuzzer=0;
			P1IE = Button;
		}
	}
}
#pragma vector = TIMER0_A0_VECTOR	//timer interrupt
__interrupt void TA0_ISR(void)
{


		enableBuzzer = 1;	//toggles the Green LED

		TA0CTL = MC_0;//then sets the control to MC_0 to stop counting
}
//if the Button is pressed, PORT1 interrupt starts
//normally, TACTL is MC_0, so this interrupt sets TACTL to MC_1
//if the button is pressed, Timer A will begin counting up to 3000
//This way the timer is only started when the button is pressed
#pragma vector = PORT1_VECTOR
__interrupt void PORT1_ISR(void)
{
	if (!(TA0CTL & MC_1)){	//if Timer A control is not set to MC_1
		TA0CTL = TASSEL_2|MC_1|ID_2|TACLR;	//sets TACTL is set to MC_1
		P1IFG = 0;	//clears flag
	}
	P1IE &= ~Button;
	P1IFG = 0;	//clears flag
}

void playNote(unsigned char pitch) //Function to play the array of notes
{
    P1OUT &= ~SPEAKERLOW;   //grounds the speaker
    P1OUT |= SPEAKERHIGH; //Speaker will constantly be changing therefore creating a sound
    int P;  //local variable for Pitch
    int L = 15000;  //sets the length of the note to be played
    int j;
    int i;
    int h;
    switch (pitch) // note that the frequency to loop ratio is 28923.8/Hz = loop number
    {//a range of 7 notes are used in this array
    case ('c'):  //middle c note in the 4th octave
        P = 360;  //calculated frequency for c
        L = L / P; //This gives each note a common time. Syncs with the chip clock
        break;
    case ('d'):  //d note in the 4th octave
        P = 232;
        L = L / P;
        break;
    case ('e'):  //e note in the 4th octave
        P = 206;
        L = L / P;
        break;
    case ('f'):  //f note in the 4th octave
        P = 195;
        L = L / P;
        break;
    case ('g'):  //g note in the 4th octave
        P = 174;
        L = L / P;
        break;
    case ('a'):  //a note in the 4th octave
        P = 155;
        L = L / P;
        break;
    case ('b'):  //b note below middle c (3rd octave)
        P = 276;
        L = L / P;
        break;
    case ('C'):  //c note in the 5th octave
        P = 130;
        L = L / P;
        break;
    case ('r'):  //rest case. This allows a musical break in between notes
        P = 0;
        L = L / 4;  //specifically catered to be a different loop cycle
        break;
    default:
        P = 0;
    }
    for (h = 5; h > 0; h--) { //multiplies the Length (L) to a play at a longer duration
        for (j = L; j > 0; j--)  //sets j = L (15000) to loop 15000 times
                {
            if (P != 0) //when P =0, there is not a set frequency, but is inaudible to hear
                    { //by setting P not to 0, this will read the rest case as a pause, not a frequency
                P1OUT ^= SPEAKERLOW;    //speakers will play a frequency.
                P1OUT ^= SPEAKERHIGH;
            }
            for (i = P; i > 0; i--)
                ; //P set to an integer to keep the frequency everytime. Otherwise P will be 0 constantly as it cycles
        }
    }
}

void playNoteForDuration(unsigned char pitch, unsigned char duration) //Duration function for playing the note
{ //this function will multiply the length of the note in playNote function for a duration multiplier set in the array
    int i;    //sets i = duration intitially
    for (i = duration; i > 0; i--)
        playNote(pitch); //passes in pitch as it cycles through the array
}

Credits

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

WIFI CONTROLLED ZUMO ROBOT
Intermediate
  • 24
  • 1

Protip

Design a robot that uses on-board IMU (Inertial Measurement Unit) sensors for autonomous motion control using Wi-Fi.

CC13xx + CC3100 WiFi IoT gateway
Intermediate
  • 11
  • 0

Protip

Learn how to use a 915MHz to Wi-Fi gateway in Energia

Upload code to TI TM4C123 using Linux, CMake and lm4tools
Intermediate
  • 120
  • 2

Protip

This is a step by step guide on how to get CMake and lm4tools setup in a Linux environment to upload code directly to your TM4C123 via usb.

Got Your Back
Intermediate
  • 2,113
  • 51

Full instructions

This ergonomic-sensitive chair add-on will help you chair-ish your health!

Got Your Back

#creaTIviteam

TiWo
Intermediate
  • 1,445
  • 35

Full instructions

TiWo, keepin' it cool

TiWo

Team ElectroVolts

The Zen Tracker - The Future of Workplace Health
Intermediate
  • 2,154
  • 32

Full instructions

An IoT, lucky bamboo garden that ambiently tracks and graphs your daily activity, ensuring wealth, health, and happiness!

Add projectSign up / Login