Skip to content

Commit 205772f

Browse files
committed
added library code files
1 parent 475a743 commit 205772f

2 files changed

Lines changed: 157 additions & 0 deletions

File tree

AutoPID.cpp

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#include "AutoPID.h"
2+
3+
AutoPID::AutoPID(double *input, double *setpoint, double *output, double outputMin, double outputMax,
4+
double Kp, double Ki, double Kd) {
5+
_input = input;
6+
_setpoint = setpoint;
7+
_output = output;
8+
_outputMin = outputMin;
9+
_outputMax = outputMax;
10+
setGains(Kp, Ki, Kd);
11+
_timeStep = 1000;
12+
}//AutoPID::AutoPID
13+
14+
void AutoPID::setGains(double Kp, double Ki, double Kd) {
15+
_Kp = Kp;
16+
_Ki = Ki;
17+
_Kd = Kd;
18+
}//AutoPID::setControllerParams
19+
20+
void AutoPID::setBangBang(double bangOn, double bangOff) {
21+
_bangOn = bangOn;
22+
_bangOff = bangOff;
23+
}//void AutoPID::setBangBang
24+
25+
void AutoPID::setBangBang(double bangRange) {
26+
setBangBang(bangRange, bangRange);
27+
}//void AutoPID::setBangBang
28+
29+
void AutoPID::setOutputRange(double outputMin, double outputMax) {
30+
_outputMin = outputMin;
31+
_outputMax = outputMax;
32+
}//void AutoPID::setOutputRange
33+
34+
void AutoPID::setTimeStep(unsigned long timeStep){
35+
_timeStep = timeStep;
36+
}
37+
38+
39+
bool AutoPID::atSetPoint(double threshold) {
40+
return abs(*_setpoint - *_input) <= threshold;
41+
}//bool AutoPID::atSetPoint
42+
43+
void AutoPID::run() {
44+
if (_stopped) {
45+
_stopped = false;
46+
reset();
47+
}
48+
//if bang thresholds are defined and we're outside of them, use bang-bang control
49+
if (_bangOn && ((*_setpoint - *_input) > _bangOn)) {
50+
*_output = _outputMax;
51+
_lastStep = millis();
52+
} else if (_bangOff && ((*_input - *_setpoint) > _bangOff)) {
53+
*_output = _outputMin;
54+
_lastStep = millis();
55+
} else { //otherwise use PID control
56+
unsigned long _dT = millis() - _lastStep; //calculate time since last update
57+
if (_dT >= _timeStep) { //if long enough, do PID calculations
58+
_lastStep = millis();
59+
double _error = *_setpoint - *_input;
60+
_integral += (_error + _previousError) / 2 * _dT / 1000.0; //Riemann sum integral
61+
//_integral = constrain(_integral, _outputMin/_Ki, _outputMax/_Ki);
62+
double _dError = (_error - _previousError) / _dT / 1000.0; //derivative
63+
_previousError = _error;
64+
double PID = (_Kp * _error) + (_Ki * _integral) + (_Kd * _dError);
65+
//*_output = _outputMin + (constrain(PID, 0, 1) * (_outputMax - _outputMin));
66+
*_output = constrain(PID, _outputMin, _outputMax);
67+
}
68+
}
69+
}//void AutoPID::run
70+
71+
void AutoPID::stop() {
72+
_stopped = true;
73+
reset();
74+
}
75+
void AutoPID::reset() {
76+
_lastStep = millis();
77+
_integral = 0;
78+
_previousError = 0;
79+
}
80+
81+
bool AutoPID::isStopped(){
82+
return _stopped;
83+
}
84+
85+
void AutoPIDRelay::run() {
86+
AutoPID::run();
87+
while ((millis() - _lastPulseTime) > _pulseWidth) _lastPulseTime += _pulseWidth;
88+
*_relayState = ((millis() - _lastPulseTime) < (_pulseValue * _pulseWidth));
89+
}
90+
91+
92+
double AutoPIDRelay::getPulseValue(){
93+
return (isStopped()?0:_pulseValue);
94+
}
95+
96+

AutoPID.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#ifndef AUTOPID_H
2+
#define AUTOPID_H
3+
#include <Arduino.h>
4+
5+
class AutoPID {
6+
7+
public:
8+
// Constructor - takes pointer inputs for control variales, so they are updated automatically
9+
AutoPID(double *input, double *setpoint, double *output, double outputMin, double outputMax,
10+
double Kp, double Ki, double Kd);
11+
// Allows manual adjustment of gains
12+
void setGains(double Kp, double Ki, double Kd);
13+
// Sets bang-bang control ranges, separate upper and lower offsets, zero for off
14+
void setBangBang(double bangOn, double bangOff);
15+
// Sets bang-bang control range +-single offset
16+
void setBangBang(double bangRange);
17+
// Allows manual readjustment of output range
18+
void setOutputRange(double outputMin, double outputMax);
19+
// Allows manual adjustment of time step (default 1000ms)
20+
void setTimeStep(unsigned long timeStep);
21+
// Returns true when at set point (+-threshold)
22+
bool atSetPoint(double threshold);
23+
// Runs PID calculations when needed. Should be called repeatedly in loop.
24+
// Automatically reads input and sets output via pointers
25+
void run();
26+
// Stops PID functionality, output sets to
27+
void stop();
28+
void reset();
29+
bool isStopped();
30+
31+
private:
32+
double _Kp, _Ki, _Kd;
33+
double _integral, _previousError;
34+
double _bangOn, _bangOff;
35+
double *_input, *_setpoint, *_output;
36+
double _outputMin, _outputMax;
37+
unsigned long _timeStep, _lastStep;
38+
bool _stopped;
39+
40+
};//class AutoPID
41+
42+
class AutoPIDRelay : public AutoPID {
43+
public:
44+
45+
AutoPIDRelay(double *input, double *setpoint, bool *relayState, double pulseWidth, double Kp, double Ki, double Kd)
46+
: AutoPID(input, setpoint, &_pulseValue, 0, 1.0, Kp, Ki, Kd) {
47+
_relayState = relayState;
48+
_pulseWidth = pulseWidth;
49+
};
50+
51+
void run();
52+
53+
double getPulseValue();
54+
55+
private:
56+
bool * _relayState;
57+
unsigned long _pulseWidth, _lastPulseTime;
58+
double _pulseValue;
59+
};//class AutoPIDRelay
60+
61+
#endif

0 commit comments

Comments
 (0)