0

Does a blinking loop cause delay in registering butotn press
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Does a blinking loop cause delay in registering butotn press

by rizla420 on Wed Feb 11, 2009 9:23 pm

Hey,

I'm messing around with a very simple sketch. I have 4 buttons and one led. When one button is pressed, the LED turns on. When another button is pressed the led begins to flash. I also have a serial output that tells me which button I hit. I've noticed that when I have the blinking loop enabled, it takes a couple button presses to sometimes register the button being presses, whereas when i only have the LED on/off. It registers the button presses instantaneously. Whats the best way to resolve the issue of latency? Is there a way? BTW, i'm using a pull up resistor so it registers the button presses accurately. Here's the code:

Code: Select all | TOGGLE FULL SIZE
void loop(){
 

  b1_val1 = digitalRead(b1);     
  delay(10); 
  b1_val2 = digitalRead(b1);
 
  b2_val1 = digitalRead(b2);     
  delay(10); 
  b2_val2 = digitalRead(b2);
 
  b3_val1 = digitalRead(b3);     
  delay(10); 
  b3_val2 = digitalRead(b3);
 
  b4_val1 = digitalRead(b4);     
  delay(10); 
  b4_val2 = digitalRead(b4); 
 

  if (b1_val1 == b1_val2) {                 
    if (b1_val1 != b1State) {         
      if (b1_val1 == LOW) {             
   
      hit_ack++;
 
        Serial.println("button 1 hit!");

        digitalWrite(ledPin, HIGH);
      }
    b1State = b1_val1;             
  }
  }
 
  if (b2_val1 == b2_val2) {                 
    if (b2_val1 != b2State) {         
      if (b2_val1 == LOW) {               
        Serial.println("button 2 hit!");

       hit_ack++;
        digitalWrite(ledPin, HIGH);
      }
    b2State = b2_val1;             
  }
  } 

  if (b3_val1 == b3_val2) {                 
    if (b3_val1 != b3State) {         
      if (b3_val1 == LOW) {               
        Serial.println("button 3 hit!");
       
        hit_ack++;
        digitalWrite(ledPin, HIGH);
      }
    b3State = b3_val1;             
  }
  }

  if (b4_val1 == b4_val2) {                 
    if (b4_val1 != b4State) {         
      if (b4_val1 == LOW) {             

       hit_ack++;
        Serial.println("button 4 hit!");
      }
    b4State = b4_val1;             
  }
  }
 
  if(hit_ack ==0){
  digitalWrite(ledPin, LOW);
  }

  if(hit_ack == 1){
    digitalWrite(ledPin, HIGH);
  }
 
  if(hit_ack >= 2){
        digitalWrite(ledPin, HIGH);
        delay(200);
        digitalWrite(ledPin, LOW);
        delay(500);
       
  }
     
 
}

rizla420
 
Posts: 332
Joined: Thu Feb 05, 2009 9:03 pm

Re: Does a blinking loop cause delay in registering butotn press

by The_Don125 on Wed Feb 11, 2009 9:51 pm

Code: Select all | TOGGLE FULL SIZE
  if(hit_ack == 1){
    digitalWrite(ledPin, HIGH);
  }
 
  if(hit_ack >= 2){
        digitalWrite(ledPin, HIGH);
        delay(200);
        digitalWrite(ledPin, LOW);
        delay(500);
       
  }

That looks like the code section that is doing it.

What is happening is with the LED solidly lit, the device is looping as fast as it can, checking the button every time. Now, when the LED is flashing, there is a 700ms delay in between button reads (since the button is read once per execution of the loop), because you have it flash the LED all in one function. I'm not very good at programming for the Arduino just yet, so you'll have to wait for someone else here to post up a fix.
The_Don125
 
Posts: 373
Joined: Tue Mar 06, 2007 11:51 pm
Location: Illinois

Re: Does a blinking loop cause delay in registering butotn press

by niksun on Wed Feb 11, 2009 9:54 pm

For this kind of thing, I'd personally use interrupts (no loops) or think of programming it as a finite state machine. But it looks like The_Don125 has a point. If you press a button anytime during the following block of code, it won't be registered:

Code: Select all | TOGGLE FULL SIZE
if(hit_ack >= 2){
        digitalWrite(ledPin, HIGH);
        delay(200);
        digitalWrite(ledPin, LOW);
        delay(500);
}
Niksun

