Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
Divers scripts, source code pour Raspberry Pi
#1
Salut,

Un sujet pour parler programmation python et C sur Raspberry :-)

Voici un premier source code permettant d'utiliser un capteur ultrasonique type hc-sr04 pour la mesure de niveau de citerne(eau de pluie dans mon cas).

Schéma de cablage du capteur HC-SR04(disponible en soirée)

Code python

Code :
#!/usr/bin/python

# Importation des lib.

import RPi.GPIO as GPIO
import time

# Mode BCM pour GPIO
GPIO.setmode(GPIO.BCM)

# Paramétrage des broches GPIO à utiliser (au choix)
GPIO_PULSE = 24

GPIO_MESURE = 25

# Paramétrage des GPIO
GPIO.setup(GPIO_PULSE,GPIO.OUT)  # Sortie pour pulse de démarrage mesure

GPIO.setup(GPIO_MESURE,GPIO.IN)  # Entrée du signal de mesure

# Forcage de la sortie pulse à zéro
GPIO.output(GPIO_PULSE, False)

# pause
time.sleep(0.5)

# On génère un pulse en passant à l'état haut la sortie pulse pendant 10µS
GPIO.output(GPIO_PULSE, True)

time.sleep(0.00001)

GPIO.output(GPIO_PULSE, False)

# On va mesurer le temps à l'état haut de l'entrée mesure.
# Le temps à l'état haut est le temps de propagation de l'onde ALLER/RETOUR

debut = time.time() # reset

while GPIO.input(GPIO_MESURE) == 0:
  debut = time.time() # début

while GPIO.input(GPIO_MESURE) == 1:
  fin = time.time() # fin


mesuretemps = fin-debut

# Le son parcours +-340m/s ou 34000cm/s, multiplié par le temps donne la distance

mesuredistancetotale = mesuretemps * 34000

# Dans la var. mesurereelle on trouvera la mesure finale, exploitable pour la visu et log SQL.

mesurereelle = mesuredistancetotale / 2


# fin de mesure, on sort proprement

GPIO.cleanup()

Concrètement comment utiliser ce code ?

Il faut l'intégrer dans votre visu, executer toutes les heures par exemple.. et stocker la valeur de "mesurereelle" dans une base de donnée si vous souhaitez faire des graphiques de conso.

Sauver le code dans un fichier, genre mesureciterne.py


Dans smarthome.py/smartvisu:

- Au préalable il faut déclarer un "item" pour recevoir la valeur de lecture. Par exemple:

Sans envoi sur le bus knx, uniquement dans DB SQlite
Code :
[exterieur]
   [[mesure]]
      [[[citerne]]]
      type = num
      sqlite = yes
Avec envoi sur le bus knx, et log dans DB SQlite(gad à changer selon votre config)

Code :
[exterieur]
   [[mesure]]
      [[[citerne]]]
        type = num
        knx_dpt = 9
        knx_send = 5/1/3
        sqlite = yes


Editer logic.conf (/usr/local/smarthome/etc/logic.conf ou via le partage de fichiers par défaut)

Code :
# /usr/local/smarthome/etc/logic.conf
[Mesureciterne]
    filename = mesureciterne.py
    cycle = 3600

Et dans mesureciterne.py, il faut ajouter la ligne suivante, afin d'assigner la mesure à une variable de smarthome:

Code :
sh.exterieur.mesure.citerne() = mesurereelle
Dans smarthome le "import time" en début de code n'est pas nécéssaire car déjà chargé.

Répondre
#2
Angry pourquoi j'ai payé 425 euros pour mon KNX SO250 moi? Angry
Répondre
#3
Salut mil3d

Tu divises par 100 et c'est à peu près le prix du capteur en Chine :-)
Il faut deux résistances 1/4w en plus.
Répondre
#4
J'ai regardé la doc de ton module KNX SO250 ca à l'air très complet, je ne trouve pas le prix exagéré par rapport aux caractéristiques, et puis c'est plug'n play .. :-)
J'ai oublié de dire que le résultat de mesure est la distance entre le capteur et la surface du liquide. Reste ensuite à appliquer quelques maths pour avoir le volume restant de la citerne, en fonction de celle-ci.
Répondre
#5
C'est assez précis, la mesure faite avec un script python ? C'est quand même pas super fiable, vu que le CPU peut interrompre le script à n'importe quel moment, pour exécuter un autre process... Il faudrait ajouter quelques vérifications, genre faire la mesure 100 fois de suite, virer les mesures totalement hors clous, et filtrer un peu...

Sinon, c'est cool, et vraiment super simple à mettre en oeuvre, effectivement !
Répondre
#6
Salut Frédéric,

Merci pour tes remarques constructives. C'est vrai que la notion de timing ici devient préoccupante car l'analyse est de l'ordre des microsecondes mais ca fonctionne plutot pas mal en python oui. Je n'ai pas constaté de grande disparité dans les mesures, mais tu as raison je vais filtrer un peu :-) Faire 100 mesures pose problème avec le sleep d'une demi seconde, si on enlève cette pause le système plante, je crois que ca vient du capteur qui n'a pas le temps de s'initialiser. Je vais voir si un dizième de seconde suffirait et 50 mesures comme base de filtrage. Ca te parait raisonnable ?
Pour le filtrage, virer les premières valeurs extremes(+5,-5 par exemple) et faire une moyenne des valeurs restantes devrait suffire pour avoir quelque chose de correct.
J'ai effectué les tests dans une habitation , pas dans une citerne(le capteur est placé mais pas encore de Raspberry sur place), ton idée de filtrage pourra supprimer aussi les valeurs induites par les reflexions parasites.. bien vu. :-)

