Same button Forward/increase speed/ stop

Hi guys having some trouble getting this to work.

Ive got one button namely my forward button that I want:

1- if pressed and released set the motors to a set speed.
2- if pressed and held for 1 second or so increase the the set speed by say 10 until the button is released.
3- But I also need it to stop the motors so if its been pressed once and released and its pressed again stop.

My code does the go and stop with the button but I cant get it to increase speed when its held in?

while (WhileLoop == 1){
    if (Stop == 0){
      int scanIncrement = 500;
      panLoop.m_pos = scanIncrement;
      md.setM1Brake(300);
      md.setM2Brake(300);
      pixy.setServos(panLoop.m_pos, tiltLoop.m_pos);
      //Serial.print("Speed:");
      ///Serial.println(Speed);
      Stop = 1;
    }

    buttonStateLeft = digitalRead(ButtonLeft);
    buttonStateRight = digitalRead(ButtonRight);
    buttonStateForward = digitalRead(ButtonForward);
    buttonStateStop = digitalRead(ButtonStop);

    if (buttonStateForward != lastButtonStateForward){
      if (buttonStateForward == HIGH) {
        buttonPushCounterForward ++ ;
      }
      delay(5);
    }

    if (buttonStateStop != lastButtonStateStop){
      if (buttonStateStop == HIGH) {
        buttonPushCounterStop ++ ;
      }
      delay(5);
    }
    
    if (buttonStateRight == HIGH){
      md.setM1Brake(250);
      md.setM2Speed(-200);
    }

    if (buttonStateLeft == HIGH){
      md.setM1Speed(-250);
      md.setM1Brake(250);
    }
   
    if (buttonPushCounterForward == 1) {
      md.setM1Speed(-250);
      md.setM2Speed(-250);
    }

    else if (buttonPushCounterForward == 2) {
      md.setM1Brake(250);
      md.setM2Brake(250);
      buttonPushCounterForward = 0;
    }

    else{
      md.setM1Speed(0);
      md.setM2Speed(0); 
    }

    //Serial.print("Whileloop:");
    //Serial.println();
    //delay(50);
    lastButtonStateForward = buttonStateForward;
    lastButtonStateStop = buttonStateStop;

    if (buttonPushCounterStop == 1){
      WhileLoop = 0;
      buttonPushCounterStop = 0;
      buzz(Buzzer, 2500, 500);
      delay(50);
      buzz(Buzzer, 2500, 500);
      delay(1200);
      break; 
    }  
  }

Thanks for any help.

I see you're used to writing code for PC's or at least learned on them. :slight_smile:

Microcontrollers are a bit different and Arduino 'language' (C++ variant) highlights that with:

void setup()
{
// do things you only need to do once here
}

void loop()
{
// code that happens over time goes here
}

The loop() function runs over and over and may contain sections of code that act independently of each other. If none of the code makes execution wait, all the sections can run together smoothly as simple but effective low-overhead tasking.

So instead of delay() we get sections to run 'on time' by putting them inside of time checks

if ( millis() - startMS >= waitMS )
{
// interval has passed, do the thing the wait is for
}

I do a one-shot version that only runs when waitMS > 0. Some other section sets that.

if ( waitMS > 0 )
{
if ( millis() - startMS >= waitMS )
{
// interval has passed, do the thing the wait is for
waitMS = 0; // will not run again until triggered by setting waitMS > 0
}
}

And what you do is have a section for each input that only handles the input. These communicate to the other sections through variables used as triggers and data, like setting waitMS for the above.

So you have input sections and you make output sections and processing sections and they all act as separate tasks, can be made and tested in smaller sketches. These are modular, you can plug them in so to speak or take them out, replace, whatever and your code will be more easily flexible.

When you write this way, try to keep loop() running more than 1000x a second... that would take quite a load since 1 millisecond takes 16000 CPU cycles which can do a lot.
OTOH, I have an example that runs loop() at over 57KHz, loops in less than 20 microseconds while handling buttons, a blinking led, a 32-bit loop counter and serial output. I stick a delay(1) into that same loop() and it runs a bit less than 1KHz... just to show what even a 'harmless little delay' is capable of.

There are --many-- tutorials to teach this. I show 3 addresses in my sig space below, the first one teaches the basics about making things happen together and the second goes into ways to deal with serial data.
The third is about interrupts but save that for things that have to be super exact on time and not to the millisecond that you should easily get without using interrupts. There are limited interrupts and maybe down the road you'd want to add a library that uses one, if you haven't used it already.