//hari final oct 2023//
#include <Wire.h>
#include <Keypad.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include <RTClib.h>
//#include <avr/wdt.h>
//#include <avr/sleep.h>
//#include "LowPower.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
// Use pins 2 and 3 to communicate with DFPlayer Mini
static const uint8_t PIN_MP3_TX = 2; // Connects to module's RX
static const uint8_t PIN_MP3_RX = 3; // Connects to module's TX
SoftwareSerial softwareSerial(PIN_MP3_RX, PIN_MP3_TX);
DFRobotDFPlayerMini player;
unsigned long warning = millis();
unsigned long warning1 = millis();
unsigned long Interval = 10000;
unsigned long Interval1 = 30000;
//long Interval2 = 10000;
Servo ServoMotor;
//int Button = 4; //Push Button
# define Lock 4 // relay
# define GSMPower A0 // relay
# define ServoPower A1
# define Feedback A2
# define buzzer 13
//int standby = A1;
const byte numRows = 4; //number of rows on the keypad
const byte numCols = 4; //number of columns on the keypad
RTC_DS3231 rtc;
int position = 0;
int pos = 0;
int posa = 0;
int wpcounter = 0;
//#define interruptPin 2
//int buzz8amHH = 1; // HH - hours ##Set these for reminder time in 24hr Format
//int buzz8amMM = 11; // MM - Minute
//int buzz8amSS = 00; // SS - Seconds
byte Lockicon1[8]={
B01110,
B10001,
B10000,
B10000,
B11111,
B11111,
B11111,
B11111,
};
byte Lockicon2[8]={
B01110,
B10001,
B10001,
B11111,
B11111,
B11111,
B11111,
B00000,
};
byte Standby1[8]={
B01110,
B10001,
B10000,
B01110,
B00001,
B10001,
B01110,
B00000,
};
char keymap[numRows][numCols] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
char keypressed; //Where the keys are stored it changes very often
char keypressed1;
//int keypressedtimer = 0;
char code[] = { '1', '1', '1', '1' }; //The default code, you can change it or make it a 'n' digits one
char code2[] = { '1', '1', '1', '1' };
char check1[sizeof(code)]; //Where the new key is stored
char check2[sizeof(code)]; //Where the new key is stored again so it's compared to the previous one
//char check3[sizeof(code2)];
short a = 0, i = 0, s = 0, j = 0; //Variables used later
short la = 0, ki = 0, mj = 0;
byte rowPins[numRows] = { 12, 11, 10, 9 }; //Rows 0 to 3 //if you modify your pins you should modify this too
byte colPins[numCols] = { 8, 7, 6, 5 }; //Columns 0 to 3
Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);
LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 column and 2 rows
void setup() {
//CLKPR = 0x80; // (1000 0000) enable change in clock frequency
//CLKPR = 0x01; // (0000 0001) use clock division factor 2 to reduce the frequency from 16 MHz to 8
//LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
//LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF);
//pinMode (interruptPin, INPUT_PULLUP);
pos = 0;
posa = 0;
wpcounter = 0;
position = 0;
Serial.begin(9600);
Serial.begin(115200);
softwareSerial.begin(9600);
rtc.begin();
//lcd.begin();
lcd.init();
lcd.backlight();
ServoMotor.attach(A3);
lcd.print(" Bike Security");
lcd.setCursor(0, 1);
lcd.print(" Password System");
//pinMode(Button, INPUT);
pinMode(Lock, OUTPUT);
pinMode(GSMPower, OUTPUT);
pinMode(ServoPower, OUTPUT);
pinMode(Feedback, OUTPUT);
pinMode(buzzer, OUTPUT);
digitalWrite(GSMPower, HIGH);
digitalWrite(Feedback, HIGH);
//pinMode(standby, OUTPUT);
//pinMode(colPins, INPUT_PULLUP);
for(i=0 ; i<sizeof(code);i++)
{ //When you upload the code the first time keep it commented
EEPROM.get(i, code[i]); //Upload the code and change it to store it in the EEPROM
} //Then uncomment this for loop and reupload the code (It's done only once)
if (player.begin(softwareSerial)) {
Serial.println("OK");
delay(500);
// Set volume to maximum (0 to 30).
player.volume(30);
// Play the first MP3 file on the SD card
player.play(01);//welcome
//player.play(02); //please enter the ignition starter password
//player.play(03); // storage box is now open
// player.play(04); //enter old password
//player.play(05); //enter new password
//player.play(06); //enter password again to verify
// player.play(07); //standby mode activated
//player.play(8); //standby disabled
// player.play(9); //storage box password
//player.play(10); //change existing password
// player.play(11); //please try again
//player.play(12); //system activated
//player.play(13); //enjoy the ride
//player.play(14); //system is shutting down
delay(1000);
//player.play(15); //Initializing system peripherals
//player.play(16); //please do not enter the worng password again otherwise the system will be locked
//player.play(17); // you have enter the wrong password
//player.play(18); // nacho
//player.play(19); // you new password has been set
//player.play(20); // beep beep
//player.play(021); // music
//player.play(022); // welcome to the diglital bike security system
} else {
Serial.println("Connect failed!");
player.volume(30);
player.play(01);
delay(100);
}
delay(100);
lcd.clear();
}
void loop() {
unsigned long currentTime = millis();
//at8am();
updateLCD(); // update LCD text
if (Serial.available()) {
char input = Serial.read();
if (input == 'u') updateRTC(); // update RTC time
}
if (digitalRead(Lock) == HIGH)
{
lcd.createChar(0, Lockicon1);
lcd.setCursor(14,1);
lcd.write(0);
}
else
{
lcd.createChar(0, Lockicon2);
lcd.setCursor(14,1);
lcd.write(0);
}
digitalWrite(ServoPower, LOW);
ServoMotor.write(0);
keypressed = myKeypad.getKey(); //Constantly waiting for a key to be pressed
if ((keypressed == 'A') && (digitalRead(Lock) == LOW))
{ // * to open the lock
beep();
//softwareSerial.begin(9600);
delay(200);
player.play(02); //please enter the ignition starter password
lcd.clear();
//lcd.init();
lcd.setCursor(0, 0);
lcd.print(" Enter Password "); //Message to show
ReadCode(); //Getting code function
if (a == sizeof(code)) //The ReadCode function assign a value to a (it's correct when it has the size of the code array)
OpenLOCK(); //Open lock function if code is correct
else {
player.pause();
lcd.clear();
lcd.print(" Wrong code"); //Message to print when the code is wrong
lcd.setCursor(0, 1);
lcd.print(" pls try again..");
digitalWrite(buzzer, HIGH);
player.play(17); // you have enter the wrong password
delay(500);
digitalWrite(buzzer, LOW);
}
//delay(100);
lcd.clear();
//lcd.setCursor(0, 0);
//lcd.print("*:Start A:Enter ");
//lcd.setCursor(0, 1);
//lcd.print("B:Box C:CG D:Lc1");
//lcd.clear();
wpcounter = wpcounter + 1;
}
keypressed1 = myKeypad.getKey();
if ((keypressed == 'B') && (digitalRead(Lock) == HIGH)) { //To change the code it calls the changecode function
beep();
OpenBox(); //Open lock function if code is correct
lcd.clear();
// lcd.setCursor(0, 0);
//lcd.print("*:Start A:Enter ");
//lcd.setCursor(0, 1);
// lcd.print("B:Box C:CG D:Lc2");
//lcd.clear();
}
if ((keypressed == 'B') && (digitalRead(Lock) == LOW)) { //To change the code it calls the changecode function
beep();
lcd.backlight();
delay(200);
player.play(9); //storage box password
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Enter box code"); //Message to show
ReadCode1(); //Getting code function
if (la == sizeof(code2)) //The ReadCode function assign a value to a (it's correct when it has the size of the code array)
OpenBox(); //Open lock function if code is correct
else {
lcd.clear();
lcd.print("Wrong Box code "); //Message to print when the code is wrong
lcd.setCursor(0, 1);
lcd.print(" Pls try agian..");
player.play(17);
delay(800);
}
lcd.clear();
}
if ((keypressed == 'C') && (digitalRead(Lock) == HIGH)) { //To change the code it calls the changecode function
beep();
ChangeCode();
delay(100);
lcd.clear();
}
if ((keypressed == '#') && (posa == 1)) {
beep();
delay(100);
beep();
delay(100);
beep();
delay(100);
beep();
delay(100);
beep();
delay(100);
beep();
delay(100);
lcd.backlight();
lcd.clear();
digitalWrite(Lock, LOW);
digitalWrite(ServoPower, LOW);
lcd.print(" Ignition Locked");
lcd.setCursor(0, 1);
lcd.print("Press A to begin..");
delay(100);
lcd.clear();
posa =0;
wpcounter = 0;
player.pause();
//reboot();
// digitalWrite(GSMPower, LOW);
digitalWrite(Feedback, LOW);
}
if ((wpcounter == 3) && (digitalRead(Lock) == LOW))
{
if(currentTime - warning > Interval) {
warning = currentTime;
player.play(19);
}
}
//if ((posa == 0) && (digitalRead(Lock) == LOW))
if ((digitalRead(Lock) == LOW)&& (posa == 0))
{
if(currentTime - warning > Interval1) {
warning = currentTime;
digitalWrite(Feedback, LOW);
}
}
if ((wpcounter == 3) && (keypressed == '#'))
{
beep();
delay(50);
wpcounter = 0;
player.pause();
}
if ((keypressed == '#') && (posa == 2))
{
beep();
posa =posa -1;
digitalWrite(Lock, LOW);
}
if ((keypressed == '#') && (posa == 3))
{
beep();
posa =posa-1;
}
if ((keypressed == '8') && (posa==1))
{
beep();
posa = posa+1;
lcd.setCursor(13,1);
lcd.clear();
}
if ((keypressed == '9') && (posa==2))
{
beep();
digitalWrite(Lock, HIGH);
digitalWrite(Feedback, HIGH);
posa = posa+1;
lcd.backlight();
}
if ((posa==1) && (digitalRead(Lock) == LOW))
{
lcd.createChar(1, Standby1);
lcd.setCursor(13,1);
lcd.write(1);
lcd.noBacklight();
}
if ((keypressed == '#') && (posa == 0))
{
player.pause();
lcd.init();
delay(100);
// reboot();
}
if ((keypressed == 'D') && (digitalRead(Lock) == LOW))
{
player.pause();
delay(100);
wpcounter = 0;
digitalWrite(Feedback, HIGH);
//reboot();
lcd.init();
}
if ((keypressed == 'D') && (digitalRead(Lock) == HIGH))
{
lcd.init();
}
if(currentTime - warning > Interval1) {
warning = currentTime;
lcd.init();
}
//..............shutting down................
//if ((posa == 0) && (digitalRead(Lock) == LOW))
//{
// unsigned long currentTime1 = millis();
//if(currentTime1 - warning1 > Interval2) {
// warning1 = currentTime1;
// beep();
// player.play(14);
// delay(2000);
// }
//}
//.................end.......................
}
void ReadCode() { //Getting code sequence
i = 0; //All variables set to 0
a = 0;
j = 0;
while (keypressed != '*') { //The user press A to confirm the code otherwise he can keep typing
keypressed = myKeypad.getKey();
if (keypressed != NO_KEY && keypressed != '*') { //If the char typed isn't A and neither "nothing"
lcd.setCursor(j, 1); //This to write "*" on the lcd whenever a key is pressed it's position is controlled by j
lcd.print("*");
j++;
beep();
if (keypressed == code[i] && i < sizeof(code)) { //if the char typed is correct a and i increments to verify the next caracter
a++;
i++;
}
else
a--; //if the character typed is wrong a decrements and cannot equal the size of code []
}
}
keypressed = NO_KEY;
}
void ReadCode1() { //Getting code sequence
ki = 0; //All variables set to 0
la = 0;
mj = 0;
while (keypressed1 != '*') { //The user press A to confirm the code otherwise he can keep typing
keypressed1 = myKeypad.getKey();
if (keypressed1 != NO_KEY && keypressed1 != '*') { //If the char typed isn't A and neither "nothing"
lcd.setCursor(mj, 1); //This to write "*" on the lcd whenever a key is pressed it's position is controlled by j
lcd.print("*");
mj++;
beep();
if (keypressed1 == code2[ki] && ki < sizeof(code2)) { //if the char typed is correct a and i increments to verify the next caracter
la++;
ki++;
} else
la--; //if the character typed is wrong a decrements and cannot equal the size of code []
}
}
keypressed1 = NO_KEY;
}
void ChangeCode() { //Change code sequence
lcd.clear();
player.play(10); //change existing password
delay(500);
lcd.print(" Changing code");
delay(1000);
lcd.clear();
lcd.print("Enter old code");
player.play(04); //enter old password
ReadCode(); //verify the old code first so you can change it
if (a == sizeof(code)) { //again verifying the a value
lcd.clear();
lcd.print("Changing code");
GetNewCode1(); //Get the new code
GetNewCode2(); //Get the new code again to confirm it
s = 0;
for (i = 0; i < sizeof(code); i++) { //Compare codes in array 1 and array 2 from two previous functions
if (check1[i] == check2[i])
s++; //again this how we verifiy, increment s whenever codes are matching
}
if (s == sizeof(code)) { //Correct is always the size of the array
for (i = 0; i < sizeof(code); i++) {
code[i] = check2[i]; //the code array now receives the new code
EEPROM.put(i, code[i]); //And stores it in the EEPROM
}
lcd.clear();
lcd.print("Code Changed");
delay(500);
player.play(18); // your new password has been set
delay(500);
}
else
{ //In case the new codes aren't matching
lcd.clear();
lcd.print("Codes are not");
lcd.setCursor(0, 1);
lcd.print("matching !!");
player.play(17); // you have enter the wrong password
delay(500);
}
}
else
{ //In case the old code is wrong you can't change it
lcd.clear();
lcd.print("Enter Wrong Code");
lcd.setCursor(0, 1);
lcd.print("Pls try again.. !!");
digitalWrite(buzzer, HIGH);
delay(500);
digitalWrite(buzzer, LOW);
}
}
void GetNewCode1() {
i = 0;
j = 0;
lcd.clear();
player.play(05); //enter new password
lcd.print("Enter new code"); //tell the user to enter the new code and press A
lcd.setCursor(0, 1);
lcd.print("and press A");
delay(100);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter new code"); //Press A keep showing while the top row print ***
while (keypressed != '*') { //A to confirm and quits the loop
keypressed = myKeypad.getKey();
if (keypressed != NO_KEY && keypressed != '*') {
lcd.setCursor(j, 1);
lcd.print("*"); //On the new code you can show * as I did or change it to keypressed to show the keys
check1[i] = keypressed; //Store caracters in the array
i++;
j++;
beep();
}
}
keypressed = NO_KEY;
}
void GetNewCode2() { //This is exactly like the GetNewCode1 function but this time the code is stored in another array
i = 0;
j = 0;
lcd.clear();
player.play(06); //enter password again to verify
lcd.print("Confirm code");
lcd.setCursor(0, 1);
lcd.print("and press A");
delay(100);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Confirm code");
while (keypressed != '*') {
keypressed = myKeypad.getKey();
if (keypressed != NO_KEY && keypressed != '*') {
lcd.setCursor(j, 1);
lcd.print("*");
check2[i] = keypressed;
i++;
j++;
beep();
}
}
keypressed = NO_KEY;
}
void OpenLOCK() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(".....WELCOME.....");
lcd.setCursor(0, 1);
lcd.print("Ignition Active");
digitalWrite(Lock, HIGH);
digitalWrite(GSMPower, HIGH);
digitalWrite(Feedback, HIGH);
digitalWrite(buzzer, HIGH);
delay(400);
digitalWrite(buzzer, LOW);
digitalWrite(ServoPower, LOW);
posa = 3;
wpcounter = 0;
player.play(12); //system activated
delay(1500);
player.play(13); //enjoy the ride
//reboot();
}
void OpenBox() { //Lock opening function open for 3s
player.play(03); // storage box is now open
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" BOX IS OPENING");
digitalWrite(ServoPower, HIGH);
lcd.setCursor(0, 1);
lcd.print("Prs Seat to LOCK");
delay(400);
beep();
for (pos = 0; pos <= 60; pos += 1) { // goes from 0 degrees to 180 degrees in steps of 1 degree
ServoMotor.write(pos); // tell servo to go to position in variable 'pos'
delay(5); // waits 15 ms for the servo to reach the position
}
for (pos = 60; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
ServoMotor.write(pos); // tell servo to go to position in variable 'pos'
delay(5); // waits 15 ms for the servo to reach the position
}
delay(1000);
beep();
delay(100);
beep();
delay(100);
beep();
digitalWrite(buzzer, HIGH);
delay(100);
digitalWrite(buzzer, LOW);
lcd.clear();
digitalWrite(ServoPower, LOW);
}
void beep() {
digitalWrite(buzzer, HIGH);
delay(20);
digitalWrite(buzzer, LOW);
//softwareSerial.begin(9600);
}
void updateRTC() {
lcd.clear(); // clear LCD display
lcd.setCursor(0, 0);
lcd.print("Edit Mode..");
// ask user to enter new date and time
const char txt[6][15] = { "year [4-digit]", "month [1~12]", "day [1~31]",
"hours [0~23]", "minutes [0~59]", "seconds [0~59]" };
String str = "";
long newDate[6];
while (Serial.available()) {
Serial.read(); // clear serial buffer
}
for (int i = 0; i < 6; i++) {
Serial.print("Enter ");
Serial.print(txt[i]);
Serial.print(": ");
while (!Serial.available()) {
; // wait for user input
}
str = Serial.readString(); // read user input
newDate[i] = str.toInt(); // convert user input to number and save to array
Serial.println(newDate[i]); // show user input
}
// update RTC
rtc.adjust(DateTime(newDate[0], newDate[1], newDate[2], newDate[3], newDate[4], newDate[5]));
Serial.println("Updated!");
}
void updateLCD() {
/*
create array to convert digit days to words:
0 = Sunday | 4 = Thursday
1 = Monday | 5 = Friday
2 = Tuesday | 6 = Saturday
3 = Wednesday |
*/
const char dayInWords[7][4] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
/*
create array to convert digit months to words:
0 = [no use] |
1 = January | 6 = June
2 = February | 7 = July
3 = March | 8 = August
4 = April | 9 = September
5 = May | 10 = October
6 = June | 11 = November
7 = July | 12 = December
*/
const char monthInWords[13][4] = { " ", "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
// get time and date from RTC and save in variables
DateTime rtcTime = rtc.now();
int ss = rtcTime.second();
int mm = rtcTime.minute();
int hh = rtcTime.twelveHour();
int DD = rtcTime.dayOfTheWeek();
int dd = rtcTime.day();
int MM = rtcTime.month();
int yyyy = rtcTime.year();
// move LCD cursor to upper-left position
lcd.setCursor(0, 0);
// print date in dd-MMM-yyyy format and day of week
if (dd < 10) lcd.print("0"); // add preceeding '0' if number is less than 10
lcd.print(dd);
lcd.print("-");
lcd.print(monthInWords[MM]);
lcd.print("-");
lcd.print(yyyy);
lcd.print(" ");
lcd.print(dayInWords[DD]);
// move LCD cursor to lower-left position
lcd.setCursor(0, 1);
// print time in 12H format
if (hh < 10) lcd.print("0");
lcd.print(hh);
lcd.print(':');
if (mm < 10) lcd.print("0");
lcd.print(mm);
lcd.print(':');
if (ss < 10) lcd.print("0");
lcd.print(ss);
if (rtcTime.isPM()) lcd.print(" PM"); // print AM/PM indication
else lcd.print(" AM");
delay(100);
}
//void Going_To_Sleep ()
//{
// lcd.noBacklight();
//sleep_enable(); //Enabling sleep mode
//attachInterrupt (0, wakeUp, LOW); //attaching a interrupt to pin d2
//set_sleep_mode (SLEEP_MODE_PWR_DOWN); //Setting the sleep mode, in our case full sleepdigitalWrite (LED_BUILTIN, LOW);//turning LED off
//delay(1000); //wait a second to allow the led to be turned off before going to sleep
//sleep_cpu ();//activating sleep mode
//Serial.println("just woke up!");//next line of code executed after the interrupt
//lcd.backlight();
//beep();
//}
//void wakeUp ()
//{
//sleep_disable(); //Disable sleep mode
//detachInterrupt (0);
//}
//void reboot() {
// wdt_disable();
//wdt_enable(WDTO_15MS);
// while (1) {}
//}
//void at8am() { // function to start buzzing at 8am
//DateTime rtcTime = rtc.now();
//if (int (rtcTime.twelveHour() >= buzz8amHH))
//{
//if (int (rtcTime.minute() >= buzz8amMM))
//{
//if (int (rtcTime.second() > buzz8amSS))
//{
/////////////////////////////////////////////////////
// beep();
/////////////////////////////////////////////////////
//}
// }
//}
//