Le schéma ca sera pour demain, pas eu le temps ce soir.

Rémy



Sinon à ton avis, il y a possibilité de minimiser l'interruption de process sur un raspberry en utilisant une sorte de multi-threading ? En tenant compte de l'architecture du RPi..
C'est un domaine de la programmation qui dépasse mes compétences pour l'instant. C'est un hobby la programmation python donc toutes optimisations sont les bienvenues :-)
Répondre
#7
Tres intéressante en plus j’étais a la recherche d'une solution pour cette problématique.
Répondre
#8
(09/04/2014, 16:36:30)RemyB a écrit : J'ai regardé la doc de ton module KNX SO250 ca à l'air très complet, je ne trouve pas le prix exagéré par rapport aux caractéristiques, et puis c'est plug'n play .. :-)

Merci d'essayer de ma rassurer Tongue pas sûr que ça marche Confused

Répondre
#9
Salut Mika, merci pour ton commentaire, tu es déjà équipé d'un
Raspberry?

Salut Mil3D,
J'aurai essayé au moins Shy Big Grin

J'ai modifié un peu le code suite à tes remarques Frédéric.

Code :
#!/usr/bin/python

# Importation des lib.

import RPi.GPIO as GPIO
import time

# Mode BCM pour GPIO
GPIO.setmode(GPIO.BCM)

# Paramétrage des broches GPIO à utiliser (au choix)
GPIO_PULSE = 24

GPIO_MESURE = 25

# Paramétrage des GPIO
GPIO.setup(GPIO_PULSE,GPIO.OUT)  # Sortie pour pulse de démarrage mesure

GPIO.setup(GPIO_MESURE,GPIO.IN)  # Entrée du signal de mesure

#boucle jusque 50, déclaration de liste
i = 1
listeresultats = []
for i in range(1, 51):


            # Forcage de la sortie pulse à zéro
            GPIO.output(GPIO_PULSE, False)

            # pause réduite, a tester
            time.sleep(0.1)

            # On génère un pulse en passant à l'état haut la sortie pulse pendant 10µS
            GPIO.output(GPIO_PULSE, True)

            time.sleep(0.00001)

            GPIO.output(GPIO_PULSE, False)

            # On va mesurer le temps à l'état haut de l'entrée mesure.
            # Le temps à l'état haut est le temps de propagation de l'onde ALLER/RETOUR

            debut = time.time() # reset

            while GPIO.input(GPIO_MESURE) == 0:
              debut = time.time() # début

            while GPIO.input(GPIO_MESURE) == 1:
              fin = time.time() # fin


            mesuretemps = fin-debut

            # Le son parcours +-340m/s ou 34000cm/s, multiplié par le temps donne la distance

            mesuredistancetotale = mesuretemps * 34000

            # Dans la var. mesurereelle on trouvera la mesure finale, exploitable pour la visu et log SQL.

            mesurereelle = mesuredistancetotale / 2
            
            listeresultats.append(mesurereelle)

# fin de mesure, on sort proprement

GPIO.cleanup()

#suppression des 5 valeurs extremes
for i in range(1, 6):

            listeresultats.remove(max(listeresultats))
            listeresultats.remove(min(listeresultats))

#moyenne
valeurmoyenne = sum(listeresultats)/len(listeresultats)

Reste à tester, je suis pas à la maison pour l'instant..
Il y a certainement des solutions plus pointues et élégantes de faire cela, mais ca devrait fonctionner :-)
Répondre
#10
Oui, il me sert de serveur linknx.
Comment a tu installer ton capteur dans ta cuve.
Ton RPI ce situ ou?
Répondre
#11
C'est une citerne cylindrique de 10000litres(8600 en fait à la limite du trop-plein), avec une ouverture sur le dessus pour chambre de visite.

D'abord une couche de vernis pour circuit imprimé(pas sur la partie capteur évidement Big Grin), j'ai intégré ensuite le capteur dans une boite de dérivation ip67, deux découpes rondes pour laisser passer les émetteurs/récepteurs ultrason, un peu de silicone..

Le capteur est fixé sur la paroi supérieure de la citerne, à 20cm de l'ouverture. Deux chevilles de 8 et des vis en fond de boite de dérivation.

Le cablage est un simple cat5e. Un cable avec des fils en 0.8mm² fait l'affaire.

Le cable(gainé) arrive dans la chaufferie a coté du socarex. Il y aura un RPi dans la chaufferie pour la mesure citerne et les contacts de fenêtres/portes. Un autre dans l'armoire électrique(mesure du courant sur le exvb 4*10² d'arrivée et capteurs t°)
Répondre
#12
(09/04/2014, 21:47:07)RemyB a écrit : Sinon à ton avis, il y a possibilité de minimiser l'interruption de process sur un raspberry en utilisant une sorte de multi-threading ? En tenant compte de l'architecture du RPi...

J'avoue ne pas trop connaître l'architecture du RPi... Je vais me renseigner.
Répondre


Atteindre :


Utilisateur(s) parcourant ce sujet : 1 visiteur(s)