//Libraries
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//Constants
const int ldr_Pin = A0;
const int temp_Pin = A1;
const int speaker_Pin = A2;
const int button_Pin = 4;
#define TIMER 30
//Timer
unsigned long startTime = 0;
bool timerStarted = false;
const unsigned long timerDuration = 1800000; // 30 minutes in milliseconds
//Temperature
const float BETA = 3950;
float previousTemp = 0; // Initialize previousTemp variable to 0
const int high_Temp = 75; // in Celsius
const float room_Temp = 25; // in Celsius
// LDR Characteristics
const float GAMMA = 0.7;
const float RL10 = 50;
float previousLux = 0; // Initialize previousLux variable to 0
const int low_Light = 50; // in percentage
//Variables
LiquidCrystal_I2C lcd(0x27, 20, 4);
enum States {INIT, COUNT, END, ERR};
int state = INIT;
int Light;
float Heat;
int Timer = 0;
int Minute = 59;
int temperature = 0;
int Automate = INIT;
bool TemperatureOK = false;
bool LightOK = false;
bool point = true;
unsigned long previousMillis = 0;
const unsigned long interval = 1000;
void setup() {
//Serial Monitor
Serial.begin(9600);
//LDR
pinMode(ldr_Pin, INPUT);
//LCD
lcd.init();
lcd.backlight();
//Button and Speaker
pinMode(button_Pin, INPUT_PULLUP);
pinMode(speaker_Pin, OUTPUT);
Automate = INIT;
}
void loop() {
static int Point = 1;
float measuredTemperature = getTemperature();
temperature = measuredTemperature + 0;
displayTemperature();
displayLux();
//Timer
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
if (Automate == COUNT)
{
if (Point)
Point = 0;
else
Point = 1;
Minute--;
if (Minute == 0)
{
Minute = 59;
if (Timer)
Timer--;
lcd.setCursor(0,2);
lcd.print("Count:");
lcd.print(Timer);
}
}
if (Automate == END)
tone(3, 3000, 100);
if (Automate == ERR)
tone(3, 300, 200);
}
// Temperature and light level checks
if (temperature >= high_Temp) {
playTone(300, 300);
lcd.setCursor(0, 2);
lcd.print("Temp too high!");
}
if (temperature >= room_Temp) {
TemperatureOK = true;
} else {
TemperatureOK = false;
}
int ldrValue = analogRead(ldr_Pin);
float voltage = ldrValue / 1024.0 * 5.0;
float resistance = 2000.0 * voltage / (1.0 - voltage / 5.0);
float lux = pow(RL10 * 1000.0 * pow(10.0, GAMMA) / resistance, (1.0 / GAMMA));
lux = round(lux * 100.0) / 100.0; // Round to nearest hundredth
if (lux >= low_Light) {
LightOK = true;
} else {
LightOK = false;
}
// State machine
switch (Automate)
{
case INIT:
Timer = 0;
if ((!digitalRead(button_Pin)) && TemperatureOK)
{
Automate = COUNT;
Timer = TIMER;
tone(3, 3000, 500);
}
if ((!digitalRead(button_Pin)) && !TemperatureOK)
{
PrintLed("lowT");
tone(3, 300, 200);
}
else
PrintSensors("Init", Timer);
break;
case COUNT:
if ((!digitalRead(button_Pin)) && !TemperatureOK)
{
Automate = ERR;
tone(3, 300, 200);
}
if ((!digitalRead(button_Pin)) && LightOK)
{
Automate = END;
tone(3, 3000, 100);
}
if (Timer == 0)
{
Automate = ERR;
tone(3, 300, 200);
}
PrintSensors("Count", Timer);
break;
case END:
if ((!digitalRead(button_Pin)) && !LightOK)
{
Automate = ERR;
tone(3, 300, 200);
}
if (Timer == 0)
Automate = INIT;
PrintSensors("End", Timer);
break;
case ERR:
if ((!digitalRead(button_Pin)) && (TemperatureOK || LightOK))
Automate = INIT;
PrintLed("Err");
break;
}
}
float measureSurTemp()
{
// Surrounding temperature measurement logic
// Implement your code here
// Return the measured temperature value
return 0;
}
float measureObjectTemp()
{
// Object temperature measurement logic
// Implement your code here
// Return the measured temperature value
return 0;
}
void PrintSensors(const char* state, int timer)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("State: ");
lcd.print(state);
lcd.setCursor(0, 1);
lcd.print("Timer: ");
lcd.print(Timer);
lcd.setCursor(0, 2);
lcd.print("Heat: ");
lcd.print(Heat);
lcd.setCursor(0, 3);
lcd.print("Light: ");
lcd.print(Light);
}
void PrintLed(const char* state)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("State: ");
lcd.print(state);
}
// Function to get temperature from thermistor
float getTemperature() {
int analogValue = analogRead(temp_Pin);
float celsius = 1 / (log(1 / (1023. / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;
celsius = round(celsius * 100.0) / 100.0; // Round to nearest hundredth
return celsius;
}
void playTone(long duration, int freq) {
duration *= 3000;
int period = (1.0 / freq) * 100000;
long elapsed_time = 0;
while (elapsed_time < duration) {
digitalWrite(speaker_Pin, HIGH);
delayMicroseconds(period / 2);
digitalWrite(speaker_Pin, LOW);
delayMicroseconds(period / 2);
elapsed_time += (period);
}
}
// Function to display temperature on LCD
void displayTemperature() {
int analogValue = analogRead(temp_Pin);
float celsius = 1 / (log(1 / (1023. / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;
celsius = round(celsius * 100.0) / 100.0; // Round to nearest hundredth
// Only update screen if temperature value changes
if (celsius != previousTemp) {
lcd.clear(); // Clear the LCD screen
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(celsius);
lcd.print("C");
previousTemp = celsius; // Update previousTemp variable to current temperature value
}
}
void displayLux(){
int analogValue = analogRead(A0);
float voltage = analogValue / 1024.0 * 5.0;
float resistance = 2000.0 * voltage / (1.0 - voltage / 5.0);
float lux = pow(RL10 * 1000.0 * pow(10.0, GAMMA) / resistance, (1.0 / GAMMA));
lux = round(lux * 100.0) / 100.0; // Round to nearest hundredth
// Only update screen if Lux value changes
if (lux != previousLux) {
lcd.clear(); // Clear the LCD screen
lcd.setCursor(0, 1);
lcd.print("Lux: ");
lcd.print(lux);
previousLux = lux; // Update previousLux variable to current Lux value
}
}