redefining variables in main program loop

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I guess this is probably a silly question, and I show my noobishness for even wanting to do such a thing, but how can I set a variable inside the main program loop?

I want to set the frequency of a flashing LED after I get a button input. So basically what I have is like this:

#include 
#include 

int blink_frequency = 1;

//blah blah, bunch of other defines and stuff (working fine)

int main (void)
{

//blah blah, bunch of statements setting up the timer and interrupts and stuff. (working fine)

for (;1=1;)

if (button_is_pressed())
blink_frequency = 4;
}

There's more to it than that, like I'm using a switch statement and a counter to tell how long the button's been pressed and then assign a value to blink_frequency, and of course there's all the PORTB |= (1 << PB1) statement to actually do the flashing, but for right now, I just can't figure out why I can set the value of blink_frequency before I get into the loop, but I can't from inside.

Is there a special way to do this?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is blink_frequency actually being used in an interrupt routine then?

If yes you've been bitten by FAQ#1 - make it 'volatile' (then read the FAQ and the whole manual)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, it's not in the interrupt. Only in main. I did try to put it in the interrupt routine and did make it volatile, but it still didn't work.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you sure that button_is_pressed() really works they way you expect it to?

/johan

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you need to show us more of a test program that demonstrates the problem you have then.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay, I got it to work. I tried reassigning blink_frequency inside main in a simpler version of the program and found that I had put the assignment in a spot that would make it never get reassigned. Duh.

Okay, now here's my next issue. I think that indeed, my button_is_pressed function isn't functioning. This is what I have

   for (;1==1;)
   {
   if (done_waiting)
      {
	  cli(); // Turn off interrupts while we're flashing
	     switch (mode_flag) // Depending on value of mode_flag, set blink_frequency
         {
         case 1: blink_frequency = 1;
         break;
         case 2: blink_frequency = 2;
         break;
         case 3: blink_frequency = 4;
         break;
         case 4: blink_frequency = 8;
         break;
         case 5: blink_frequency = 10;
         break;
         default: blink_frequency = 10;
         break;
         }
	  blink_cycles = blink_frequency * blink_seconds; //Number of times to flash the LED
      on_off_cycles = 10 / blink_frequency; //How long to leave the LED on or off per flash
}

//blah blah flashing the LED using the value of blink_frequency. (working fine)

}
ISR(TIMER0_COMPA_vect)
{
if (wait_count < wait_cycles) // Wait for "wait_minutes" minutes before we start flashing the LEDs
{
   wait_count++;
      if (button_is_pressed())
	        {
            mode_flag++;
            PORTB |= (1 << PB1); // Flash the LED
            _delay_ms(250);
            _delay_ms(250);
            PORTB &= ~(1 << PB1);
            }
}
else
   done_waiting = 1; // Flash the LEDs in the main loop
}


//-----------------Functions-----------------//

int button_is_pressed (void)
{
   if (bit_is_clear(PINB, PB2)) // The button is pressed when PB2 is clear
      {
      _delay_ms(50); // Should be done bouncing after 50 ms, hopefully
      if (bit_is_clear(PINB, PB2)) // Check again that the bit is clear
         return 1; // If it is, the button is really pressed
      else
         return 0;
      }
   return 0;
}

(the LED is supposed to wait before it starts flashing. So, supposedly, depending on how long you hold down the button, mode_flag should increment and change the value of blink_frequency in the switch statement. It should also blink the LED at 1 Hz as long as the button is held, but it doesn't, and the switch always goes to the default.

Thanks guys.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK same silly question - is 'done_waiting' volatile?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes, it's volatile.

however, I notice that if I put the button_is_pressed debounce code in main (without actually calling the function), it works, but when I try to call the function in the ISR, it doesn't work. I tried to call the function "volatile", but it hasn't seemed to help

also, if I try to call the function from inside the main loop, it says that "button_is_pressed will always evaluate as true."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

woo hoo! nevermind guys. I got it working. I guess just talking about it helped me work it out. I had an extra "return 0;" in the function. I think that's what messed me up.

I also called the function "volatile int" so it could be called in main and the ISR.

It's working now just how it want it. Holding the button for a certain time makes the led flash and then when the "waiting" time is over, it flashes at the correct frequency. Yay!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I also called the function "volatile int"

You do mean "I also named the variable [...]", don't you?

No not nitpicking. Just pointing it out so that future visitors to this thread won't get confused.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]