Skip to content

Commit 299ce37

Browse files
committed
Update PID_RelayOutput.ino
1 parent 44fa110 commit 299ce37

File tree

1 file changed

+54
-53
lines changed

1 file changed

+54
-53
lines changed
Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,68 @@
1-
/*************************************************************
2-
PID Relay Output Example
3-
Same as basic example, except that this time, the output
4-
is going to a digital pin which (we presume) is controlling
5-
a relay. The pid is designed to Output an analog value,
6-
but the relay can only be On/Off.
1+
/****************************************************************************
2+
PID Relay Output Example
3+
https://github.com/Dlloydev/QuickPID/tree/master/examples/PID_RelayOutput
74
8-
To connect them together we use "time proportioning
9-
control", essentially a really slow version of PWM.
10-
First we decide on a window size (5000mS for example).
11-
We then set the pid to adjust its output between 0 and that
12-
window size. Lastly, we add some logic that translates the
13-
PID output into "Relay On Time" with the remainder of the
14-
window being "Relay Off Time". The minWindow setting is a
15-
floor (minimum time) the relay would be on.
16-
*************************************************************/
5+
Similar to basic example, except the output is a digital pin controlling
6+
a mechanical relay, SSR, MOSFET or other device. To interface the PID output
7+
to a digital pin, we use "time proportioning control" (software PWM).
8+
First we decide on a window size (5000mS for example). We then set the pid
9+
to adjust its output between 0 and that window size and finally we set the
10+
PID sample time to that same window size.
1711
18-
#include "QuickPID.h"
12+
The digital output has the following features:
13+
• The PID compute rate controls the rate of updating the digital output
14+
• All transitions are debounced (rising and falling)
15+
• Full control range (0 to windowSize) isn't limited by debounce
16+
• Only one call to digitalWrite() per transition
17+
*****************************************************************************/
1918

20-
#define PIN_INPUT 0
21-
#define RELAY_PIN 6
19+
#include <QuickPID.h>
2220

23-
//Define Variables we'll be connecting to
24-
float Setpoint, Input, Output;
21+
// pins
22+
const byte inputPin = 0;
23+
const byte relayPin = 3;
2524

26-
//Specify the links and initial tuning parameters
27-
float Kp = 2, Ki = 5, Kd = 1;
25+
// user settings
26+
const unsigned long windowSize = 5000;
27+
const byte debounce = 50;
28+
float Input, Output, Setpoint = 30, Kp = 2, Ki = 5, Kd = 1;
2829

29-
QuickPID myPID(&Input, &Output, &Setpoint);
30+
// status
31+
unsigned long windowStartTime, nextSwitchTime;
32+
boolean relayStatus = false;
3033

31-
unsigned int WindowSize = 5000;
32-
unsigned int minWindow = 500;
33-
unsigned long windowStartTime;
34+
QuickPID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd,
35+
myPID.pMode::pOnError,
36+
myPID.dMode::dOnMeas,
37+
myPID.iAwMode::iAwClamp,
38+
myPID.Action::direct);
3439

35-
void setup()
36-
{
37-
pinMode(RELAY_PIN, OUTPUT);
38-
windowStartTime = millis();
39-
40-
//initialize the variables we're linked to
41-
Setpoint = 100;
42-
43-
//tell the PID to range between 0 and the full window size
44-
myPID.SetOutputLimits(0, WindowSize);
45-
46-
//apply PID gains
47-
myPID.SetTunings(Kp, Ki, Kd);
48-
49-
//turn the PID on
40+
void setup() {
41+
pinMode(relayPin, OUTPUT);
42+
pinMode(LED_BUILTIN, OUTPUT);
43+
myPID.SetOutputLimits(0, windowSize);
44+
myPID.SetSampleTimeUs(windowSize * 1000);
5045
myPID.SetMode(myPID.Control::automatic);
5146
}
5247

53-
void loop()
54-
{
55-
Input = analogRead(PIN_INPUT);
48+
void loop() {
49+
unsigned long msNow = millis();
50+
Input = analogRead(inputPin);
51+
if (myPID.Compute()) windowStartTime = msNow;
5652

57-
/************************************************
58-
turn the output pin on/off based on pid output
59-
************************************************/
60-
if (millis() - windowStartTime >= WindowSize)
61-
{ //time to shift the Relay Window
62-
windowStartTime += WindowSize;
63-
myPID.Compute();
53+
if (!relayStatus && Output > (msNow - windowStartTime)) {
54+
if (msNow > nextSwitchTime) {
55+
nextSwitchTime = msNow + debounce;
56+
relayStatus = true;
57+
digitalWrite(relayPin, HIGH);
58+
digitalWrite(LED_BUILTIN, HIGH);
59+
}
60+
} else if (relayStatus && Output < (msNow - windowStartTime)) {
61+
if (msNow > nextSwitchTime) {
62+
nextSwitchTime = msNow + debounce;
63+
relayStatus = false;
64+
digitalWrite(relayPin, LOW);
65+
digitalWrite(LED_BUILTIN, LOW);
66+
}
6467
}
65-
if (((unsigned int)Output > minWindow) && ((unsigned int)Output > (millis() - windowStartTime))) digitalWrite(RELAY_PIN, HIGH);
66-
else digitalWrite(RELAY_PIN, LOW);
6768
}

0 commit comments

Comments
 (0)