#include <stdio.
h>
double pid_controller(double setpoint, double process_variable)
{
double kp = 0.5; // Proportional gain
double ki = 0.2; // Integral gain
double kd = 0.1; // Derivative gain
double error = setpoint - process_variable;
static double integral = 0;
static double last_error = 0;
integral += error;
double derivative = error - last_error;
last_error = error;
double output = kp * error + ki * integral + kd * derivative;
return output;
}
int main()
{
double setpoint = 50; // Desired setpoint
double process_variable = 0; // Current process variable (e.g. temperature)
// Loop to simulate the PID control
for (int i = 0; i < 100; i++)
{
double output = pid_controller(setpoint, process_variable);
process_variable += output;
printf("Process variable: %f, Output: %f\n", process_variable, output);
}
}
return 0;
}
Complex version:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SAMPLE_TIME 0.01 // PID control loop sample time
#define Kp 1.0 // Proportional gain
#define Ki 0.5 // Integral gain
#define Kd 0.1 // Derivative gain
double error, integral, derivative, previous_error, output, setpoint, feedback;
void pid_control_loop()
{
// Compute error between setpoint and feedback
error = setpoint - feedback;
// Compute integral using trapezoidal integration
integral += (error + previous_error) * SAMPLE_TIME / 2.0;
// Compute derivative using backward difference
derivative = (error - previous_error) / SAMPLE_TIME;
// Compute PID output
output = Kp * error + Ki * integral + Kd * derivative;
// Update previous error for next iteration
previous_error = error;
// Apply output to system
// ...
int main()
{
// Initialize variables
setpoint = 10.0;
feedback = 0.0;
error = 0.0;
integral = 0.0;
derivative = 0.0;
previous_error = 0.0;
output = 0.0;
// Run PID control loop for 100 iterations
for (int i = 0; i < 100; i++)
{
pid_control_loop();
// Update feedback from system
feedback = sin(i * SAMPLE_TIME);
// Print output for debugging
printf("Output: %lf\n", output);
}
return 0;
}
Other
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// PID controller struct
typedef struct {
double kp; // Proportional gain
double ki; // Integral gain
double kd; // Derivative gain
double Ts; // Sampling time
double Tmin; // Minimum control signal
double Tmax; // Maximum control signal
double beta; // Setpoint weighting factor
double gamma; // Anti-windup gain
double tau; // Derivative filter time constant
double N; // Derivative filter parameter
double prev_error; // Previous error
double integral; // Integral term
double derivative; // Derivative term
double prev_derivative; // Previous derivative
double prev_output; // Previous control signal
} pid_controller_t;
// Initialize the PID controller
void pid_controller_init(pid_controller_t *pid, double kp, double ki, double kd,
double Ts, double Tmin, double Tmax, double beta, double gamma, double tau, double
N)
{
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->Ts = Ts;
pid->Tmin = Tmin;
pid->Tmax = Tmax;
pid->beta = beta;
pid->gamma = gamma;
pid->tau = tau;
pid->N = N;
pid->prev_error = 0;
pid->integral = 0;
pid->derivative = 0;
pid->prev_derivative = 0;
pid->prev_output = 0;
}
// Calculate the PID control signal
double pid_controller_compute(pid_controller_t *pid, double setpoint, double
process_variable, double disturbance)
{
double error = setpoint - process_variable;
// Setpoint ramping
double beta_term = pid->beta * (setpoint - pid->prev_output);
pid->prev_output += beta_term;
// Proportional term
double proportional = pid->kp * error;
// Integral term
pid->integral += pid->ki * pid->Ts * (error + beta_term);
double saturation_limit = (pid->Tmax - pid->Tmin) / pid->ki;
if (pid->integral > saturation_limit) {
pid->integral = saturation_limit;
} else if (pid->integral < -saturation_limit) {
pid->integral = -saturation_limit;
}
// Derivative term
double delta_error = error - pid->prev_error;
pid->derivative = (1 - pid->N / (pid->tau / pid->Ts + pid->N)) * pid-
>derivative + pid->N / (pid->tau / pid->Ts + pid->N) * (delta_error - pid-
>prev_derivative);
pid->prev_error = error;
pid->prev_derivative = delta_error;
// Control signal
double control_signal = proportional + pid->integral + pid->kd * pid-
>derivative + pid->gamma * disturbance;
if (control_signal > pid->Tmax) {
control_signal = pid->Tmax;
pid->integral -= pid->ki * pid->Ts * error;
} else if (control_signal < pid->Tmin) {
control_signal = pid->Tmin;
pid->integral -= pid->ki * pid->Ts * error;
}
pid->prev_output = control_signal;