CYTHEIA AIOpen the editor

Stepper Dial

A stepper motor follows a knob: turn it and the shaft moves to the matching angle, one precise step at a time.

Open this circuit and run it

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

Wiring

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

Open this circuit and run it

Next challenge

More projects in Motors