Differences

This shows you the differences between two versions of the page.

Link to this comparison view

iothings:proiecte:2022sric:motion-detection [2023/06/02 04:04]
denis.zoican
iothings:proiecte:2022sric:motion-detection [2023/06/02 08:25] (current)
denis.zoican [Software Design]
Line 20: Line 20:
   - [[https://​www.emag.ro/​fire-cabluri-tata-tata-arduino-modulosy-20-cm-40-buc-5903689130493/​pd/​DSXWKRMBM/?​cmpid=87002&​gclid=CjwKCAjwg-GjBhBnEiwAMUvNW5PwIBJRkQa1B_L6_S4qtSAiKIHZwc8SP9CVTK0SFbi0vcymN0HNMhoC2AMQAvD_BwE | Connection wires]]   - [[https://​www.emag.ro/​fire-cabluri-tata-tata-arduino-modulosy-20-cm-40-buc-5903689130493/​pd/​DSXWKRMBM/?​cmpid=87002&​gclid=CjwKCAjwg-GjBhBnEiwAMUvNW5PwIBJRkQa1B_L6_S4qtSAiKIHZwc8SP9CVTK0SFbi0vcymN0HNMhoC2AMQAvD_BwE | Connection wires]]
  
-=== Hardware ​Schematics ===+=== Schematics ===
  
 {{:​iothings:​proiecte:​2022sric:​motion-detection-schema.png?​700|}} {{:​iothings:​proiecte:​2022sric:​motion-detection-schema.png?​700|}}
Line 26: Line 26:
 ==== Software Design ==== ==== Software Design ====
  
-The project was developed on 2 different boards: ​ +The project was developed on 2 different boards: ESP32 and Raspberry Pi 4.
-1. ESP32 board - the code was written using Arduino IDE, where I used the Arduino libraries +
-2. Raspberry Pi 4 - the code was written in Python, where I used OpenCV and Flask+
  
-1. ESP32 board+=== ESP32 board code ===
  
 The first part of the code is the setup part where I define the variables, constants, used libraries and the logic in the setup function. The first part of the code is the setup part where I define the variables, constants, used libraries and the logic in the setup function.
Line 45: Line 43:
 //define sound speed in cm/uS //define sound speed in cm/uS
 #define SOUND_SPEED 0.034 #define SOUND_SPEED 0.034
-#define CM_TO_INCH 0.393701 
  
-#define WIFI_NETWORK "MERCUSYS_DCEE+#define WIFI_NETWORK "WIFI_NAME
-#define WIFI_PASSWORD "74745814"+#define WIFI_PASSWORD "WIFI_PASS"
 #define WIFI_TIMEOUT 20000 #define WIFI_TIMEOUT 20000
 #define API_URL "​http://​ip-:​5000/​upload_photo"​ #define API_URL "​http://​ip-:​5000/​upload_photo"​
Line 58: Line 55:
  
 void setup() { void setup() {
-  Serial.begin(115200); ​// Starts the serial communication+  Serial.begin(115200); ​
  
   pinMode(buzzerPin,​ OUTPUT);   pinMode(buzzerPin,​ OUTPUT);
-  pinMode(trigPin,​ OUTPUT); ​// Sets the trigPin as an Output +  pinMode(trigPin,​ OUTPUT);  
-  pinMode(echoPin,​ INPUT); ​// Sets the echoPin as an Input+  pinMode(echoPin,​ INPUT); ​
  
   connectToWifi();​   connectToWifi();​
Line 74: Line 71:
 <​code>​ <​code>​
 void connectToWifi(){ void connectToWifi(){
-  Serial.println("​Connecting.. status: " + String(WiFi.status()));​ 
   WiFi.mode(WIFI_STA);​   WiFi.mode(WIFI_STA);​
   WiFi.begin(WIFI_NETWORK,​WIFI_PASSWORD);​   WiFi.begin(WIFI_NETWORK,​WIFI_PASSWORD);​
Line 134: Line 130:
 } }
 </​code>​ </​code>​
 +
 +The loop function contains the main logic of the project. We will calculate the distance every 1 second and if the distance is smaller than 50 cm, the buzzer will generate a high pitched sound for 5 seconds and the esp32 board will make a POST request to the raspberry pi 4 board. After this, a photo will be taken and will be saved in the database.
 +
 +<​code>​
 +void loop() {
 +
 +  long distance = getDistance();​
 +
 +  if(distance < 50){
 +    tone(buzzerPin,​ 1000); ​
 +    makeRequest();​
 +
 +    // Wait for 5 seconds
 +    delay(5000);​
 +    noTone(buzzerPin);​
 +    ​
 +  }
 +  ​
 +  delay(1000);​
 +}
 +</​code>​
 +
 +=== Raspberry Pi 4 board code ===
 +
 +The code that is used on this board is written in Python. This board will play the role of a server that will store the images in a database. The web server is implemented using the Flask framework and the database is implemented using SQLlite.
 +In order to create the database, I used the following python code where I defined a table with id, name and the image content.
 +
 +<​code>​
 +import sqlite3
 +import os
 +
 +database_path = "​./​database.db"​
 +
 +conn = sqlite3.connect(database_path)
 +cursor = conn.cursor()
 +
 +cursor.execute("""​
 +    CREATE TABLE IF NOT EXISTS images (
 +        id INTEGER PRIMARY KEY,
 +        name TEXT,
 +        image_data BLOB
 +    )
 +"""​)
 +
 +conn.commit()
 +conn.close()
 +</​code>​
 +
 +In order to capture a photo using the web cam, I used OpenCV, a library of functions for real-time computer vision. I implemented 3 endpoints:
 +
 +1. upload_photo
 +When it receives a POST request, a photo will be taken using the web cam and the image will be saved in the database.
 +
 +2. image/{id}
 +Is a GET endpoint and returns a image based on the received id.
 +
 +3. image
 +Is a GET endpoint and returns the latest image in the database.
 +
 +<​code>​
 +from flask import Flask, send_file
 +import sqlite3
 +import cv2
 +
 +
 +app = Flask(__name__)
 +database_path = "​./​database.db" ​ # SQLite database file
 +
 +@app.route('/​upload_photo',​ methods=['​POST'​])
 +def upload_photo():​
 +    # Connect to database
 +    conn = sqlite3.connect(database_path)
 +    cursor = conn.cursor()
 +    ​
 +    # Capture a photo
 +    cam = cv2.VideoCapture(0)
 +    ret, frame = cam.read()
 +
 +    if not ret:
 +        print("​failed to grab frame"​)
 +        return
 +
 +    photo_file_path = "​opencv_photo.png" ​
 +
 +    # Read the photo file as binary
 +    with open(photo_file_path,​ '​rb'​) as photo_file:
 +        photo_data = photo_file.read()
 +
 +    # Insert the photo in database
 +    cursor.execute("​INSERT INTO images (name, image_data) VALUES (?, ?)", (photo_file_path,​ photo_data))
 +
 +    conn.commit()
 +    conn.close()
 +
 +    return "Photo was uploaded"​
 +    ​
 +@app.route('/​image'​)
 +def get_image():​
 +    # Connect to database
 +    conn = sqlite3.connect(database_path)
 +    cursor = conn.cursor()
 +
 +    # Retrieve the image from the database wih the highest ID
 +    cursor.execute("​SELECT image_data FROM images WHERE id= (SELECT MAX(id) from images)"​)
 +    result = cursor.fetchone()
 +
 +    # Save the image data to a temporary file
 +    image_data = result[0]
 +    temp_file = "​tempFile.jpg" ​ # Path to temporary file
 +    with open(temp_file,​ "​wb"​) as file:
 +        file.write(image_data)
 +
 +    # Close the database connection
 +    conn.close()
 +
 +    # Send the image file
 +    return send_file(temp_file,​ mimetype='​image/​jpeg'​)
 +    ​
 +@app.route('/​image/<​image_id>'​)
 +def get_image_id(image_id):​
 +    # Connect to the database
 +    conn = sqlite3.connect(database_path)
 +    cursor = conn.cursor()
 +
 +    # Retrieve the image from the database based on the id 
 +    cursor.execute("​SELECT image_data FROM images WHERE id=?", (image_id,​))
 +    result = cursor.fetchone()
 +
 +    # Save the image data to a temporary file
 +    image_data = result[0]
 +    temp_file = "​tempFile.jpg"​
 +    with open(temp_file,​ "​wb"​) as file:
 +        file.write(image_data)
 +
 +    # Close the database connection
 +    conn.close()
 +
 +    # Send the image file
 +    return send_file(temp_file,​ mimetype='​image/​jpeg'​)
 +
 +if __name__ == '​__main__':​
 +    app.run(host='​0.0.0.0',​ port=5000)
 +
 +</​code>​
 +
 +The last photo can be viewed by accessing the url: raspberry-pi-ip:​5000/​image
 +=== Demo ===
 +
 +YouTube link: https://​www.youtube.com/​watch?​v=mqfNEk4cIAE
 +
 +=== References ===
 +
 +  - [[https://​docs.opencv.org/​4.x/​|OpenCV]]
 +  - [[https://​flask.palletsprojects.com/​en/​2.3.x/​|Flask]]
 +  - [[https://​projecthub.arduino.cc/​Isaac100/​getting-started-with-the-hc-sr04-ultrasonic-sensor-7cabe1|HC-SR04]]
 +  - [[https://​www.sqlite.org/​docs.html|SQLlite]]
  
  
  
  
iothings/proiecte/2022sric/motion-detection.1685667844.txt.gz · Last modified: 2023/06/02 04:04 by denis.zoican
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0