Domotique : Détecteur d'ouverture de porte par ultrason

05 avril 2018 rdorigny 0 commentaires

Nous avons vu précedement comment mesurer une distance avec un capteur à ultrason. Je vous propose dans cet article une autre application du HY-SRF05, il s'agit de détecter l'ouverture d'une porte sectionnelle de garage.

Nous allons voir comment mettre en oeuvre un sonar communiquant qui nous avertira en cas d'ouverture/fermeture de la porte par SMS. Pour cela, nous utiliserons un Raspberry pi Zero WH et un peu de code Python.



Je ne reviens pas dans cet article sur le principe de fonctionnement du capteur à ultrason et sur le schéma du montage avec le RasBerry Pi. Vous trouverez tous les détails ici.

1) Mise en oeuvre du boitier

Pour commencer, il faut disposer d'un boitier le plus adapté à notre engin afin de le protéger. L'idéal serait de disposer d'une imprimante 3D pour fabriquer un boitier adapté, malheureusement ce n'est pas mon cas. Après un moment de réflexion, j'ai opté pour une boite de dérivation de taille classique (105 mn). Avantages, on en trouve partout, les trous pour passer les câbles sont déjà existants, et l'ouverture faciale est facile.

Avant de commencer, je conseille de réaliser une maquette avec un carton, un peu de scotch et une plaque de montage breadboard. Il suffira alors de faire deux trous dans le carton pour l'émetteur et le récepteur. Cela permet nous de savoir où positionner le futur boitier et surtout de son orientation. Point important, l'angle doit être le plus perpendiculaire possible. Autre point, qui parait évident, une surface plane de réception pour obtenir des données de distance cohérentes.


Une fois que l'on obtient des mesures cohérentes, on passe à la préparation du boitier. Faite un marquage au crayon gras, pour ensuite percer (foret métal de 5mn) le plastique.


On peut assez facilement fixer le Raspberry pi avec de petites vis dans la boite. Pour le pont diviseur, j'ai réalisé une soudure à l'arrache, je vous conseille plutôt d'utiliser des plaques de prototypes pour circuit électronique. On en trouve de toutes les tailles sur Amazon. J'en ai profité pour ajouter une sonde thermique ds18b20 (vous trouverez un article ici sur le sujet) et le faire sortir le capteur de la boite.

Voila ce que çà donne une fois sur place dans le garage:

2)Le script

Forcément,j'ai quelque peu modifié le script Python. Comme souvent dans mes scripts, je fais un daemon fonctionner en arrière plan plutôt que via un module Linux. Ensuite, toutes les 10 secondes, je lance un processus qui réalise 3 mesures, fais la moyenne des trois, et envoie un SMS s'il détecte un changement d'état sur l'ouverture/fermeture de la porte.

#*****************************************************************************************************
#
#                          Robert DORIGNY - www.doritique.fr le 2 avril 2018
#
#                 Ce script pour construire un sonar de detection de porte avec un HY-SRF05
#
#*****************************************************************************************************

from __future__ import print_function
import os
import sys
import time
import datetime
import urllib2
import urllib
import threading	
import RPi.GPIO as GPIO

GPIO_TRIGGER = 23
GPIO_ECHO    = 24
speedSound   = 33112
position     = 0  # Conserve en memoire la position de la porte, 0 pour fermee et 1 pour ouverte
Mem = [0,0,0] #Conserve en memoire les dernieres mesures
Longueur_Seuil=300
TabSMS = [["votreid", "votrecle"]]  #telephones cible des SMS

#Fonction chargee de la transmission des donnees
def sendval():
  #Emission SMS
  date = datetime.datetime.now()
  txt=str(date)
  if (position==0):
    txt="Garage : Porte fermee : "+txt
  else:
    txt="Garage : Porte ouverte : "+txt
  for i in TabSMS:
	data={}
	data['user']=i[0]
	data['pass']=i[1]
	data['msg']=txt
	url_values=urllib.urlencode(data)
	data=urllib2.urlopen("https://smsapi.free-mobile.fr/sendmsg"+"?"+url_values)
  #print("Transmission SMS OK")
  #Trace dans BDD
  data={}
  data['action']='set'
  data['var']='loggarage'
  data['data']=str(position)
  url_values=urllib.urlencode(data)
  data=urllib2.urlopen("http://www.votresite.fr/Myapi.php"+"?"+url_values)

#Cette fonction mesure la distance  
def measure():
  #On lance un front pour lancer la mesure
  GPIO.output(GPIO_TRIGGER, True)
  # Attend 10us
  time.sleep(0.00001)
  GPIO.output(GPIO_TRIGGER, False)
  start = time.time() #heure de debut
  
  while GPIO.input(GPIO_ECHO)==0:
    start = time.time()

  while GPIO.input(GPIO_ECHO)==1:
    stop = time.time()

  elapsed = stop-start
  distance = (elapsed * speedSound)/2
  return distance

#Cette fonction effectue 3 mesures et retoune la valeur moyenne  
def measure_average():
  distance1=measure()
  time.sleep(0.1)
  distance2=measure()
  time.sleep(0.1)
  distance3=measure()
  distance = distance1 + distance2 + distance3
  distance = distance / 3
  return distance
	

class myThread (threading.Thread):
  def __init__(self,name):
	threading.Thread.__init__(self)
	self.name=name
		
  def run(self):
    #Recuperation des donnees
	distance=measure_average()
	#print("Distance : {0:5.1f}".format(distance))
	#Gestion du changement de position de la porte
	Mem[2]=Mem[1]
	Mem[1]=Mem[0]
	Mem[0]=int(distance)
	#print("Mem:"+str(Mem[0])+","+str(Mem[1])+","+str(Mem[2]))
	global position
	if ((position==0) and (Mem[0]>Longueur_Seuil) and (Mem[1]>Longueur_Seuil) and (Mem[2]>Longueur_Seuil)):
	  position=1
	  #print("Porte ouverte")
	  sendval()

	if ((position==1) and (Mem [ 0 ] < Longueur_Seuil) and (Mem[ 1 ] < Longueur_Seuil)
 and (Mem[ 2 ]  < Longueur_Seuil)):
	  position=0
	  #print("Porte fermee")	
	  sendval()
	sys.exit() 

#*******************************************Fonction principale************************************ 
def main(): 
  #Mise en daemon
  fpid = os.fork()
  if fpid!=0:
    # Fonctionne en daemon desormais. Le PID est fpid
    sys.exit(0)

  # Utilise le mode BCM des GPIO references
  GPIO.setmode(GPIO.BCM)
  # Setup des pins output et input
  GPIO.setup(GPIO_TRIGGER,GPIO.OUT)  # Trigger
  GPIO.setup(GPIO_ECHO,GPIO.IN)      # Echo
  # Setup trigger pour False (niveau Low)
  GPIO.output(GPIO_TRIGGER, False)
  # Laisse du temps pour la prise en compte du setup
  time.sleep(0.5)
  
  try :
    while True:
      thread1 = myThread("HYSRF05")
      thread1.start()
      thread1.join()	
      time.sleep(10)

  except KeyboardInterrupt:
    # User pressed CTRL-C
    # Reset GPIO settings
    GPIO.cleanup()
	
if __name__ == "__main__":
    main()

Pour la transmission du SMS, je vous renvoie sur l'article ici que j'avais réalisé sur l'utilisation de l'API de l'opérateur Free (si tu as free, tu as tout compris!). Cette option est offerte gratuitement pour ceux qui ont un forfait mobile chez cet opérateur. Il est à noter que les ouvertures/fermetures peuvent être journalisées si vous disposez d'un base de données dans le "cloud".

Conclusion

Voici donc un exemple de mise en oeuvre de la sonde HYSRF05. Elle fonctionne parfaitement depuis 15 jours dans mon garage. Pas de soucis particulier, juste à bien respecter les deux règles qui sont : il faut une surface plane pour faire un écho propre; il faut respecter le parallélisme pour que les mesures soient juste. Je compte ajouter une caméra en façade quand j'aurais peu plus de temps. On en recause! :-)







Pseudonyme (obligatoire) :
Adresse mail (obligatoire) :
Site web :




© 2024 www.doritique.fr par Robert DORIGNY