From 033ca031be2a04502449b055bfde3e05a5101d9f Mon Sep 17 00:00:00 2001 From: Minos Park Date: Thu, 29 Jul 2021 15:52:24 -0700 Subject: [PATCH 01/11] display correct unit, show time-on minutes --- controller/controller.ino | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/controller/controller.ino b/controller/controller.ino index 61eb183..8acf709 100644 --- a/controller/controller.ino +++ b/controller/controller.ino @@ -124,13 +124,18 @@ void loop() { lcd.setCursor(0,0); lcd.print("Temp: "); - lcd.print(current_temp); + lcd.print(USE_CELCIUS ? current_temp : toFahrenheit(current_temp)); lcd.print(USE_CELCIUS ? "C.": "F."); lcd.setCursor(0,1); - lcd.print("Time left: "); + lcd.print("Time left (min): "); unsigned long time_left_min = (CURE_NOMINAL_HOURS_MINIMUM * 1000 * 3600 - (millis() - setpoint_reached_timestamp)) / (60 * 1000); lcd.print(time_left_min); + + lcd.setCursor(0,2); + lcd.print("Time on (min): "); + unsigned long time_on_min = millis() / (60 * 1000); + lcd.print(time_on_min); } // Delay the loop for human readable debugging From 413b0bb338722b462791a927f78860c0dc3928c3 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Thu, 29 Jul 2021 15:56:40 -0700 Subject: [PATCH 02/11] update lcd only once per sec --- controller/controller.ino | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/controller/controller.ino b/controller/controller.ino index 8acf709..ae15bd2 100644 --- a/controller/controller.ino +++ b/controller/controller.ino @@ -55,6 +55,7 @@ float prev_temp; unsigned long prev_meas_timestamp = 0; unsigned long last_heat_adjustment_timestamp = 0; unsigned long setpoint_reached_timestamp = 0; +unsigned long last_lcd_update_timestamp = 0; bool update_setpoint_timestamp; long votes_for_heat = 0; @@ -118,7 +119,7 @@ void loop() { } unsigned long current_meas_timestamp = millis(); - if (LCD_PRESENT) { + if (LCD_PRESENT && (current_meas_timestamp - last_lcd_update_timestamp > 1000)) { // Refresh the LCD screen lcd.clear(); // Clear the screen @@ -136,6 +137,8 @@ void loop() { lcd.print("Time on (min): "); unsigned long time_on_min = millis() / (60 * 1000); lcd.print(time_on_min); + + last_lcd_update_timestamp = current_meas_timestamp; } // Delay the loop for human readable debugging From b9c4ff700816a4dbc83fd636e1da9a621bb66e0d Mon Sep 17 00:00:00 2001 From: Minos Park Date: Thu, 29 Jul 2021 19:57:56 -0700 Subject: [PATCH 03/11] ensure floating point division --- controller/controller.ino | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/controller/controller.ino b/controller/controller.ino index ae15bd2..2dd4c63 100644 --- a/controller/controller.ino +++ b/controller/controller.ino @@ -80,7 +80,7 @@ void setup() { lcd.clear(); } - prev_temp = (t1.read() + t2.read() + t3.read() + t4.read() + t5.read()) / THERMOCOUPLE_COUNT; + prev_temp = (t1.read() + t2.read() + t3.read() + t4.read() + t5.read()) / (1.0 * THERMOCOUPLE_COUNT); prev_meas_timestamp = millis(); update_setpoint_timestamp = true; last_heat_adjustment_timestamp = millis(); @@ -113,7 +113,7 @@ void loop() { } // For now, we'll average all the temp readings - float current_temp = (t1.read() + t2.read() + t3.read() + t4.read() + t5.read()) / THERMOCOUPLE_COUNT; + float current_temp = (t1.read() + t2.read() + t3.read() + t4.read() + t5.read()) / (1.0 * THERMOCOUPLE_COUNT); if (!USE_CELCIUS) { current_temp = toCelcius(current_temp); } @@ -130,12 +130,12 @@ void loop() { lcd.setCursor(0,1); lcd.print("Time left (min): "); - unsigned long time_left_min = (CURE_NOMINAL_HOURS_MINIMUM * 1000 * 3600 - (millis() - setpoint_reached_timestamp)) / (60 * 1000); + unsigned long time_left_min = (CURE_NOMINAL_HOURS_MINIMUM * 1000 * 3600 - (millis() - setpoint_reached_timestamp)) / (60.0 * 1000); lcd.print(time_left_min); lcd.setCursor(0,2); lcd.print("Time on (min): "); - unsigned long time_on_min = millis() / (60 * 1000); + unsigned long time_on_min = millis() / (60.0 * 1000); lcd.print(time_on_min); last_lcd_update_timestamp = current_meas_timestamp; @@ -179,12 +179,12 @@ void loop() { // Controller Logic // Evaluate the rate of change in temperature between now and the previous measurement - double temperature_change_rate = (current_temp - prev_temp) / (current_meas_timestamp - prev_meas_timestamp); + double temperature_change_rate = (current_temp - prev_temp) / (1.0 * (current_meas_timestamp - prev_meas_timestamp)); if (!DO_POSTCURING) { // Initial curing mode - if (temperature_change_rate <= (MAX_CURE_DESIRED_TEMP_C_INCREASE_RATE_PER_MIN / (60 * 1000)) && - current_temp < (CURE_NOMINAL_TEMP_C_CEILING + CURE_NOMINAL_TEMP_C_FLOOR)/2) { + if (temperature_change_rate <= (MAX_CURE_DESIRED_TEMP_C_INCREASE_RATE_PER_MIN / (60.0 * 1000)) && + current_temp < (CURE_NOMINAL_TEMP_C_CEILING + CURE_NOMINAL_TEMP_C_FLOOR)/2.0) { // Heat up vote votes_for_heat++; } @@ -195,7 +195,7 @@ void loop() { } else { // Postcuring mode - if (temperature_change_rate <= (MAX_POSTCURE_DESIRED_TEMP_C_INCREASE_RATE_PER_MIN / (60 * 1000))) { + if (temperature_change_rate <= (MAX_POSTCURE_DESIRED_TEMP_C_INCREASE_RATE_PER_MIN / (60.0 * 1000))) { // Heat up votes votes_for_heat++; } From 23ffd22d8a26774e3df5fb0b502897b851afe346 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Thu, 29 Jul 2021 20:06:33 -0700 Subject: [PATCH 04/11] set previous values --- controller/controller.ino | 3 +++ 1 file changed, 3 insertions(+) diff --git a/controller/controller.ino b/controller/controller.ino index 2dd4c63..c81846e 100644 --- a/controller/controller.ino +++ b/controller/controller.ino @@ -203,6 +203,9 @@ void loop() { votes_for_heat--; } } + + prev_temp = current_temp; + prev_meas_timestamp = current_meas_timestamp; } // TODO From afc635dffe872364cb7fa66629b76e79d9ff5414 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sat, 31 Jul 2021 16:56:01 -0700 Subject: [PATCH 05/11] slope adjustment --- controller/controller.ino | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/controller/controller.ino b/controller/controller.ino index c81846e..de9bc96 100644 --- a/controller/controller.ino +++ b/controller/controller.ino @@ -179,11 +179,11 @@ void loop() { // Controller Logic // Evaluate the rate of change in temperature between now and the previous measurement - double temperature_change_rate = (current_temp - prev_temp) / (1.0 * (current_meas_timestamp - prev_meas_timestamp)); + double temperature_change_rate = (current_temp - prev_temp) / (1.0 * (current_meas_timestamp/100.0 - prev_meas_timestamp/100.0)); if (!DO_POSTCURING) { // Initial curing mode - if (temperature_change_rate <= (MAX_CURE_DESIRED_TEMP_C_INCREASE_RATE_PER_MIN / (60.0 * 1000)) && + if (temperature_change_rate <= (MAX_CURE_DESIRED_TEMP_C_INCREASE_RATE_PER_MIN / (60.0 * 10)) && current_temp < (CURE_NOMINAL_TEMP_C_CEILING + CURE_NOMINAL_TEMP_C_FLOOR)/2.0) { // Heat up vote votes_for_heat++; @@ -195,7 +195,7 @@ void loop() { } else { // Postcuring mode - if (temperature_change_rate <= (MAX_POSTCURE_DESIRED_TEMP_C_INCREASE_RATE_PER_MIN / (60.0 * 1000))) { + if (temperature_change_rate <= (MAX_POSTCURE_DESIRED_TEMP_C_INCREASE_RATE_PER_MIN / (60.0 * 10))) { // Heat up votes votes_for_heat++; } @@ -210,4 +210,4 @@ void loop() { // TODO // implement postcuring cooldown mode -// All internal logic is in celcius -- only display to user is selectable \ No newline at end of file +// The logic needs improvement - integrator \ No newline at end of file From fe30711dc2c68c497278f219b638b1be804a7100 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sat, 31 Jul 2021 16:56:58 -0700 Subject: [PATCH 06/11] adjust lcd output --- controller/controller.ino | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/controller/controller.ino b/controller/controller.ino index de9bc96..8de6752 100644 --- a/controller/controller.ino +++ b/controller/controller.ino @@ -129,15 +129,16 @@ void loop() { lcd.print(USE_CELCIUS ? "C.": "F."); lcd.setCursor(0,1); - lcd.print("Time left (min): "); - unsigned long time_left_min = (CURE_NOMINAL_HOURS_MINIMUM * 1000 * 3600 - (millis() - setpoint_reached_timestamp)) / (60.0 * 1000); - lcd.print(time_left_min); - - lcd.setCursor(0,2); lcd.print("Time on (min): "); unsigned long time_on_min = millis() / (60.0 * 1000); lcd.print(time_on_min); + lcd.setCursor(0,2); + lcd.print("Time left (min): "); + long time_elapsed_since_setpoint_reached = millis() - setpoint_reached_timestamp; + long time_left_min = (CURE_NOMINAL_HOURS_MINIMUM * 1000 * 3600 - time_elapsed_since_setpoint_reached ) / (60.0 * 1000); + lcd.print(update_setpoint_timestamp ? 480 : time_left_min); + last_lcd_update_timestamp = current_meas_timestamp; } From ff7f6b96cdae90ff0681a5b9552492c2a8a637f8 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sat, 31 Jul 2021 16:57:50 -0700 Subject: [PATCH 07/11] disable default temp calib mode --- controller/controller.ino | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/controller/controller.ino b/controller/controller.ino index 8de6752..6aeb2e7 100644 --- a/controller/controller.ino +++ b/controller/controller.ino @@ -5,7 +5,7 @@ // Ensure Pin numbers are customized before flashing #define LCD_PRESENT true #define LCD_ADDRESS 0x27 -#define TEMP_CALIBRATION true +#define TEMP_CALIBRATION false #define DO_POSTCURING false #define HUMAN_DEBUGGING false #define THERMOCOUPLE_COUNT 5.0 @@ -129,16 +129,15 @@ void loop() { lcd.print(USE_CELCIUS ? "C.": "F."); lcd.setCursor(0,1); + lcd.print("Time left (min): "); + unsigned long time_left_min = (CURE_NOMINAL_HOURS_MINIMUM * 1000 * 3600 - (millis() - setpoint_reached_timestamp)) / (60.0 * 1000); + lcd.print(time_left_min); + + lcd.setCursor(0,2); lcd.print("Time on (min): "); unsigned long time_on_min = millis() / (60.0 * 1000); lcd.print(time_on_min); - lcd.setCursor(0,2); - lcd.print("Time left (min): "); - long time_elapsed_since_setpoint_reached = millis() - setpoint_reached_timestamp; - long time_left_min = (CURE_NOMINAL_HOURS_MINIMUM * 1000 * 3600 - time_elapsed_since_setpoint_reached ) / (60.0 * 1000); - lcd.print(update_setpoint_timestamp ? 480 : time_left_min); - last_lcd_update_timestamp = current_meas_timestamp; } From cd957e956a429b1a3ed8d99531ae7c95fd74ba2d Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sat, 31 Jul 2021 17:16:38 -0700 Subject: [PATCH 08/11] use arrays to hold thermocouple objects --- controller/controller.ino | 40 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/controller/controller.ino b/controller/controller.ino index 6aeb2e7..14f2c3b 100644 --- a/controller/controller.ino +++ b/controller/controller.ino @@ -8,7 +8,6 @@ #define TEMP_CALIBRATION false #define DO_POSTCURING false #define HUMAN_DEBUGGING false -#define THERMOCOUPLE_COUNT 5.0 #define USE_CELCIUS true #define HEATER_CTRL_PIN A1 @@ -27,14 +26,15 @@ // Setup the LCD Matrix LiquidCrystal_I2C lcd(LCD_ADDRESS,20,4); -// Setup the thermocouples, use Fahrenheit -// For now, use one thermocouple for ease of setup and testing +// Setup the thermocouples // Set the second argument to true if Celsius is desired. +#define THERMOCOUPLE_COUNT 5 Thermocouple t1(A0, USE_CELCIUS, 0.5); Thermocouple t2(A0, USE_CELCIUS, 0.5); Thermocouple t3(A0, USE_CELCIUS, 0.5); Thermocouple t4(A0, USE_CELCIUS, 0.5); Thermocouple t5(A0, USE_CELCIUS, 0.5); +Thermocouple thermocouples[THERMOCOUPLE_COUNT] = {t1, t2, t3, t4, t5}; // PID object params double dt = 0.1; // loop interval time @@ -91,32 +91,26 @@ void loop() { if (TEMP_CALIBRATION) { // Log the temperature to serial output // We'll save this to an output file on a companion computer - Serial.print("T1, "); - Serial.print(t1.read()); - Serial.println(USE_CELCIUS ? "C": "F"); - Serial.print("T2, "); - Serial.print(t2.read()); - Serial.println(USE_CELCIUS ? "C": "F"); - - Serial.print("T3, "); - Serial.print(t3.read()); - Serial.println(USE_CELCIUS ? "C": "F"); - - Serial.print("T4, "); - Serial.print(t4.read()); - Serial.println(USE_CELCIUS ? "C": "F"); - - Serial.print("T5, "); - Serial.print(t5.read()); - Serial.println(USE_CELCIUS ? "C": "F"); + for (int i=0;i 1000)) { From f68513eee6140f6872bfea9afd6f8bd23dffc388 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sat, 31 Jul 2021 17:43:13 -0700 Subject: [PATCH 09/11] adjust delay periods --- controller/controller.ino | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/controller/controller.ino b/controller/controller.ino index 14f2c3b..3d1d250 100644 --- a/controller/controller.ino +++ b/controller/controller.ino @@ -10,6 +10,7 @@ #define HUMAN_DEBUGGING false #define USE_CELCIUS true #define HEATER_CTRL_PIN A1 +#define LOOP_DELAY_MS 100 // Requirements from curing spec #define DESIRED_TEMP_C_SETPOINT 60.0 @@ -21,7 +22,7 @@ #define MAX_CURE_DESIRED_TEMP_C_INCREASE_RATE_PER_MIN 1.0 #define MAX_POSTCURE_DESIRED_TEMP_C_INCREASE_RATE_PER_MIN 0.3 #define MAX_POSTCURE_DESIRED_TEMP_C_DECREASE_RATE_PER_MIN 3.0 -#define TEMP_ADJUSTMENT_PERIOD_SECONDS 1 +#define TEMP_ADJUSTMENT_PERIOD_SECONDS 5 // Setup the LCD Matrix LiquidCrystal_I2C lcd(LCD_ADDRESS,20,4); @@ -80,7 +81,7 @@ void setup() { lcd.clear(); } - prev_temp = (t1.read() + t2.read() + t3.read() + t4.read() + t5.read()) / (1.0 * THERMOCOUPLE_COUNT); + prev_temp = 0.0; prev_meas_timestamp = millis(); update_setpoint_timestamp = true; last_heat_adjustment_timestamp = millis(); @@ -98,6 +99,11 @@ void loop() { Serial.print(", "); } Serial.print("\n"); + + // Delay the loop for human readable debugging + if (HUMAN_DEBUGGING) { + delay(300); + } } // Measure average temperature in the oven @@ -135,11 +141,6 @@ void loop() { last_lcd_update_timestamp = current_meas_timestamp; } - // Delay the loop for human readable debugging - if (HUMAN_DEBUGGING) { - delay(300); - } - // Stop the heater after the desired curing time, and let the oven cool down if (!DO_POSTCURING && (millis() - setpoint_reached_timestamp) > CURE_NOMINAL_HOURS_MINIMUM * 1000 * 3600) { return; @@ -181,10 +182,20 @@ void loop() { current_temp < (CURE_NOMINAL_TEMP_C_CEILING + CURE_NOMINAL_TEMP_C_FLOOR)/2.0) { // Heat up vote votes_for_heat++; + + // Human readable output + if (HUMAN_DEBUGGING) { + Serial.print("Vote for heat++\n"); + } } else { // Heat down vote votes_for_heat--; + + // Human readable output + if (HUMAN_DEBUGGING) { + Serial.print("Vote for heat--\n"); + } } } else { @@ -200,6 +211,7 @@ void loop() { prev_temp = current_temp; prev_meas_timestamp = current_meas_timestamp; + delay(LOOP_DELAY_MS); } // TODO From bd4a98fea4cb5e7544b0ff83ea60f0b49e804cd6 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sat, 31 Jul 2021 17:44:20 -0700 Subject: [PATCH 10/11] remove todo --- controller/controller.ino | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/controller/controller.ino b/controller/controller.ino index 3d1d250..95016fe 100644 --- a/controller/controller.ino +++ b/controller/controller.ino @@ -212,8 +212,4 @@ void loop() { prev_temp = current_temp; prev_meas_timestamp = current_meas_timestamp; delay(LOOP_DELAY_MS); -} - -// TODO -// implement postcuring cooldown mode -// The logic needs improvement - integrator \ No newline at end of file +} \ No newline at end of file From b60a7b107a9bc4aca853f152daaca83b62e01f76 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sat, 31 Jul 2021 18:19:14 -0700 Subject: [PATCH 11/11] show heater status on lcd --- controller/controller.ino | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/controller/controller.ino b/controller/controller.ino index 95016fe..ec7c354 100644 --- a/controller/controller.ino +++ b/controller/controller.ino @@ -58,6 +58,7 @@ unsigned long last_heat_adjustment_timestamp = 0; unsigned long setpoint_reached_timestamp = 0; unsigned long last_lcd_update_timestamp = 0; bool update_setpoint_timestamp; +bool heater_on; long votes_for_heat = 0; double toFahrenheit(double celcius) { @@ -81,6 +82,7 @@ void setup() { lcd.clear(); } + heater_on = false; prev_temp = 0.0; prev_meas_timestamp = millis(); update_setpoint_timestamp = true; @@ -138,6 +140,10 @@ void loop() { unsigned long time_on_min = millis() / (60.0 * 1000); lcd.print(time_on_min); + lcd.setCursor(0,3); + lcd.print("Heater is "); + lcd.print(heater_on ? "ON" : "OFF"); + last_lcd_update_timestamp = current_meas_timestamp; } @@ -150,9 +156,11 @@ void loop() { if (millis() - last_heat_adjustment_timestamp >= TEMP_ADJUSTMENT_PERIOD_SECONDS * 1000) { if (votes_for_heat > 0) { analogWrite(HEATER_CTRL_PIN, 255); + heater_on = true; } else { analogWrite(HEATER_CTRL_PIN, 0); + heater_on = false; } // Reset the timer var and votes last_heat_adjustment_timestamp = millis();