Skip to content

Instantly share code, notes, and snippets.

@Mad182
Last active October 17, 2025 16:34
Show Gist options
  • Select an option

  • Save Mad182/f17033fb88ec0f4a0f32d1dad42a4c56 to your computer and use it in GitHub Desktop.

Select an option

Save Mad182/f17033fb88ec0f4a0f32d1dad42a4c56 to your computer and use it in GitHub Desktop.
// -------------------- 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