Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
Arduino Sketches
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
NLOQO
Arduino Sketches
Commits
fc5d1e4f
Commit
fc5d1e4f
authored
Jul 2, 2024
by
Myres
Browse files
Options
Downloads
Patches
Plain Diff
Improve TemperatureController for short duty cycles.
parent
016cdc0a
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
TemperatureController/CHANGELOG.md
+11
-0
11 additions, 0 deletions
TemperatureController/CHANGELOG.md
TemperatureController/TemperatureController.ino
+29
-26
29 additions, 26 deletions
TemperatureController/TemperatureController.ino
with
40 additions
and
26 deletions
TemperatureController/CHANGELOG.md
+
11
−
0
View file @
fc5d1e4f
# CHANGELOG
## 2.0.0
_PID calculation changed to fraction, for upgrade reduce PID factors (Kp, Ki) by factor 1000._
### Changed
*
Duty cycle is fraction of period instead per mille.
*
Cycle period unit is ms instead of second, allowing 1 ms duty cycle.
*
Duty cycle time resolution is µs instead of ms.
## 1.4.0
### Added
...
...
This diff is collapsed.
Click to expand it.
TemperatureController/TemperatureController.ino
+
29
−
26
View file @
fc5d1e4f
...
...
@@ -12,9 +12,9 @@
*/
//** CONSTANTS PARAMETERS change for your application **//
const
String
version
=
"
1.4
.0"
;
// Version of this script. Filename is added before, date of compilation afterwards.
const
String
version
=
"
2.0
.0"
;
// Version of this script. Filename is added before, date of compilation afterwards.
const
int
cyclePeriod
=
3
0
;
//program cycle period in s
const
unsigned
long
cyclePeriod
=
100
0
;
//program cycle period in
m
s
const
int
controlPin
=
11
;
//Pin by which the control unit is controlled (11 or 12)
const
int
secondaryControlPin
=
-
1
;
// Secondary Pin to control output (or -1)
...
...
@@ -40,13 +40,15 @@ const int redLedPin = 4; //Pin for a red LED
const
int
errorPin
=
7
;
//Pin for a bright red warning LED
// ERROR indicator
const
int
errorCyclePeriod
=
2000
;
// Interval between two error indicators
const
int
errorCyclePeriod
=
2000
;
// Interval between two error indicators
in ms
const
int
errorOnTime
=
100
;
// How long the output is on (in ms) for a single blink
const
int
errorInterval
=
200
;
// Interval for the error blinks
// MISC
const
long
rolloverThreshold
=
4294965000
;
//After how many milliseconds should we suspend normal operation to await millis()-rollover?
// (Should be at least cyclePeriod+digitalPinSetDelay below the maximum value of an unsigned long of 4.294.967.295)
const
unsigned
long
cycle_period_us
=
cyclePeriod
*
1000
;
// for the µs counter
const
unsigned
long
max_ulong
=
-
1
;
// maximum value of unsigned long needed for rollover detection
const
float
duty_cycle_upper_limit
=
1.05
;
// what the duty cycle should be at most. Should be more than 1 for continuous control
const
unsigned
long
rolloverThreshold
=
max_ulong
-
cycle_period_us
*
duty_cycle_upper_limit
*
1.5
;
// when the rollover protection should kick in.
// ********************************************************************************
...
...
@@ -88,7 +90,7 @@ float setpoint; // setpoint for the temperature = 36°C
float
PIDKp
;
//Wert für die PID Regelung (Proportional-Teil)
float
PIDKi
;
//Wert für die PID Regelung (Integral-Teil)
float
integral
;
//Wert für die PID Integralteil
float
duty_cycle
;
//Current duty cycle
in per mille
float
duty_cycle
;
//Current duty cycle
as fraction of cycle period
int
controller
=
1
;
// controller mode: 0 = off, 1 = on
int
error
=
0
;
// current error code
...
...
@@ -118,15 +120,15 @@ void setup() {
}
EEPROM
.
get
(
1
*
floatsize
,
PIDKp
);
if
(
isnan
(
PIDKp
)){
PIDKp
=
1
000
;
PIDKp
=
1
;
}
EEPROM
.
get
(
2
*
floatsize
,
PIDKi
);
if
(
isnan
(
PIDKi
)){
PIDKi
=
1
;
PIDKi
=
0.00
1
;
}
EEPROM
.
get
(
3
*
floatsize
,
integral
);
if
(
isnan
(
integral
)
||
integral
<
0
||
integral
>
1
000
){
integral
=
100
;
if
(
isnan
(
integral
)
||
integral
<
0
||
integral
>
1
){
integral
=
0.1
;
}
}
...
...
@@ -253,7 +255,7 @@ void loop(){
case
'x'
:
// Parameters, name TBD
Serial
.
print
(
"cyclePeriod: "
);
Serial
.
print
(
cyclePeriod
);
Serial
.
print
(
"s, "
);
Serial
.
print
(
"
m
s, "
);
Serial
.
print
(
"controlPin: "
);
Serial
.
print
(
controlPin
);
Serial
.
print
(
", "
);
...
...
@@ -280,15 +282,15 @@ void loop(){
}
// Start new pulse, calculating the duty cycle and pulse length
if
(
mi
lli
s
()
>=
nextCycle
){
if
(
mi
cro
s
()
>=
nextCycle
){
if
(
controller
>
0
){
calculatePID
();
}
nextCycle
+=
cycle
P
eriod
*
1000
;
nextCycle
+=
cycle
_p
eriod
_us
;
}
// stop the pulse, if pulse length elapsed
if
(
mi
lli
s
()
>=
nextOff
&&
nextOff
>
0
){
if
(
mi
cro
s
()
>=
nextOff
&&
nextOff
>
0
){
enable_control
(
false
);
}
...
...
@@ -298,10 +300,10 @@ void loop(){
nextError
=
millis
()
+
errorCyclePeriod
;
}
//if we are within
2300ms
of rollover of
millis
counter suspend normal operation
if
(
mi
lli
s
()
>
rolloverThreshold
){
nextCycle
=
cyclePeriod
*
1000
;
//set everything for continuing normal operation after rollover
while
(
millis
()
>
rolloverThreshold
){};
//wait for rollover to happen
//if we are within
cycle_period
of rollover of counter suspend normal operation
if
(
mi
cro
s
()
>
rolloverThreshold
){
while
(
micros
()
>
rolloverThreshold
){};
//wait for rollover to happen
nextCycle
=
0
;
// continue normally after rollover
};
}
...
...
@@ -346,17 +348,21 @@ void calculatePID(){
// Calculate the PID signal and duty cycle, and start a new pulse
float
error
=
setpoint
-
average0
.
getAverage
();
// calculate integral part, clamp it between 0 and 1
000
// calculate integral part, clamp it between 0 and 1
integral
+=
PIDKi
*
error
;
if
(
integral
>
1
000
){
integral
=
1
000
;
if
(
integral
>
1
){
integral
=
1
;
}
else
if
(
integral
<
0
){
integral
=
0
;
}
// ca
c
lulate the duty cycle, clamp it between 0 and 1
000
// cal
c
ulate the duty cycle, clamp it between 0 and 1
duty_cycle
=
PIDKp
*
error
+
integral
;
// limit duty cycle against overflow
if
(
duty_cycle
>
duty_cycle_upper_limit
){
duty_cycle
=
duty_cycle_upper_limit
;
}
if
(
duty_cycle
<
0
){
nextOff
=
0
;
duty_cycle
=
0
;
...
...
@@ -364,12 +370,9 @@ void calculatePID(){
}
else
{
// start a new pulse and set the pulse length
nextOff
=
mi
lli
s
()
+
cycle
P
eriod
*
duty_cycle
;
nextOff
=
mi
cro
s
()
+
cycle
_p
eriod
_us
*
duty_cycle
;
enable_control
(
true
);
}
if
(
duty_cycle
>
1000
){
duty_cycle
=
1000
;
}
}
void
enable_control
(
const
boolean
enabled
){
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment