// Source Code program oleh @irfan_tuxz
#include "max6675.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Deklarasi PIN input-output Arduino Nano
#define PIN_ROTARY_CLK 3
#define PIN_ROTARY_DTA 8
#define PIN_ROTARY_BTN 7
#define PIN_BUTTON_R 6
#define PIN_BUTTON_L 5
#define PIN_PWM_OUT 4
// Define the Arduino pins, the MAX6675 module is connected to
int SO_PIN = 4; // Serail Out (SO) pin
int CS_PIN = 5; // Chip Select (CS) pin
int SCK_PIN = 6; // Clock (SCK) pin
MAX6675 thermocouple(SCK_PIN, CS_PIN, SO_PIN);
// Deklarasi Global Variable
char *nameMode[] = {"heat", "hold", "cool", " off"};
int setTemp[] = {300,300,40,30};
int setTime[] = {60,120,120,0};
int cancelTemp[] = {300,300,40,35};
int cancelTime[] = {60,120,120,30};
int indexSetup = 0;
int indexNow = 0;
byte currentMode = 0; // 0 = heating,
// 1 = holding,
// 2 = cooling,
// 3 = inactive,
long startTime = 0; // start time Running
long curTime = 0; // current time Running
long desTime = 0; // target time Running
bool running = false;
float stepTemp = 0;
int tempAwal = 0;
int curTemp = 30; // suhu terbaca °C
int curHour = 0; // waktu berjalan jam
int curMin = 0; // waktu berjalan menit
int curSec = 0; // waktu berjalan detik
byte currentDisplay = 0; // 0 = Status,
// 1 = Setup,
int currentSetup = 0; // 0 = SetMode,
// 1 = SetTemper,
// 2 = SetTime,
typedef enum {
SET_MODE,
SET_TEMP,
SET_TIME,
} MenuSetup;
MenuSetup menuSetup = SET_MODE;
void selectDown() {
switch (menuSetup) {
case SET_MODE:
menuSetup = SET_TEMP;
break;
case SET_TEMP:
menuSetup = SET_TIME;
break;
case SET_TIME:
menuSetup = SET_MODE;
break;
}
}
void updateValue(int delta) {
switch (menuSetup) {
case SET_MODE:
indexSetup = constrain(indexSetup + delta, 0, 3);
break;
case SET_TEMP:
setTemp[indexSetup] = constrain(setTemp[indexSetup] + delta, 0, 999);
break;
case SET_TIME:
setTime[indexSetup] = constrain(setTime[indexSetup] + delta, 0, 9999);
break;
}
}
void displayStatus() {
lcd.setCursor(16,0);
lcd.print(nameMode[indexNow]);
lcd.setCursor(0, 1);
lcd.print("SetTemp=");
lcd.print(setTemp[indexNow]);
lcd.print((char)0xDF);
lcd.print("C");
lcd.setCursor(13, 1);
lcd.print((char)0x7E);
lcd.print(setTime[indexNow] / 60);
lcd.print("h");
lcd.print(setTime[indexNow] % 60);
lcd.print("m");
if(running){
curTime = (millis() - startTime) * 3 / 50;//1000;
curHour = curTime / 3600;
curMin = (curTime - (curHour*3600)) / 60;
curSec = (curTime - (curHour*3600)-(curMin*60));
curTemp = round((stepTemp * curTime) + tempAwal);
lcd.setCursor(0, 0);
lcd.print("CurTemp=");
lcd.print(curTemp);
lcd.print((char)0xDF);
lcd.print("C ");
lcd.setCursor(0, 2);
lcd.print("RunTime=");
if (curHour < 10) lcd.print(" ");
lcd.print(curHour);
lcd.print(":");
if (curMin < 10) lcd.print("0");
lcd.print(curMin);
lcd.print(":");
if (curSec < 10) lcd.print("0");
lcd.print(curSec);
lcd.setCursor(8,3);
lcd.print("STOP ");
//--- Detect time des
if (curTime >= desTime){
indexNow = (indexNow + 1) % 4;
StartMode();
lcd.clear();
}
//-------------------
}else{
lcd.setCursor(0, 2);
lcd.print("RunTime=");
lcd.print("Stopped ");
lcd.setCursor(0, 0);
lcd.print("CurTemp=");
lcd.print(curTemp);
lcd.print((char)0xDF);
lcd.print("C");
lcd.setCursor(8,3);
lcd.print("START");
}
lcd.setCursor(0,3);
lcd.print("RESET");
lcd.setCursor(15,3);
lcd.print("SETUP");
}
void displaySetup() {
lcd.setCursor(1, 0);
lcd.print("SetMode= ");
lcd.print(nameMode[indexSetup]);
if (indexSetup < 3) lcd.print("ing"); else lcd.print(" ");
lcd.setCursor(1, 1);
lcd.print("SetTemp= ");
lcd.print(setTemp[indexSetup]);
lcd.print((char)0xDF);
lcd.print("C ");
lcd.setCursor(1, 2);
lcd.print("SetTime= ");
//lcd.print(setTime[indexSetup]);
//lcd.print("m (");
lcd.print(setTime[indexSetup] / 60);
lcd.print("h");
if ((setTime[indexSetup] % 60) < 10) lcd.print("0");
lcd.print(setTime[indexSetup] % 60);
lcd.print("m ");
lcd.setCursor(0, 0);
if (menuSetup == SET_MODE) lcd.print(">"); else lcd.print(" ");
lcd.setCursor(0, 1);
if (menuSetup == SET_TEMP) lcd.print(">"); else lcd.print(" ");
lcd.setCursor(0, 2);
if (menuSetup == SET_TIME) lcd.print(">"); else lcd.print(" ");
lcd.setCursor(0,3);
lcd.print("CANCEL");
lcd.setCursor(8,3);
lcd.print((char)0x7F);
lcd.print("ADJ");
lcd.print((char)0x7E);
lcd.setCursor(16,3);
lcd.print("SAVE");
}
volatile unsigned long lastInterruptEncoder = 0;
void readEncoder() {
unsigned long interruptTime = millis();
// Debounce: Abaikan interrupt jika terlalu cepat
if (interruptTime - lastInterruptEncoder > 20) { // Sesuaikan nilai debounce
int currentStateDT = digitalRead(PIN_ROTARY_DTA);
if (currentStateDT != digitalRead(PIN_ROTARY_CLK)) {
updateValue(1); // Putaran ke kanan
} else {
updateValue(-1); // Putaran ke kiri
}
}
lastInterruptEncoder = interruptTime;
}
void StartMode() {
if(setTime[indexNow] == 0){
running = false;
indexNow = (indexNow + 1) % 4;
lcd.clear();
}else{
tempAwal = setTemp[(indexNow - 1) % 4];
float a = (setTemp[indexNow] - tempAwal);
float b = (setTime[indexNow] * 60);
stepTemp = a/b;
desTime = b;
running = true;
startTime = millis();
}
}
void setup() {
// Initialize LCD
lcd.init();
lcd.backlight();
// Atur pinMode
pinMode(PIN_BUTTON_R, INPUT_PULLUP);
pinMode(PIN_BUTTON_L, INPUT_PULLUP);
pinMode(PIN_ROTARY_BTN, INPUT_PULLUP);
pinMode(PIN_ROTARY_CLK, INPUT);
pinMode(PIN_ROTARY_DTA, INPUT);
pinMode(PIN_PWM_OUT, OUTPUT);
attachInterrupt(digitalPinToInterrupt(PIN_ROTARY_CLK), readEncoder, FALLING);
//Serial.begin(115200);
//Serial.println("Program Ready");
//displayStatus();
delay(100);
currentDisplay = 0;
}
const int debounceDelay = 300; // Waktu debounce dalam milidetik
unsigned long lastDebounceTime = 0;
bool prevClk = HIGH;
void loop() {
bool trigBtnL = 0;
bool trigBtnM = 0;
bool trigBtnR = 0;
if(millis() - lastDebounceTime > debounceDelay){
if (digitalRead(PIN_BUTTON_L) == LOW) {
lastDebounceTime = millis();
trigBtnL = 1;
}else
if (digitalRead(PIN_ROTARY_BTN) == LOW) {
lastDebounceTime = millis();
trigBtnM = 1;
}else
if (digitalRead(PIN_BUTTON_R) == LOW) {
lastDebounceTime = millis();
trigBtnR = 1;
}
}
//----- STATUS -----------//
if (currentDisplay == 0){
displayStatus();
if (trigBtnR){
currentDisplay = 1;
indexSetup = 0;
lcd.clear();
}
if (trigBtnM){
if(running){
running = false;
}else{
StartMode();
}
lcd.clear();
}
//-------------------------
}
//----- SETUP ------------//
else if (currentDisplay == 1){
displaySetup();
if (trigBtnL){
for (int i = 0; i < 4; i++) {
setTemp[i] = cancelTemp[i];
setTime[i] = cancelTime[i];
}
currentDisplay = 0;
lcd.clear();
}
if (trigBtnM){
selectDown();
lcd.clear();
}
if (trigBtnR){
for (int i = 0; i < 4; i++) {
cancelTemp[i] = setTemp[i];
cancelTime[i] = setTime[i];
}
currentDisplay = 0;
lcd.clear();
}
//------------------------//
}
}
//--END