What should I do for stop the loop at the background when I am not pressing the button?

88 Views Asked by At

I am new here ,sooo sorry for the mistakes :P.
So whatever. I am trying to do a simple counter circuit with Arduino UNO, a catot 7-segment display and a button. I just want to when I press the button system circle start and takes one footstep. For example 7-segment shows "0" from earlier push, when ı push the button it needs to be "1". But ıdk why its keep counting from background and I couldn't stop it. Then I make some adjustments in my code( btw ı am coding in micro-c for AVR and using AVRDUDES for load my code in Arduino.) and then its stuck at "F" (System should count like 1,2,3,4,5,6,7,8,9,A,b,c,d,E,F). I don't understand why and how can I solve it. Additionally 7 segment led connected with my D port. I want to do B0 pin is input. Then I want to control the B0 pin's value. When B0 pin is HİGH, then i want to program continue.

This is my circuit connections

unsigned char dizi[] = {0x40,0xF9,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x27,0x21,0x06,0x0E};
unsigned int i ;

void main()
{
 DDRD = 0xFF ;
 DDB0_bit = 0 ;
 

  while(PINB.B0);
  {
          for(i = 0;i<=15;i++)
          {
          PORTD = dizi[i] ;
          Delay_ms(700);
          }
  }
}

I just write the code and just ıdk ı hope it work. But it didn't. Idk why and my mind is so blurry ı can't see the error. I hope u can help :D.

2

There are 2 best solutions below

4
On

What are you using to program your Arduino? The loop never stops after you press the button because you don't have a stop condition aside from i reaching 15. I'm rusty on Arduino but you could add

if(!(PINB.B0)){ break; }

in the for loop, after the delay to exit the loop when you're not pressing the button.

0
On

Your program needs to work like this:

  • for(;;) { /* program here */ } Microcontroller programs never leave main().

  • You need to read the button and then debounce it. This should be mentioned in any embedded systems beginner tutorial. Debouncing is mandatory whenever you have a button, or the program will just behave randomly, sometimes missing keyboard presses, other times taking several at once etc.

    (The most proper way to do this is to read the button repeatedly from a timer callback, but then you need to write the code for the timer/RTC hardware peripheral driver first.)

  • Once you have a debounced signal pressed/not pressed, then implement a simple state machine like in this pseudo code:ish C below:


typedef enum
{
  NOT_PRESSED,
  PRESSED_UPDATE_DISPLAY,
  PRESSED_STILL_DISPLAYED,
} simple_state_machine_t;
simple_state_machine_t state = NOT_PRESSED;

...

int index_7seg = 0;

for(;;)
{
  /* debounce button */
  bool is_pressed = debounced_value;

  switch(state)
  {
    case NOT_PRESSED:
      state = is_pressed ? PRESSED_UPDATE_DISPLAY : NOT_PRESSED;
      break;

    case PRESSED_UPDATE_DISPLAY:
      index_7seg++;
      if(index_7seg == max_7seg)
      {
        index = 0;
      }

      state = is_pressed ? PRESSED_DISPLAYED : NOT_PRESSED;
      break;

    case PRESSED_DISPLAYED:
      state = is_pressed ? PRESSED_DISPLAYED : NOT_PRESSED;
      break;
  }

  PORTD = the7seg_table[index_7seg];
} /* for(;;) */

The PRESSED_UPDATE_DISPLAY state will only get entered when you go from not pressed to pressed, essentially giving you a rising edge trigger through software. That's the only time you should increase the table index.