#include <LiquidCrystal_I2C.h>
// LCD
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 20, 4);
// LED
#define LED_Pin 2
// motion sensor
#define M_Pin 16
// temperature
#define T_Pin 12
const float BETA = 3950; // should match the Beta Coefficient of the thermistor
// special char
const char specialChar = 223;
// used for calculate
float T_sum = 0; // temperature sum
float T_n = 0; // number of temperature
float avg_celsius; // avg of temperature
int _500ms_n = 18; // init more than 9s (i.e 18 * 500ms)
bool prev_level = false; // prev motion level
bool light_status = false; // light on: true
// init
void setup() {
LCD.init();
// put your setup code here, to run once:
pinMode(LED_Pin, OUTPUT);
pinMode(M_Pin, INPUT);
pinMode(T_Pin, INPUT);
Serial.begin(9600);
}
// calculate celsius
float get_celsius(){
int analogValue = analogRead(T_Pin); // analogRead
float celsius = 1 / (log(1 / (4096. / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;
return celsius;
}
// LCD display current Temperature
void LCD_print_T(float celsius){
LCD.setCursor(0, 0);
LCD.print("Cur_Temp: ");
LCD.print(celsius);
LCD.print(" ");
LCD.print(specialChar);
LCD.print("C");
}
// LCD display avg temperature
void LCD_print_Avg_T(){
LCD.setCursor(0, 1);
LCD.print("Avg_Temp: ");
LCD.print(avg_celsius);
LCD.print(" ");
LCD.print(specialChar);
LCD.print("C");
}
// LCD clear avg temp
void LCD_clear_Avg_T(){
LCD.setCursor(0, 1);
LCD.print(" ");
}
// LCD diplay light
void LCD_print_light(){
LCD.setCursor(0, 3);
if(light_status) LCD.print("Light on");
else LCD.print(" ");
}
// serial print temp
void Serial_print_T(float celsius){
Serial.print("Cur_Temp: ");
Serial.print(celsius);
Serial.println(" ℃");
}
// serial print light
void Serial_print_light_status(){
if(light_status) Serial.println("Light On");
else Serial.println("Light Off");
}
// turn off light
void Light_off(){
digitalWrite(LED_Pin, LOW);
light_status = false;
}
// turn on light
void Light_on(){
digitalWrite(LED_Pin, HIGH);
light_status = true;
}
void loop() {
int val = digitalRead(M_Pin); // read motion input
if(val == HIGH){
// if prev level is low
if(!prev_level){
prev_level = true;
T_sum = 0; // reset
T_n = 0;
}
// read temperature, cal avg temp
float celsius = get_celsius();
T_sum += celsius;
T_n += 1;
avg_celsius = T_sum / T_n;
// light on or off
if(celsius >= 10) Light_on();
else Light_off();
// dispaly
LCD_print_T(celsius);
LCD_print_Avg_T();
LCD_print_light();
Serial_print_T(celsius);
Serial_print_light_status();
}else{
// if prev level is high
if(prev_level){
_500ms_n = 0; // reset
prev_level = false;
LCD_clear_Avg_T(); // clear
}
else _500ms_n++; // count
// every 3 s and less than 9 s
if(_500ms_n % 6 == 0 && _500ms_n < 18){
// read temperature
float celsius = get_celsius();
// light on or off
if(celsius >= 10) Light_on();
else Light_off();
// dispaly
LCD_print_T(celsius);
LCD_print_light();
Serial_print_T(celsius);
Serial_print_light_status();
}else if(_500ms_n % 6 == 0 && _500ms_n >= 18){
// every 3 s and low level more than 9 s
LCD.clear();
Light_off();
// read temperature
float celsius = get_celsius();
// light on or off
if(celsius >= 10) Light_on();
else Light_off();
Serial_print_T(celsius);
Serial_print_light_status();
}
}
delay(500);
}