Overview
The servo starts at 0°. Each press of the button moves it 45° further: 0°, 45°, 90°, 135°, 180°, and then back to 0°. One press always means one step, however long you hold the button.
You will need
- Arduino Uno R3 and USB cable
- Momentary pushbutton (normally open)
- Hobby servo such as an SG90
- Jumper wires
Wiring
| Uno pin | Connects to | Notes |
|---|---|---|
| 13 | Pushbutton, one side | Internal pull-up keeps the pin HIGH. Pressed reads LOW (active-low). |
| GND | Pushbutton, other side | On the Uno R3 the GND socket sits right next to pin 13. |
| 10 | Servo signal wire (orange or yellow) | Servo library pulse output. |
| 5V | Servo V+ (red) | Only for one small, lightly loaded micro servo. Otherwise use a separate supply; see the power note. |
| GND | Servo GND (brown or black) | Must be shared with any external servo supply. |
How the pins are arranged
The pushbutton goes between pin 13 and the GND socket beside it. INPUT_PULLUP turns on the
ATmega328P's internal pull-up resistor (roughly 20–50 kΩ), so pin 13 reads HIGH while the button is
released and LOW while it is pressed. The logic is active-low: the code checks for
LOW to mean "pressed".
Pin 13 also drives the on-board "L" LED. On the Uno R3 and later that LED is driven through a buffer, so
it does not disturb the input, but the LED may glow faintly while the pull-up is active. Very old boards
with the LED wired straight to pin 13 could not use it reliably as a pulled-up input; if you have one, move
the button to pin 2 and change the 13s in the sketch.
A single micro servo such as an SG90, moving freely with nothing attached to its horn, can usually run from the Uno's 5V pin while the board is on USB. Any bigger servo, more than one servo, or a servo pushing against a load can pull several hundred milliamps in bursts. That causes the board to reset, the USB connection to drop, or the servo to jitter. In those cases power the servo from a separate regulated 5–6 V supply and connect that supply's ground to the Uno's GND. See Powering servos safely.
Diagrams
The sketch
#include <Servo.h>
Servo servoMotor;
int angleDegrees = 0;
void setup() {
servoMotor.attach(10);
pinMode(13, INPUT_PULLUP);
servoMotor.write(0);
}
void loop() {
if (digitalRead(13) == LOW) {
delay(50);
if (digitalRead(13) == LOW) {
angleDegrees = angleDegrees + 45;
if (angleDegrees > 180) {
angleDegrees = 0;
}
servoMotor.write(angleDegrees);
while (digitalRead(13) == LOW) {
delay(10);
}
delay(50);
}
}
}How the code works
The button is debounced by reading it twice, 50 ms apart. If it is still LOW the
press is real. The while loop then waits for release, and a final 50 ms delay skips the
bounce on release. That is why holding the button gives only one step.
Because the wait is a blocking loop, the sketch does nothing else while the button is held. That is fine here; for sketches that must keep working, see non-blocking debouncing.
Review result: no changes were needed. The wrap check (> 180) correctly
allows 180° and resets on the following press.
What you should observe
- On power-up the servo moves to 0°.
- Each press moves it one 45° step; after 180° the next press sends it back to 0°.
- Holding the button down does not repeat the step.