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.

LED BRIGHTNESS CONTROL USING SWITCH

In my project I need to control Led brightness.I am using MSP430G2432IN20 device.When one switch is pressed I have to increase the brightness.When another switch is pressed brightness has to be decreased.The increment and decrements of Led brightness should be step by step.How I can implement it.

34706.main.c
#include <msp430.h>
#define THRESHOLD0  0x0000
#define THRESHOLD1  0x0136
#define THRESHOLD2  0x026c
#define THRESHOLD3  0x03a2
#define hystyrisis  0x005D

#define TIM1 8

#define TIM2 62
#define VAR 1
int main(void)
{

    WDTCTL = WDTPW + WDTHOLD;                 		// Stop WDT

  BCSCTL1 = CALBC1_16MHZ;
  DCOCTL = CALDCO_16MHZ;

  ADC10CTL1 = INCH_0;             					// Conversion code singed format, input A0
  ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE;		// ADC10ON, interrupt enabled
  ADC10AE0 |= 0x00;                         		// P1.0 ADC option select

                     				// Set P1.0 LED on


  P2DIR |= 0x0F;                            // P1.0 output
  P2OUT |= 0x00;

CCTL1 = CCIE + OUTMOD_7;                  // CCR1 interrupt enabled
CCTL2 = CCIE + OUTMOD_7;                  // CCR2 interrupt enabled
 CCR1 = 40;
//CCR2 = 30;
  CCR0 = 100;
  TACTL = TASSEL_2 + MC_1;                  // SMCLK, Contmode


  for (;;)
  {
	  volatile unsigned long i;	// volatile to prevent optimization
    ADC10CTL0 |= ENC + ADC10SC;             		// Sampling and conversion start
    __bis_SR_register(CPUOFF + GIE);        		// LPM0, ADC10_ISR will force exit




    if((THRESHOLD3+0x003E) >= ADC10MEM && ADC10MEM > (THRESHOLD3-hystyrisis) & TACCR1>=TIM1)
    			{
    	  	  	  	  CCR1 -= VAR;
    	  	  	  _delay_cycles(350000);

    			}

    else if((THRESHOLD2+hystyrisis) >= ADC10MEM && ADC10MEM > (THRESHOLD2-hystyrisis) & TACCR1<=TIM2)
    			{
 				  	  CCR1 += VAR;

 				  	 _delay_cycles(350000);


    			}
    else if((THRESHOLD1+hystyrisis) >= ADC10MEM && ADC10MEM > (THRESHOLD1-hystyrisis) & TACCR2>TIM1)
    			{
    				  CCR2 -= VAR;

    				  _delay_cycles(350000);


    			}
    else if((THRESHOLD0+hystyrisis) >= ADC10MEM & TACCR2<TIM2)
    			{
			 	 	  CCR2 += VAR;


			 	 	 _delay_cycles(350000);


    			}
    else
    			{
		  	  	   _delay_cycles(0);
    			}


}}



// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
	_delay_cycles(1);
  __bic_SR_register_on_exit(CPUOFF);                    // Clear CPUOFF bit from 0(SR)
}
// Timer_A3 Interrupt Vector (TA0IV) handler
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A1_VECTOR))) Timer_A (void)
#else
#error Compiler not supported!
#endif
{
  switch( TA0IV )
  {
  case  2:                                  // CCR1
  {
	P2OUT ^= 0x06;                          // Toggle P1.0
  }
  break;
  case  4:
  {
//	P2OUT ^= 0x09;                          // Toggle P1.
  }
  break;

  case 10: break;                           // overflow not used
 }}

  • Hi Neena!

    I would drive the LED at an output pin that can be hardware-controlled by a timer and operate it in OUTMOD_7 (reset/set). Then I would set a fixed frequency with CCR0 and a variable duty-cycle in CCRx. Then check the buttons and increase CCRx by a fixed value when pressing one button and decrease CCRx by the value when pressing the other one.

    Dennis

  • Hi Dennis
    I tried in that way.I also attached my code with that post.I used timer in up down mode.But I am not getting the correct output.When certain time increment button is pressed decrement is happening.I don't know why its happening like that.
  • Better use the timer in up mode here.
  • Hi

    I am also attached my code with this case.Could you please check that there is any mistakes is there in that code.

  • You should narrow down your problem a bit. Debug your program and look what works correctly and what part of the code doesn't.
  • Hi Dennis,
    Actually I am trying to control LED brightness.I have totally 4 LED arrays are there.Also 4 switches are there.My requirement is that two LED arrays I am controlling using two switches.When one switch is pressed I have increase the brightness.When another switch is pressed I have to decrease the brightness.But my code is working only for some certain range of duty cycle.The range is determined by the the parameter T1M1 and T2M2 in the code.When their values 8 and 62 the code is working.But I want a wide range.When I changed the values the code is not working properly.For certain values only toggling is occurring and some time for the same switch increment and decrements is happening.Now in the code only two switch control I have activated.But when all the four switches are get activated in the code then this 8 to 62 range also the code is not working proper way.
  • PWM dimming LEDs don't have to be to be fast as anything over 100-200 Hz looks smooth to a human eye.

    So say you are using 1MHz DCO for  taclk source.
    1'000'000/200 = 500-1 to be used for the CCR0 value

    Set CCR1 to 20 and use CCR0's IRQ to increase it each 16th cycle until it reach 480.

    With a msp that has no store-and-latched Timmer, then comes the problems of not changing it in time so don't go below 20 for ccr1

    once you got this working, your are ready to use buttons to change CCR1 value.

  • Hi Tony,

    Now I changed the code in the following way.Now we have four LEDs and two different brightness levels are there.But now the problem is that when we are working continously the PWM output get changed.That means one become zero and zero become one.So the duty cycle will change.Before the problem occur the duty cycle was (10%-58%) but after this toggling issue the duty cycle was (62%-90%).

    #include <msp430.h>
    #define THRESHOLD0 0x0000
    #define THRESHOLD1 0x0136
    #define THRESHOLD2 0x026c
    #define THRESHOLD3 0x03a2
    #define hystyrisis 0x005D

    #define TIM1 120

    #define TIM2 560
    #define VAR 1
    int main(void)
    {

    WDTCTL = WDTPW + WDTHOLD; // Stop WDT

    BCSCTL1 = CALBC1_16MHZ;
    DCOCTL = CALDCO_16MHZ;

    ADC10CTL1 = INCH_0; // Conversion code singed format, input A0
    ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE; // ADC10ON, interrupt enabled
    ADC10AE0 |= 0x00; // P1.0 ADC option select

    // Set P1.0 LED on


    P2DIR |= 0x0F; // P1.0 output
    P2OUT |= 0x00;

    CCTL1 = CCIE + OUTMOD_7; // CCR1 interrupt enabled
    CCTL2 = CCIE + OUTMOD_7; // CCR2 interrupt enabled
    CCR1 = 100;
    CCR2 = 100;
    CCR0 = 1000;
    TACTL = TASSEL_2 + MC_3; // SMCLK, Contmode


    for (;;)
    {
    ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
    __bis_SR_register(CPUOFF + GIE); // LPM0, ADC10_ISR will force exit


    if((THRESHOLD3+0x003E) >= ADC10MEM && ADC10MEM > (THRESHOLD3-hystyrisis) & TACCR1>=TIM1)
    {

    CCR1 -= VAR;

    _delay_cycles(350000);

    }

    else if((THRESHOLD2+hystyrisis) >= ADC10MEM && ADC10MEM > (THRESHOLD2-hystyrisis) & TACCR1<=TIM2)
    {
    CCR1 += VAR;

    _delay_cycles(350000);

    }
    else if((THRESHOLD1+hystyrisis) >= ADC10MEM && ADC10MEM > (THRESHOLD1-hystyrisis) & TACCR2>=TIM1)
    {
    CCR2 -= VAR;


    _delay_cycles(350000);

    }
    else if((THRESHOLD0+hystyrisis) >= ADC10MEM & TACCR2<=TIM2)
    {
    CCR2 += VAR;


    _delay_cycles(350000);

    }
    else
    {
    _delay_cycles(0);
    }


    }}

    // ADC10 interrupt service routine
    #pragma vector=ADC10_VECTOR
    __interrupt void ADC10_ISR(void)
    {
    _delay_cycles(1);
    __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
    }
    // Timer_A3 Interrupt Vector (TA0IV) handler
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=TIMER0_A1_VECTOR
    __interrupt void Timer_A(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(TIMER0_A1_VECTOR))) Timer_A (void)
    #else
    #error Compiler not supported!
    #endif
    {
    switch( TA0IV )
    {
    case 2: // CCR1
    {
    P2OUT ^= 0x06; // Toggle P1.0
    }
    break;
    case 4:
    {
    P2OUT ^= 0x09; // Toggle P1.
    }
    break;

    case 10: break; // overflow not used
    }}

  • You should use only one method for LED control:
    a) Toggle the LED inside the ISR with CCIE interrupt
    b) Use the hardware PWM with OUTMOD_7
  • Hi Dennis,
    I am not toggling LED.I am changing the brightness when switch is pressed.
  • NEENA JOSEPH said:
    I am not toggling LED.

    This looks like you toggle the output:

    P2OUT ^= 0x06; // Toggle P1.0

    But you also have

    CCTL1 = CCIE + OUTMOD_7; // CCR1 interrupt enabled

    the OUTMOD_7 in your code, although I cannot see any PxSEL settings to assign a pin to that functionality.

  • Hi Dennis
    P2OUT ^= 0x06; // Toggle P1.0
    this is four selecting output led arrays.In this command we are selecting 2nd and 3rd LED array.
  • OK! So if you're using OUTMOD_7, where is the PxSEL setting that sets an output pin to the timer function?
  • NEENA JOSEPH said:
    P2OUT ^= 0x06;

    NEENA JOSEPH said:
    // Toggle P1.0

    NEENA JOSEPH said:
    this is four selecting output led arrays.In this command we are selecting 2nd and 3rd LED array.

    The above three quotes from you are talking about three different subjects. Are they not?

  • Maybe you could add a schematic of your hardware?

**Attention** This is a public forum