#include <PID_v1.h> //inkluderer PID-biblioteket
#include <Bounce.h> //inkluderer bounce biblioteket som gjør det enkelt å bruke trykk-knapper
//PID
double Setpoint, Input, Output, gap;
double aggKp=4, aggKi=0.2, aggKd=1;
double consKp=1, consKi=0.05, consKd=0.25;
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, REVERSE);
int hysteri = 1; //definerer dødsone mellom kjøling og varming
//VIFTESTYRING
float sensor0, sensor1, sensor2, sensor3; //oppretter sensorer
float temp0, temp1, temp2, temp3; //konvertert til Celsius
int fan1, fan2, fan3; //pwm-utganger for vifter
int heatsink1Delta, heatsink2Delta, heatsink3Delta; //mulig må være float
int selectedHeatsinkDelta; //mulig må være float
int targetSpeed; //mulig må være float
//Betjening
Bounce button0 = Bounce(0, 5);
Bounce button1 = Bounce(1, 5); //setter bounce tid på knapp 1 og 0 til 5ms
void setup() {
//Definer pinner
pinMode(0, INPUT_PULLUP);
pinMode(1, INPUT_PULLUP); //skrur på pullup resistors for trykknapper på pinne 1 og 0
pinMode(4, OUTPUT); //peltier PWM
pinMode(5, OUTPUT); //peltier relé
pinMode(9, OUTPUT); //fan1
pinMode(10, OUTPUT); //fan2
pinMode(12, OUTPUT); //fan3
//temp.sensorer pinne 18, 19, 20, 21
//PID
Input=20;
Setpoint=20;
myPID.SetMode(AUTOMATIC);
//Viftestyring
fan1=9;
fan2=10;
fan3=12;
//betjening
Serial.begin(38400);
}
void loop(){
//Betjening
button0.update();
button1.update();
if (button0.fallingEdge()) {
Setpoint --;
Serial.print("teermostaten er satt til: ");
Serial.println(Setpoint);
}
if (button1.fallingEdge()) {
Setpoint ++;
Serial.print("termostaten er satt til: ");
Serial.println(Setpoint);
}
//Hent temperaturer
sensor0 = analogRead(2); //leser pinne 2 og lagrer resultatet som sensor0
sensor1 = analogRead(3); //leser pinne 3 og lagrer resultatet som sensor1
sensor2 = analogRead(4); //leser pinne 4 og lagrer resultatet som sensor2
sensor3 = analogRead(5); //leser pinne 5 og lagrer resultatet som sensor3
temp0 = 25 + (sensor0 - 512) / 11.3; //konverterer til Celsius
temp1 = 25 + (sensor1 - 512) / 11.3; //konverterer til Celsius
temp2 = 25 + (sensor2 - 512) / 11.3; //konverterer til Celsius
temp3 = 25 + (sensor3 - 512) / 11.3; //konverterer til Celsius
//Viftestyring
heatsink1Delta = abs(temp1 - Setpoint); //avvik mellom termostatverdi og temp på kjøleribbe
heatsink2Delta = abs(temp2 - Setpoint);
heatsink3Delta = abs(temp3 - 20);
delay(50); //sjekk vifte1
selectedHeatsinkDelta = heatsink1Delta; //lagrer verdien av heatsink0Delta i selectedHeatsinkDelta
targetSpeed = constrain(selectedHeatsinkDelta*15, 100, 255); //definer viftehastighet for fan1
fanControl(fan1); //kaller opp funksjonen fanControl, og gir med verdien av fan1
delay(50); //sjekk vifte2
selectedHeatsinkDelta = heatsink2Delta;
targetSpeed = constrain(selectedHeatsinkDelta*15, 100, 255);
fanControl(fan2);
delay(50); //sjekk vifte3
selectedHeatsinkDelta = heatsink3Delta;
targetSpeed = constrain(selectedHeatsinkDelta*15, 100, 255);
fanControl(fan3);
//PID
Input = temp0;
gap = abs(Setpoint-Input); //distance away from setpoint
if(gap<3)
{ //we're close to setpoint, use conservative tuning parameters
myPID.SetTunings(consKp, consKi, consKd);
}
else
{//we're far from setpoint, use aggressive tuning parameters
myPID.SetTunings(aggKp, aggKi, aggKd);
}
if(temp0<Setpoint-hysteri){
myPID.SetControllerDirection(DIRECT);
myPID.Compute();
digitalWrite(5, HIGH); //bytt til varming)
analogWrite(4,Output);
}
else if(temp0>Setpoint+hysteri){
myPID.SetControllerDirection(REVERSE);
myPID.Compute();
digitalWrite(5, LOW); //bytt til varming)
analogWrite(4,Output);
}
else{
myPID.Compute();
analogWrite(4,Output);
}
}
void fanControl(int selectedFan) { //kjører funksjonen fanControl, og navngir variablen sendt i kallet "selectedFan"
if (selectedHeatsinkDelta <= 3){
analogWrite(selectedFan, 0); // vifte av. Skalaen går fra 0 til 255
}
if (selectedHeatsinkDelta > 3){
analogWrite(selectedFan, targetSpeed);
}
}