# define BUTTTON  12

void setup() {
  Serial.begin(115200);
  Serial.println("Hello World!");

  pinMode(BUTTTON, INPUT_PULLUP);
}

void loop()
{
  if (!turnMachineStep(1) and !digitalRead(BUTTTON)) {
  	turnMachineStep(0);
  }
}

// command 0 - reset, 1 - normal step

# define K200 100   // frame dwell or tween time
# define FRAMES  7

unsigned char turnMachineStep(unsigned char command)
{
  static byte frame = 0;
  static unsigned long lastTime = 0;
  static unsigned long tween = 0;

  static unsigned char busy = 0;        // not busy!
  static unsigned long lastFrame;

  unsigned char returnValue = 0; // not done - will change if not

  if (command == 0) {
    frame = 0;
    lastTime = millis();
    tween = 0;		               // next call gets immediate enough attention.
    busy = 1;

    return 1;
  }

  if (!busy) 
    return 0;

  if (millis() - lastTime < tween)
    return (2);

  lastTime = millis();
  returnValue = 1;  // until we done. Last frame on display. 0 done/not busy

  switch (frame) {
  case 0 ... (FRAMES - 1) : /* case 0 - 21 elided here */

    Serial.print(" <frame "); Serial.print(frame); Serial.print(" ");
    Serial.print(" "); Serial.print(millis() - lastFrame); Serial.print("> "); Serial.println(millis());

    lastFrame = millis();   // last time a frame was actually rendered
    tween = K200;
    frame++;
    break;

  case FRAMES : // not a real frame, only briefly on way to idle or repeat

    Serial.print(" < "); Serial.print(FRAMES); Serial.print(" > "); Serial.println(millis());

    tween = 0;  // immediate attention.
    frame = 0;

    returnValue = 0;		// we done
    busy = 0;				    // we not
    break;
  }

  return returnValue;
}