#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
//initialize display
LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 column and 2 rows
//initialize keypad
const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
uint8_t colPins[COLS] = { 5, 4, 3, 2 }; // Pins connected to C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 9, 8, 7, 6 }; // Pins connected to R1, R2, R3, R4
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
//define PIR and light pins
#define pir1 10
#define pir2 11
#define pir3 12
#define pir4 13
#define pir5 14
#define pir6 15
#define light1 16
#define light2 17
#define light3 18
#define light4 19
#define light5 22
#define displayToggle 52
//state variables
byte lightBanks [] = {1, 1, 1, 1, 0};
byte lightBanksPrevious [] = {1, 1, 1, 1, 0};
byte lastState[6] = {0, 0, 0, 0, 0, 0};
byte previousSensorState;
byte sensorState;
byte lightState = 0;
byte displayState = 1;
byte lastDisplay = 1;
int timeDelay = 5000;
unsigned long lastMotion = 0;
unsigned long lastPress = millis();
void setup() {
lcd.init(); // initialize the lcd
lcd.backlight();
lcd.println("Setup Complete");
delay(1500);
lcd.clear();
pinMode(pir1, INPUT);
pinMode(pir2, INPUT);
pinMode(pir3, INPUT);
pinMode(pir4, INPUT);
pinMode(pir5, INPUT);
pinMode(pir6, INPUT);
pinMode(light1, OUTPUT);
pinMode(light2, OUTPUT);
pinMode(light3, OUTPUT);
pinMode(light4, OUTPUT);
pinMode(light5, OUTPUT);
pinMode(displayToggle, OUTPUT);
Serial.begin(9600);
}
void loop() {
char key = keypad.getKey();
if (key != NO_KEY) {
int selector = keyID(key);
displayState = 1;
if (selector > 0) {
lightBanks[selector - 1] = lightBankSet(selector, lightBanks, sensorState, previousSensorState);
} else if (key == 'D') {
timeDelay = setDelay(timeDelay, lastMotion);
} else if (key == '*') {
displayState = 1;
}
lastPress = millis();
}
if(millis()-lastPress >=10000) {
displayState = 0;
}
if( lastDisplay != displayState){
Serial.println(displayState);
backlightTimeout(displayState);
lastDisplay = displayState;
}
sensorState = sensorRead();
switch (sensorState) {
case 1:
lastMotion = millis();
if (previousSensorState != sensorState) {
lightsOn(lightBanks);
lightState = 1;
previousSensorState = sensorState;
}
break;
case 0:
if (millis() - lastMotion >= timeDelay && previousSensorState != sensorState) {
lightsOff();
lightState = 0;
previousSensorState = sensorState;
}
}
switch (lightState) {
case 1:
for (byte i = 0; i <= 5; i++) {
if (lightBanks[i] != lightBanksPrevious [i]) {
lightBanksPrevious [i] = lightBanks[i];
digitalWrite(i + 16, lightBanks[i]);
Serial.println(i);
Serial.println(lightBanks[i]);
}
}
}
}
byte sensorRead() {
byte sensorState = 0;
for (int i = 10; i <= 15; i++) {
byte sensorValue = digitalRead(i);
if (lastState[i - 10] != sensorValue) {
lastState[i - 10] = sensorValue;
sensorState = 1;
}
}
return sensorState;
}
byte lightBankSet(int key, byte lightBanks[], byte sensorState, byte previousSensorState) {
byte stateChange;
switch (lightBanks[key - 1]) {
case 0:
lcd.clear();
lcd.print("light Bank ");
lcd.print(key);
lcd.print(" ON");
stateChange = 1;
break;
case 1:
lcd.clear();
lcd.print("light Bank ");
lcd.print(key);
lcd.print(" OFF");
stateChange = 0;
}
return stateChange;
}
int keyID(char key) {
int selector = 0;
switch (key) {
case '1':
selector = 1;
break;
case '2':
selector = 2;
break;
case '3':
selector = 3;
break;
case '4':
selector = 4;
break;
case '5':
selector = 5;
break;
}
return selector;
}
void lightsOn(byte lightBanks[]) {
digitalWrite(light1, lightBanks[0]);
digitalWrite(light2, lightBanks[1]);
digitalWrite(light3, lightBanks[2]);
digitalWrite(light4, lightBanks[3]);
digitalWrite(light5, lightBanks[4]);
lcd.clear();
lcd.println("Lights ON");
}
void lightsOff() {
digitalWrite(light1, 0);
digitalWrite(light2, 0);
digitalWrite(light3, 0);
digitalWrite(light4, 0);
digitalWrite(light5, 0);
lcd.clear();
lcd.println("Lights OFF");
}
int setDelay(int timeDelay, unsigned long lastMotion) {
int previousTimeDelay = timeDelay;
byte exitStatus = 0;
lcd.clear();
lcd.println("Select timeDelay:");
lcd.setCursor(0, 1);
lcd.print(timeDelay / 1000);
lcd.print(" Seconds");
while (exitStatus == 0) {
if (previousTimeDelay != timeDelay) {
lcd.setCursor(0, 1);
lcd.print(timeDelay / 1000);
lcd.print(" Seconds");
previousTimeDelay = timeDelay;
}
char key = keypad.getKey();
if (key != NO_KEY) {
switch (key) {
case '1':
timeDelay = 3000;
break;
case '2':
timeDelay = 5000;
break;
case '3':
timeDelay = 8000;
break;
case '4':
timeDelay = 10000;
break;
case '5':
timeDelay = 15000;
break;
case 'D':
exitStatus = 1;
lcd.clear();
lcd.println("Time delay set!");
delay (1000);
lcd.clear();
}
}
}
return timeDelay;
}
void backlightTimeout(byte displayState){
switch (displayState){
case 0:
Serial.println("off");
lcd.noBacklight();
break;
case 1:
Serial.println("on");
lcd.backlight();
}
}