// Librarys
#include <LiquidCrystal.h>
#include <IRremote.h>
#include <EEPROM.h>
// Const Variable
#define TRIGGER_PIN 4
#define ECHO_PIN 3
#define BUTTON_PIN 2
#define LED_1_PIN 12
#define LED_2_PIN 11
#define LED_3_PIN 10
#define PHOTORESISTOR_PIN A0
#define IRRECEIVER_PIN 5
#define MAX_PAGE 3
#define ULTRASONIC_UNIT_ROW 10
#define ULTRASONIC_DEFAULT_UNIT 1
#define DEFAULT_PAGE 1
// Variables
int LCDPIN[6] = { 168, 144, 224, 176, 162 };
// Play, Up, Down, EQ, Power
constexpr int IRRemoteCode[5] = { 5, 10, 8, 13, 0 };
unsigned long ultrasonicTimeToSub = millis();
unsigned long ultrasonicDelayTime = 60;
volatile unsigned long ultrasonicTimeBegin;
volatile unsigned long ultrasonicTimeEnd;
volatile bool isDistanceAvialable = false;
double UltrasonicDistance;
double perviousDistance = 400.0;
double maxDistance1 = 10;
bool lockApplication = false;
unsigned long buttonTimeToSub = millis();
unsigned long buttonDelay = 50;
byte buttonState = LOW;
unsigned long LED1TimeToSub = millis();
unsigned long LED1DelayTime = 300;
byte LED1State = LOW;
unsigned long LED2TimeToSub = millis();
unsigned long LED2DelayTime;
byte LED2State = LOW;
int ultrasonicUnit = 1;
int LCDPage = 1;
int LCDPage1 = 1;
double maxDistance2 = 10;
// Functions
void triggerUltrasonic() {
digitalWrite(TRIGGER_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER_PIN, LOW);
}
void interruptsUltrasonic() {
if (digitalRead(ECHO_PIN) == HIGH) {
ultrasonicTimeBegin = micros();
} else {
ultrasonicTimeEnd = micros();
isDistanceAvialable = true;
}
}
double getUltrasonicDistance() {
long durationMicro = ultrasonicTimeEnd - ultrasonicTimeBegin;
double distance = durationMicro / 58.0;
if (distance > 401.0) {
return perviousDistance;
}
distance = distance * 0.9 + perviousDistance * 0.1;
perviousDistance = distance;
return distance;
}
// OUTSIDE SETUP
LiquidCrystal lcd(LCDPIN[0], LCDPIN[1], LCDPIN[2], LCDPIN[3], LCDPIN[4], LCDPIN[5]);
// Main Setup
void setup() {
// put your setup code here, to run once:
pinMode(TRIGGER_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(BUTTON_PIN, INPUT);
pinMode(LED_1_PIN, OUTPUT);
pinMode(LED_2_PIN, OUTPUT);
pinMode(LED_3_PIN, OUTPUT);
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Initializing... ");
lcd.setCursor(0, 1);
lcd.print(" ");
Serial.begin(115200);
IrReceiver.begin(IRRECEIVER_PIN);
UltrasonicDistance = 400.0;
delay(1000);
lcd.setCursor(0, 0);
lcd.print("Loading... ");
lcd.setCursor(0, 1);
lcd.print(" ");
if (EEPROM.read(ULTRASONIC_UNIT_ROW) > 2 || EEPROM.read(ULTRASONIC_UNIT_ROW) <= 0) {
EEPROM.write(ULTRASONIC_UNIT_ROW, ULTRASONIC_DEFAULT_UNIT);
}
ultrasonicUnit = EEPROM.read(ULTRASONIC_UNIT_ROW);
LCDPage = DEFAULT_PAGE;
delay(500);
attachInterrupt(digitalPinToInterrupt(ECHO_PIN), interruptsUltrasonic, CHANGE);
}
// Main Loop
void loop() {
// put your main code here, to run repeatedly:
unsigned long timeNow = millis();
if (timeNow - ultrasonicTimeToSub > ultrasonicDelayTime) {
ultrasonicTimeToSub += ultrasonicDelayTime;
triggerUltrasonic();
}
if (isDistanceAvialable) {
isDistanceAvialable = false;
UltrasonicDistance = getUltrasonicDistance();
}
double luminosity = analogRead(PHOTORESISTOR_PIN);
double brightness = 255 - luminosity / 4;
analogWrite(LED_3_PIN, brightness);
if (luminosity < maxDistance2) {
lockApplication = true;
}
if (UltrasonicDistance < maxDistance1) {
lockApplication = true;
}
if (timeNow - buttonTimeToSub > buttonDelay) {
byte newButtonState = digitalRead(BUTTON_PIN);
if (buttonState != newButtonState) {
buttonTimeToSub = timeNow;
buttonState = newButtonState;
if (buttonState == LOW) {
lockApplication = false;
}
}
}
if (lockApplication) {
lcd.setCursor(0, 0);
lcd.print(" !Locked! ");
lcd.setCursor(0, 1);
lcd.print("Press to Unlock.");
if (timeNow - LED1TimeToSub > LED1DelayTime) {
LED1TimeToSub += LED1DelayTime;
if (LED1State == HIGH) {
LED1State = LOW;
} else {
LED1State = HIGH;
}
}
LED2State = LED1State;
} else {
if (LCDPage1 == 1) {
lcd.setCursor(0, 0);
lcd.print("Dist: ");
if (ultrasonicUnit == 1) {
lcd.print(UltrasonicDistance);
lcd.print(" cm ");
} else {
lcd.print((UltrasonicDistance * 58.0) / 148.0);
lcd.print(" in ");
}
lcd.setCursor(0, 1);
if (UltrasonicDistance > 10 && UltrasonicDistance < 50) {
lcd.print(" !Warning! ");
} else {
lcd.print(" No Obstacle. ");
}
} else if (LCDPage1 == 2) {
lcd.setCursor(0, 0);
lcd.print("Press on OFF to ");
lcd.setCursor(0, 1);
lcd.print("reset settings. ");
} else if (LCDPage1 == 3) {
lcd.setCursor(0, 0);
lcd.print("Luminosity: ");
lcd.print(luminosity);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" ");
} else if (LCDPage1 == 4) {
lcd.setCursor(0, 0);
lcd.print("Settings have ");
lcd.setCursor(0, 1);
lcd.print("been reset. ");
}
LED1State = LOW;
if (timeNow - LED2TimeToSub > LED2DelayTime) {
LED2TimeToSub += LED2DelayTime;
if (LED2State == HIGH) {
LED2State = LOW;
} else {
LED2State = HIGH;
}
}
}
LED2DelayTime = UltrasonicDistance * 4;
digitalWrite(LED_2_PIN, LED2State);
digitalWrite(LED_1_PIN, LED1State);
if (IrReceiver.decode()) {
int command = IrReceiver.decodedIRData.command;
Serial.println(command);
switch (command) {
case IRRemoteCode[0]: // Play
lockApplication = false;
break;
case IRRemoteCode[1]: // UP
if (!lockApplication) {
LCDPage++;
if (LCDPage > MAX_PAGE) {
LCDPage = 1;
}
if (LCDPage1 == 4) {
LCDPage = 1;
}
LCDPage1 = LCDPage;
}
break;
case IRRemoteCode[2]: // Down
if (!lockApplication) {
LCDPage--;
if (LCDPage == 0) {
LCDPage = MAX_PAGE;
}
if (LCDPage1 == 4) {
LCDPage = 1;
}
LCDPage1 = LCDPage;
}
break;
case IRRemoteCode[3]: // EQ
if (!lockApplication) {
if (LCDPage == 1) {
if (ultrasonicUnit == 1) {
ultrasonicUnit = 2;
} else {
ultrasonicUnit = 1;
}
EEPROM.write(ULTRASONIC_UNIT_ROW, ultrasonicUnit);
}
}
break;
case IRRemoteCode[4]: // POWER
if (!lockApplication) {
if (LCDPage == 2) {
ultrasonicUnit = ULTRASONIC_DEFAULT_UNIT;
EEPROM.write(ULTRASONIC_UNIT_ROW, ULTRASONIC_DEFAULT_UNIT);
LCDPage1 = 4;
}
}
break;
}
IrReceiver.resume();
}
}