Last active
October 17, 2025 16:34
-
-
Save Mad182/f17033fb88ec0f4a0f32d1dad42a4c56 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // -------------------- Stage Durations in milliseconds -------------------- | |
| const unsigned long stageDurations[] = { | |
| 4UL * 60UL * 60UL * 1000UL, // Stage 1 | |
| 6UL * 60UL * 60UL * 1000UL, // Stage 2 | |
| 8UL * 60UL * 60UL * 1000UL, // Stage 3 | |
| 3UL * 60UL * 60UL * 1000UL, // Stage 4 | |
| 1UL * 60UL * 60UL * 1000UL, // Stage 5 | |
| 4UL * 60UL * 60UL * 1000UL // Stage 6 | |
| }; | |
| // -------------------- Stage Target Temperatures -------------------- | |
| const float stageTemps[] = { | |
| 20.0, // Stage 1 | |
| 25.0, // Stage 2 | |
| 30.0, // Stage 3 | |
| 40.0, // Stage 4 | |
| 50.0, // Stage 5 | |
| 60.0 // Stage 6 | |
| }; | |
| // -------------------- Includes -------------------- | |
| #include <LiquidCrystal.h> | |
| #include <OneWire.h> | |
| #include <DallasTemperature.h> | |
| // -------------------- LCD Setup -------------------- | |
| LiquidCrystal lcd(12, 11, 5, 4, 3, 2); | |
| // -------------------- Temperature Sensors -------------------- | |
| // Channel 1 on pin 7 | |
| #define ONE_WIRE_BUS_1 7 | |
| OneWire oneWire1(ONE_WIRE_BUS_1); | |
| DallasTemperature sensor1(&oneWire1); | |
| // Channel 2 on pin 6 | |
| #define ONE_WIRE_BUS_2 6 | |
| OneWire oneWire2(ONE_WIRE_BUS_2); | |
| DallasTemperature sensor2(&oneWire2); | |
| // -------------------- Heater Relay Pins -------------------- | |
| #define HEATER_PIN_1 9 | |
| #define HEATER_PIN_2 8 | |
| // -------------------- Timing -------------------- | |
| unsigned long startTime; | |
| unsigned long lastLcdInit = 0; | |
| const int numStages = sizeof(stageDurations) / sizeof(stageDurations[0]); | |
| // -------------------- Global Variables -------------------- | |
| float targetTemp = 0.0; | |
| bool finished = false; | |
| bool heater1On = false; | |
| bool heater2On = false; | |
| bool blinkState = false; // For blinking indicator | |
| int blinkCounter = 0; // Count loop cycles | |
| // -------------------- Setup -------------------- | |
| void setup() { | |
| lcd.begin(16, 2); | |
| sensor1.begin(); | |
| sensor2.begin(); | |
| pinMode(HEATER_PIN_1, OUTPUT); | |
| pinMode(HEATER_PIN_2, OUTPUT); | |
| // Turn both heaters OFF (active LOW relay) | |
| digitalWrite(HEATER_PIN_1, HIGH); | |
| digitalWrite(HEATER_PIN_2, HIGH); | |
| startTime = millis(); | |
| lastLcdInit = millis(); | |
| } | |
| // -------------------- Loop -------------------- | |
| void loop() { | |
| unsigned long elapsed = millis() - startTime; | |
| // Determine current stage | |
| unsigned long accumulated = 0; | |
| int currentStage = -1; | |
| for (int i = 0; i < numStages; i++) { | |
| accumulated += stageDurations[i]; | |
| if (elapsed < accumulated) { | |
| currentStage = i; | |
| break; | |
| } | |
| } | |
| if (currentStage != -1) { | |
| targetTemp = stageTemps[currentStage]; | |
| finished = false; | |
| } else { | |
| // All stages complete - stop heating | |
| targetTemp = 0.0; | |
| finished = true; | |
| digitalWrite(HEATER_PIN_1, HIGH); | |
| digitalWrite(HEATER_PIN_2, HIGH); | |
| } | |
| // -------------------- Read temperatures -------------------- | |
| sensor1.requestTemperatures(); | |
| sensor2.requestTemperatures(); | |
| float temp1 = sensor1.getTempCByIndex(0); | |
| float temp2 = sensor2.getTempCByIndex(0); | |
| // -------------------- Fault Detection -------------------- | |
| bool sensor1Fault = (temp1 < -30.0); | |
| bool sensor2Fault = (temp2 < -30.0); | |
| if (sensor1Fault) digitalWrite(HEATER_PIN_1, HIGH); | |
| if (sensor2Fault) digitalWrite(HEATER_PIN_2, HIGH); | |
| // -------------------- Control heaters -------------------- | |
| if (!sensor1Fault) | |
| heater1On = controlHeater(HEATER_PIN_1, temp1); | |
| else | |
| heater1On = false; | |
| if (!sensor2Fault) | |
| heater2On = controlHeater(HEATER_PIN_2, temp2); | |
| else | |
| heater2On = false; | |
| delay(100); | |
| // -------------------- Blink toggle every other loop -------------------- | |
| blinkCounter++; | |
| if (blinkCounter >= 2) { // toggle every 2 loops (~0.5 sec at delay(250)) | |
| blinkCounter = 0; | |
| blinkState = !blinkState; | |
| } | |
| // Re-init LCD every 10 seconds | |
| if (millis() - lastLcdInit >= 10000UL) { | |
| lcd.begin(16, 2); | |
| lcd.clear(); | |
| lastLcdInit = millis(); | |
| } | |
| // -------------------- Display on LCD -------------------- | |
| lcd.setCursor(0, 0); | |
| // Channel 1 display | |
| if (heater1On && blinkState) | |
| lcd.print(" "); // Blink T1 off | |
| else | |
| lcd.print("T1:"); | |
| if (sensor1Fault) | |
| lcd.print("ERR "); | |
| else | |
| lcd.print(temp1, 1); | |
| // Channel 2 display | |
| lcd.print(" "); | |
| if (heater2On && blinkState) | |
| lcd.print(" "); // Blink T2 off | |
| else | |
| lcd.print("T2:"); | |
| if (sensor2Fault) | |
| lcd.print("ERR "); | |
| else | |
| lcd.print(temp2, 1); | |
| lcd.setCursor(0, 1); | |
| if (!finished) { | |
| lcd.print("MT:"); | |
| lcd.print(targetTemp, 0); | |
| lcd.print("C "); | |
| } else { | |
| lcd.print("Gatavs! "); | |
| } | |
| // Display elapsed time HH:MM:SS | |
| unsigned long elapsedSeconds = elapsed / 1000UL; | |
| unsigned int hours = elapsedSeconds / 3600UL; | |
| unsigned int minutes = (elapsedSeconds % 3600UL) / 60UL; | |
| unsigned int seconds = elapsedSeconds % 60UL; | |
| if (hours < 10) lcd.print("0"); | |
| lcd.print(hours); | |
| lcd.print(":"); | |
| if (minutes < 10) lcd.print("0"); | |
| lcd.print(minutes); | |
| lcd.print(":"); | |
| if (seconds < 10) lcd.print("0"); | |
| lcd.print(seconds); | |
| delay(100); | |
| } | |
| // -------------------- Heater Control Function -------------------- | |
| // Returns true if heater is ON | |
| bool controlHeater(int heaterPin, float currentTemp) { | |
| bool isOn = false; | |
| if (targetTemp > 0) { | |
| if (currentTemp < targetTemp - 0.5) { | |
| digitalWrite(heaterPin, LOW); // Turn ON (active LOW) | |
| isOn = true; | |
| } else if (currentTemp > targetTemp + 0.5) { | |
| digitalWrite(heaterPin, HIGH); // Turn OFF | |
| isOn = false; | |
| } else { | |
| // Keep current state | |
| isOn = (digitalRead(heaterPin) == LOW); | |
| } | |
| } else { | |
| digitalWrite(heaterPin, HIGH); // Force OFF | |
| isOn = false; | |
| } | |
| return isOn; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment