Skip to content

Commit 95def29

Browse files
author
David Forrest
committed
Add PID_simulated_heater.ino
1 parent ea92f8a commit 95def29

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/********************************************************
2+
PID Basic simulated heater Example
3+
Reading analog input 0 to control analog PWM output 3
4+
********************************************************/
5+
// This simulates a 20W heater block driven by the PID
6+
// Vary the setpoint with the Pot, and watch the heater drive the temperature up
7+
//
8+
// Code at https://wokwi.com/projects/357409124554569729
9+
//
10+
// Based on
11+
// Wokwi https://wokwi.com/projects/357374218559137793
12+
// Wokwi https://wokwi.com/projects/356437164264235009
13+
14+
//#include <PID_v1.h> // https://github.com/br3ttb/Arduino-PID-Library
15+
#include <PID_v1_bc.h> // https://github.com/drf5n/Arduino-PID-Library
16+
17+
//Define Variables we'll be connecting to
18+
double Setpoint, Input, Output;
19+
20+
//Specify the links and initial tuning parameters
21+
//double Kp = 17, Ki = .1, Kd = 2; // works reasonably with sim heater block
22+
//double Kp = 255, Ki = .0, Kd = 0; // works reasonably with sim heater block
23+
double Kp = 2, Ki = 5, Kd = 1; // commonly used defaults
24+
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, P_ON_E, DIRECT);
25+
26+
const int PWM_PIN = 3; // UNO PWM pin
27+
const int INPUT_PIN = -1; // Analog pin for Input (set <0 for simulation)
28+
const int SETPOINT_PIN = A1; // Analog pin for Setpoint Potentiometer
29+
const int SETPOINT_INDICATOR = 6; // PWM pin for indicating setpoint
30+
const int INPUT_INDICATOR = 5; // PWM pin for indicating Input
31+
32+
void setup()
33+
{
34+
Serial.begin(115200);
35+
Serial.println(__FILE__);
36+
myPID.SetOutputLimits(0, 255);
37+
if (SETPOINT_INDICATOR >= 0) pinMode(SETPOINT_INDICATOR, OUTPUT);
38+
if (INPUT_INDICATOR >= 0) pinMode(INPUT_INDICATOR, OUTPUT);
39+
Setpoint = 0;
40+
//turn the PID on
41+
myPID.SetMode(AUTOMATIC);
42+
if(INPUT_PIN>0){
43+
Input = analogRead(INPUT_PIN);
44+
}else{
45+
Input = simPlant(0); // simulate heating
46+
}
47+
Serial.println("Setpoint Input Output Watts");
48+
}
49+
50+
void loop()
51+
{
52+
// gather Input from INPUT_PIN or simulated block
53+
float heaterWatts = (int)Output * 20.0 / 255; // 20W heater
54+
if (INPUT_PIN > 0 ) {
55+
Input = analogRead(INPUT_PIN);
56+
} else {
57+
float blockTemp = simPlant(heaterWatts); // simulate heating
58+
Input = blockTemp; // read input from simulated heater block
59+
}
60+
61+
if (myPID.Compute())
62+
{
63+
analogWrite(PWM_PIN, (int)Output);
64+
65+
Setpoint = analogRead(SETPOINT_PIN) / 4; // Read setpoint from potentiometer
66+
if (INPUT_INDICATOR >= 0) analogWrite(INPUT_INDICATOR, Input);
67+
if (SETPOINT_INDICATOR >= 0) analogWrite(SETPOINT_INDICATOR, Setpoint);
68+
}
69+
report();
70+
}
71+
72+
void report(void)
73+
{
74+
static uint32_t last = 0;
75+
const int interval = 1000;
76+
if (millis() - last > interval) {
77+
last += interval;
78+
// Serial.print(millis()/1000.0);
79+
Serial.print(Setpoint);
80+
Serial.print(' ');
81+
Serial.print(Input);
82+
Serial.print(' ');
83+
Serial.print(Output);
84+
Serial.print(' ');
85+
Serial.println(20.0 * (int)Output/255);
86+
}
87+
}
88+
89+
float simPlant(float Q) { // heat input in W (or J/s)
90+
// simulate a 1x1x2cm aluminum block with a heater and passive ambient cooling
91+
// float C = 237; // W/mK thermal conduction coefficient for Al
92+
float h = 5 ; // W/m2K thermal convection coefficient for Al passive
93+
float Cps = 0.89; // J/g°C
94+
float area = 1e-4; // m2 area for convection
95+
float mass = 10 ; // g
96+
float Tamb = 25; // °C
97+
static float T = Tamb; // °C
98+
static uint32_t last = 0;
99+
uint32_t interval = 100; // ms
100+
101+
if (millis() - last >= interval) {
102+
last += interval;
103+
// 0-dimensional heat transfer
104+
T = T + Q * interval / 1000 / mass / Cps - (T - Tamb) * area * h;
105+
}
106+
return T;
107+
}
108+

0 commit comments

Comments
 (0)