Stepper Dial
A stepper motor follows a knob: turn it and the shaft moves to the matching angle, one precise step at a time.
- Intermediate
- Motors
- 3 parts
Opens in your browser with the parts, wiring and code already in place. Press Run to watch it work, then change anything you like.
How it works
A stepper motor turns in small exact steps instead of spinning freely. The 28BYJ-48 shown here takes 2048 steps for one full turn, so each step is about 0.18 degrees. Its four coil wires go to pins 8 to 11, through a driver board on real hardware because the coils need more current than the pins can give. The Arduino energises the coils in a repeating order and the shaft follows.
The Stepper library does the coil sequencing. Stepper dial(stepsPerRevolution, 8, 10, 9, 11) lists the pins in the order the coils must fire for this motor (IN1, IN3, IN2, IN4), and setSpeed(12) asks for 12 revolutions per minute. loop() reads the knob, maps it to a target position between 0 and 2048, and compares it with currentStep, where the shaft is now. If they differ by more than 8 steps, dial.step(difference) moves the shaft by exactly that many steps, forwards for a positive number and backwards for a negative one. The small dead zone stops the motor twitching with every wobble of the knob. step() does not return until the move is finished, so loop() is busy during a move.
Parts
- Arduino Uno
- Potentiometer
- Stepper Motor
Wiring
- Arduino Uno 5V → Potentiometer VCC
- Potentiometer Wiper → Arduino Uno A0
- Arduino Uno GND → Potentiometer GND
- Arduino Uno D8 → Stepper Motor IN1
- Arduino Uno D9 → Stepper Motor IN2
- Arduino Uno D10 → Stepper Motor IN3
- Arduino Uno D11 → Stepper Motor IN4
Arduino code
// Stepper Dial
// A 28BYJ-48 stepper turns 2048 steps for one full circle. The knob is read
// as a target position; the stepper moves by the difference. Note that
// step() waits until the move is finished before loop() carries on.
#include <Stepper.h>
const int stepsPerRevolution = 2048;
// The coil order for this motor is IN1, IN3, IN2, IN4
Stepper dial(stepsPerRevolution, 8, 10, 9, 11);
int currentStep = 0;
void setup() {
dial.setSpeed(12); // revolutions per minute
Serial.begin(9600);
}
void loop() {
int knob = analogRead(A0);
int target = map(knob, 0, 1023, 0, stepsPerRevolution);
int difference = target - currentStep;
// Ignore tiny knob wobble so the motor isn't constantly twitching
if (abs(difference) > 8) {
dial.step(difference);
currentStep = target;
Serial.print("Moved to step ");
Serial.println(currentStep);
}
}
Try changing it
- Turn faster by changing setSpeed(12) to setSpeed(15). Real 28BYJ-48 motors get unreliable much above that.
- Make the dead zone tighter by changing 8 to 2 in abs(difference) > 8. The motor may twitch more.