#include <time.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <Servo.h>
#include "Stepper.h"
// Define the I2C address of the LCD display
#define I2C_ADDR 0x27
// Define the number of columns and rows on the LCD display
#define LCD_COLUMNS 20
#define LCD_ROWS 4
#define DHTTYPE DHT22
// Digital pin connected to the DHT sensor
#define DHTPIN 7
#define LDR_PIN A15
#define LUX_THRE_DARK 400
#define LED_LIGHT_PIN 8
// pins connected
#define STEPPER_MOTOR_AN 5 // A- line
#define STEPPER_MOTOR_AP 4 // A+ line
#define STEPPER_MOTOR_BP 3 //B+ line .
#define STEPPER_MOTOR_BN 2 //B- line .
#define DISTANCE_SENSOR_TRIG_PIN 10
#define DISTANCE_SENSOR_ECHO_PIN 9
#define DOOR_AUTO_CLOSE_THRE (10*1000) // 10 sec
#define DOOR_CONTROL_PIN A6
#define DOOR_SENSOR_THRE 200
#define STEPS_PER_REV 200
#define FLOOR_DEC(v) (((int)(v * 10)/10) + ((int)((int)(v * 10) % 10))/10.0)
// Create a part objects
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_ROWS);
DHT dht(DHTPIN, DHTTYPE);
Servo door;
/* Get Fan Speed based on given temperature and humidity based on the table below
Temperature Humidity Fan speed
----------- -------- ----------
25 and below - 0
25-29 40-60 2
25-29 61-80 3
25-29 81-100 4
30-34 40-60 3
30-34 61-80 4
30-34 81-100 5
35-39 40-60 4
35-39 61-100 5
40 and above 40-100 5
*/
#define checkRange(val, min, max) ((int)val >=min && (int)val <= max)
// initialize the stepper library on pins 8 through 11:
Stepper fanStepper(STEPS_PER_REV, STEPPER_MOTOR_AN, STEPPER_MOTOR_AP, STEPPER_MOTOR_BP, STEPPER_MOTOR_BN);
// Get fan speed based on temperature and humidity
int getFanSpeed(float temp, float humidity)
{
if (checkRange(temp, 0, 25) && checkRange(humidity, humidity, humidity))
{
return 0;
}
else if (checkRange(temp, 25, 29) && checkRange(humidity, 40, 60))
{
return 2;
}
else if (checkRange(temp, 25, 29) && checkRange(humidity, 61, 80))
{
return 3;
}
else if (checkRange(temp, 25, 29) && checkRange(humidity, 81, 100))
{
return 4;
}
else if (checkRange(temp, 30, 34) && checkRange(humidity, 40, 60))
{
return 3;
}
else if (checkRange(temp, 30, 34) && checkRange(humidity, 61, 80))
{
return 4;
}
else if (checkRange(temp, 30, 34) && checkRange(humidity, 81, 100))
{
return 5;
}
else if (checkRange(temp, 35, 39) && checkRange(humidity, 40, 60))
{
return 4;
}
else if (checkRange(temp, 35, 39) && checkRange(humidity, 61, 100))
{
return 5;
}
else if (checkRange(temp, 40, 0xFFFFFFFF) && checkRange(humidity, 40, 100))
{
return 5;
}
return 0;
}
// Display temperature and humidity on LCD display
void displayData(float temp, float humidity)
{
static bool changeValueOnly = false;
static float prevTemp = 0.0, prevHumidity = 0.0;
if ((temp == prevTemp) && (humidity == prevHumidity))
{
// Same value no update needed
return;
}
if (true == changeValueOnly)
{
lcd.setCursor(12, 1);
lcd.print(" ");
lcd.setCursor(12, 1);
lcd.print(temp);
lcd.print("\xdf");
lcd.print("C");
lcd.setCursor(12, 2);
lcd.print(" ");
lcd.setCursor(12, 2);
lcd.print(humidity);
lcd.print("%");
}
else
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Home Corp.");
lcd.setCursor(0, 1);
lcd.print("Temperature:");
lcd.print(temp);
lcd.print("\xdf");
lcd.print("C");
lcd.setCursor(0, 2);
lcd.print("Humidity :");
lcd.print(humidity);
lcd.print("%");
changeValueOnly = true;
}
prevTemp = temp;
prevHumidity = humidity;
//delay(1000);
}
void readTempAndHumidity(float *t, float *h)
{
if ((NULL == t) || (NULL == h))
{
return;
}
// Reading humidity
*h = dht.readHumidity();
// Read temperature as Celsius (the default)
*t = dht.readTemperature();
}
void setup() { // put your setup code here, to run once:
Serial.begin(115200);
// Initialize the LCD display
lcd.init();
// Turn on the backlight
lcd.backlight();
// Print splash screen to the LCD display
lcd.setCursor(0, 0);
lcd.println(" Home Corp.");
lcd.println("\n");
lcd.println("Initializing ...");
// Init DHT sensor
dht.begin();
pinMode(LED_LIGHT_PIN, OUTPUT);
pinMode(DISTANCE_SENSOR_TRIG_PIN, OUTPUT);
pinMode(DISTANCE_SENSOR_ECHO_PIN, INPUT);
// Door control
door.attach(DOOR_CONTROL_PIN);
door.write(0);
pinMode(STEPPER_MOTOR_AP, OUTPUT);
pinMode(STEPPER_MOTOR_AN, OUTPUT);
pinMode(STEPPER_MOTOR_BP, OUTPUT);
pinMode(STEPPER_MOTOR_BN, OUTPUT);
fanStepper.setSpeed(1000);
delay(1000);
lcd.clear();
}
// Change fan speed by changing stepper motor speed
void changeFanSpeed(int speed)
{
fanStepper.setSpeed((speed/5.0)*100);
fanStepper.step(speed*100);
}
void controlDoor()
{
static bool opened = false;
static unsigned long startTime = 0;
// Start a new measurement:
digitalWrite(DISTANCE_SENSOR_TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(DISTANCE_SENSOR_TRIG_PIN, LOW);
// Read the result:
int duration = pulseIn(DISTANCE_SENSOR_ECHO_PIN, HIGH);
float distance = duration / 58.0;
if (false == opened)
{
//Open door
if (distance <= DOOR_SENSOR_THRE)
{
door.write(90);
opened = true;
startTime = millis();
}
}
else
{
// Close the opened door
if ((millis() - startTime) > DOOR_AUTO_CLOSE_THRE)
{
door.write(0);
opened = false;
}
}
}
// Convert analog light value to lux
float analogValueToLux(int analogValue)
{
const float GAMMA = 0.7;
const float RL10 = 50.0;
// Convert the analog value into lux value:
float voltage = analogValue / 1024.0 * 5.0;
float resistance = 2000 * voltage / (1 - voltage / 5);
float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
return lux;
}
//Check light intensity and switch on light
void checkLight()
{
float lux = 0.0;
lux = analogValueToLux(analogRead(LDR_PIN));
// Switch on LED based on detected light sensivity
if (lux < LUX_THRE_DARK)
{
digitalWrite(LED_LIGHT_PIN, HIGH);
}
else
{
digitalWrite(LED_LIGHT_PIN, LOW);
}
}
// Main loop
void loop() {
float temp = 0.0;
float humidity = 0.0;
int fanSpeed = 0;
// Open or close door
controlDoor();
// Check light intensity
checkLight();
// Check temp and humidity
readTempAndHumidity(&temp, &humidity);
// Display temp and humidity
displayData(temp, humidity);
// Change fan speed if needed
fanSpeed = getFanSpeed(temp, humidity);
changeFanSpeed(fanSpeed);
Serial.print("Fan Speed : ");
Serial.println(fanSpeed);
}