#include <Servo.h>
// Pin assignments
const int servoPin = 9;
const int ledPin = 13;
const int btn1Pin = 22; // Increment servo angle (+30)
const int btn2Pin = 23; // Decrement servo angle (-30)
// Servo limits and step increment
const int minAngle = 0;
const int maxAngle = 180;
const int stepSize = 30;
int currentAngle = 90; // starting angle
Servo servo1;
// Debounce time (milliseconds)
const unsigned long debounceDelay = 150;
// Function to smoothly move the servo from startAngle to endAngle
void smoothMove(int startAngle, int endAngle) {
int direction = (endAngle > startAngle) ? 1 : -1;
int diff = abs(endAngle - startAngle);
// Determine how long to delay per degree such that the total time is at least 2 seconds.
// For example, if diff is 30 degrees then delay per degree = 2000 ms / 30 ≈ 67 ms.
int stepDelay = 2000 / (diff > 0 ? diff : 1);
// Move smoothly one degree at a time
for (int pos = startAngle; pos != endAngle; pos += direction) {
servo1.write(pos);
delay(stepDelay);
}
// Final command to ensure it reaches the exact target angle
servo1.write(endAngle);
}
void setup() {
// Initialize serial monitor (optional)
Serial.begin(9600);
// Attach the servo to the designated pin and set initial angle.
servo1.attach(servoPin);
servo1.write(currentAngle);
// Setup LED pin
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW); // LED off
// Setup push button pins with internal pull-up resistors.
pinMode(btn1Pin, INPUT_PULLUP);
pinMode(btn2Pin, INPUT_PULLUP);
}
void loop() {
// Check btn1: increment servo (if not at maximum)
if (digitalRead(btn1Pin) == LOW) { // button pressed (active LOW)
delay(debounceDelay); // debounce delay
if (digitalRead(btn1Pin) == LOW) { // confirm press after debounce
if (currentAngle < maxAngle) {
int newAngle = currentAngle + stepSize;
if (newAngle > maxAngle) {
newAngle = maxAngle;
}
// Turn on LED while moving
digitalWrite(ledPin, HIGH);
Serial.print("Moving servo from ");
Serial.print(currentAngle);
Serial.print(" to ");
Serial.println(newAngle);
smoothMove(currentAngle, newAngle);
// Update current angle and turn off LED
currentAngle = newAngle;
digitalWrite(ledPin, LOW);
}
// Wait until btn1 is released to avoid multiple triggers
while (digitalRead(btn1Pin) == LOW) {
delay(10);
}
}
}
// Check btn2: decrement servo (if not at minimum)
if (digitalRead(btn2Pin) == LOW) { // button pressed (active LOW)
delay(debounceDelay); // debounce delay
if (digitalRead(btn2Pin) == LOW) { // confirm press after debounce
if (currentAngle > minAngle) {
int newAngle = currentAngle - stepSize;
if (newAngle < minAngle) {
newAngle = minAngle;
}
// Turn on LED while moving
digitalWrite(ledPin, HIGH);
Serial.print("Moving servo from ");
Serial.print(currentAngle);
Serial.print(" to ");
Serial.println(newAngle);
smoothMove(currentAngle, newAngle);
// Update current angle and turn off LED
currentAngle = newAngle;
digitalWrite(ledPin, LOW);
}
// Wait until btn2 is released to avoid multiple triggers
while (digitalRead(btn2Pin) == LOW) {
delay(10);
}
}
}
// Short delay to allow other events; prevents bouncing in software loop
delay(10);
}