Hello everyone,
I am writing a code for position control of this (Pololu - 131:1 Metal Gearmotor 37Dx57L mm 12V with 64 CPR Encoder (No End Cap)) 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?