smart car parking webserver with bill systerm using Arduino & Nodemcu
Connection:-
Arduino Uno:
[I2C LCD] -- SDA → A4
-- SCL → A5
-- VCC → 5V
-- GND → GND
[Ultrasonic Sensors] -- Entry: Trig → D2, Echo → D3
-- Exit: Trig → D4, Echo → D5
-- VCC → 5V
-- GND → GND
[IR Sensors] -- Slot 1: OUT → D6
-- Slot 2: OUT → D7
-- Slot 3: OUT → D8
-- Slot 4: OUT → D9
-- VCC → 5V
-- GND → GND
[Servo Motor] -- Signal → D10
-- VCC → 5V
-- GND → GND
[NodeMCU] -- TX → RX (Arduino)
-- RX → TX (Arduino)
-- GND → GND (Arduino)
-- 3.3V → External 3.3V
----------------------------------------------------------------------------------------------------------------------------
[NodeMCU] -- TX → RX (Arduino)
-- RX → TX (Arduino)
-- GND → GND (Arduino)
-- 3.3V → External 3.3V
Code for Nodemcu Board:-
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
const char* ssid = "wifi name";
const char* password = "password";
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 19800, 60000);
ESP8266WebServer server(80);
unsigned long entryTime = 0;
unsigned long exitTime = 0;
float billAmount = 0.0;
int availableSlots = 4;
String parkingStatus[4] = {"Available", "Available", "Available", "Available"};
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("\nConnected to WiFi!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
timeClient.begin();
server.on("/", handleRoot);
server.on("/status", handleStatus);
server.on("/bill", handleBill);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
timeClient.update();
if (Serial.available()) {
char command = Serial.read();
if (command == 'E') {
entryTime = timeClient.getEpochTime();
availableSlots--;
updateSlotStatus();
Serial.println("Car entered at: " + getFormattedTime(entryTime));
} else if (command == 'X') {
exitTime = timeClient.getEpochTime();
calculateBill();
availableSlots++;
updateSlotStatus();
Serial.println("Car exited at: " + getFormattedTime(exitTime));
Serial.println("Bill: LKR " + String(billAmount));
}
}
}
void calculateBill() {
unsigned long parkingDuration = exitTime - entryTime;
float ratePerHour = 50.0;
billAmount = (parkingDuration / 3600.0) * ratePerHour;
}
void updateSlotStatus() {
for (int i = 0; i < 4; i++) {
if (i < 4 - availableSlots) {
parkingStatus[i] = "Occupied";
} else {
parkingStatus[i] = "Available";
}
}
}
String getFormattedTime(unsigned long epochTime) {
timeClient.setTimeOffset(19800);
timeClient.setUpdateInterval(60000);
timeClient.forceUpdate();
String formattedTime = timeClient.getFormattedTime();
return formattedTime;
}
void handleRoot() {
String html = "<html><head>";
html += "<style>";
html += "body { background: #201f1f; color: #FFF8E0; font-family: Arial, sans-serif; margin: 0; padding: 0; height: 100vh; display: flex; justify-content: center; align-items: center; text-align: center; }";
html += ".card { background: rgb(0, 0, 0); backdrop-filter: blur(10px); border-radius: 20px; border: 1px solid rgba(255, 255, 255, 0.2); padding: 30px; width: 800px; height: 400px; box-shadow: 0 20px 32px rgba(255, 255, 255, 0.441); display: flex; align-items: center; justify-content: space-between; }";
html += ".content { flex: 1; text-align: left; }";
html += "h1 { font-size: 2.5em; color: #FFC300; margin-bottom: 20px; margin-top: -20px; }";
html += "p { font-size: 1.2em; margin: 10px 0; }";
html += "#ip { margin-top: -15px; font-size: 0.7em; color: rgb(121, 120, 120); margin-bottom: 20px; }";
html += "#avSlots { font-size: 1.6em; margin-bottom: 10px; font-weight: bold; }";
html += "button { background-color: #FFC300; color: #000814; width: 150px; height: 45px; font-size: 1em; font-weight: bold; border: none; border-radius: 20px; cursor: pointer; transition: background-color 0.3s ease, transform 0.2s ease; margin-top: 25px; margin-left: 2px; }";
html += "#slotBtn { background-color: transparent; border: #FFC300 solid 2px; color: #fcce37; margin-right: 10px; }";
html += "button:hover { background-color: #e0ac00; transform: scale(1.05); }";
html += "img { width: 350px; height: auto; border-radius: 10px; }";
html += "ul { list-style-type: none; padding: 0; margin: 0; }";
html += "li { font-size: 1.2em; margin-bottom: 10px; padding-left: 0; margin-left: 0; }";
html += "@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }";
html += "@keyframes slideIn { from { transform: translateX(-100%); } to { transform: translateX(0); } }";
html += "</style>";
html += "</head><body>";
html += "<div class='card'>";
html += "<img src='https://assurancecreative.com/wp-content/uploads/2023/09/Car-Photo-Mirror-Effect-After.jpg' alt='Smart Parking'>";
html += "<div class='content'>";
html += "<h1>Smart Parking System</h1>";
html += "<p id='ip'>IP Address: " + WiFi.localIP().toString() + "</p>";
html += "<p id='avSlots'>Available Slots: " + String(availableSlots) + "</p>";
for (int i = 0; i < 4; i++) {
html += "<p>Slot " + String(i + 1) + ": " + parkingStatus[i] + "</p>";
}
html += "<div>";
html += "<a href='/status'><button id='slotBtn'>Slot Status</button></a>";
html += "<a href='/bill'><button id='billBtn'>View Bill</button></a>";
html += "</div>";
html += "</div>";
html += "</div>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void handleStatus() {
String html = "<html><body>";
html += "<h1>Slot Status</h1>";
for (int i = 0; i < 4; i++) {
html += "<p>Slot " + String(i + 1) + ": " + parkingStatus[i] + "</p>";
}
html += "<a href='/'><button>Back</button></a>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void handleBill() {
String html = "<html><body>";
html += "<h1>Parking Bill</h1>";
html += "<p>Entry Time: " + getFormattedTime(entryTime) + "</p>";
html += "<p>Exit Time: " + getFormattedTime(exitTime) + "</p>";
html += "<p>Bill Amount: LKR " + String(billAmount) + "</p>";
html += "<a href='/'><button>Back</button></a>";
html += "</body></html>";
server.send(200, "text/html", html);
}
-----------------------------------------------------------------------------------------------------------------------------
Code for Arduino Board:-
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);
const int entryTrig = 2;
const int entryEcho = 3;
const int exitTrig = 4;
const int exitEcho = 5;
const int irPins[4] = {6, 7, 8, 9};
const int servoPin = 10;
bool slotStatus[4] = {false, false, false, false};
bool entryDetected = false;
bool exitDetected = false;
Servo barrierServo;
void setup() {
Serial.begin(9600);
lcd.begin();
lcd.backlight();
lcd.print("Smart Parking");
pinMode(entryTrig, OUTPUT);
pinMode(entryEcho, INPUT);
pinMode(exitTrig, OUTPUT);
pinMode(exitEcho, INPUT);
for (int i = 0; i < 4; i++) {
pinMode(irPins[i], INPUT);
}
barrierServo.attach(servoPin);
barrierServo.write(0);
}
void loop() {
entryDetected = checkUltrasonic(entryTrig, entryEcho);
exitDetected = checkUltrasonic(exitTrig, exitEcho);
for (int i = 0; i < 4; i++) {
slotStatus[i] = !digitalRead(irPins[i]);
}
displaySlotStatus();
if (entryDetected) {
openBarrier();
Serial.println("E");
} else if (exitDetected) {
openBarrier();
Serial.println("X");
} else {
closeBarrier();
}
delay(500);
}
bool checkUltrasonic(int trigPin, int echoPin) {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
int distance = duration * 0.034 / 2;
if (distance < 10) {
return true;
} else {
return false;
}
}
void displaySlotStatus() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Slots: ");
for (int i = 0; i < 4; i++) {
lcd.print(slotStatus[i] ? "X" : "O");
}
}
void openBarrier() {
barrierServo.write(90);
}
void closeBarrier() {
barrierServo.write(0);
}
0 Comments