Skip to content
Snippets Groups Projects
Commit c54a39d6 authored by Pico2's avatar Pico2
Browse files

Merge branch 'master' of git.rwth-aachen.de:nloqo/arduino-sketches

parents ca8b31a2 fc5d1e4f
No related branches found
No related tags found
No related merge requests found
# 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
......
......@@ -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 = 30; //program cycle period in s
const unsigned long cyclePeriod = 1000; //program cycle period in ms
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 = 1000;
PIDKp = 1;
}
EEPROM.get(2 * floatsize, PIDKi);
if ( isnan(PIDKi)){
PIDKi = 1;
PIDKi = 0.001;
}
EEPROM.get(3 * floatsize, integral);
if ( isnan(integral) || integral < 0 || integral > 1000 ){
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("ms, ");
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 ( millis() >= nextCycle ){
if ( micros() >= nextCycle ){
if (controller > 0){
calculatePID();
}
nextCycle += cyclePeriod * 1000;
nextCycle += cycle_period_us;
}
// stop the pulse, if pulse length elapsed
if ( millis() >= nextOff && nextOff > 0){
if ( micros() >= 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 (millis() > 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 (micros() > 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 1000
// calculate integral part, clamp it between 0 and 1
integral += PIDKi * error;
if (integral > 1000){
integral = 1000;
if (integral > 1){
integral = 1;
}
else if (integral < 0){
integral = 0;
}
// caclulate the duty cycle, clamp it between 0 and 1000
// calculate 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 = millis() + cyclePeriod * duty_cycle;
nextOff = micros() + cycle_period_us * duty_cycle;
enable_control( true );
}
if (duty_cycle > 1000){
duty_cycle = 1000;
}
}
void enable_control(const boolean enabled){
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment