Chess clock servo sweep

I am in need of help with my first arduino project. I am making a chess clock with 180 servos as time indicators instead of an lcd screen. I have mashed the servo and button example programs together but I am not sure how to proceed.

I want two buttons and two servos. When one button is pressed the opponents servo starts incrementing. When the other button is pressed the servo freezes and the other servo starts incrementing.

Here is the feeble code I have so far:

// constants won't change. They're used here to set pin numbers:
#include <Servo.h>
Servo myservo;
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin


// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status
int pos = 0;
void setup() {
  myservo.attach(9);
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
}

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) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
    for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
 } } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
   myservo.write(90);
  }
}

Thank you for looking =)

Look at the StateChangeDetection sketch in the Digital examples. Then copy that code to make it detect both your button changes. Depending on which button was last pressed, either drive the first servo or the second.

You could also just use 1 button. When it is pressed, drive server1. When it is pressed again, drive servo2. Repeat.

Thank you! I have my flow chart sketched out for my program Given the StateCangeDetection code. What I don't know how to do is read whether the button counter is odd or even. I know that in the example state detection code I can assign different actions based on the total number of button presses but I don't know what syntax to use to inquire if the counter is odd/even.

I figured it out! changing the 4 to a 2 solved the issue =)

I am making a chess clock with 180 servos

Now that would be ambitious for a first project :slight_smile:

So I have time control figured out with the delay after each degree movement for the servo. I was able to control one servo set to 0 degrees on odd button pushes and increment 1 degree per second on even button pushes.

After tinkering some more I came up with this code but it does not respond like my single servo code did. I’m sure this looks bad but its my first try:

// this constant won't change:
#include <Servo.h>
Servo myservo;
Servo myservo2;
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int ledPin = 13;       // the pin that the LED 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
int pos = 0;
int pos2 = 0;

void setup() {
  myservo.attach(9);
  myservo2.attach(10);
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
}


void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;


  // turns on the LED every four button pushes by checking the modulo of the
  // button push counter. the modulo function gives you the remainder of the
  // division of two numbers:
  if (buttonPushCounter % 2 == 0) {
    digitalWrite(ledPin, HIGH);
   for (pos = 0; pos <= 180; 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(1000); 
}  } else {
    digitalWrite(ledPin, LOW);
    for (pos2 = 0; pos2 <= 180; pos2 += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo2.write(pos2);              // tell servo to go to position in variable 'pos'
    delay(1000); 
  }

}}

What obvious thing am I doing wrong?

The button does not seem to be activating anything now. In serial monitor the button presses are not registered. myservo2 keeps incrementing by one degree and myservo stays still

It’s looking good. Rather than delay(1000), you need to look at the example “BlinkWithoutDelay” so it will show you how to track how long it has been since your last servo move and still be able to check to see if a button has been pressed. The way your code is now, you move the servo the entire range before you get back to checking for a button press.

Since you don’t want to do the entire for() loop to move the servo, you will need to have a variable for each servo to keep track of the current position.

Also, your pushbutton is set up as an INPUT and you say it is HIGH when it is pushed. This implies there is a pull-down resistor on your circuit. Is that true? The more typical way is to use the build-in pull-up resistors of the Arduino which inverts the logic (LOW = pressed, HIGH = not pressed).

Thanks! I do have a pull down resistor and the button works with the normal state change detection code. Holding the button down for one sweep and letting it go for the next sweep alternates the servos just like it should so the delay is definitely the problem.

Do I need variables other than pos and pos2 which are used in the sweep function?

Thank you! I'm off to learn the blink without delay.

I'm off to learn the blink without delay

Take a look at Using millis() for timing. A beginners guide and Several things at the same time too