If you thought before that science was certain--well, that is just an error on your part. -- Richard Feynman
niksun
 
Posts: 202
Joined: Sun Jul 27, 2008 9:59 pm

Re: Does a blinking loop cause delay in registering butotn press

by rizla420 on Wed Feb 11, 2009 10:34 pm

niksun wrote:For this kind of thing, I'd personally use interrupts (no loops) or think of programming it as a finite state machine. But it looks like The_Don125 has a point. If you press a button anytime during the following block of code, it won't be registered:

Code: Select all | TOGGLE FULL SIZE
if(hit_ack >= 2){
        digitalWrite(ledPin, HIGH);
        delay(200);
        digitalWrite(ledPin, LOW);
        delay(500);
}



Hmm.. im not sure I understand your response in relation to his. He said it was the loop that checks to see if the hit_ack==1 and turns the LED on that is causing the button to not register, not the flashing LED code that you refrenced.. Do you have some sample code on how to use interruts in this case?

rizla420
 
Posts: 332
Joined: Thu Feb 05, 2009 9:03 pm

Re: Does a blinking loop cause delay in registering butotn press

by westfw on Wed Feb 11, 2009 10:35 pm

There's some standard methods of implementing blinking LEDs and such without using delay() (delay() delays EVERYTHING.)
See the examples/digital/BlinkWithoutDelay sketch for an example.
Basically, you do things like:
Code: Select all | TOGGLE FULL SIZE
unsigned long nextLedToggle;
byte ledstate = 0;
void loop(void)
{
    :
  if (millis() >= nextLedToggle) {
    nextLedToggle = millis() + LEDBLINKTIME;
    ledstate = ! ledstate;
    digitalWrite(LEDpin, ledstate);
  }
    :
}
westfw
 
Posts: 1568
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: Does a blinking loop cause delay in registering butotn press

by rizla420 on Wed Feb 11, 2009 10:40 pm

westfw wrote:There's some standard methods of implementing blinking LEDs and such without using delay() (delay() delays EVERYTHING.)
See the examples/digital/BlinkWithoutDelay sketch for an example.
Basically, you do things like:
Code: Select all | TOGGLE FULL SIZE
unsigned long nextLedToggle;
byte ledstate = 0;
void loop(void)
{
    :
  if (millis() >= nextLedToggle) {
    nextLedToggle = millis() + LEDBLINKTIME;
    ledstate = ! ledstate;
    digitalWrite(LEDpin, ledstate);
  }
    :
}



Is LEDBLINKTIME a variable i define with whatever value I want it to blink at in miliseconds?

rizla420
 
Posts: 332
Joined: Thu Feb 05, 2009 9:03 pm

Re: Does a blinking loop cause delay in registering butotn press

by magician13134 on Wed Feb 11, 2009 10:42 pm

Yes.
Here's some complete code (notice, it's called 'interval' in this copy)
Code: Select all | TOGGLE FULL SIZE
/* Blink without Delay
 *
 * Turns on and off a light emitting diode(LED) connected to a digital 
 * pin, without using the delay() function.  This means that other code
 * can run at the same time without being interrupted by the LED code.
 *
 * http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
 */

int ledPin = 13;                // LED connected to digital pin 13
int value = LOW;                // previous value of the LED
long previousMillis = 0;        // will store last time LED was updated
long interval = 1000;           // interval at which to blink (milliseconds)

void setup()
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, is the difference
  // between the current time and last time we blinked the LED bigger than
  // the interval at which we want to blink the LED.
  if (millis() - previousMillis > interval) {
    previousMillis = millis();   // remember the last time we blinked the LED

    // if the LED is off turn it on and vice-versa.
    if (value == LOW)
      value = HIGH;
    else
      value = LOW;

    digitalWrite(ledPin, value);
  }
}
magician13134
 
Posts: 1119
Joined: Wed Jun 13, 2007 9:17 am
Location: Ann Arbor

Re: Does a blinking loop cause delay in registering butotn press

by rizla420 on Wed Feb 11, 2009 11:08 pm

Alright, so i added that code into my sketch and it works, but how do you do specific interval blinks. Like... blink, break, blink, long break, blink, break, blink

rizla420
 
Posts: 332
Joined: Thu Feb 05, 2009 9:03 pm

