0% found this document useful (0 votes)
47 views

Pidnn Arduino2

This Arduino code implements a PID controller to regulate the speed of a motor. It uses a DAC, encoder, and timer interrupts to read the motor speed, calculate the error from the setpoint, and output a control signal. Key elements include: initializing the DAC and timer, continuously measuring the speed, calculating the PID output to minimize error, and saturating the output between 0-4095 for the DAC.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
47 views

Pidnn Arduino2

This Arduino code implements a PID controller to regulate the speed of a motor. It uses a DAC, encoder, and timer interrupts to read the motor speed, calculate the error from the setpoint, and output a control signal. Key elements include: initializing the DAC and timer, continuously measuring the speed, calculating the PID output to minimize error, and saturating the output between 0-4095 for the DAC.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 2

#include <MCP4922.

h>
#include <SPI.h>

const int T = 32; // Sampling period (ms)


const int ref = A0; // Reference input pin
int counter[2] = {0,0}; // Counter vector for speed reading
int error[3] = {0,0,0}; // Error vector
int u[2] = {0,0}; // Control vector
int setpoint = 0; // Setpoint variable

MCP4922 DAC(11,13,10,5); //(MOSI,SCK,CS,LDAC) Connections for UNO_board

void setup() {
// *********************** - Timer 2 configuration - ***********************
SREG = (SREG & 0b01111111); // Disable interruptions **
TIMSK2 = TIMSK2|0b00000001; // Overflow interruption enable **
TCCR2B = 0b00000111; // Prescaler FT2 = 7812.5Hz **
SREG = (SREG & 0b01111111) | 0b10000000; // IS enabled // IS disabled **
//**************************************************************************

SPI.begin();
attachInterrupt(0, counterUp, FALLING);
Serial.begin(9600);
}

void loop() {
int speedRPM = speedCalculation(); // Reference acquistion
error[0] = setpoint - speedRPM; // Error calculation
u[0] = pidAntiWindUp(error[0], error[1], error[2], u[1], 0, 4000, T);
Serial.print(setpoint);
Serial.print(" ");
Serial.print(speedRPM);
Serial.print(" ");
Serial.println(u[0]);
counter[1] = counter[0]; // Shift register
error[1] = error[0]; // Shifting operation
error[2] = error[1]; // Shifting operation
u[1] = u[0]; // Shifting operation
delay(T);
}

int pidAntiWindUp(int e0, int e1, int e2, int u1, int lb, int ub, float T){
const float Kp = 2; // Proportional gain
const float Ti = .2; // Integral time
const float Td = 0; // Derivative time
const float Tt = Ti; // Anti windup gain
T = T/1000; // Conversion from ms to s
int v = sat(u1, lb, ub) - u1; // Saturation difference calculation
int u = u1 + Kp * (e0 - e1 + T/Ti * e0 + Td/T * (e0 - 2*e1 + e2)) + T/Ti * v;
return u;
}

void counterUp() {
counter[0] += 1; // Accumulator
}

int speedCalculation(){ // Considers T, encoder, rpm


int speedRPM = abs((counter[0] - counter[1])/0.05) * 1.67;
return speedRPM;
}

ISR(TIMER2_OVF_vect){ // FT2 = 7812.5Hz -> 255 counts = 32ms


setpoint = analogRead(ref) * 2.5;
DAC.Set(sat(u[0], 0, 4095), 0);
}

int sat(int s, int lb, int ub) { // Saturation function


if (s >= ub) return ub;
if (s <= lb) return lb;
return s;
}

You might also like