Go Down

Topic: How can I pause a function? (Read 312 times) previous topic - next topic

Delta_G

I'm sorry.  I'm not sure how I missed that. 

Well, here's the next problem.  The pin is high, so it toggles the paused variable.  Then a split millisecond later the loop repeats.  The pin is still high, so it toggles it again and runs the function. 

You need to detect when the button first becomes pressed, not when it is pressed.  See the "State Change Example" for help with that. 
Ad hoc, ad loc, and quid pro quo.  So little time - so much to know!  ~Jeremy Hillary Boob Ph.D

davidrh

No, it checks whether a digital pin is high or low.  You can use that to detect a button press, but as I said you need to do some other stuff as well to make it work reliably.  Did you have a look at the tutorial I linked to?

Until you remove the delay(), the digitalRead isn't being executed often enough to detect the button press.  Your flash speed is 100 milliseconds, while the digitalRead will take a fraction of a millisecond.  Even if you hold the button down, the digitalRead will return HIGH, so you will toggle the paused variable back and forth until you release the button, which is not what you want either.

davidrh

Have a look at the first page of the forum here.  I suggest you read the first two posts.  They are called sticky posts as they are always the first two posts so that people can find them easily.

1204NeRd

Never mind... I had a wire unplugged. :D  ;D  :D  ;D

Delta_G

Never mind... I had a wire unplugged. :D  ;D  :D  ;D
You'll still have the issues mentioned. 
Ad hoc, ad loc, and quid pro quo.  So little time - so much to know!  ~Jeremy Hillary Boob Ph.D

1204NeRd

I took a look at the tutorial and will try to use that. But even though the delay is in there, it still works how I want it to...Strange.

Delta_G

That's not strange at all.  It's a coincidence.  It will catch up to you soon.  It's not at all uncommon for a program to appear to work properly even though it has mistakes in it.  You'll eventually find the case where it doesn't.

With only a 100ms delay it isn't likely you'll miss a button press.  You'd have to be pressing pretty darn fast to press the button and get back off of it in 100ms.  But as soon as you ask this code to do more you'll hit the barrier and you can learn to do timing without the delay.
Ad hoc, ad loc, and quid pro quo.  So little time - so much to know!  ~Jeremy Hillary Boob Ph.D

1204NeRd

I am going to get rid of the delay, But is this how I should implement the blink without delay?

Code: [Select]
int ln = 1;
int pn = 1;
int pln = 1;
int flashSpeed = 100;
boolean paused = false;
int button = 8;
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 250;

void setup() {
  // put your setup code here, to run once:
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
 
}


void loop(){
 
 
  if (digitalRead(button) == HIGH)
  {
    paused = true;
    digitalWrite(ln, HIGH);
    delay(1500);
    digitalWrite(ln, LOW);
    ln = 1;
    paused = false;
  }
  if (!paused)
  {
    tofro();
  }
}



void tofro() {
  // put your main code here, to run repeatedly:
  digitalWrite(ln, HIGH);

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval){
    previousMillis = currentMillis;
    digitalWrite(ln, LOW);
  }
 
 
 
   

  if (ln >= 7 && pln == 6)
  {
    pn = -1;
  }
  else if (ln == 6 && pln == 7)
  {
    pn = -1;
  }
  else if (ln == 5 && pln == 6)
  {
    pn = -1;
  }
  else if (ln == 4 && pln == 5)
  {
    pn = -1;
  }
  else if (ln == 3 && pln == 4)
  {
    pn = -1;
  }
  else if (ln == 2 && pln == 3)
  {
    pn = -1;
  }
  else
  {
    pn = 1;
  }

 
  pln = ln;
  ln += pn;
}


davidrh

Not quite.  As you have your code for moving to the next LED outside of the logic to check if the write amount of time has passed, that code will keep getting executed all of the time.  I think you can move it inside the if statement block, and only write the LED pin HIGH when you have changed it.

When trying to fathom this stuff out in your early days of programming, it also helps to put in some debugging output to the serial monitor, like:

