DashCam à base de Raspberry Pi Zero

Préambule

Parfois, il faut savoir changer. Et j’ai acheté des étagères (bibliothèque Billy) pour (enfin) ranger/classer/trier/regrouper/concaténer mes innombrables récupérations.
Ce faisant, j’ai testé des cartes µSD qui « traînaient » et retrouvé ma version de RaspberryPiOS qui me servait de DashCam et de prise de photos mode TimeLapse.

Et vous savez quoi ?
Ben, j’ai voulu refaire ça à la sauce du jour (c’est à dire sur un OS à jour).

Concept

L’idée est assez simple.

J’utilise un Raspberry Pi Zero avec un module RaspiCam V2.

Quand on l’allume (batterie externe servant à recharger les téléphones), il démarre et lance un script python qui réalise une vidéo de 30 secondes puis fait une pause de 1 seconde puis recommence (boucle while).

Pour que tout soit clair et facile (en cas de besoin), il nomme ses vidéos selon un horodatage type 2025-06-01_22-04-15.jpg ce qui signifie que le système nécessite un module RTC DS3231 pour rester à l’heure.

Évidemment, aucun moyen de le piloter donc j’utilise un Raspberry Pi Zero W (W signifie qu’il dispose d’un module WiFi) afin de générer un point d’accès permettant de s’y connecter en SSH si besoin.

Et comme je veux pourvoir l’éteindre sans rien faire (le SSH, c’est cool, mais faut un tel ou un PC), il doit s’éteindre avec un simple bouton minimaliste (le même genre de micro interrupteur qui fait le « clic » dans une clef de voiture).

Matériel

  • Raspberry Pi Zéro W
  • Module RaspiCam V2
  • Module RTC DS3231
  • Adaptateur microUSB vers USB
  • Batterie externe et/ou adaptateur allume-cigare
  • Micro interrupteur (1 ou 2, mais 2, c’est mieux)
  • Câbles Dupont
  • Un truc pour faire le corps (j’avais modifié et imprimé un boîtier*)
  • Un adaptateur USB vers RJ45 le temps de l’installation

Installation de l’OS

Je ne vais rien vous cacher. J’ai voulu porter mon ancien système sur BookWorm (Debian12) et j’ai bien galéré. Surtout, le résultat final n’était pas satisfaisant. Pour faire simple, la vidéo de 30 secondes ne durait que 15-20 secondes car était accélérée.

Je voulais donc repartir sur Raspivid et j’ai pour cela utilisé la version de BullsEye (Debian 11) avec mises à jour de sécurité qui est aisément disponible sur imager

Raspberry Pi OS (Legacy) Lite

  • Release date: May 6th 2025
  • System: 32-bit
  • Kernel version: 6.1
  • Debian version: 11 (bullseye)
  • Size: 366MB

Pour résumer, vous installez Imager et l’utilisez pour flasher votre carte µSD avec cette image « ancienne mais récente ».
Perso, j’applique des modif à l’écriture avec un nom d’utilisateur et un mot de passe.

Configurations additionnelles

Caméra

Pour réaliser une Dashcam, on va devoir enregistrer des vidéos donc il nous faut un script python qui utilise le module caméra.
Selon mes tests, c’est vraiment raspivid qui fonctionne le mieux (j’ai testé le nouveau système libcamera (module V2 et module V2) et ffmpeg (avec WebCam), mais, sur Rpi Zero, c’est décevant).
Du coup, il faut activer l’ancien module pour utiliser raspivid sur Bullseye.
Cela est réalisable via raspi-config (option Interface > Caméra).
(Explication : le support de la PiCam est désormais basé sur libcamera et raspivid n’est plus supporté nativement. Sur Bullseye, on peut encore choisir de basculer sur l’ancien support).

Module RTC

Comme on veut enregistrer et garder les vidéos avec nommage parlant, on va activer l’option I2C (désactivée par défaut) avec sudo raspi-config .
Vous pouvez voir mon article Ajout d’un module RTC DS3231 au Raspberry Pi qui me parait de toute beauté (en toute objectivité, hein).

Bouton(s)

Je conseille de connecter un bouton au port 24 pour avoir une extinction propre.
Voire même un autre sur le port 13 pour un arrêt de l’enregistrement facilité (création du fichier STOP).
Ici, je n’ai qu’un bouton car c’est un truc de récup qui s’intègre proprement.
J’ajouterai un autre bouton « volant » plus tard (ce que j’avais fait sur la version initiale).

Script vidéo

Ce script est l’élément principal qui permet de transformer le Raspberry Pi Zéro équipé d’une caméra en une dashcam basique.
Il enregistre des vidéos de 30 secondes en boucle, les stocke dans un dossier dédié, et s’arrête proprement si un fichier nommé STOP est détecté.

Fonctionnement :

  1. Création du dossier videos/ s’il n’existe pas.

  2. Capture en boucle de vidéos de 30 s (raspivid).

  3. Pause de 1 s entre chaque enregistrement.

  4. Vérification de l’existence du fichier STOP — si trouvé, le script s’arrête (je veux pouvoir garder la main sur l’enregistrement).

  5. Tout est journalisé dans dashcam.log.

Code complet :

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import os
import time
import logging
import subprocess

# Configuration
CURRENT_WORKING_DIR = "/home/alban/DashCam"
ARCHIVE_DIR = "videos"
VIDEO_DIR = os.path.join(CURRENT_WORKING_DIR, ARCHIVE_DIR)
VIDEO_DURATION_MS = 30000  # Durée vidéo en millisecondes (30s)
VIDEO_WIDTH = 967
VIDEO_HEIGHT = 628
SLEEP_AFTER_VIDEO = 1  # Pause entre les vidéos (en secondes)
STOP_FILENAME = "STOP"

# Setup logging simple
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler(os.path.join(CURRENT_WORKING_DIR, "dashcam.log")),
        logging.StreamHandler()
    ]
)

def ensure_video_dir():
    if not os.path.isdir(VIDEO_DIR):
        logging.info(f"Création du dossier vidéos : {VIDEO_DIR}")
        os.makedirs(VIDEO_DIR, mode=0o777, exist_ok=True)

def record_video():
    filename = time.strftime("%Y-%m-%d_%Hh%Mm%S") + ".mp4"
    filepath = os.path.join(VIDEO_DIR, filename)
    logging.info(f"Lancement de la capture vidéo : {filename}")
    try:
        subprocess.run([
            "raspivid",
            "-t", str(VIDEO_DURATION_MS),
            "-w", str(VIDEO_WIDTH),
            "-h", str(VIDEO_HEIGHT),
            "--annotate", "12",
            "-o", filepath,
        ], check=True)
    except subprocess.CalledProcessError as e:
        logging.error(f"Erreur lors de la capture vidéo : {e}")
    else:
        logging.info(f"Vidéo sauvegardée : {filepath}")

def check_stop_file():
    stop_path = os.path.join(VIDEO_DIR, STOP_FILENAME)
    exists = os.path.exists(stop_path)
    if exists:
        logging.info(f"Fichier STOP détecté : {stop_path}")
    return exists

def main():
    logging.info("Démarrage du script DashCam")
    ensure_video_dir()
    time.sleep(10)
    while True:
        record_video()
        time.sleep(SLEEP_AFTER_VIDEO)
        if check_stop_file():
            logging.info("Arrêt demandé, fin du script.")
            break

if __name__ == "__main__":
    main()

Création d’un point d’accès

Je souhaite que cette DashCam soit autonome. Cependant, je veux (comme toujours) garder la main sur le système.

Il suffit de configurer le Raspberry Pi (j’ai pris le RpiZero WiFi) pour qu’il génère un point d’accès. Le but n’est pas d’accéder à Internet, mais de pouvoir s’y connecter et donc de pouvoir bosser dessus en SSH et en SFTP depuis mon PC Linux.

Cela se fait simplement en suivant cette procédure :

Installation de hostapd et de dnmasq :
sudo apt install hostapd dnsmasq -y

Arrêt des deux services afin de modifier les conf :
sudo systemctl stop hostapd && sudo systemctl stop dnsmasq

Passage en mode édition du point d’accès :
sudo nano /etc/hostapd/hostapd.conf

Pour y insérer ces info (à personnaliser selon votre cas) :

interface=wlan0
driver=nl80211
ssid=DashCam
hw_mode=g
channel=6
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=DashCam_Pass
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

Puis édition de la configuration du point d’accès :
sudo nano /etc/default/hostapd

Afin d’y ajouter la ligne pointant vers hostpad.conf créé précédemment (ajout en fin de fichier).
DAEMON_CONF="/etc/hostapd/hostapd.conf"

Ensuite, on édite la conf du proxy :
sudo nano /etc/dnsmasq.conf

Pour ajouter (en fin de fichier)

# Point d'accès DashCam :
# Interface utilisée
interface=wlan0
# Ne transmet pas les requêtes avec nom de domaine incomplet
domain-needed
# Ne retourne pas toutes les requêtes DNS inverses
bogus-priv
# plage d'adressage IP, masque et durée du bail
dhcp-range=192.168.80.150,192.168.80.159,255.255.255.0,12h

Enfin, on édite le fichier dhcpd pour utiliser une adresse IP fixe spécifique :
sudo nano /etc/dhcpcd.conf

En ajoutant (à la fin du fichier) :

nohook wpa_supplicant
interface wlan0
static ip_address=192.168.80.10/24
static routers=192.168.80.1

On passe hostapd, en « unmask » :
sudo systemctl unmask hostapd

Normalement, au redémarrage, le signal WiFi « DashCam » sera détectable.

Ajout du module RTC

Si vous ne l’avez pas fait auparavant, c’est le moment.
Cela permet d’avoir un horodatage des images avec la date réelle.
D’autant plus que j’incruste l’horodatage sur la vidéo elle-même.

Automatisation

Il suffit d’éditer le fichier /etc/rc.local en sudo et de transformer la partie :

fi

exit 0

en :

fi
hwclock -s &

#Lancement du script d'extinction par bouton :
python3 /home/alban/extinction.py &

#Lancement de la fonction DashCam
python3 /home/alban/DashCam/dashcam_new.py &

