Arduino Nano PID Controller with Potentiometer + IBT-2 Motor Control Board

I have a potentiometer connected to an analog pin A1 and would like to implement PID Control to move a robot arm up and down based on to a given serial command. For this to work I will need PID out produce a direction and speed output.

#include <AutoPID.h>

// PID settings and gains
#define OUTPUT_MIN 0
#define OUTPUT_MAX 255
#define KP 0.12
#define KI 0.8
#define KD 0.003


// Variables on PID values
float analogReadValue, setPoint, outputVal;

int SENSOR_PIN = A0; // center pin of the potentiometer

int RPWM_Output = 10; //IBT-2 Motor Control 
int LPWM_Output = 11; // 

bool BarUp;
bool BarLow;
bool BarStop;

char c;

// Input/output variables passed by reference, so they are updated automatically
AutoPID myPID(&analogReadValue, &setPoint, &outputVal, OUTPUT_MIN, OUTPUT_MAX, KP, KI, KD);

void setup()
{
  Serial.begin(9600);

  //Motor Direction controls
  pinMode(RPWM_Output, OUTPUT);
  pinMode(LPWM_Output, OUTPUT);

  myPID.setTimeStep(500);
}

float AnalogSensor()
{
    // read the input on analog pin 0:
    int sensorValue = analogRead(SENSOR_PIN);
    // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
    float voltage = sensorValue * (5.0 / 1023.0);

    return voltage;
}

void loop()
{
   analogReadValue=AnalogSensor(); 

  //Reading serial command
  if(Serial.available())
  {
     char c = Serial.read();

     if(c=='r')
     {
         BarLow=false;
         BarUp=true;
         Serial.println("Arm is Rising");
     }
     else if(c=='l')
     {
         BarUp=false;
         BarLow=true;
         Serial.println("Arm is lowering");
     }
}

if(BarUp)
{
  setPoint=UpperLimit;
  myPID.run(); 
}

if(BarLow)
{
  setPoint=LowerLimit;
  myPID.run(); 
}
}


void RaiseArm()
{
   analogWrite(LPWM_Output, 0);
   analogWrite(RPWM_Output, 20);

   delay(1000);

   StopArm();

   BarUp=false;
 }


 void LowerArm()
 {
   analogWrite(LPWM_Output, 20);
   analogWrite(RPWM_Output, 0);

   delay(1000);

   StopArm();

   BarLow=false;

 }

 void StopArm()
 {
    analogWrite(LPWM_Output, 0);
    analogWrite(RPWM_Output, 0);
 }

Ideally I would like to set the Setpoint to analog 5.0 for raising arm and analog 0 for lower arm. Baring in mind.

   analogWrite(LPWM_Output, 20);
   analogWrite(RPWM_Output, 0);

Is for raising arm and

   analogWrite(LPWM_Output, 20);
   analogWrite(RPWM_Output, 0);

Is lowering arm. Hope you can help as the current system is not implementing PID that can potentially work. The question is how can I change the current code to raise and lower arm to the setpoints.

This is the code but in the text You tell A1 is the input. That simple mistake?

Hi Railroader,

Sorry about that. A simple mistake. Hope you can help.

Wrong typing or wrong connection?

No, Your project is outside my comfort zone.

I’d suggest a google of how PID works followed by some of the PID examples available for Arduino .

Hi Hammy

The code is from the online PID examples. I wanted to find out if some one know more and can guide me through to whats wrong the current code.

Well you probably need to actually use outputVal...

Perhaps

if (outputVal < 0.0)
{
   analogWrite(LPWM_Output, constrain (-outputVal, 0, 255));
   analogWrite(RPWM_Output, 0);
}
else
{
   analogWrite(LPWM_Output, 0);
   analogWrite(RPWM_Output, constrain (outputVal, 0, 255));
}

Hi MarkT

Thank you so much for the response. I will give it a go.