Good day,
I am using an encoder to control the PWM speed of a motor. The encoder I am using is an industrial grade, optical encoder with 1000 pulses per rev. Together with the encoder, I am implementing the use of the PID library for smooth operation of the motor. The problem I am having is that I am getting random spikes in my encoder reading which directly influences the output PWM signal. I would appreciate if someone could assist me in this matter. Below is the code as well as an image from the serial plotter. The blue line represent the setpoint, The red the encoder reading (from which these spikes can be seen) and the read is the PWM output. The help is much appreciated!!
#include <PID_v1.h>
#define ENCA 2 //Green
#define ENCB 3 //White
float eintegral=0;
float PWRPrev;
float RPMset;
float vFilt = 0;
float vPrev = 0;
int pos = 0;
int Motor = 9;
long prevT = 0;
int posPrev = 0;
float deltaT = 0;
volatile int pos_i = 0;
volatile float velocity_i = 0;
volatile long prevT_i = 0;
int t = 0;
int rev = 0;
float RPM = 0.0;
double Kp = 5, Ki =2 , Kd = 0;
double Input,Output,Setpoint;
PID encoder(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(ENCA, INPUT_PULLUP);
pinMode (ENCB, INPUT_PULLUP);
pinMode(Motor, OUTPUT);
encoder.SetMode(AUTOMATIC);
attachInterrupt(digitalPinToInterrupt(ENCA), readEncoderA, RISING);
// attachInterrupt(digitalPinToInterrupt(ENCB), readEncoderB, RISING);
Serial.print("Setpoint");
Serial.print(" ");
Serial.print("Input");
Serial.print(" ");
Serial.print("Output");
Serial.println();
}
void loop() {
// put your main code here, to run repeatedly:
float velocity2;
velocity2 = velocity_i;
float v2 = velocity2 / 1000.0 * 60.0;
int Res = analogRead(A0);
int PWM = map(Res, 0, 1014, 255, 0);
//int b=digitalRead(ENCB);
vFilt = 0.969 * vFilt + 0.0155 * v2 + 0.0155 * vPrev;
vPrev = v2;
Input=(vFilt/125)*255;
// float kp=5;
// float ki=7;
// float e=PWM-Input;
// eintegral=eintegral+e*deltaT;
//
// float u=kp*e+ki*eintegral;
//
// int PWR=(int)fabs(u);
// if(PWR>255){
// PWR=255;
// }
Setpoint=PWM;
encoder.Compute();
analogWrite(Motor, Output);
Serial.print(Setpoint);
Serial.print(" ");
Serial.print(Input);
Serial.print(" ");
Serial.print(Output);
Serial.println();
delay(1);
}
void readEncoderA() {
int a = digitalRead(ENCA);
deltaT = 0;
if (a > 0) {
pos++;
}
else {
pos--;
}
long currT = micros();
deltaT = ((float)(currT - prevT_i)) / 1.0e06;
velocity_i = (pos - pos_i) / deltaT;
prevT_i = currT;
pos_i = pos;
}
