/*********
Rui Santos
Complete project details at https://randomnerdtutorials.com
*********/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <max6675.h>
#include <Button.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define encoder0PinA 2
#define encoder0PinB 4
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Button targetTmpBtn(7);
int thermoDO = 4;
int thermoCS = 5;
int relayPin = 8;
int thermoCLK = 6;
int fanSpeed = 0;
int maxFanSpeed = 100;
int maxTemperature = 700;
int fanMult = 2;
bool up;
bool encChanged;
unsigned long lastTrgTmpCheck = 0;
bool checkTrgTmp = false;
//Thermal managment data
unsigned long lastLoopTime = 0;
bool isHeatingOn = true;
float targetTemp = 300;
float temp;
float tmpTargetTemp;
unsigned long lastRelayToggleTime = 0;
const unsigned long relayToggleInterval = 100; // Adjust the interval as needed
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
void setup() {
Serial.begin(115200);
targetTmpBtn.begin();
pinMode(relayPin, OUTPUT);
attachInterrupt (digitalPinToInterrupt (encoder0PinA), isr, CHANGE);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
delay(2000);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
// Display static text
display.display();
}
void isr ()
{
if (digitalRead (encoder0PinA))
up = digitalRead (encoder0PinB);
else
up = !digitalRead (encoder0PinB);
encChanged = true;
}
bool prevHeatingState;
void loop() {
unsigned long currentTime = millis(); // Get the current time
updateTemp();
isHeatingOn = (!isnan(temp)) && temp <= targetTemp;
if (currentTime - lastRelayToggleTime >= relayToggleInterval) {
digitalWrite(relayPin, isHeatingOn ? HIGH : LOW);
lastRelayToggleTime = currentTime; // Update the last toggle time
}
if (encChanged) {
if (checkTrgTmp) {
if (up)
targetTemp += fanMult;
else
targetTemp -= fanMult;
lastTrgTmpCheck = currentTime;
} else {
if (up)
fanSpeed += fanMult;
else
fanSpeed -= fanMult;
}
encChanged = false;
}
display.clearDisplay();
display.setCursor(0, 0);
fanSpeed = constrain(fanSpeed, 0, maxFanSpeed);
targetTemp = constrain(targetTemp, 0, maxTemperature);
//
if (checkTrgTmp) {
display.setTextSize(3);
display.print(targetTemp, 2);
display.println("c");
display.setTextSize(2);
display.print("Target");
//display.print(thermocouple.readCelsius());
} else {
display.setTextSize(3);
//display.print(thermocouple.readCelsius());
if (isnan(temp)) {
display.println("DISCNCT");
} else {
display.print(temp, 2);
display.println("c");
}
display.setTextSize(2);
display.print("Degrees");
}
display.println();
display.setTextSize(2);
display.print("Fan:");
display.print(fanSpeed);
display.println("%");
display.display();
// Calculate the elapsed time since the last loop
if (checkTrgTmp) {
unsigned long elapsedTrgTmpTime = currentTime - lastTrgTmpCheck;
if (elapsedTrgTmpTime > (10 * 1000)) {
checkTrgTmp = false;
lastTrgTmpCheck = currentTime;
}
}
if (targetTmpBtn.pressed()) {
checkTrgTmp = !checkTrgTmp;
if (checkTrgTmp)lastTrgTmpCheck = currentTime;
}
prevHeatingState = isHeatingOn;
delay(50);
}
void updateTemp() {
unsigned long currentTime = millis(); // Get the current time
// Calculate the elapsed time since the last loop
unsigned long elapsedTime = currentTime - lastLoopTime;
if (elapsedTime <= 200)return;
temp = thermocouple.readCelsius();
//heating simulation;
/* if (isHeatingOn) {
temp += random(0, 5);
} else if (temp > 0) {
temp -= 1;
} */
lastLoopTime = currentTime;
}