//Servo Libraries
#include <Servo.h>
//Keypad Libraries
#include <Keypad.h>
//OLED Libraries
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
//IR
#define IRIN 3
#define IROUT 2
//OLED
Adafruit_SSD1306 display(128, 64, &Wire, -1);
//Keypad
char keys[4][4] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
byte pin_rows[4] = { 12, 10, 9, 8 };
byte pin_column[4] = { 7, 6, 5, 4 };
Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_column, 4, 4);
//Servo
Servo ProServo;
//Visitors
volatile int visitors = 0;
//Password
String Input = ""; //Input
String passNorm = "0000"; //Normal Gate
String passOpen = "1111"; //Always Open Gate
String passClose = "2222"; //Always Closed Gate
//Variables
int irOut;
short flag = 0; //Gate State (0: CLOSED) (1: OPEN) (2: ALWAYS OPEN) (3: ALWAYS CLOSED)
int threshold = 0; //Visitor's Limit
int IRINREAD = 0; //IRIN Value
int IROUTREAD = 0; //IROUT Value
/*---------------------[Setup]-----------------------*/
void setup() {
noInterrupts();
//Serial Monitor
Serial.begin(9600);
//Servo
ProServo.attach(11);
ProServo.write(0);
//IR
pinMode(IRIN, INPUT);
pinMode(IROUT, INPUT);
IRINREAD = digitalRead(IRIN);
IROUTREAD = digitalRead(IROUT);
//Input
Input.reserve(4); //Password doesn't exceed 4 characters
interrupts();
//OLED
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(21, 20);
display.println(F("Welcome"));
display.display();
delay(3000);
display.setTextSize(1);
}
/*---------------------[Loop]-----------------------*/
void loop() {
Display();
char key = keypad.getKey();
if (INPUT == passNorm || key == NO_KEY) { //Normal Mode 0000
if (IRINREAD == HIGH) { //IRIN
ProServo.write(90);
flag = 1; //OPEN
delay(250);
while (true) {
if (IRINREAD == LOW) {
break;
}
}
visitors++;
ProServo.write(0);
flag = 0; //CLOSED
delay(250);
}
if (IROUTREAD == HIGH) {
ProServo.write(90);
flag = 1; //OPEN
delay(250);
while (true) {
if (IROUTREAD == LOW) { //IROUT
break;
}
}
visitors--;
ProServo.write(0);
flag = 0; //CLOSED
delay(250);
}
}
if (key != NO_KEY) {
Serial.print(key);
if (key == '*') {
Input = "";
} else if (key == '#') {
if (Input == passClose) //Always Closed Gate 2222
{
closeGate();
} else if (Input == passOpen) //Always Open Gate 1111
{
openGate();
} else //Invalid Input
{
Invalid();
}
} else {
Input += key;
}
}
}
/*---------------------[Gate Always Open State]-----------------------*/ //1111
void openGate() {
if (INPUT == passOpen) { //Always Open Mode 1111
ProServo.write(90);
if (IRINREAD == HIGH) { //IRIN
flag = 2; //Always Open
delay(250);
while (true) {
if (IRINREAD == LOW) {
break;
}
}
visitors++;
delay(250);
}
if (IROUTREAD == HIGH) {
flag = 2; //Always Open
delay(250);
while (true) {
if (IROUTREAD == LOW) { //IROUT
break;
}
}
visitors--;
delay(250);
}
}
}
/*---------------------[Gate Always Closed State]-----------------------*/ //2222
void closeGate() {
if (INPUT == passClose) { //Always Closed Mode 2222
ProServo.write(0);
if (IRINREAD == HIGH) { //IRIN
flag = 3; //Always Close
delay(250);
while (true) {
if (IRINREAD == LOW) {
break;
}
}
delay(250);
}
if (IROUTREAD == HIGH) {
flag = 3; //Always Close
delay(250);
while (true) {
if (IROUTREAD == LOW) { //IROUT
break;
}
}
delay(250);
}
}
}
/*---------------------[Display]-----------------------*/
void Display() {
display.clearDisplay();
display.setCursor(0, 0);
display.println(F("State:"));
//State
if (flag == 0) {
display.println(F("CLOSED"));
} else if (flag == 1) {
display.println(F("OPEN"));
} else if (flag == 2) {
display.println(F("ALWAYS OPEN"));
} else if (flag == 3) {
display.println(F("ALWAYS CLOSED"));
}
display.println(F("Visitors:"));
display.println(visitors);
display.display();
}
/*---------------------[Invalid Input]-----------------------*/
void Invalid() {
display.setTextSize(2);
//display.setTextColor(WHITE);
display.clearDisplay();
display.setCursor(23, 18);
display.println(F("INVALID"));
display.setCursor(35, 35);
display.println(F("INPUT"));
display.display();
delay(3000);
display.clearDisplay();
display.setCursor(5, 20);
display.println(F("Enter Code"));
display.display();
delay(3000);
}