How do perform an action after an amount of time? Is it possible?

Hi all,

** Edit - there's an update to this post at the bottom **

I'm using my Arduino Mega in a CNC machine that I'm building. I'm using buttons to drive the machine manually. I would like to increase the speed of the machine the longer you hold the button.

I've managed to write three functions that set the PWM output slow / med / fast.

Now I want to basically say....

if ( digitalRead(myButton) == HIGH ){
  // Start a timer of some sort?
  if( timeVal > 5 seconds ){
     setSpeedFast();
  } else if( timeVal > 2 seconds ){
     setSpeedMed();
  } else {
     setSpeedSlow();
  }
}

Is something like this possible?

My other thought was to just have something incrementing into a "Long" while a button was pressed and then just compare the Long value to set different speeds? But, in the interests of learning I wondered if there was a more eloquent solution?

I've checked out the reference but that refers to millis(), micros(), delay() etc which I don't think are suitable here?

Thanks for any help you can give me. :slight_smile:

** Update to post **

I've been playing around and I've come up with this solution but it doesn't work for some reason...

void runAxisBasedOnInputs(int directionButtonOne, int directionButtonTwo, int outRelayDirection, int outRelayPulse, int axisDirectionBit){ 

  if( (digitalRead(directionButtonOne) == HIGH) || (digitalRead(directionButtonTwo) == HIGH) ){
    
    incrementSpeedBasedOnDurationButtonPress(myTimingSpeedCount);  
    digitalWrite(outRelayDirection, LOW);  // THESE BITS WORK FINE
    digitalWrite(outRelayPulse, LOW);       // THESE BITS WORK FINE
  } else {

    myTimingSpeedCount = 0;         // IF I COMMENT THIS OUT IT WORKS? BUT ONCE AT FAST SPEED
                                                 // IT NEVER GOES BACK TO SLOW SPEED

    digitalWrite(outRelayDirection, HIGH);  // THESE BITS WORK FINE
    digitalWrite(outRelayPulse, HIGH);       // THESE BITS WORK FINE
  }

}


void incrementSpeedBasedOnDurationButtonPress(){
  
      myTimingSpeedCount++;
      if( myTimingSpeedCount > 50000 ){
        setSpeedToFast();
      } else if( myTimingSpeedCount > 20000 ){
        setSpeedToMed();
      } else {
        setSpeedToSlow();
      } 

}

(BTW - "myTimingSpeedCount" is declared as a "long" at the start of the code).

I've tried passing in "myTimingSpeedCount" as a variable into the function etc but to no avail.

It's like the "else" part of the "if( (digitalRead(directionButtonOne) == HIGH) || (digitalRead(directionButtonTwo) == HIGH) )" is being triggered even if the button is held down? Is this normal behaviour?

If anyone can shed any light on this it would be appreciated :slight_smile:

There is more to it than you seem to think.

You want more than one thing working together, whether you know that or not.

Contact button/switch 'bounces' on press or release.

This lesson is gold for dealing with changing situations.

Hi Smoke,

I've updated my last post with some progress I've made. I think I'm nearly there (*think!!) but need some pointers.

Thanks for your help. I've read that "blink" article before but will look at the others. Cheers

Probably better not to update the opening post, but have a new post. That way we can read from top to bottom. With your update timed after GfS's post, the chronology's all screwed, awkward to follow.

ardy_guy:
Probably better not to update the opening post, but have a new post. That way we can read from top to bottom. With your update timed after GfS's post, the chronology's all screwed, awkward to follow.

Will know for next time :slight_smile:

The demo Several Things at a Time is an extended example of BWoD and illustrates the use of millis() to manage timing. It may help with understanding the technique.

There may also be useful ideas in Planning and Implementing a Program

...R

uptown47:
Hi Smoke,

I've updated my last post with some progress I've made. I think I'm nearly there (*think!!) but need some pointers.

Thanks for your help. I've read that "blink" article before but will look at the others. Cheers

Generally when there's button(s) involved I have code in loop() that does nothing but watch the button(s) and update button status variable(s). Other parts of code use the status to decide what to do instead of reading the button pin(s) which may be bouncing.
When I have the user able to enter serial data it is the same, one part to get the entry, check it for error or relevance and abstract the result that the rest of the code uses as and when ready.

The "rest of the code" has to run in short steps that may be interrupted or steered by the status/data of input events.

It's a lot easier to to write real-time interactive code this way but not so easy to see why until you've got the tee shirt (been there, etc).
Consider the case where you replace the contact button with a different sensor. You only have to replace the button code with other sensor code that updates the status variable and the rest of the code needs zero changes, zero debugging to run as before.

I expect that you're going to have to do some small "homework" sketches on the different aspects I gave you links to before you're ready to turn back to the drawing board for the cnc project. At least get a debounced button or two interacting with one or more blinking leds to change the blink pattern(s) in creative ways to build the proficiency and view for cutting metal.