Utiliser la caméra du Raspberry Pi avec un détecteur de mouvement

Bonjour à tous,

Après avoir utilisé un capteur ultrason et la caméra du Raspberry Pi lors des derniers tutos, nous allons désormais les coupler pour créer un système de détection de mouvement qui prendra une photo de la « cible » à chaque mouvement détecté.

Le matériel et le montage

  • Un raspberry Pi
  • La caméra Raspberry Pi
  • Un capteur ultrason HC-SR04
  • Une planche de prototypage (ou breadboard)
  • Quelques fils M/F et M/M
  • 1 résistance de 470 ohm
  • 1 résistance de 330 ohm

Pour les détails sur ce capteur et son montage, je vous invite à vous rendre sur le tutoriel qui lui est dédié. C’est par ici.

Nous allons utiliser exactement le même montage, si ce n’est qu’en plus, nous allons utiliser la caméra du Raspberry Pi. Pour savoir comment l’installer, rendez vous ici.

Le code

Le code a utiliser est le suivant :

#!/usr/bin/python
# Measure distance using an ultrasonic module
# and take a photo using the raspberry pi camera
# Author : Yaug / Manuel Esteban
# Inspired by : Matt Hawkins
# Date   : 04/06/2013

# Import required Python libraries
import time
import RPi.GPIO as GPIO
import datetime
from subprocess import call

# Use BCM GPIO references
# instead of physical pin numbers
GPIO.setmode(GPIO.BCM)

# A couple of variables Define GPIO to use on Pi ---------------------
GPIO_TRIGGER = 23
EXIT = 0 # Infinite loop
GPIO_ECHO = 24
lastdistance = 0.0
sensitivity = 10 #sensitivity %

# Set pins as output and input
GPIO.setup(GPIO_TRIGGER,GPIO.OUT)  # Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN)      # Echo

# Set trigger to False (Low)
GPIO.output(GPIO_TRIGGER, False)

# Allow module to settle
time.sleep(0.5)

# Send 10us pulse to trigger
def measure():
  GPIO.output(GPIO_TRIGGER, True)
  time.sleep(0.00001)
  GPIO.output(GPIO_TRIGGER, False)
  start = time.time()

  while GPIO.input(GPIO_ECHO)==0:
    start = time.time()

  while GPIO.input(GPIO_ECHO)==1:
    stop = time.time()
  # Calculate pulse length
  elapsed = stop-start

  # Distance pulse travelled in that time is time
  # multiplied by the speed of sound (cm/s)
  distance = elapsed * 34300

  # That was the distance there and back so halve the value
  distance = distance / 2

  #print "Distance : %.1f" % distance
  return distance

def measure_average():
  count = 1
  # Reset GPIO settings GPIO.cleanup()
  distance = 0
  while ( count <= 3 ):
    distance = distance + measure()
    time.sleep(0.1)
    count = count + 1
  distance = distance / 3
  return distance

try:
  # Never ending loop -----------------
  while EXIT == 0:
    distance = measure_average()
    if lastdistance <> 0.0:
      minDiff = lastdistance * (100 - sensitivity) / 100
      maxDiff = lastdistance * (100 + sensitivity) / 100
      if distance < minDiff or distance > maxDiff:
        print "on prend une photo"
        t = datetime.datetime.now()
        timeStr = t.strftime('%Y%m%d-%H%M%S')
        call (["raspistill -o image_"+timeStr+".jpg -t 100"], shell=True)
        time.sleep(0.2)
      #print "minDiff : %.1f" % minDiff
      #print "maxDiff : %.1f" % maxDiff
    print "distance : %.1f" % distance
    print "last distance : %.1f" % lastdistance
    lastdistance = distance

except KeyboardInterrupt:
  # Reset GPIO settings
  GPIO.cleanup()

On lance ensuite le script de la manière suivante :

sudo python detector.py

Et hop le script va tourner en boucle, et prendre une photo dès qu’il détecte une variation de distance importante.

Voici le genre d’affichage qu’on obtient

Affichage du script

Affichage du script

Les images se trouvent dans le même dossier sous la forme «  image_20130617-071154.jpg ».

Personnaliser le script

Pour l’adapter à vos besoins, vous pouvez modifier le code autant que vous le souhaitez. Les variables qui peuvent vous intéresser sont les suivantes :

  • sensitivity : permet de régler la sensibilité du capteur, en pourcentage. Essayez d’abaisser ce pourcentage voir si cela n’est pas trop sensible. Plus c’est bas mieux c’est, mais vu qu’avec son capteur, on peut avoir quelques mauvaises mesures dans le lot.
  • time.sleep(0.2) : à la ligne 83. Cette ligne est importante, car sans l’avoir, la plupart des photos sont juste noire, et pour cause, du coup, le buffer n’a pas le temps de se vider dans le fichier image. Vous pouvez tester d’abaisser cette période morte pour accélérer les choses.
  • timeStr : Format de la date qui sert pour le fichier.

Pour un peu plus de propreté, vous pouvez déplacer les photos dans un autre dossier.

Autre astuce : si vous avez installé un serveur de mail, vous pouvez envoyer un email avec la photo prise à l’intérieur. Mais du coup… attention, pensez à sortir votre animal de compagnie de la pièce si vous ne voulez pas vous faire flooder de mails dans la journée :)

Si vous avez une question ou une amélioration

Laisser un commentaire

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

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>