Code: [Select]

  if (currentMillis - previousMillis >= interval){
    Serial.println(F("Times up - switching to next LED"));


You can then see where your code is going in order to help you understand it.

I also think you can simplify your logic significantly by only changing direction when you reach the ends.

Code: [Select]

void tofro() {
  // put your main code here, to run repeatedly:
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval){
    previousMillis = currentMillis;

    digitalWrite(ln, LOW);

    ln += pn;

    if (ln == 7) {
      pn = -1;
    } else if (ln == 1) {
      pn = 1;
    }

    digitalWrite(ln, HIGH);
  }


I don't have an Arduino handy or your hardware to try this, but give it a go.  With just LEDs you can't really break anything through code, so don't be afraid to try things out to see what happens.

1204NeRd

I have a couple problems. The first is that the arduino thinks that I am pressing the button alot, but I am only pressing it once. Also, the LED's are jumping around instead of going back and forth in a line. Here is the code.

Code: [Select]
int ln = 1;
int pn = 1;
int pln = 1;
int flashSpeed = 100;
boolean paused = false;
int button = 8;
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 250;

void setup() {
  // put your setup code here, to run once:
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  Serial.begin(9600);
}


void loop(){
  
  
  if (digitalRead(button) == HIGH)
  {
    Serial.println("Button Pressed");
    paused = true;
    digitalWrite(ln, HIGH);
    delay(1500);
    digitalWrite(ln, LOW);
    ln = 1;
    paused = false;
  }
  if (!paused)
  {
    tofro();
  }
}



void tofro() {
  // put your main code here, to run repeatedly:
  digitalWrite(ln, HIGH);

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval){
    previousMillis = currentMillis;
    digitalWrite(ln, LOW);
    Serial.println("Times up, Switching to next LED");
  
    if (ln >= 7 && pln == 6)
    {
      pn = -1;
    }
    else if (ln == 6 && pln == 7)
    {
      pn = -1;
    }
    else if (ln == 5 && pln == 6)
    {
      pn = -1;
    }
    else if (ln == 4 && pln == 5)
    {
      pn = -1;
    }
    else if (ln == 3 && pln == 4)
    {
      pn = -1;
    }
    else if (ln == 2 && pln == 3)
    {
      pn = -1;
    }
    else
    {
      pn = 1;
    }

    pln = ln;
    ln += pn;
  
  }

}


The Serial Monitor had this in it, even though I only pressed the button once.

Times up, Switching to next LED
Times up, Switching to next LED
Times up, Switching to next LED
Times up, Switching to next LED
Times up, Switching to next LED
Button Pressed
Times up, Switching to next LED
Button Pressed
Times up, Switching to next LED
Button Pressed
Times up, Switching to next LED
Button Pressed
Times up, Switching to next LED
Button Pressed
Times up, Switching to next LED
Times up, Switching to next LED
Times up, Switching to next LED
Times up, Switching to next LED
Times up, Switching to next LED
Times up, Switching to next LED
Button Pressed
Times up, Switching to next LED
Times up, Switching to next LED
Times up, Switching to next LED
Times up, Switching to next LED
Times up, Switching to next LED
Times up, Switching to next LED
Times up, Switching to next LED


davidrh

Quote
That's not strange at all.  It's a coincidence.  It will catch up to you soon
And it has.  You might think that when you press the button and let it go that the Arduino will only see LOW - HIGH - LOW inside your loop() method.  Because the Arduino can do things quite quickly and you have removed the delay (which is good), what it really sees in each iteration through loop() is something like LOW - HIGH - LOW - HIGH - HIGH - LOW.  That LOW in the middle is what is known as a bounce.  I mentioned it in one of my previous posts.  All of the HIGHs are the Arduino going through the loop method while the button is down.

You need to implement all of the recommendations for this to work properly.  What is missing now is the correct button handling logic with debounce as per previous posts.  I strongly recommend you do the tutorial I linked to previously to get a better understanding of just the button bit.

You also have a problem here:

Code: [Select]

void loop(){
  if (digitalRead(button) == HIGH)
  {
    Serial.println("Button Pressed");
    paused = true;
    digitalWrite(ln, HIGH);
    delay(1500);
    digitalWrite(ln, LOW);
    ln = 1;
    paused = false;
  }
  if (!paused)
  {
    tofro();
  }
}


Can you see that because you set paused to true, then do some stuff with the LEDs, then delay then set it to false again, your if statement around the call to tofro() is superfluous.  I don't think this is doing what you want, and you still have that delay in there.  What I think you want to do on a button press is toggle the state of paused:

Code: [Select]

if (buttonPressed()) {
  paused = !paused;  // Toggle state
}
if (!paused) {
  tofro();
}


As to your LEDs jumping around, I posted some simpler code, have you tried that?  It's not in the latest code you posted.

1204NeRd

I did try your recommended code, but it seemed to do the same thing. The code :
Code: [Select]
digitalWrite(ln, HIGH);
    delay(1500);
    digitalWrite(ln, LOW);

is just so that the LED lights up and you can see what you landed on before it starts again. I will put in all the recommendations to my code, but first I have a question. Is the tutorial for removing bounce the one called "Debounce?"

davidrh

Yes - here is the link again Debounce.  This will help give you an understanding of what is happening.  There are loads of other examples and libraries out there if you don't like this one.

As far as the LEDs go, put some Serial.println statements in at the key points and see if you can work it out.  You haven't posted the simplified code, so I can't see what the problem could be.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy