Alternative delay() - servo with pushbutton issues

Hey all,

Im having a problem with using a pushbutton and a servo together specifically with delay().

In my loop function I am listening for when the push button gets pushed down, then I switch a boolean.

If the boolean is true, the servo will move until that boolean is set to false.

The problem I have is that the server function has a lot of delays in it to move the motor smoothly.

With the delays, I cant listen for the pushbutton events properly.

I was wondering how people solve for this case?

Here is my code:

void loop(){
  doBtnHitCheck();

  if (isActive) {   // check if the input is HIGH (button released) 
    digitalWrite(ledPin, HIGH);  // turn LED ON
    rotateServo();
  } 
  else {  
    digitalWrite(ledPin, LOW);  // turn LED OFF
  }

}

void doBtnHitCheck(){
  val = digitalRead(inPin);  // read input value
  if (val == LOW) {         // check if the input is HIGH (button released)
    isActive = !isActive;
    delay(500);
  } 
}

void rotateServo()
{
  int pos = 0;
 // delay(10000);
  for(pos = 0; pos < 25; pos += 1)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
   // delay(10);      // waits 15ms for the servo to reach the position
  }

  //delay(10000);
  for(pos = 25; pos>=4; pos-=1)     // goes from 180 degrees to 4 degrees, Stoping at 4 because 0 will make motor make noise(maybe because it cant get to 0)
  {
    myservo.write(pos);              // tell servo to go to position in variable 'pos'

  //  delay(10);                       // waits 15ms for the servo to reach the position

  }

}

Thanks!

I think you could use an interrupt for this, since this would cancel out the need to check whether or not the button is pushed, rather, it will execute the code as soon as/only if the button is pressed. Also, you should consider adding some debounce logic, since those buttons can sometimes trigger multiple times when pressed just once.

1 Like

Thanks @Moors7 I will research interrupts, I have also looked into PWM pins though I dont really understand fully. It sounds like they have their own timer and I can use it to have its own delay that wont effect my entire program?

ha, I get what your saying about the debounce logic. When first building I experienced that and added that delay(500) as a quick fix(you can see in code after boolean is switched). I know I need to implement more accurate logic later.

Thanks!

Let’s ask @peekay123 for some help, since he knows a fair bit more about the PWM/timer stuff. He should be able to give you a more concrete answer to those questions.

1 Like

@flashyourface and @Moors7, i am not sure what you mean by “server function” adding delay. Your main loop will run at about 200Hz (5ms delay) with the cloud enabled and connected which is plenty fast for sampling your button using the clickButton library.

As for the servo stuff, you can write a state machine that steps through each servo “state” and use the elapsedMillis library for the delays between servo changes. That library is non blocking unlike delay().

I have no idea why you want to use PWM?

Hey thanks @peekay123, I actually typed an error it should be servo not server.

Thank you for the suggestion on using a milisecond timer, I was just reading info on that and it looks like a good place to start. Do you have an example using a state machine for this example.

I was going to make something like a ‘tick()’ function and record values and update appropriately. My goal is to make something like a for loop that is based off the elapsedMills lib.

I only say PWM because im super noob with microcontrollers and in research I kept seeing suggestions to play with PWM and the ISR. I followed some of these examples - http://letsmakerobots.com/content/arduino-101-timers-and-interrupts however, they did not work for my case.

Thanks for info/help, im going to play with elapsedMills now!