Servos as Input Devices

Another neat feature of feedback servos is that they can be used as an input device too! The Servo Record/Play Demo lets you record a series of servo movements, then it will replay them back for you! The recorded positions are saved in EEPROM, so they will be remembered even after resetting or powering down the Arduino

To run this demo, first wire up your Servo as in the Fritzing diagram below:

Components used:
Next, download the example sketch from Github using this button:
// Example code for recording and playing back servo motion with a 
// analog feedback servo
// http://www.adafruit.com/products/1404


#include <Servo.h>
#include <EEPROM.h>

#define CALIB_MAX 512
#define CALIB_MIN 100
#define SAMPLE_DELAY 25 // in ms, 50ms seems good

uint8_t recordButtonPin = 12;
uint8_t playButtonPin = 7;
uint8_t servoPin = 9;
uint8_t feedbackPin = A0;
uint8_t ledPin = 13;

Servo myServo;  
  
void setup() {
  Serial.begin(9600);
  pinMode(recordButtonPin, INPUT);
  digitalWrite(recordButtonPin, HIGH);
  pinMode(playButtonPin, INPUT);
  digitalWrite(playButtonPin, HIGH);
  pinMode(ledPin, OUTPUT);
  
  Serial.println("Servo RecordPlay");
}

void loop() {
 if (! digitalRead(recordButtonPin)) {
   delay(10);
   // wait for released
   while (! digitalRead(recordButtonPin));
   delay(20);
   // OK released!
   recordServo(servoPin, feedbackPin, recordButtonPin);
 }
 
  if (! digitalRead(playButtonPin)) {
   delay(10);
   // wait for released
   while (! digitalRead(playButtonPin));
   delay(20);
   // OK released!
   playServo(servoPin, playButtonPin);
 }
}

void playServo(uint8_t servoPin, uint8_t buttonPin) {
  uint16_t addr = 0;
  Serial.println("Playing");


  myServo.attach(servoPin);
  while (digitalRead(buttonPin)) {    
    uint8_t x = EEPROM.read(addr);
    Serial.print("Read EE: "); Serial.print(x);
    if (x == 255) break;
    // map to 0-180 degrees
    x = map(x, 0, 254, 0, 180);
    Serial.print(" -> "); Serial.println(x);
    myServo.write(x);
    delay(SAMPLE_DELAY);
    addr++;
    if (addr == 512) break;
  }
  Serial.println("Done");
  myServo.detach();
  delay(250);  
}

void recordServo(uint8_t servoPin, uint8_t analogPin, uint8_t buttonPin) {
  uint16_t addr = 0;
  
  Serial.println("Recording");
  digitalWrite(ledPin, HIGH);
  


  
  pinMode(analogPin, INPUT); 
  while (digitalRead(buttonPin)) {
     uint16_t a = analogRead(analogPin);
     
     Serial.print("Read analog: "); Serial.print(a);
     if (a < CALIB_MIN) a = CALIB_MIN;
     if (a > CALIB_MAX) a = CALIB_MAX;
     a = map(a, CALIB_MIN, CALIB_MAX, 0, 254);
     Serial.print(" -> "); Serial.println(a);
     EEPROM.write(addr, a);
     addr++;
     if (addr == 512) break;
     delay(SAMPLE_DELAY);
  }
  if (addr != 512) EEPROM.write(addr, 255);

  digitalWrite(ledPin, LOW);

  Serial.println("Done");
  delay(250);
}

To run the Servo Record/Play Demo Sketch:

  1. Upload servo_recordplay to the arduino
  2. press the top button to start recording. (The LED should light up.)
  3. Press the top button once more to stop recording.
  4. Press the bottom button to replay.
  5. You can press the green button as many times as you want.
  6. To record a new sequence, go back to step 2.
Watch the video below to see it in operation:
You can record up to 512 samples (about 12.8 seconds worth). When you reach the limit, the led will go out and recording will stop automatically.
This guide was first published on Aug 24, 2013. It was last updated on Aug 24, 2013. This page (Servos as Input Devices) was last updated on Sep 14, 2019.