#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <MLX90614.h>
#include <VL53L0X.h>
#include <PID_v1_bc.h>
#include "RBDdimmer.h"
#include <Adafruit_MLX90614.h>
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
// VL53L0X setup
VL53L0X sensor;
// LCD setup
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Push button pins
#define UP_BTN 6
#define DOWN_BTN 5
#define SWITCH_BTN 4
#define START_STOP_BTN 2
// Buzzer pin
#define BUZZER_PIN 7
// AC dimmer pin
#define outputPin 3
#define zerocross 2
dimmerLamp dimmer(outputPin);
// PID variables
double Setpoint, Input, output;
PID myPID(&Input, &output, &Setpoint, 2, 5, 1, DIRECT);
// Variables
double jarakset = 50.0;
double jarakread;
double suhuSet = 35.0; // Default set temperature (in Celsius)
unsigned long timerSet = 5 * 60; // Default set time (in seconds)
unsigned long remainingTime = 0;
bool pidRunning = false;
bool countdownActive = false;
unsigned long previousMillis = 0;
const unsigned long interval = 1000; // Timer interval (1 second)
int selectedVar = 0; // 0 for suhuSet, 1 for timerSet
// Debounce variables
unsigned long lastButtonPress = 0;
const unsigned long DEBOUNCE_DELAY = 200;
void setup() {
pinMode(UP_BTN, INPUT_PULLUP);
pinMode(DOWN_BTN, INPUT_PULLUP);
pinMode(SWITCH_BTN, INPUT_PULLUP);
pinMode(START_STOP_BTN, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
mlx.begin();
sensor.init();
lcd.init();
lcd.backlight();
dimmer.begin(NORMAL_MODE, ON); //dimmer initialisation: name.begin(MODE, STATE)
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(0, 100);
}
void handleButtonPress(int pin, void (*callback)()) {
if (digitalRead(pin) == LOW) {
unsigned long currentMillis = millis();
if (currentMillis - lastButtonPress >= DEBOUNCE_DELAY) {
lastButtonPress = currentMillis;
callback();
}
}
}
void switchVariable() {
selectedVar = (selectedVar + 1) % 3;
}
void increaseValue() {
if (selectedVar == 0) suhuSet += 1.0;
else if (selectedVar == 1) timerSet += 60;
else if (selectedVar == 2) jarakset += 1.0;
}
void decreaseValue() {
if (selectedVar == 0 && suhuSet > 0) suhuSet -= 1.0;
else if (selectedVar == 1 && timerSet >= 60) timerSet -= 60;
else if (selectedVar == 2 && jarakset > 0) jarakset -= 1.0;
}
void toggleStartStop() {
if (pidRunning) {
pidRunning = false;
countdownActive = false;
dimmer.setPower(0); // Stop dimmer (heating)
digitalWrite(BUZZER_PIN, LOW); // Turn off buzzer if running
} else {
pidRunning = true;
countdownActive = true;
remainingTime = timerSet; // Reset timer
dimmer.setPower(0); // Reset power to avoid incorrect heating behavior when restarted
}
}
void loop() {
Input = mlx.readObjectTempC();
jarakread = sensor.readRangeSingleMillimeters() / 10.0; // Convert mm to cm
// Handle button presses
handleButtonPress(SWITCH_BTN, switchVariable);
handleButtonPress(UP_BTN, increaseValue);
handleButtonPress(DOWN_BTN, decreaseValue);
handleButtonPress(START_STOP_BTN, toggleStartStop);
// PID Control and Timer Countdown
if (pidRunning && countdownActive) {
Setpoint = suhuSet;
myPID.Compute();
dimmer.setPower(output);
if (millis() - previousMillis >= interval) {
previousMillis = millis();
if (remainingTime > 0) {
remainingTime--;
} else {
countdownActive = false;
pidRunning = false;
dimmer.setPower(0);
digitalWrite(BUZZER_PIN, HIGH);
delay(3000); // Buzzer alert for 3 seconds
digitalWrite(BUZZER_PIN, LOW);
}
}
}
// LCD Display
lcd.setCursor(1, 0);
lcd.print("J: ");
lcd.print(jarakset);
lcd.print("cm / ");
lcd.print(jarakread);
lcd.print("cm ");
lcd.setCursor(1, 1);
lcd.print("S: ");
lcd.print(suhuSet);
lcd.print("c / ");
lcd.print(Input);
lcd.print("c ");
lcd.setCursor(1, 2);
lcd.print("T: ");
unsigned long displayTime = pidRunning ? remainingTime : timerSet;
unsigned long hours = displayTime / 3600;
unsigned long minutes = (displayTime % 3600) / 60;
unsigned long seconds = displayTime % 60;
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);
lcd.setCursor(0, 3);
if (!pidRunning) {
lcd.print("Stopped "); // Show stopped message when PID is off
} else {
lcd.print("Power: ");
lcd.print((int)output);
lcd.print(" ON ");
}
if (selectedVar == 0){
lcd.setCursor(0, 1);
lcd.print(">");
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print(" ");
}
if (selectedVar == 1){
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print(">");
lcd.setCursor(0, 0);
lcd.print(" ");
}
if (selectedVar == 2){
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print(">");
}
}