CameraSend

CameraSend is a arduino sketch created to save photos from esp32 to a http server using http POST.

This sketch also included MQTT

The PIR motion sensor used in this sketch behaviour has two potentiometer based controls: In summary, the sensitivity adjustment on PIR motion sensors affects how responsive they are to changes in infrared radiation within their detection range. Higher sensitivity settings increase responsiveness to smaller changes but may also increase the likelihood of false triggers, while lower sensitivity settings reduce false triggers but may require larger movements to activate the sensor.

Coverage Area: PIR sensors have a field of view (FOV) that determines the area they can monitor. This FOV is typically cone-shaped and can vary based on the sensor’s design.

Distance: The maximum detection distance depends on the sensor’s optics and sensitivity settings. Lower sensitivity settings might extend the effective detection distance slightly because they filter out smaller changes in infrared radiation that might not be relevant to detecting human-sized movements.

Setting the sensitivity to minimal and time delay to medium seem to give optimal number of photos for humans , as of 2024-06-22 12:28

Timestamped filenames

Storing and Restoring Epoch Time: preferences.putULong(“lastEpochTime”, currentEpochTime); stores the current epoch time before going to sleep. restoreEpochTime() restores the epoch time upon waking up and adjusts it based on the elapsed time since the last update.

Reducing NTP Queries:

The code queries the NTP server only once per day or after a reboot. This minimizes the number of NTP queries and helps to generate unique filenames even without continuous internet access.

Fallback Mechanism:

If the ESP32 cannot get the time from the NTP server, it uses the previously stored epoch time and keeps it updated based on the internal clock (using millis()).

Timezone Setting: The setTimezone() function adjusts the time zone based on the provided timezone string.

Updating Time from NTP: The updateEpochTimeFromNTP() function connects to the NTP server and updates the time, then sets the timezone.

Restoring Time: The restoreEpochTime() function restores the time from preferences and the time zone is set again to ensure it is correct.

Initialization Logic: The initTime() function decides whether to update the time from the NTP server or restore it from preferences. It ensures the time zone is set correctly in both cases.

Generating Filenames: The getPictureFilename() function generates filenames based on the current time, ensuring unique and accurate timestamps.

Flask App

For testing purpose,this sketch made use of flask and python as http server.

prabu@homepc2 ~/s/CameraSend (master)> python uploads/app.py
prabu@homepc2 ~/s/CameraSend (master)> cat uploads/app.py

from flask import Flask, request, jsonify
import os

app = Flask(__name__)

# UPLOAD_FOLDER = '/path/to/your/upload/folder'  # Replace with your desired upload folder
UPLOAD_FOLDER = '/home/prabu/sketches/CameraSend/uploads'  # Replace with your desired upload folder
if not os.path.exists(UPLOAD_FOLDER):
    os.makedirs(UPLOAD_FOLDER)

@app.route('/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return 'No file part in the request', 400

    file = request.files['file']
    if file.filename == '':
        return 'No selected file', 400

    file.save(os.path.join(UPLOAD_FOLDER, file.filename))
    return 'File uploaded successfully', 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000, debug=True)

Suggestion from Chatgpt for Using Apache or Nginx

If you’re using Apache or Nginx, you can configure them to work with more modern methods:

For Apache:

Install mod_wsgi: This module allows Apache to serve Python applications via the WSGI (Web Server Gateway Interface).

sh

sudo apt-get install libapache2-mod-wsgi-py3

Create a Flask Application:

Follow the Flask example provided earlier.

Configure Apache:

Create a configuration file for your site, e.g., /etc/apache2/sites-available/myapp.conf:

apache

<VirtualHost *:80> ServerName mysite.com WSGIScriptAlias / /var/www/myapp/myapp.wsgi <Directory /var/www/myapp> Require all granted </Directory> Alias /static /var/www/myapp/static <Directory /var/www/myapp/static/> Require all granted </Directory> </VirtualHost>

Create the WSGI file:

/var/www/myapp/myapp.wsgi

python

import sys import logging logging.basicConfig(stream=sys.stderr) sys.path.insert(0, “/var/www/myapp”)

from myapp import app as application

Enable the site and restart Apache:

sh

sudo a2ensite myapp sudo service apache2 restart

For Nginx:

Install Gunicorn: This is a WSGI HTTP Server for Python applications.

sh

pip install gunicorn

Create a Gunicorn service:

Create a systemd service file for Gunicorn, e.g., /etc/systemd/system/myapp.service:

ini

[Unit] Description=gunicorn daemon for myapp After=network.target

[Service] User=www-data Group=www-data WorkingDirectory=/var/www/myapp ExecStart=/usr/local/bin/gunicorn –workers 3 –bind unix:/var/www/myapp/myapp.sock -m 007 wsgi:app

[Install] WantedBy=multi-user.target

Configure Nginx:

Create an Nginx configuration file, e.g., /etc/nginx/sites-available/myapp:

nginx

server { listen 80; server_name mysite.com;

location / { proxy_pass http://unix/var/www/myapp/myapp.sock ↗ ; }

location _static_ {
    alias _var/www/myapp/static_;
}

}

Enable the Nginx site and restart services:

sh

sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled sudo systemctl start myapp sudo systemctl enable myapp sudo systemctl restart nginx


© Prabu Anand K 2020-2026