0% found this document useful (0 votes)
48 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
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
48 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
We take content rights seriously. If you suspect this is your content, claim it here.
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