Car Reverse Sensor

ถอยรถจนตูดเป็นรอยหมดใช่ไหม ดูนี่สิเซนเซอร์ตรวจจับระยะห่างท้ายรถ! ทำให้คุณถอยรถได้โดยไม่ต้องใช้ตามอง เพียงฟังเสียงตี๊ดๆๆ ตูดคุณก็จะไม่เป็นรอยอีกต่อไป
Demo

Message

Message
No signal

Project Detail

Car Reverse Sensor หรือ เซนเซอร์วัดระยะห่างของรถยนต์ สร้างขึ้นมาเพื่อใช้ในการถอยรถยนต์เพื่อเข้าจอด โดยใช้ ultrasonic distance sensor ซึ่งเป็นเซ็นเซอร์ที่ใช้สำหรับตรวจจับวัดถุต่างๆ โดยอาศัยหลักการสะท้อนของคลื่นความถี่เสียง คำนวณหาค่าระยะทางได้จากการเดินทางของคลื่นและนำมาเทียบกับเวลา ด้วยกลไกดังกล่าวทำให้สามารถนำมาประยุกต์ใช้งานในรูปแบบต่างๆ ได้อย่างมากมาย มาเป็นตัวควบคุมการทำงานของระบบ โดยหากรถยนต์ได้ถอยมากระทบกับวัตถุบางอย่าง จะใช้สัญญาณ WiFi เพื่อส่งสัญญานเตือนผ่านหน้า Website เพื่อแจ้งเตือนให้ผู้ใช้งานได้ทราบ

Example Video

Source code

ในส่วนของ Code นั้นเราได้ทำการอัพไว้บน Github สามารถกดลิงค์นี้ https://github.com/poompongphun/compro-project/blob/main/microcontroller-code/esp32.cpp เพื่อเข้าไปดูได้เลย หรือจะใช้ลิงค์นี้ https://wokwi.com/projects/330841959706919507 เพื่อดูโค้ดและการต่อวงจร พร้อมผลลัพธ์ได้

Code


// Import Library
#include "LiquidCrystal.h"
#include "WiFi.h"
#include "PubSubClient.h"
            
เริ่มแรกเราได้ทำการ Include library เข้ามาคือ LiquidCrystal.h ใช้สำหรับแสดงผลข้อความบนจอ LCD, WiFi.h ใช้สำหรับเชื่อต่อ wifi และ PubSubClient.h ใช้สำหรับ connect mqtt และทำการกำหนด Global variable ดังนี้

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;
            
จากนั้นสร้าง function ที่ชื่อว่า setup_wifi ขึ้นมาเพื่อใช้สำหรับ connect wifi ซึ่งเราได้ใช้ ssid และ password ของ wokwi ที่ตั้งไว้ข้างต้นในการ connect ถ้ายัง connect ไม่ติดก็จะแสดงผล ... ไปเรื่อยๆ เมื่อ connected ก็จะแสดงผล WiFi connected พร้อมกับ local IP

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());
}
            
จากนั้นสร้าง function ชื่อว่า reconnect ที่ใช้สำหรับ connect mqtt โดยจะทำซ้ำเรื่อยๆหากยังไม่สามารถ connect กับ mqtt server และเราได้ Random client id ใหม่ทุกครั้งที่มีการ connect เพื่อใช้ในการ connect หาก connect สำเร็จก็จะส่งข้อความว่า Client id นี้ได้ทำการ Join ไปยัง channel ที่ชื่อว่า swood ซึ่งบนเว็บของเราได้ทำการ handle channel นี้ไว้ด้วย สามารถเลื่อนขึ้นไปดูด้านบนหัวข้อ Message

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());
    }
    else
    {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
            
ต่อมาทำการ setup esp32 โดยมีการกำหนด pinMode, กำหนดขนาด LCD และเปิดใช้งาน, เรียกใช้ func setup_wifi เพื่อเชื่อมต่อ wifi และตั้งค่า mqtt server และ port ที่จะเชื่อมต่อ

void setup()
{
  Serial.begin(115200);
  pinMode(buzzer, OUTPUT);
  pinMode(switchBtn, INPUT);

  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);
}
            
ก่อนจะทำการเขียนการทำงานต่างๆในตัวบอร์ด เราได้สร้าง function เหล่านี้ขึ้นมาเพื่อความสะดวกในการเขียนและอ่าน ดังนี้

// Sonar Function ใช้สำหรับอ่านค่าจาก HC-SR04 และแปรงเป็นระยะห่างหน่วย Cm
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)
}
          

// beepDelay ใช้สำหรับ Return ค่า Delay ที่จะหน่วง buzzer ให้ถี่ตามที่กำหนด
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;
}

// beepSound Function ใช้สำหรับสั่งให้ buzzer ดัง
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);
  }
}
            

// showText Funtion ใช้สำหรับแสดงตัวอักษรตามระยะห่างที่รับค่าเข้ามา และส่งข้อความไปยัง mqtt server หากระยะห่างนั้นน้อยมาก
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;
}
            
สุดท้ายเขียนการทำงานต่างๆลงใน function loop ของเจ้าบอร์ด โดยทุกครั้งจะมีการเช็คว่าเชื่อมต่อกับ server อยู่รึป่าวหากไม่ก็จะทำการเชื่อต่อใหม่ และทำการอ่านค่าจาก Switch หากเป็น Low ก็ทำการ clear LCD และแสดงผลข้อความให้รู้ว่า Switch ยังถูกปิดอยู่ แต่หากเป็น High ก็จะทำการเรียกใช้ function sonar เพื่อรับค่าระยะห่างจาก HC-SR04 แล้วส่งไปยัง function showText เพื่อแสดงข้อความตามระยะห่างนั้นๆ และก็ส่งไปยัง function beepSound เพื่อให้ buzzer ถี่ตามระยะห่างนั้นๆ และก็เสร็จสมบูรณ์!!

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);
}
            

Meet the Team