-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.ino
321 lines (279 loc) · 8.01 KB
/
main.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
// Define Pins for RFID
#define SS_PIN 10
#define RST_PIN 9
MFRC522 rfid(SS_PIN, RST_PIN); // Create instance of RFID
// Servo motor for barrier
Servo barrierServo;
#define SERVO_PIN 3 // Servo connected to pin A3
// IR Sensors
#define IR_ENTRY 2 // Entry IR sensor before barrier
#define IR_EXIT 4 // Exit IR sensor after barrier
#define IR_SLOT_1 5 // IR sensor for Parking Slot 1
// LCD Display
LiquidCrystal_I2C lcd(0x27, 16, 2); // Set LCD address to 0x27 for a 16 chars and 2 line display
// Keypad
const byte ROWS = 4; // Four rows
const byte COLS = 4; // Four columns
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {A0, A1, A2, A3}; // Row pins
byte colPins[COLS] = {6, 7, 8, A6}; // Column pins
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Parking fee settings
#define PARKING_FEE_PER_MINUTE 10 // Rs 10 per minute
unsigned long entryTime; // Time when car entered
unsigned long exitTime; // Time when car exited
// User's RFID card data (3 users)
struct User {
String id;
String name;
float balance;
};
// Array of 3 users
User users[3] = {
{"14DB8A7", "Aditya", 10.0}, // User 1: Aditya
{"3B5A7111", "Vishnu", 300.0}, // User 2: Vishnu
{"2BD46D3C", "Prachiti", 100.0} // User 3: Prachiti
};
User *currentUser = nullptr; // Pointer to store current user after RFID scan
// System State
bool carParked = false; // Car parked status
// bool cardScanned = false;
void setup() {
// Initialize Serial Monitor
Serial.begin(9600);
SPI.begin(); // Init SPI bus
rfid.PCD_Init(); // Init MFRC522
// Initialize servo motor
barrierServo.attach(SERVO_PIN);
barrierServo.write(0); // Close the barrier initially
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("RFID based Car");
lcd.setCursor(0, 1);
lcd.print("Parking System");
delay(3000);
lcd.clear();
// Initialize IR sensors
pinMode(IR_ENTRY, INPUT);
pinMode(IR_EXIT, INPUT);
pinMode(IR_SLOT_1, INPUT);
// Welcome message on LCD
lcd.setCursor(0, 0);
lcd.print("Waiting for car");
}
void loop() {
// Check if car is arriving at the entry
if (digitalRead(IR_ENTRY) == LOW && !carParked) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Car Detected");
lcd.setCursor(0, 1);
lcd.print("Scan RFID Card");
// Wait for RFID card scan
if (checkRFIDCard()) {
openBarrier();
entryTime = millis(); // Record the entry time
parkCar();
}
}
// Check if car is leaving from the exit
if (digitalRead(IR_EXIT) == LOW && carParked) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Car Exiting");
lcd.setCursor(0, 1);
lcd.print("Scan RFID Card");
// Wait for RFID card scan
if (checkRFIDCard()) {
exitTime = millis(); // Record the exit time
float fee = calculateParkingFee(); // Calculate parking fee
if (currentUser->balance >= fee) {
deductFee(fee); // Deduct fee from card balance
openBarrier();
thankUser(); // Display thank you message
leaveParking();
} else {
promptRecharge(fee); // Prompt user to recharge if balance is low
}
}
}
}
// Function to check RFID card
bool checkRFIDCard() {
if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
// cardScanned = true;
String cardUID = "";
for (byte i = 0; i < rfid.uid.size; i++) {
// cardUID.concat(String(rfid.uid.uidByte[i] < 0x10 ? " 0" : " "));
cardUID.concat(String(rfid.uid.uidByte[i], HEX));
}
cardUID.toUpperCase();
Serial.println(cardUID); // Print scanned card UID
// Check if the scanned card belongs to any user
for (int i = 0; i < 3; i++) {
if (cardUID == users[i].id) {
currentUser = &users[i]; // Set the current user
if (!carParked) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Welcome " + currentUser->name);
delay(1000);
}
return true;
}
}
// If card not found in the list
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Card Not Found");
delay(2000);
return false;
}
return false;
}
// Function to open barrier
void openBarrier() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Opening Barrier");
barrierServo.write(90); // Rotate the servo to open the barrier
delay(3000); // Wait for the car to pass
barrierServo.write(0); // Close the barrier
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Barrier Closed");
delay(2000);
}
// Function to park the car
void parkCar() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Slot 1 Empty");
// Wait until the car parks at slot 1
while (digitalRead(IR_SLOT_1) == HIGH) {
delay(100);
}
carParked = true; // Set car parked status
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Car Parked");
lcd.setCursor(0, 1);
lcd.print("Slot 1 Occupied");
}
// Function to calculate parking fee based on time parked
float calculateParkingFee() {
unsigned long parkingDuration = (exitTime - entryTime) / 60000; // Calculate parking time in minutes
if (parkingDuration == 0) {
parkingDuration = 1; // Minimum charge for 1 minute
}
float fee = parkingDuration * PARKING_FEE_PER_MINUTE; // Rs 10 per minute
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Parking Fee: Rs");
lcd.setCursor(0, 1);
lcd.print(fee);
delay(3000);
return fee;
}
// Function to deduct parking fee from user's balance
void deductFee(float fee) {
currentUser->balance -= fee;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Fee Deducted");
lcd.setCursor(0, 1);
lcd.print("Rem Bal: Rs " + String(currentUser->balance));
delay(3000);
}
// Function to display thank you message when leaving
void thankUser() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Thanks, " + currentUser->name);
lcd.setCursor(0, 1);
lcd.print("Visit Again!");
delay(3000);
}
// Function for car exiting the parking
void leaveParking() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Car Leaving");
// Wait for car to leave
while (digitalRead(IR_EXIT) == LOW) {
delay(100);
}
carParked = false; // Set car parked status to false
currentUser = nullptr; // Clear the current user
// cardScanned = false; // Reset the card scanned flag
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Slot 1 Empty");
}
// Function to prompt recharge if balance is low
void promptRecharge(float fee) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Low Balance!");
lcd.setCursor(0, 1);
lcd.print("Please Recharge!");
delay(3000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Amt:");
float enteredAmount = 0.0;
while (true) {
char key = keypad.getKey();
if (key) {
if (key == '#') { // Confirm the amount entered
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Recharged Rs:");
lcd.setCursor(0, 1);
lcd.print(enteredAmount);
currentUser->balance += enteredAmount; // Update balance
delay(2000);
break;
} else if (key >= '0' && key <= '9') {
enteredAmount = (enteredAmount * 10) + (key - '0'); // Append digit to amount
lcd.setCursor(10, 0);
lcd.print(enteredAmount);
}
}
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("New Bal: ");
lcd.print(currentUser->balance);
delay(3000);
// Check if balance is enough to deduct the fee after recharge
if (currentUser->balance >= fee) {
deductFee(fee); // Deduct fee from card balance
openBarrier(); // Open the barrier
thankUser(); // Display thank you message
leaveParking(); // Car leaves the parking
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Insufficient Bal");
lcd.setCursor(0, 1);
lcd.print("Recharge Again!");
delay(2000);
}
}