// Import Library
#include <LiquidCrystal.h>
#include <WiFi.h>
#include <PubSubClient.h>
// Update these with values suitable for your network.
const char *ssid = "Wokwi-GUEST";
const char *password = "";
const char *mqtt_server = "broker.mqttdashboard.com";
int port = 1883;
// Create a random client ID
String clientId = String("CarSensor-1000") + String(random(0xffff), HEX);
WiFiClient espClient;
PubSubClient client(espClient);
// rs (LCD pin 4) to Arduino pin 5
// enable (LCD pin 6) to Arduino pin 19
// LCD pins d4, d5, d6, d7 to Arduino pins 13, 12, 14, 27
LiquidCrystal lcd(5, 19, 13, 12, 14, 27);
// Buzzer Positive to pin 1
// Switch Common to pin 2
// Ultrasonic SIG to pin 3
int buzzer = 2, switchBtn = 15;
int echoPin = 23, trigPin = 22;
// Show "Off" Text State
int showOffAlr = 0;
long oldDistance = 0;
// All distance
int stop = 70, should = 95, tclose = 150, closes = 200, gtclose = 300;
void setup_wifi()
{
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect()
{
// Loop until we're reconnected
while (!client.connected())
{
Serial.print("Attempting MQTT connection...");
clientId = String("CarSensor-1000") + String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str()))
{
Serial.println("connected");
// Once connected, publish an announcement...
String text = clientId + String(" Join");
client.publish("swood", text.c_str());
// ... and resubscribe
// client.subscribe("swood");
}
else
{
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup()
{
Serial.begin(115200);
pinMode(buzzer, OUTPUT);
pinMode(switchBtn, INPUT);
// pinMode(bl, OUTPUT);
// digitalWrite(bl, HIGH); // turn backlight on
lcd.begin(16, 2); // use 16 col and 2 row
lcd.clear(); // start with a blank screen
lcd.display(); // Turn on the display:
setup_wifi();
client.setServer(mqtt_server, port);
}
void loop()
{
if (!client.connected())
{
reconnect();
}
int sw = digitalRead(switchBtn); // Read switch state
if (sw == HIGH)
{
long cm = sonar();
showText(cm); // Display Distance num, text
beepSound(cm); // Beep Beep Sound up to distance
showOffAlr = 0; // just set value to 0 for off state
}
else
{
if (showOffAlr == 0) // clear display if already show some text
lcd.clear();
// Show this text if switch state is off
lcd.setCursor(6, 0);
lcd.print("Off.");
lcd.setCursor(1, 1);
lcd.print("turn on switch");
showOffAlr = 1;
}
delay(100);
}
long sonar()
{
// The HC-SR04 is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
pinMode(trigPin, OUTPUT);
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(5);
digitalWrite(trigPin, LOW);
return pulseIn(echoPin, HIGH) / 29 / 2; // convert the time into a distance (cm)
}
void beepSound(long cm)
{
int delayVal = beepDelay(cm); // get beep beep delay value
digitalWrite(buzzer, HIGH);
if (delayVal != 0) // if val is 0 then buzzer will not stop beepๆๆๆ
{
delay(delayVal);
digitalWrite(buzzer, LOW); // stop beep
delay(delayVal);
}
}
void showText(int cm)
{
if (oldDistance != cm) // if distance not change then dont need to update display
{
lcd.clear(); // clear all text
lcd.setCursor(0, 0);
if (cm < 336) // Should be in range
{
// Row 1: Show Distance num
lcd.print("Distance: ");
lcd.print(cm);
lcd.print(" cm");
Serial.println(cm);
// Row 2: Show warning text
lcd.setCursor(0, 1);
if (cm <= stop)
{
lcd.print("STOP!");
// Send to MQTT
String text = clientId + String(" Crached");
client.publish("swood", text.c_str());
Serial.println(text);
}
else if (cm <= should)
lcd.print("SHOULD STOP");
else if (cm <= tclose)
lcd.print("TOO CLOSE");
else if (cm <= closes)
lcd.print("CLOSE");
else if (cm <= gtclose)
lcd.print("GETTING CLOSE");
else
lcd.print("NOT CLOSE");
}
else
lcd.print("OUT OF RANGE");
}
oldDistance = cm;
}
int beepDelay(long cm)
{
// return beep beep delay
int milisec = 1000;
if (cm <= stop)
milisec = 0;
else if (cm <= should)
milisec = 75;
else if (cm <= tclose)
milisec = 150;
else if (cm <= closes)
milisec = 300;
else if (cm <= gtclose)
milisec = 600;
return milisec;
}