Controling a servo with a single push button

Hi All,

I started a project with servos being controlled by 2 push buttons moving the servo from 180-0 degrees when button left is pushed and 0-180 degrees when button right is pushed. see code below.

#include <Servo.h>

Servo servo1;  // create servo object to control a servo
Servo servo2;  // create servo object to control a servo

int angle =180;    // initial angle  for servo
int angleStep =180;

#define LEFT 12   // pin 12 is connected to left button
#define RIGHT  2  // pin 2 is connected to right button

void setup() {
  
  Serial.begin(9600);          //  setup serial
  servo1.attach (9);  // attaches the servo on pin 9 to the servo object
  servo2.attach (10);  // attaches the servo on pin 10 to the servo object
  pinMode(LEFT,INPUT_PULLUP); // assign pin 12 ass input for Left button
  pinMode(RIGHT,INPUT_PULLUP);// assing pin 2 as input for right button
  servo1.write(angle);// send servo to the middle at 180 degrees
  servo2.write(angle);// send servo to the middle at 180 degrees
 Serial.println("Exhaust Valves ");
}

void loop() {
  
  while(digitalRead(RIGHT) == LOW){

    if (angle > 0 && angle <= 180) {
      angle = angle - angleStep;
       if(angle < 0){
        angle = 0;
       }else{
      servo1.write(angle); // move the servo to desired angle
      servo2.write(angle); // move the servo to desired angle
      Serial.print("Moved to: ");
      Serial.print(angle);   // print the angle
      Serial.println(" degree");
       }
    }
    
  delay(100); // waits for the servo to get there
  }

  while(digitalRead(LEFT) == LOW){

    
    if (angle >= 0 && angle <= 180) {
      angle = angle + angleStep;
      if(angle >180){
        angle =180;
       }else{
      servo1.write(angle); // move the servo to desired angle
      servo2.write(angle); // move the servo to desired angle
      Serial.print("Moved to: ");
      Serial.print(angle);   // print the angle
      Serial.println(" degree");
       }
    }
    
  delay(100); // waits for the servo to get there
  }// 

  
}

Now I am trying to replicate the project but using just 1 push button. I have found some code and modified it to kind of suite what I need, but it’s not quite there. I can get it to work with a latching push button but what I want to do is use a momentary button and have the code do the latching. is it even possible to use code as a latch? Please see the code below that works with a latching push button.

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int angle = 180;   // initial angle  for servo
int angleStep = 180;

#define button 9   // pin 9 is connected to button


void setup() {

  myservo.attach(8);  // attaches the servo on pin 9 to the servo object
  pinMode(9, INPUT); // assign pin 9 as input for button
  pinMode (8, OUTPUT);
  myservo.write(angle);// send servo to the desired angle
  int buttonState = 0;
  int directionState = 0;
}

void loop(){

  while (digitalRead(button) == HIGH) {


    if (angle > 0 && angle <= 180) {
      angle = angle - angleStep;
      if (angle < 0) {
        angle = 0;
      } else {
        myservo.write(angle); // move the servo to desired angle
        Serial.print("Moved to: ");
        Serial.print(angle);   // print the angle
        Serial.println(" degree");
      }
    }

    delay(100); // waits for the servo to get there

    while (digitalRead(button) == LOW) {

      if (angle >= 0 && angle <= 180) {
        angle = angle + angleStep;
        if (angle > 180) {
          angle = 180;
        } else {
          myservo.write(angle); // move the servo to desired angle
          Serial.print("Moved to: ");
          Serial.print(angle);   // print the angle
          Serial.println(" degree");
        }
      }

      delay(100); // waits for the servo to get there
    }

}
}

Kind regards,
Mike.

So you want your momentary button input to toggle the stepper motor.

Code wise, you would set a variable upon detecting the button press, then have your stepper motor code run only if said variable was set.

In your case you would replace the while loops with if.

Next step would be to decide if a second button press while the stepper code was running would alter the stepper control or trigger even something else completely and handle bounce.

What I want to do is just use 1 momentary push button and when the button is pushed have the code move and keep the servo at 0 degrees and when pressed again move the servo to 180 degrees and keep it there, and keep doing the same every time the button is pushed.

Mike.

Use a finite state machine.

Button press toggles between states: move left or move right. Do your movement based on that state.

You'll have to implement debouncing on the button or you will see multiple presses, and react to state change of the button.

Ok! I got the code to almost do what I want it to do. The problem I am having now is the button control. I have to keep pressing or hold the button to get the servo to move. is this to do with debouncing i keep hearing about?

Mike.

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int angle = 180;   // initial angle  for servo
int angleStep = 180;


const int  button = 9;    // the pin that the pushbutton is attached to
const int  Servo = 8;       // the pin that the servo is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  Serial.begin(9600);
  myservo.attach(8);  // attaches the servo on pin 8 to the servo object
  pinMode(9, INPUT); // assign pin 9 as input for button
  pinMode (8, OUTPUT); //assign pin 8 as output for servo
  myservo.write(angle);// send servo to the desired angle

}

void loop() {

  
  buttonState = digitalRead(button); // read the pushbutton input pin:

  
  if (buttonState != lastButtonState)// compare the buttonState to its previous state {
    
    if (buttonState == HIGH) // if the state has changed, increment the counter {
      // if the current state is HIGH then the button went from off to on:

      if (angle > 0 && angle <= 180) {
        angle = angle - angleStep;
        if (angle < 0) {
          angle = 0;
        } else {
          myservo.write(angle); // move the servo to desired angle
          Serial.print("Moved to: ");
          Serial.print(angle);   // print the angle
          Serial.println(" degree");
        }
      }

      delay(1000); // waits for the servo to get there

      
      buttonState = digitalRead(button); // read the pushbutton input pin:

      
      if (buttonState != lastButtonState) // compare the buttonState to its previous state {
        
        if (buttonState == HIGH) // if the state has changed, increment the counter {
          // if the current state is HIGH then the button went from off to on:


          if (angle >= 0 && angle <= 180) {
            angle = angle + angleStep;
            if (angle > 180) {
              angle = 180;
            } else {
              myservo.write(angle); // move the servo to desired angle
              Serial.print("Moved to: ");
              Serial.print(angle);   // print the angle
              Serial.println(" degree");
            }
          }

          delay(1000); // waits for the servo to get there
        }

Not a debounce issue.

More an issue of stopping the servo movement based on the button being released rather than the servo reaching its target.

Problem, Sorted.

Mike.

s200bym:
Problem, Sorted.

Can you describe the solution so other people can benefit from your learning.

...R