From 0b8e4d3a5c86c4692087c7644e474f1da8e50e48 Mon Sep 17 00:00:00 2001 From: fliegerjohn Date: Wed, 24 Apr 2024 12:32:34 +0200 Subject: [PATCH] Add PID. --- firmware/weckkubator/weckkubator.ino | 104 +++++++++++++++++++++------ 1 file changed, 84 insertions(+), 20 deletions(-) diff --git a/firmware/weckkubator/weckkubator.ino b/firmware/weckkubator/weckkubator.ino index 2c4997b..1a48d32 100644 --- a/firmware/weckkubator/weckkubator.ino +++ b/firmware/weckkubator/weckkubator.ino @@ -2,28 +2,67 @@ #include // Support for PCF8574 --> LCD #include // 1-Wiresupport for DS18B20 #include // Easy reading of DS18B20 +#include // PID-Controller #define ONE_WIRE_BUS 10 // Enable 1-Wirebus on digital 10 (PB2 - Pin16) +#define fan 8 +#define wecktopf 9 LiquidCrystal_I2C lcd(0x3F,20,4); // declare LCD OneWire oneWire(ONE_WIRE_BUS); // declare 1-Wirebus DallasTemperature sensors(&oneWire); // declare sensors -float tempset; -float watertemp; +// Define variables PID is connected to +double pidset, watertemp, output; + +// PID adjustment +double Kp=2, Ki=5, Kd=1; +PID myPID(&watertemp, &output, &pidset, Kp, Ki, Kd, DIRECT); +int WindowSize = 5000; +unsigned long windowStartTime; + +// Temp adjustment +int tempset; int poti; +// time +int onesecond = 1000; +unsigned long previousMillis; + + +// °C for LCD +byte customChar[8] = { + 0b01110, + 0b01010, + 0b01010, + 0b01110, + 0b00000, + 0b00000, + 0b00000, + 0b00000 +}; + void setup() { + // Setup GPIO - pinMode(9, OUTPUT); // Output "Wecktopf" - pinMode(8, OUTPUT); // Fan + pinMode(wecktopf, OUTPUT); // Output "Wecktopf" + pinMode(fan, OUTPUT); // Fan + // Setup sensors sensors.begin(); + // Setup I2C-LCD lcd.init(); lcd.backlight(); lcd.clear(); + lcd.createChar(0, customChar); lcd.setCursor(1, 0); + + // Setup PID + windowStartTime = millis(); + myPID.SetOutputLimits(0, WindowSize); //tell the PID to range between 0 and the full window size + myPID.SetMode(AUTOMATIC); //turn the PID on + // Greetings lcd.print("Weckkubator 0.0.1"); delay(3000); @@ -32,23 +71,34 @@ void setup() { } void loop() { - // - settemp(); - readtemp(); - lcdoutput(); - delay(100); - - if (tempset >= watertemp) { - digitalWrite(9, HIGH); + // run pid + pid(); - + // update LCD + unsigned long currentMillis = millis(); + if (currentMillis - previousMillis >= onesecond) { + settemp(); + readtemp(); + lcdoutput(); } - else { - digitalWrite(9, LOW); +} +//------------------------------------------ +// PID-Controller +void pid() { + + myPID.Compute(); + + /************************************************ + * turn the output pin on/off based on pid output + ************************************************/ + if (millis() - windowStartTime > WindowSize) + { //time to shift the Relay Window + windowStartTime += WindowSize; } - + if (output < millis() - windowStartTime) digitalWrite(wecktopf, LOW); + else digitalWrite(wecktopf, HIGH); } //------------------------------------------ @@ -68,18 +118,32 @@ void readtemp() { void lcdoutput() { // Output temperatureset lcd.setCursor(0, 1); - lcd.print("s:"); + lcd.print("set: "); lcd.print(tempset); + lcd.write((byte)0); + lcd.print("C"); // Output watertemp - lcd.setCursor(9, 1); - lcd.print("t:"); + lcd.setCursor(0, 2); + lcd.print("temp: "); lcd.print(watertemp); + lcd.write((byte)0); + lcd.print("C"); + lcd.print(" "); + + // output PID + lcd.setCursor (0, 3); + lcd.print("output: "); + lcd.print(output); + lcd.print(" "); + } + //------------------------------------------ // Read Poti void settemp() { poti = analogRead(A3); - tempset = (18+(poti*0.05)); + tempset = (18+(poti*0.07)); // range between 18°C and 18+1024*0,07 (~89°C) + pidset = tempset; }