Re: Does a blinking loop cause delay in registering butotn press

by magician13134 on Thu Feb 12, 2009 8:25 am

Well, you could add something like this:
Code: Select all | TOGGLE FULL SIZE
if(whatever condition goes here){
     interval=2000;
}
And just change interval whenever you need to change the delay. Unless it's a predefined blink pattern, then you could create an array called interval. It all just depends how you want it to work.
magician13134
 
Posts: 1119
Joined: Wed Jun 13, 2007 9:17 am
Location: Ann Arbor

Re: Does a blinking loop cause delay in registering butotn press

by phil.drummond on Fri Feb 27, 2009 9:57 pm

I want to learn to use interrupts, but this is what I have so far...
I have been working on a similar project, checking for a button press while blinking the LED on pin-13.
I used the "While" function like this.

Code: Select all | TOGGLE FULL SIZE
/*
* Count to 60 with blinks and output Number of button presses when done.
* I am trying to blink the Pin-13 LED 60 times and record random numbers
* of button presses. Then output the count of button presses to the
* Serial Monitor when completed.
* Serial Monitor needs to be enabled to see output.
* The Prototype board needs to be installed with a button attached to pin 2.
* So far, the thing is working, but it's so fast that you get several hundred "counts"
* of the button press each time you touch the button.  This is useful to the end-game
* project, but is kinda useless counting human finger events.
* This Sketch is preliminary to my Geiger Counter Sketch.
* (c) Phil Drummond - 02/21/2009
*/

int ledPin = 13;                // LED connected to digital pin 13
int switchPin = 2;              // Switch connected to digital pin 2
int b;                          // A variable to record the Button status.
int x = 0;                      // A counter for the number of button presses
int l = 0;                      // A counter for time delay loops.
int s = 0;                      // A counter to track the completed minute in seconds.

void setup()                    // run once, when the sketch starts
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  Serial.begin(9600);           // set up Serial library at 9600 bps
  pinMode(switchPin, INPUT);    // sets the digital pin as input to read switch
}

void loop()                     // run over and over again
{
  while(s < 60){                            // Sets-up the main loop to count the minute out in seconds.
    digitalWrite(ledPin, HIGH);             // sets the LED on at the start of a one second period.
    do{                                     // This "Do/While" makes a 500 millisecond loop, LED on.
      if(digitalRead(switchPin) == 0){      // Get Button input and Test for "false".
        x = x + 1;                          // If the pin is "true" (+5V) then increment the
        }                                      // Presses count and continue looping.  If "False" continue
                                               // without adding anything to the press count.
      delay(1);                            // Delay for one millisecond.
      l = l + 1;                           // Increment the Loop timer.
      }
    while(l < 500);                        // Makes a 1/2 second loop.
    l = 0;                                 // Clear the Loop Timer.
    digitalWrite(ledPin, LOW);             // sets the LED off...
    do{                                    // This "Do/While" makes a 500 millisecond loop, LED off.
      if(digitalRead(switchPin) == 0){     // Get Button input and Test for "false".
        x = x + 1;                         // If the pin it "true" (1) then increment the
        }                                     // Presses count and continue looping.
      delay(1);                            // Delay for one millisecond.
      l = l + 1;                           // Increment the Loop timer.
      }
    while(l < 500);                        // Makes a 1/2 second loop.
    l = 0;                                 // Clear the Loop Timer at the end of the one second loop.
  s = s + 1;                               // Increment the Second counter by one second.
  Serial.print("Seconds Elasped; ");       // Prints a running Second count.
  Serial.print(s);                         // I am trying to get the count to "overlap" but that's not working yet.
  Serial.print(0x13, BYTE);                // This is the part that's failing. The carriage return character is not
                                              // being "honored" by the Serial Monitor.
  }
  Serial.println("");                      // Prints a CRLF to put next output on a new line.
  Serial.print("Button was pressed ");     // output number of button presses that occurred...
  Serial.print(x);
  Serial.println(" times in 60 Seconds.");
  delay(5000);                             // Waits for 5 seconds so you can read the results.
  s = 0;                                   // Clears the Second Count to zero.
  x = 0;                                   // Clears the button press count.
  }                                        // loop
 
phil.drummond
 
Posts: 126
Joined: Sun Feb 08, 2009 4:57 pm

Please be positive and constructive with your questions and comments.