1
votes

I want to configure my button and configure LED blink speed so that when I press the button the first time the LEDs blink slower. When I press a second time the LEDs blink more slowly still, When I press a third time and LEDs blink the slowest.

After all when I press the button a fourth time I want to LEDs off (i.e. not blink until I press the button). I thought I can do this with mod operator (a % 3 == 0 ???)

Here is my code after update :

unsigned int rate = 1000000;
int NUM_STATES = 4 ;
unsigned int counter=1;
for(;;)
{
  if( buttonPressed() )
  {
    rate += 2000000;
    counter++;
  }
  if(counter  % 4 == 0)
  {
  rate = 0;
  }

  flashSequence(rate);
}
}
int buttonPressed(void)
{
    if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0))
   return 1;
else
 return 0;
}
void flashSequence (int rating)
{              
          if (rating == 0)
            GPIO_ResetBits(GPIOD, 
 GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
        else
          {
            /* PD12 to be toggled */
            GPIO_SetBits(GPIOD, GPIO_Pin_12);
            /* Insert delay */
            Delay(rating);
            /* PD13 to be toggled */
            GPIO_SetBits(GPIOD, GPIO_Pin_13); 
            /* Insert delay */
            Delay(rating);
            /* PD14 to be toggled */
            GPIO_SetBits(GPIOD, GPIO_Pin_14);
            /* Insert delay */
            Delay(rating); 
            /* PD15 to be toggled */
            GPIO_SetBits(GPIOD, GPIO_Pin_15);     
            /* Insert delay */
            Delay(rating);
            GPIO_ResetBits(GPIOD, 
 GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
            Delay(rating);
          }
  }
2
You can implement this with a state machine.Burstfulovic
I cannot write a code for it but I can suggest. You need to interface the button on External Interrupt pin of the uC, set-up the ISR for external interrupt, inside the ISR increment a global variable. In main function keep checking the value of that global variable depending on the global variable value use Timer 0 or Any timer to generate a delay and use that delay to blink the LED.Gaurav Pathak
If you expect others to read your code, it is just polite ot format and indent it in some conventional manner. Questions on SO are persistent; starting off saying your "new here" serves no purpose, neither does explicitly asking for help - that is what we are all here for. Fixed that for you; but next time, consider this.Clifford
You have posted code that presumably does not do what you want it to; it would be helpful if you were to explain what it does do or how you expected it to work.Clifford
In the first press, you say tit should blink "slower". Slower than what? What should the LED be doing before the first press?Clifford

2 Answers

0
votes

counter % 3 will yield 0, 1 or 2, but you have described four states, so counter % 4 would be needed. Actually you did not describe the state before the first press, so perhaps there are 5.

If the number of states is not a power of 2, using modulo n will cause a discontinuity when the counter wraps around. With an unsigned int counter this may not be a practical limit, but it is at least a latent bug.

The code fragment you have posted will not work because (amongst other issues) counter is not modified in the loop, so it will never exit, and never change the flash rate.

You need something of the following form:

int rate = 0 ;  // Off
#define NUM_STATES = 4 ; (0 to 3)
for(;;)
{
    if( buttonPressed() )
    {
        rate++ ;
        rate %= NUM_STATES ;
    }

    flashSequence( rate ) ;
}

The flashSequence() is a function that flashes at a rate proportional to rate, with zero(0) being a special case of "OFF".

0
votes

I afraid it is a bit too much to explain but LED blinking patterns and key readings should be done in the timer interrupt and do not block the normal program flow.

Imagine the situation if after the keypress you need to blink a LED but program needs to execute as normally.

You can take look on my code for it:

LED - https://www.diymat.co.uk/arm-blinking-led-driver/

Button - https://www.diymat.co.uk/arm-three-function-click-double-and-long-click-button-library-timer-interrupt-driven/

PS my page is in a permanent under construction state :).