Help needed with PID Auto-tune Library

Hello everyone,

I am writing a code for position control of this (https://www.pololu.com/product/1447) motor. It is a DC motor with a quadrature encoder of a resolution for 8400 cpr. I have used the Arduino’s PID Library to write the code I have attached.

#include <PID_v1.h>

#include “Arduino.h”
#include <digitalWriteFast.h> // library for high performance reads and writes by jrraines

// Quadrature encoders
// Left encoder
#define c_LeftEncoderInterruptA 0
#define c_LeftEncoderInterruptB 1
#define c_LeftEncoderPinA 2
#define c_LeftEncoderPinB 3
#define LeftEncoderIsReversed

volatile bool _LeftEncoderASet;
volatile bool _LeftEncoderBSet;
volatile bool _LeftEncoderAPrev;
volatile bool _LeftEncoderBPrev;
volatile long _LeftEncoderTicks = 0;
volatile float timearray [300];
int angle=0;
double Input=0;
double Output=0;
double Setpoint=0;
volatile int n=0;

//Motor1 Pins
int pin9 = 6; //Motor1, In pinA
int pin1 = 4; //Motor1, In pinB
int pin2 = 5; //Motor1, PWM

PID myPID(&Input, &Output, &Setpoint,0.1,0.0009,0.001, DIRECT);

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

// Quadrature encoders
// Left encoder
pinMode(c_LeftEncoderPinA, INPUT); // sets pin A as input
digitalWrite(c_LeftEncoderPinA, LOW); // turn on pullup resistors
pinMode(c_LeftEncoderPinB, INPUT); // sets pin B as input
digitalWrite(c_LeftEncoderPinB, LOW); // turn on pullup resistors
attachInterrupt(c_LeftEncoderInterruptA, HandleLeftMotorInterruptA, CHANGE);
attachInterrupt(c_LeftEncoderInterruptB, HandleLeftMotorInterruptB, CHANGE);

pinMode(pin1, OUTPUT);
pinMode(pin2, OUTPUT);
pinMode(pin9, OUTPUT);

//initialize the variables we’re linked to
Input = _LeftEncoderTicks;
angle=360;
Setpoint = (8400/360)*angle;

//turn the PID on
myPID.SetMode(AUTOMATIC);
}

void loop()
{

Input = _LeftEncoderTicks;
myPID.Compute();
analogWrite(pin2, Output);
digitalWrite(pin9, HIGH);
digitalWrite(pin1, LOW);

//Serial.print(“Encoder Ticks: “);
Serial.print(_LeftEncoderTicks);
Serial.print(” “);
Serial.print(”\n”);

}

// Interrupt service routines for the left motor’s quadrature encoder
void HandleLeftMotorInterruptA(){

_LeftEncoderBSet = digitalReadFast(c_LeftEncoderPinB);
_LeftEncoderASet = digitalReadFast(c_LeftEncoderPinA);

_LeftEncoderTicks+=ParseEncoder();

_LeftEncoderAPrev = _LeftEncoderASet;
_LeftEncoderBPrev = _LeftEncoderBSet;
}

// Interrupt service routines for the right motor’s quadrature encoder
void HandleLeftMotorInterruptB(){
// Test transition;

_LeftEncoderBSet = digitalReadFast(c_LeftEncoderPinB);
_LeftEncoderASet = digitalReadFast(c_LeftEncoderPinA);

_LeftEncoderTicks+=ParseEncoder();

_LeftEncoderAPrev = _LeftEncoderASet;
_LeftEncoderBPrev = _LeftEncoderBSet;
}

int ParseEncoder(){
if(_LeftEncoderAPrev && _LeftEncoderBPrev){
if(!_LeftEncoderASet && _LeftEncoderBSet) return 1;
if(_LeftEncoderASet && !_LeftEncoderBSet) return -1;
}else if(!_LeftEncoderAPrev && _LeftEncoderBPrev){
if(!_LeftEncoderASet && !_LeftEncoderBSet) return 1;
if(_LeftEncoderASet && _LeftEncoderBSet) return -1;
}else if(!_LeftEncoderAPrev && !_LeftEncoderBPrev){
if(_LeftEncoderASet && !_LeftEncoderBSet) return 1;
if(!_LeftEncoderASet && _LeftEncoderBSet) return -1;
}else if(_LeftEncoderAPrev && !_LeftEncoderBPrev){
if(_LeftEncoderASet && _LeftEncoderBSet) return 1;
if(!_LeftEncoderASet && !_LeftEncoderBSet) return -1;
}
}
I now want to use Arduino’s PID Auto-Tune Library to obtain the gains. Pertaining to my mechanical engineering background I am not good with programming. Can anyone please help me with using this library for my particular application?

Single_Motor_Position_Control_PID-Library.ino (3.21 KB)

I now want to use Arduino's PID Auto-Tune Library to obtain the gains.

Permission is granted.

Can anyone please help me with using this library for my particular application?

What happened when you ran the sketch?

This sketch runs fine. But I have to iterate manually to get the gains. I need help with using the autotune library.

hi tanvir

any luck with the autotune function???