i would like to tuning pid controller for position controller of dc motor but all result for gain similar each other. did i write code mistake some where?
picture ->https://www.img.in.th/image/4kcyvA
#include <PID_v1.h>
//Abosolute Encoder 12 Bit 4096
int CLK = 13; // Blu Pin 10
int DO = 12; // Grn Pin 11
int CSn = 11; // Ylw Pin 12
//DC motor30
const int in_1 = 7 ;
const int in_2 = 6 ;
const int pwm = 5 ;
double setpoint = 180;
double p = 100;
double Ku = p/0.5;
double Pu = (12.981-12.488);
//Pcontroller
double kp = 0.5*Ku ,ki=0,kd = 0;
//PIcontroller
//double kp = 0.45*Ku, ki = (1.2*kp)/Pu , kd =0;
//PIDcontrollet
//double kp = 0.6*Ku, ki = (2*kp)/Pu , kd = (kp*Pu)/8;
double input = 0,output = 0;
PID myPID(&input,&output,&setpoint,kp,ki,kd,DIRECT);
double Degree = 0;
double x;
double total_error,last_error;
double last_time,T = 1.3,current_time,delta_time;
void setup() {
// put your setup code here, to run once:
pinMode(pwm,OUTPUT) ; pinMode(in_1,OUTPUT) ; pinMode(in_2,OUTPUT) ;
TCCR1B = TCCR1B & 0b11111000 | 1;
Serial.begin(9600);
pinMode(CSn, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(DO, INPUT_PULLUP);
digitalWrite(CSn, HIGH);digitalWrite(CLK, HIGH);
myPID.SetMode(AUTOMATIC);
myPID.SetSampleTime(T);
myPID.SetOutputLimits(-255,255);
}
void loop() {
// put your main code here, to run repeatedly:
int ee = 170;
ReadEncoder() ;
if(Serial.available())
{ int Angle = Serial.parseInt();
if(Angle>ee || Angle<-ee)
{ stop();
Serial.println("---------------------------------");
Serial.println("Error:Angle should be in -170 to 170");
Serial.println("---------------------------------");
//stop
delay(90000);
kp = 30;
setpoint = 180;}
else
{
setpoint = 180+Angle;}
}
input = Degree;
myPID.Compute();
pwmOut(output);
//Serial.print(" x = "); Serial.print(((x/4095)*359)-180);
Serial.print("Kp=");Serial.print(kp);
Serial.print("Ki=");Serial.print(ki);
Serial.print("Kd=");Serial.print(kd);
Serial.print(" ");Serial.print(setpoint-180);
Serial.print(" "); Serial.print(input-180);
Serial.print(" ");Serial.print(output);
Serial.print(" ");Serial.println(delta_time);
}
void pwmOut(int out)
{
if (out>0)
{ analogWrite(pwm,out);forward();}
else
{ analogWrite(pwm,abs(out));reverse();}
}
void time()
{
current_time = millis();
delta_time = current_time - last_time;
if(delta_time>= T)
{
double error = setpoint - input;
double delta_error = error-last_error;
total_error+= error;
last_error = error;
last_time = current_time;
}
}
void ReadEncoder()
{ time();
float Data = ReadSSI();
x=Data;
Degree = map(Data, 0, 4095, 0, 359); //cange data to Degree
}
int ReadSSI(void)//read clk cs do from encoder
{ int i, dReading;
char Resolution = 12;
unsigned int bitStart = 0x0800;
dReading = 0;
digitalWrite(CSn, LOW);
delayMicroseconds(5);
digitalWrite(CLK, LOW);
for (i = (Resolution - 1); i >= 0; i--)
{ digitalWrite(CLK, HIGH);
delayMicroseconds(5);
if (digitalRead(DO)) dReading |= bitStart;
digitalWrite(CLK, LOW);
delayMicroseconds(5);
bitStart = bitStart >> 1;
if (i == 0)
{ digitalWrite(CLK, HIGH);
if (digitalRead(DO)) dReading |= bitStart;
}
}
digitalWrite(CSn, HIGH);
return dReading;
}
void forward()
{
digitalWrite(in_1,LOW) ;digitalWrite(in_2,HIGH);
}
void reverse()
{
digitalWrite(in_1,HIGH) ;digitalWrite(in_2,LOW);
}
void stop()
{
digitalWrite(in_1,HIGH) ;digitalWrite(in_2,HIGH);
}