Browse Source

temperature control improvements

master
Barb 10 months ago
parent
commit
d1ddac8faf
3 changed files with 1170 additions and 1109 deletions
  1. +49
    -22
      PyCoffeeNano/PyCoffeeNano.ino
  2. +561
    -544
      PyCoffeeNano/PyCoffeeNano.ino.eightanaloginputs.hex
  3. +560
    -543
      PyCoffeeNano/PyCoffeeNano.ino.with_bootloader.eightanaloginputs.hex

+ 49
- 22
PyCoffeeNano/PyCoffeeNano.ino View File

@ -27,6 +27,7 @@ const int milliseconds = 10;
int timeratio = 1;
// pumpRatio is = seconds to pump water for and will be updated over serial
int pumpRatio = 15; // warning: there is usually ~5s dead time from pump startup to water flowing out of nozzle
int pumpStatus = 0; // support variable to enable pumping while heating, added feb 24
// This next variable is used to get current "time" in ms and break out of while cycles that need a time limit safeguard
unsigned long startTime;
unsigned long pMillis;
@ -257,6 +258,7 @@ void Heat() {
delay(100);
Serial.print(desiredTemp);
delay(100);
// initialize variables at safe values
Tc = 0; // current temperature
Tp = -10; // temperature at previous cycle
Tstart = - 100; // temperature at start of Heat() function
@ -268,38 +270,38 @@ void Heat() {
Vo = analogRead(tempSensorPin);
R2 = R1 * (1023.0 / (float)Vo - 1.0);
logR2 = log(R2);
T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
Tc = (T - 273.15);
T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2)); // compute temperature from NTC
Tc = (T - 273.15); // convert from Kelvin to Celsius for readability
if (millis() - startTime == 1000) {
if (millis() - startTime > 500 && millis() - startTime < 1500) {
Tstart = Tc; // support variable to store temp at beginning, so that we can be sure it's increasing
delay(1001); // make sure we only set startTime once!
}
// check if temperature is within the acceptable range and break out of the loop without error if done heating:
if (Tc > desiredTemp) {
// temperature is within range, so break out of the loop:
if (Tc > desiredTemp && pumpStatus == 0) {
delay(100);
Serial.write("reached desired temp\n");
delay(100);
Serial.print(Tc);
break;
break; // temperature is within range, break out of the loop:
}
if (Tc < -100) {
if (Tc < -100) { // break the loop if temperature < -100, can only happen if cable gets unplugged
delay(100);
Serial.write("u-Thermocouple: unplugged or failed\n");
unrecoverableErr = 1;
break;
}
if (millis() - startTime > 20000 && Tc - Tstart < 1) {
if (millis() - startTime > 20000 && Tc - Tstart < 1 && pumpStatus == 0) { // break the loop if temperature is not increasing
delay(100);
Serial.write("p-Thermocouple: positioning or relay fault\n");
Serial.write("p-Thermocouple: not detecting heating, positioning or relay fault\n");
unrecoverableErr = 1;
break;
}
if (millis() - startTime > 60000) {
if (millis() - startTime > 90000 && pumpStatus == 0) { // break out of the loop after 60s if the boiler is not yet hot
delay(100);
Serial.write("h-taking too long, continuing...\n");
break;
@ -309,12 +311,19 @@ void Heat() {
// check aprox. derivative every second and shut off heater if temperature is increasing too quickly!
// conversely, heater is turned on if temperature is not incresing quickly enough
if (millis() > (pMillis + 1000)){
if (Tc < (desiredTemp - 20)) {
// initially run the heater on fully. eg: if we set the number to 30 and start with
// Tambient = 20C and desiredTemp = 90 the heater will stay fully on until 90-30 = 60C
//if (Tc < (desiredTemp - 30)) { // old if with variable temp
// new if with hard-coded minimum pulsing enable temperature of 70C
if (Tc < 70 || Tc < (desiredTemp - 20)) {
digitalWrite(boilerPin, HIGH);
}
else if ((Tc - Tp) < 0.5) {
// change this value for proportional behaviour: lower values will cycle the relay more often.
// Cycling often reduces temperature undershoot, but will shorten contact lifespan
else if ((Tc - Tp) < 0.6) {
digitalWrite(boilerPin, HIGH);
}
@ -324,6 +333,20 @@ void Heat() {
else {
digitalWrite(boilerPin, LOW);
// delay(1000); // extra 1s delay to keep boiler off for 2s total (delay + millis())
}
// this next if lets us call us for pumping while still monitoring heat
if (pumpStatus == 1 && ((millis() - startTime)/1000) < pumpRatio) {
digitalWrite(pumpPin, HIGH);
}
else if (pumpStatus == 1 && ((millis() - startTime)/1000) > pumpRatio) {
digitalWrite(pumpPin, LOW);
break;
}
else {
//digitalWrite(pumpPin, LOW);
//pumpStatus = 0;
}
Tp = Tc;
@ -414,12 +437,15 @@ void Pump() {
digitalWrite(greenLED, LOW);
delay(100);
Serial.write("pumping Water...\n");
digitalWrite(pumpPin, HIGH);
while (pumpRatio > 1) {
pumpRatio--;
delay(1000);
}
digitalWrite(pumpPin, LOW);
pumpStatus = 1; // set pumpStatus variable to 1 to tell Heat() function to pump
Heat(); // call Heat function with current parameters
pumpStatus = 0; // set pumpStatus variable to 0
//digitalWrite(pumpPin, HIGH);
//while (pumpRatio > 1) {
// pumpRatio--;
// delay(1000);
//}
//digitalWrite(pumpPin, LOW);
delay(100);
Serial.write("Pumping water done\n");
digitalWrite(greenLED, HIGH);
@ -434,7 +460,7 @@ void makeCoffee() {
// care must be taken to place these functions earlier in the code, or the compiler will rightfully freak out
while (true) {
desiredTemp = 85;
desiredTemp = 80;
Heat(); // First we pre-heat the boiler
if (unrecoverableErr == 1) {
break;
@ -491,7 +517,7 @@ void makeCoffee() {
break;
}
desiredTemp = 95;
desiredTemp = 90;
Heat(); // First we pre-heat the boiler
if (unrecoverableErr == 1) {
break;
@ -500,6 +526,7 @@ void makeCoffee() {
if (dry == 0) {
//digitalWrite(boilerPin, HIGH);
delay(100);
desiredTemp = 95; // temperature to try and maintain while making coffee
Pump(); // Pump ratio (in seconds) will be read from serial input in final release
digitalWrite(boilerPin, LOW);
}


+ 561
- 544
PyCoffeeNano/PyCoffeeNano.ino.eightanaloginputs.hex
File diff suppressed because it is too large
View File


+ 560
- 543
PyCoffeeNano/PyCoffeeNano.ino.with_bootloader.eightanaloginputs.hex
File diff suppressed because it is too large
View File


Loading…
Cancel
Save