Prototype

 

Wiring

Schematic

Breadboard view

Code for the controller

#include

double error = 0;
double dtError = 0;
double old_error = 0;
double potValue = 0;
double oldPotValue = 0;

int ctrlSign =0;
int directrion =0;
int wait = 5;

String temp;

int setValue = 0;
int kp = 12;
int kd = 1;

void setup()
{
  Serial.begin(9600);
  myservo.attach(9);
  myservo.write(105,255,true);
  delay(1000);
  potValue = analogRead(1);
  setValue = potValue - 50;
}

void loop()
{  
  potValue = analogRead(1);
  sendPotValue(potValue);
 
  delay(wait);
  //printInfo();
 
  // Filter input  
  potValue = (0.5 * potValue + 0.5 * oldPotValue) + 0.5;
 
  // Control part
  error = (setValue - potValue);
 
  // Derivitive (delta e / delta t)
  dtError = (error - old_error);///(wait*0.001);
 
  // PD-control
  ctrlSign =  kp * error + kd * dtError;
 
  // Set servo speed and direction
  if(failSafe(error))
  {
    setSpeed(ctrlSign);  
  }
 
  // Update old error
  old_error = error;
  oldPotValue = potValue;
}

void setSpeed(int out)
{
  if(out <= -1)
  {
    myservo.write(170, (int)abs(out), false);
  }
  else if(out >= 1)
  {
    myservo.write(10, (int)abs(out), false);
  }
  else// Do nothing
  {
    myservo.write(myservo.read(), 0, false);
  }
}

int failSafe(int val)
{
  // Error is too big
  if(val < -10 || val > 10)
  {
    myservo.write(105,40,true);
    return 0;
  }
  else
  {
    return 1;
  }
}

void printInfo(){
  Serial.print(setValue);
  Serial.print(", ");
  Serial.print(potValue);
  Serial.print(", ");
  Serial.println(error);
}

int getAngle(int potValue){
  return (int)((setValue - potValue) * 3.5);
}

void sendPotValue(double potValue)
{
  Serial.write('@');// Start stream
  Serial.flush();
 
  writeStream(potValue);
 
  Serial.write('#');// End stream
  Serial.flush();
}

void writeStream(double potValue)
{
  temp = String(potValue);
  byte charBuf[temp.length()];
 
  temp.getBytes(charBuf, temp.length() + 1);
 
  Serial.write(charBuf, temp.length());// Write data
  Serial.flush();
}