PID control

I have an Arduino Leonardo board with an Arduino motor shield connected on top, I have a potentimeter in pin A4 which will be acting as the setpoint for my PID control and a servo connected to pin A5 which will be moving by twisting the potentiometer(A4) the motor for the servo is connected into A on the motor shield, I also have a 9v battery connected to the board for extra power as the 5v input from the usb lead is not enough ... can you please have a look at my code and tell me where I've gone wrong. I have no idea how to set up a PID control loop as you can probably see. Regards.

#include <PID_v1.h>
#include <stdio.h>
#include <Servo.h>
double Error, Time, PreviousTime, PreviousError, LastPosition, Proportional, Integral, Derivative, DutyCycle, ActualPosition;
int Drive, ScaleFactor, IntThresh, Motor, P, I, D, dt;

int Pot = A4;
Servo myServo;

double Kp = 0.5;
double Ki = 1.55;
double Kd = -0.01;

double SetPoint, Input, Output;

PID myPID(&Input, &Output, &SetPoint, Kp, Ki, Kd, DIRECT);

void setup()
{
  Serial.begin(9600);
  myPID.SetMode(MANUAL);
  myPID.SetOutputLimits(0,255);
  myPID.SetTunings(Kp,Ki,Kd);
  myPID.SetSampleTime(500);
  myPID.SetControllerDirection(DIRECT);
  Input = analogRead(A4);
  SetPoint = map(analogRead(A4), 0, 1024, 0, 255);
  myServo.attach(A5);
}
void loop()
{
  Serial.print("PID formula (P + I + D): ");
  Serial.print(Proportional, 2);
  Serial.print(" + ");
  Serial.print(Integral, 2);
  Serial.print(" + ");
  Serial.println(Derivative, 2);

  ControlTheory();
  SetPoint = map(analogRead(A4), 0, 1024, 0, 255);
  ActualPosition = analogRead(A5);
  myPID.Compute();
  analogWrite(A5, OUTPUT);

  Time = millis();

  Error = SetPoint - ActualPosition;

  P = Error*Kp;
  I = Integral*Ki;
  D = (LastPosition - ActualPosition)*Kd;
  Drive = P + I + D;
  
  if (Drive < 0)
  {
    analogWrite(A5, LOW);  
  }
  else
  {
    analogWrite(A5, HIGH);
  }

  LastPosition = ActualPosition; 
}

int ControlTheory()
{
  Error = SetPoint - ActualPosition;
  Proportional = Error*Kp;
  Integral = Integral+(Error*dt);
  Derivative = (Error-PreviousError)/dt;
  Drive = (Proportional)+(Integral*Ki)+(Derivative*Kd);
  PreviousError = Error;
  
  return  Proportional + Integral + Derivative;
}

I'd suggest to make your circuitry work. What's the use of a motor shield with a servo? A 9V (block) battery is too weak for driving a motor, get a stronger power supply.

Then make the servo follow the pot, using the Knob example of the Servo library.

Once you got that working, add a PID controller. Either use the PID library, and follow the instructions and code examples, or roll your own PID code.

A servo motor already includes a PID controller, what difference or improvement do you expect from an additional software controller? For other motors you'll need feedback from the motor, about position or rotation, as input for a PID.

Hi circuitry is fine I have buzzed it out and all good. The motor in the servo I have taken apart and connected to the motor shield pcb so thats why im using that. How stronger of a supply should I get?

I am just trying to get a precise control by turning a potentiometer that will make the servos potentiometer and motor move when the input pot is being twisted at different speed.

Thanks for your reply I appreciate the help

So you want to drive the motor of the servo yourself, using a motor driver, and use the servo pot for position feedback?

Motors usually require more voltage and current than can be delivered by USB or a 9V battery. The servo motor may be happy with 5V, so you can use a 5V DC power supply, to power both the Arduino and the motor. You also can use a supply or battery of higher voltage,and connect it to the Arduino Vin and to the motor driver board.

I'm not sure about your idea of "twisting a pot at different speed", and how the motor should react on such input.

Yes correct, that is exactly what I want to do. The only problem is my servo is not responding and I cant work out wether it is my code or if there is not enough power going into the boards.

I have 5v going in through usb and 9v battery connected to motor shield vin, surely thats enough power?

The twisting of the knob at different speeds is to prove that the precision and tuning is perfect.. I have created a spreadsheet on excel which will work out how long it will take for my PID to react without overshooting and being a controlled system. I just want to prove my workings out are correct.

I believe my only set back right now is the code itself and the servo not having enough power (I have tried the knob library code and the servo did not respond, after connecting a serial comms to it the 'twisting pot' responds but the servo does not)

A 9V block battery is not usable with motors. Most probably your battery is already empty from preceding experiments.

Try to control your motor first. This test will show whether power, wiring and signals to the driver are okay. You can move the motor in either direction, until its pot will indicate some limit, then reverse the direction until the other limit is reached. Start with slow motion (low analogWrite), then increase the duty cycle to verify that speed control is working. Be prepared for disconnecting the motor power lines manually, until your code works as expected.

If you have another DC motor at hand, you can use it for the first tests. Then you don't risk to damage the pot and gear box of the servo by coding errors.