Skip to content

Commit

Permalink
added library code files
Browse files Browse the repository at this point in the history
  • Loading branch information
r-downing committed Oct 22, 2017
1 parent 475a743 commit 205772f
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 0 deletions.
96 changes: 96 additions & 0 deletions AutoPID.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include "AutoPID.h"

AutoPID::AutoPID(double *input, double *setpoint, double *output, double outputMin, double outputMax,
double Kp, double Ki, double Kd) {
_input = input;
_setpoint = setpoint;
_output = output;
_outputMin = outputMin;
_outputMax = outputMax;
setGains(Kp, Ki, Kd);
_timeStep = 1000;
}//AutoPID::AutoPID

void AutoPID::setGains(double Kp, double Ki, double Kd) {
_Kp = Kp;
_Ki = Ki;
_Kd = Kd;
}//AutoPID::setControllerParams

void AutoPID::setBangBang(double bangOn, double bangOff) {
_bangOn = bangOn;
_bangOff = bangOff;
}//void AutoPID::setBangBang

void AutoPID::setBangBang(double bangRange) {
setBangBang(bangRange, bangRange);
}//void AutoPID::setBangBang

void AutoPID::setOutputRange(double outputMin, double outputMax) {
_outputMin = outputMin;
_outputMax = outputMax;
}//void AutoPID::setOutputRange

void AutoPID::setTimeStep(unsigned long timeStep){
_timeStep = timeStep;
}


bool AutoPID::atSetPoint(double threshold) {
return abs(*_setpoint - *_input) <= threshold;
}//bool AutoPID::atSetPoint

void AutoPID::run() {
if (_stopped) {
_stopped = false;
reset();
}
//if bang thresholds are defined and we're outside of them, use bang-bang control
if (_bangOn && ((*_setpoint - *_input) > _bangOn)) {
*_output = _outputMax;
_lastStep = millis();
} else if (_bangOff && ((*_input - *_setpoint) > _bangOff)) {
*_output = _outputMin;
_lastStep = millis();
} else { //otherwise use PID control
unsigned long _dT = millis() - _lastStep; //calculate time since last update
if (_dT >= _timeStep) { //if long enough, do PID calculations
_lastStep = millis();
double _error = *_setpoint - *_input;
_integral += (_error + _previousError) / 2 * _dT / 1000.0; //Riemann sum integral
//_integral = constrain(_integral, _outputMin/_Ki, _outputMax/_Ki);
double _dError = (_error - _previousError) / _dT / 1000.0; //derivative
_previousError = _error;
double PID = (_Kp * _error) + (_Ki * _integral) + (_Kd * _dError);
//*_output = _outputMin + (constrain(PID, 0, 1) * (_outputMax - _outputMin));
*_output = constrain(PID, _outputMin, _outputMax);
}
}
}//void AutoPID::run

void AutoPID::stop() {
_stopped = true;
reset();
}
void AutoPID::reset() {
_lastStep = millis();
_integral = 0;
_previousError = 0;
}

bool AutoPID::isStopped(){
return _stopped;
}

void AutoPIDRelay::run() {
AutoPID::run();
while ((millis() - _lastPulseTime) > _pulseWidth) _lastPulseTime += _pulseWidth;
*_relayState = ((millis() - _lastPulseTime) < (_pulseValue * _pulseWidth));
}


double AutoPIDRelay::getPulseValue(){
return (isStopped()?0:_pulseValue);
}


61 changes: 61 additions & 0 deletions AutoPID.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#ifndef AUTOPID_H
#define AUTOPID_H
#include <Arduino.h>

class AutoPID {

public:
// Constructor - takes pointer inputs for control variales, so they are updated automatically
AutoPID(double *input, double *setpoint, double *output, double outputMin, double outputMax,
double Kp, double Ki, double Kd);
// Allows manual adjustment of gains
void setGains(double Kp, double Ki, double Kd);
// Sets bang-bang control ranges, separate upper and lower offsets, zero for off
void setBangBang(double bangOn, double bangOff);
// Sets bang-bang control range +-single offset
void setBangBang(double bangRange);
// Allows manual readjustment of output range
void setOutputRange(double outputMin, double outputMax);
// Allows manual adjustment of time step (default 1000ms)
void setTimeStep(unsigned long timeStep);
// Returns true when at set point (+-threshold)
bool atSetPoint(double threshold);
// Runs PID calculations when needed. Should be called repeatedly in loop.
// Automatically reads input and sets output via pointers
void run();
// Stops PID functionality, output sets to
void stop();
void reset();
bool isStopped();

private:
double _Kp, _Ki, _Kd;
double _integral, _previousError;
double _bangOn, _bangOff;
double *_input, *_setpoint, *_output;
double _outputMin, _outputMax;
unsigned long _timeStep, _lastStep;
bool _stopped;

};//class AutoPID

class AutoPIDRelay : public AutoPID {
public:

AutoPIDRelay(double *input, double *setpoint, bool *relayState, double pulseWidth, double Kp, double Ki, double Kd)
: AutoPID(input, setpoint, &_pulseValue, 0, 1.0, Kp, Ki, Kd) {
_relayState = relayState;
_pulseWidth = pulseWidth;
};

void run();

double getPulseValue();

private:
bool * _relayState;
unsigned long _pulseWidth, _lastPulseTime;
double _pulseValue;
};//class AutoPIDRelay

#endif

0 comments on commit 205772f

Please sign in to comment.