I am not a programmer. The basic code presented here was written in 2012 by a person known in the stepping motor forums only as cannedmushrooms. It was modified for pushbutton input and various speeds for me in October of 2013 by my own son, a C programmer extraordinaire (who, alas, is not a ham).

So I thank them both for their help without which I might have spent a year or more attempting to learn - possibly unsuccessfully - C programming and its implementation for this application.

Here’s the code exactly as I use it which any and all are welcome to use:

#include <Wire.h>

#include <Adafruit_MotorShield.h>

#include "utility/Adafruit_PWMServoDriver.h"

// Create the motor shield object with the default I2C address

Adafruit_MotorShield AFMS = Adafruit_MotorShield();

// Connect a stepper motor with 200 steps per revolution (1.8 degree)

// to motor port #2 (M3 and M4)

Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

int state, prevstate = 500, count = 500;

int nextEncoderState[4] = { 2, 0, 3, 1 };

int prevEncoderState[4] = { 1, 3, 0, 2 };

// Number of steps per turn of encoder

int forward=1;

int backward=1;

// Fast forward and backward steps

int fastforward=3;

int fastbackward=3;

// Used to calculate direction

int direct=0;

// Encoder inactivity counter

// using an unsigned int here effectively removes negative numbers and doubles the range of the integer

// I read that Aruduino Uno is limited to 16 bits, so the max value here is 65535

unsigned int inactivity_count;

// Setup an arbitray value to compare inactivity counter against

// Make this smaller if the time before motor stop is too long.  If this is never big enough, we might need a nested counter loop

#define ARBITRARY_COUNT 65534

void setup() {


Serial.println("Follows encoder, Fast & Slow mod by SPT");

AFMS.begin(); //default frequency is 1.6kHz

//AFMS.begin(1000); //sets frequency to 1kHz

myMotor->setSpeed(200);  // 100 rpm

//place a Rotary encoder on pins

//A=Pin10, B=Pin2

pinMode(10, INPUT);

pinMode(2, INPUT);

pinMode(6, INPUT);

pinMode(4, INPUT);  //To run motor forward on button push

pinMode(8, INPUT);  //To run motor backward on button push

digitalWrite(2, HIGH);

digitalWrite(10, HIGH);

digitalWrite(6, HIGH);

digitalWrite(4, HIGH);

digitalWrite(8, HIGH);


void loop() {

state = (digitalRead(10) << 1) | digitalRead(2);

if (state != prevstate) {  // encoder is active

   inactivity_count = 0;  // clear the encoder inactivity counter

   if (state == nextEncoderState[prevstate]) {


     direct= count-1;

     if (count > direct){


         myMotor->step(forward, FORWARD, DOUBLE);



         myMotor->step(forward, FORWARD, INTERLEAVE);





   else if (state == prevEncoderState[prevstate]) {


     direct= count+1;

     if (count < direct){


         myMotor->step(backward, BACKWARD, DOUBLE);



         myMotor->step(backward, BACKWARD, INTERLEAVE);





   prevstate = state;


else {  // encoder is inactive

   // If button 4 is depressed, step the motor at fastforward rate


     myMotor->step(fastforward, FORWARD, DOUBLE); 

     inactivity_count = 0;



   else {  // if buttons 4 and 8 are depressed, button 4 wins...

     // If button 8 is depressed, step the motor at fastforward rate


       myMotor->step(fastbackward, BACKWARD, DOUBLE); 

       inactivity_count = 0;



   // if inactivity count is greater than our arbitrary value, turn motor off

   if(inactivity_count > ARBITRARY_COUNT){




    // Avoid letting the counter roll over by only incrementing it when it is not > arbitrary count value