0

I'm trying to control the motor torque. This I'm trying to accomplish by implementing a PID control on motor current and hence on the PWM. Higher PWM means higher torque. I'm new to arduino-uno, hence would need help with the coding. I have written a code for the same but a bit unsure on its correctness. I'm still unsure about the value of the 'Integral' variable to be used though. Any help is much appreciated Thanks in advance

#include "RunningAverage.h"
 int m1 = 13;
int m2 = 12;
int me = 9;
int t = millis()+5000;
RunningAverage myRA(80);
int stat=0;
int pwmn=100;
int counter=0;
int kP;
int kI=0;
int kD=0;
int SetPt;
int Last;
int Actual;
int Error;
int Integral;
float P;
float I;
float D;
int Drive;
int ScaleFactor;


void motorRight(){
digitalWrite(m1,HIGH);
digitalWrite(m2, LOW);
}


void motorLeft(){
digitalWrite(m2,HIGH);
digitalWrite(m1, LOW);
}

void motorOff(){
digitalWrite(m2, LOW);
digitalWrite(m1, LOW);
}


void motorBrake(){
digitalWrite(m2, HIGH);
digitalWrite(m1, HIGH);
delay(10);
motorOff();
}

void setup() {
// put your setup code here, to run once:
pinMode(m1,OUTPUT);
pinMode(m2,OUTPUT);
pinMode(me,OUTPUT);
analogWrite(me,pwmn);
Serial.begin(115200);
motorRight();
}

void loop() {
// put your main code here, to run repeatedly:
myRA.addValue(analogRead(A1));
Serial.print(myRA.getAverage());
Serial.println(",500,600");
Actual = myRA.getAverage();
Error = SetPt - Actual;
P = Error*kP; // calc proportional term
I = Integral*kI; // integral term
D = (Last-Actual)*kD; // derivative term
Drive = P + I + D; // Total drive = P+I+D
Drive = Drive*ScaleFactor; // scale Drive to be in the range 0-255
//Serial.println(pwmn);
if(counter>10){
if(pwmn<250){
pwmn++;
}
counter=0;
}
counter++;
if (abs(Drive)>255) {
Drive=255;
}
analogWrite (me,Drive); // send PWM command to motor board
Last = Actual; // save current value for next time
// analogWrite(me,pwmn);
delay(50);
}' 
lokusking
  • 7,396
  • 13
  • 38
  • 57
Sakshi
  • 29
  • 11

1 Answers1

-1

You are correct, the integral calculation is wrong. Integral (from integrate) means to add up. What you want is

I = I + kI*Error;

You should also limit the Integral term (I) to some maximum and minimum value to avoid "wind-up" error. This happens when the servo cannot reach is goal and since the I term is the sum of the errors it can get out of control.

tddguru
  • 392
  • 1
  • 4
  • That is wrong too. It is actually $I += err * dt$. If you do it the way you did then you don't have an easy way to adjust Ki since it becomes baked into the integral. Integral should just be the sum of the error. – Martin Sep 04 '17 at 21:50