exit 0

(Oui, je m’appelle Alban… Donc oui, vous devez adapter et ne pas juste copier/coller 😉 )

Script d’arrêt

Création d’un fichier nommé /home/alban/extinction.py et contenant :

#!/usr/bin/python3

#on importe les modules nécessaires
import time
import os
import RPi.GPIO as GPIO

#on met RPi.GPIO en mode notation BCM (numéro des pins ; ne vous trompez pas ; voir https://fr.pinout.xyz)
GPIO.setmode(GPIO.BCM)

#on initialise le GPIO 13 en écoute (broche physique 33 mais BCM pin 13)
GPIO.setup(13, GPIO.IN, pull_up_down=GPIO.PUD_UP)

#on initialise le GPIO 24 en écoute (broche physique 18 mais BCM pin 24)
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)

#on définit la fonction appelée par la pression du bouton
def extinction(channel):
#on reinitialise les GPIO
GPIO.cleanup()
#on lance la commande d'extinction
print('Arrêt demandé via bouton')
os.system('sudo poweroff')

def stop_video(channel):
#on reinitialise les GPIO
GPIO.cleanup()
#on lance la commande d'arrêt
os.system('touch /home/pi/DashCam/videos/STOP')

#on met le bouton en écoute
GPIO.add_event_detect(13, GPIO.FALLING, callback=stop_video)
GPIO.add_event_detect(24, GPIO.FALLING, callback=extinction)

#on lance une boucle infinie, pour garder le script actif
while True:
#Avec une légère pause entre chaque boucle dans le but de réduire la charge CPU
time.sleep(0.02)

#on réinitialise les ports GPIO en sortie de script
GPIO.cleanup()

Notes additionnelles

Rappel : on fait un chmod +x des différents scripts (pour les rendre exécutables).

Le boîtier d’origine est visible ici : Raspberry Pi Zero W Case w/Camera (le mien est modifié pour être plus profond afin que tout rentre facilement).

Galerie et vidéo

Vidéo du 08 Juin 2025 (la date incrustée est au format américain) :

Accès depuis mon PC LinuxMint en SFTP au RpiZero grâce à son point d’accès WiFi.

Cela me permet de visualiser les vidéos « en direct » comme si j’étais vraiment sur le Rpi car je bénéficie de la navigation par explorateur de fichiers.

Cela me permet aussi de créer un fichier STOP dans le dossier « videos », ce qui aura pour conséquence de stopper les enregistrements (sans éteindre la DashCam).

 

Accès depuis mon PC LinuxMint en SSH au RpiZero grâce à son point d’accès WiFi.

On visualise bien que, suite à la création du fichier STOP, le script s’est arrêté (je l’avais lancé manuellement pour vous faire la démonstration visuelle).

On visualise également la perte de connectivité suite à mon appui sur le bouton au dos de la DashCam (ce bouton envoie un « poweroff »).

 

 

Conclusion

Voilà une petite DashCam sans prétention utile pour certains voyages et pour « apprendre à faire ». On est bien d’accord que les DashCams se trouvent dans le commerce à des prix raisonnables. Cependant, je n’aime pas dépenser et j’aime « jouer à faire », ce qui motive cette réalisation et cet article.

Une évolution serait d’avoir un écran minimaliste et 4 boutons pour « Arrêt » ; « Création du fichier STOP » ; « Remove du fichier STOP » ; « Reboot ». Cependant, cela signifie acheter et, vraiment, je n’aime pas l’idée 😀

Pour compléter : je suis doté d’une carte SD de 128 Go pour être large et ne pas devoir effacer les vidéos au fur et à mesure.

Cependant, l’idée serait de 

  • Soit prévoir un effacement lorsque la carte atteint 90% (simple script)
  • Soit prévoir de ne sauvegarder que sur conditions (comme dans une vraie DashCam (genre si on appuie sur un bouton, ça « marque » les vidéos pour éviter leur suppression.

Mais soyons d’accord, on sort du contexte du truc « juste pour jouer » 😉

A propos de Alban

Papa de 4 enfants étant lui-même resté un enfant. Diététicien-Nutritionniste tombé par obligation dans l'informatique à 22 ans pour le boulot et s'étant "un peu" pris au jeu ... Pas un génie de l'informatique (loin de là), mais intéressé et carrément orienté Linux et entraide. Lassé de l'évolution du Monde de la Santé dans lequel les patients sont de plus en plus à traiter comme des clients (je suis un soignant !!!), j'ai opté pour une reconversion en repartant en Alternance... à... 44 ans D'abord dans le cadre d'un BTS SIO option SISR (Solutions d’Infrastructure, Systèmes et Réseaux) en Septembre 2019. Après l’obtention du BTS, j'ai décidé de poursuivre (toujours en alternance) en Bac+3 avec un Bachelor Concepteur de Systèmes d'Information. Depuis septembre 2022, je suis donc encore plus vieux, mais un jeune diplômé "Administrateur Systèmes et Réseaux". Citation personnelle : « Si la réussite facile flatte l’égo, C’est de la persévérance que nait le plaisir de la réussite. »

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.