3 Button Presses to move a servo 180

Just started my Arduino journey so this is going to probably be laughable but I’m currently trying to get a simple setup where I press a button 3 time to have a servo turn 180 in one direction and then press the button 3 times again to move it the other direction by 180. I’ve been at this code for a good 3 hours and I know I’m screwing up something silly but my new guy brain can’t seem to find the big issue.

Preferably, if you could just point me to where the problematic areas are and a small nudge in the right direction would be greatly appreciated.

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

const int buttonPin = 2; //Button is connected to pin 2.
const int ledPin =  13;      // the number of the LED pin
const int servoPin = 8; //port for servo data pin

//variabels

int pos = 0;    // variable to store the servo position
int pressed = 0;

//variables for debouncing

int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  // initialize led as output
  pinMode(ledPin, OUTPUT);
  // initializing servo pin
  myservo.attach(servoPin);
}

void loop() {
  //debouncing button press
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:
    if (reading != buttonState){
      if (pos == 180){
        pressed = pressed--;
      } else{ 
        if( pos == 0){
          pressed = pressed++;
         }
      }
    } 
  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
}
    if (pressed == 3){
      pos = 180;
    } 
    if (pressed == 0){
      pos = 0;
    }
}

Divide and concur.

Start with the button and serial monitor. Make the serial monitor tell you "rotate 180 cw" and "rotate 180 ccw". Then, when that is going as planned, you have the button code figured out. At this point, start playing about with the servo.

-jim lee

What’s not working?

How is the switch wired ?

FYI

Thanks for your replies,

Here is an image of how I currently have it set up.

I thought I was going in the right direction as I had made this code before thing attempt but that’s what I learnt about debouncing and I did not redo the previous code with debouncing. I guess I should just step back a step and do what you advise me to do jimLee.

Previous code:

/* Sweep
 by BARRAGAN <http://barraganstudio.com>
 This example code is in the public domain.

 modified 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

const int buttonPin = 2; //Button is connected to pin 2.

//variabels

int pos = 0;    // variable to store the servo position
int pushButton = 2;
int buttonState = 0;  

const int ledPin =  13;      // the number of the LED pin

void setup() {
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  myservo.attach(8);
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    pos = 180;
    myservo.write(pos); 
    digitalWrite(ledPin, HIGH);
  } else {
    pos = 0;
    myservo.write(pos); 
    digitalWrite(ledPin, LOW);
  }
}

Image of current setup:

Compiles but not checked:

//Version 1.01

#include <Servo.h>

Servo myservo;

const byte buttonPin    = 2;

const byte heartbeatLED = 12;
const byte ledPin       = 13;

byte buttonState;
byte lastSwitchState;

//Timing stuff
unsigned long heartbeatMillis;
unsigned long switchMillis;

//*************************************************************************************
void setup()
{
  pinMode(buttonPin, INPUT_PULLUP);

  pinMode(ledPin, OUTPUT);
  pinMode(heartbeatLED, OUTPUT);

  myservo.attach(8);

} //END of setup()

//*************************************************************************************
void loop()
{
  //************************************
  //toggle the heartbeat LED every 1/2 second
  if (millis() - heartbeatMillis >= 500)
  {
    //restart timer
    heartbeatMillis = millis();

    //toggle the heartbeat LED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  //************************************
  //check the switches every 50ms
  if (millis() - switchMillis >= 50)
  {
    //restart timer
    switchMillis = millis();

    checkSwitches();
  }

  //************************************

} //END of loop()

//*************************************************************************************
void checkSwitches()
{
  buttonState = digitalRead(buttonPin);

  //has the switch changed state ?
  if (lastSwitchState != buttonState)
  {
    //update to the new state
    lastSwitchState = buttonState;
    
    //is the switch pressed ?
    if (buttonState == HIGH)
    {
      myservo.write(180);

      digitalWrite(ledPin, HIGH);
    }

    else
    {
      myservo.write(0);
      
      digitalWrite(ledPin, LOW);
    }
  }
  
} //END of checkSwitches()

//*************************************************************************************

If the above sketch works, try adding your counter handling code to it.

This sketch should do what you wanted in your opening post:

//Version 2.00

#include <Servo.h>

Servo myservo;

const byte buttonPin    = 2;

const byte heartbeatLED = 12;
const byte ledPin       = 13;

byte buttonState;
byte lastSwitchState;
byte counter;

int direction = 1;

//Timing stuff
unsigned long heartbeatMillis;
unsigned long switchMillis;

//*************************************************************************************
void setup()
{
  pinMode(buttonPin, INPUT_PULLUP);
  lastSwitchState = digitalRead(buttonPin);

  pinMode(ledPin, OUTPUT);
  pinMode(heartbeatLED, OUTPUT);

  myservo.attach(8);

} //END of setup()

//*************************************************************************************
void loop()
{
  //************************************
  //toggle the heartbeat LED every 1/2 second
  if (millis() - heartbeatMillis >= 500)
  {
    //restart timer
    heartbeatMillis = millis();

    //toggle the heartbeat LED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  //************************************
  //check the switches every 50ms
  if (millis() - switchMillis >= 50)
  {
    //restart timer
    switchMillis = millis();

    checkSwitches();
  }

  //************************************

} //END of loop()

//*************************************************************************************
void checkSwitches()
{
  buttonState = digitalRead(buttonPin);

  //has the switch changed state ?
  if (lastSwitchState != buttonState)
  {
    //update to the new state
    lastSwitchState = buttonState;

    //is the switch pressed ?
    if (buttonState == HIGH)
    {
      counter = counter + direction;

      //****************
      if (counter == 3)
      {
        direction = -direction;

        myservo.write(180);

        digitalWrite(ledPin, HIGH);
      }

      //****************
      else if (counter == 0)
      {
        direction = -direction;

        myservo.write(0);

        digitalWrite(ledPin, LOW);
      }
    }
  }

} //END of checkSwitches()

//*************************************************************************************

You code can be as simple as below:

#include <Servo.h>
#include <ezButton.h>

const int BUTTON_PIN = 7; // Arduino pin connected to button's pin
const int SERVO_PIN  = 9; // Arduino pin connected to servo motor's pin

ezButton button(BUTTON_PIN); // create ezButton object that attach to pin 7;
Servo servo;                 // create servo object to control a servo

int angle = 0; // the current angle of servo motor

void setup() {
  Serial.begin(9600);         // initialize serial
  button.setDebounceTime(50); // set debounce time to 50 milliseconds
  servo.attach(SERVO_PIN);    // attaches the servo on pin 9 to the servo object

  servo.write(angle);
}

void loop() {
  button.loop(); // MUST call the loop() function first

  if((button.getCount() % 3) == 0) {
    // change angle of servo motor
    if(angle == 0)
      angle = 180;
    else
    if(angle == 180)
      angle = 0;

    // control servo motor arccoding to the angle
    servo.write(angle);
  }
}

That code used this button library

Wiring diagram is available in the button control servo motor tutorial

The above code already included: internal pull-up resistor and debouncing