PID Loop

From Bright Things Wiki
Jump to: navigation, search

The PID algorithm is central in all automation systems. This is handled by the Arduino environment, and a library will be made to handle all our cases.

The algorithm in itself is fairly straight forward and support for that can be obtained from Brett Beauregard and his PID library intended for Arduino.

What is unique for us is that not only do we need a PID function and corresponding structure, but we need a flexible and performant way to wire the inputs and outputs to its surrounding environment. For this, I propose that shared variables are used, via regular C pointers.

Declaration

Each PID Loop is declared as a C struct, which has pointers for each and every one of its members.

struct PID {
    boolean* on;
    boolean* auto;
    float* manual;
    float* input;
    float* setpoint;
    float* output;
    float* highLimit;
    float* lowLimit;
    float* pConst;
    float* iTime;
    float* dTime;
    float* mdGain;
};

Initialization

The allocated variables are in the communications area (VPacs if Exoline, Registers if ModBus) and then assigned by the initialize() function.

PID pid1;
PID pid2;
VPac data1;

void setup() {
    pid1.on = &data1.logic1;
    pid1.auto = &data1.logic2;
    pid1.input = &data1.real1;
    pid1.setpoint = &data1.real2;
    pid1.output = &data1.real3;
    pid1.highLimit = &data1.real4;
    pid1.lowLimit = &data1.real5;
    pid1.pConst = &data1.real6;
    pid1.iTime = &data1.real7;
    pid1.dTime = &data1.real8;
    pid1.mdGain = &data1.real9;


    pid2.on = &data1.logic3;
    pid2.auto = &data1.logic4;
    pid2.input = &data1.real10;
    pid2.setpoint = &data1.real11;
    pid2.output = &data1.real12;
    pid2.highLimit = &data1.real13;
    pid2.lowLimit = &data1.real14;
    pid2.pConst = &data1.real15;
    pid2.iTime = &data1.real16;
    pid2.dTime = &data1.real17;
    pid2.mdGain = &data1.real18;
}

Usage

Inside the loop, the only thing needed is to call the pid_tick() function with the current time.

struct PID pid1;

void loop() {
    pid_tick( pid1, millis() );
}