samedi 11 juillet 2015

Firmata et Arduino 4: Lecture de l'état d'une entrée numérique (Python)

Dans les premiers articles de cette série concernant la communication entre un ordinateur et un Arduino au moyen de pyFirmata, nous avons eu l'occasion d'apprendre comment contrôler l'état d'une sortie numérique de l'Arduino, incluant l'émission d'un signal PWM.  Aujourd'hui, nous allons explorer la lecture de l'état d'une entrée numérique de l'Arduino.

Le circuit

Construisons un circuit simple qui nous permettra de modifier l'état de la pin numéro 5 de l'Arduino.  Je vous propose ce bouton poussoir associé à une résistance de tirage.  La pin sera à l'état logique haut (5 V) lorsque le bouton sera enfoncé, et à l'état logique bas (0 v) lorsque le bouton sera relâché.


Si vous êtes vraiment très pressé, vous pouvez laisser tomber le bouton poussoir et vous contenter de relier directement la pin 5 à la pin 5 V (lorsque vous désirez la mettre à l'état logique haut), ou à la pin GND (lorsque vous désirez la mettre à l'état logique bas). 

Bibliothèque PyFirmata, etc.

Nous supposons que le sketch "StandardFirmata" a été téléversé dans votre Arduino, et que la bibliothèque pyFirmata a déjà été installée sur l'ordinateur hôte (si ce n'est pas le cas, référez-vous au deuxième article de cette série pour plus de détails sur la façon de procéder).

Rédaction d'un script en python

Commençons par un simple script qui affichera à l'écran l'état de la pin numéro 5 de l'Arduino chaque fois quelle sera modifiée.

Lorsqu'on appuie sur le bouton, le message "Le bouton est enfoncé" s'affiche à l'écran.  Lorsqu'on relâche le bouton, le message "Le bouton est relâché" s'affiche à l'écran.


Il faut configurer la pin numéro 5 en entrée numérique au moyen de cette commande:

      pin5 = board.get_pin('d:5:i')

La syntaxe est "d" pour digital, "5" est le numéro de la pin, et "i" pour input.

Ensuite on pourra lire l'état de la pin au moyen de cette commande:

      valeur = pin5.read()

... qui retourne "1" lorsque l'entrée est à 5 V, et "0" lorsqu'elle est à 0 V.

Il faut aussi utiliser un itérateur prévu dans pyFirmata pour éviter qu'un trop grand nombre de mesures n'encombrent la communication série entre l'Arduino et l'ordinateur:

       it = pyfirmata.util.Iterator(board)
       it.start()

#!/usr/bin/env python
# -*- coding: latin-1 -*-
'''
Lecture de l'état de la pin 5 de l'Arduino au moyen de Firmata
Version en lignes de commandes
Pour plus de détails:
http://electroniqueamateur.blogspot.com/2015/07/firmata-et-arduino-4-lecture-de-letat.html
'''
import pyfirmata
#port = 'COM3' #windows
port = '/dev/ttyACM0' #linux
board = pyfirmata.Arduino(port)
it = pyfirmata.util.Iterator(board) # itérateur permet de ne pas engorger la communication série
it.start()
pin5 = board.get_pin('d:5:i') # d = digital, 5 = numéro de la pin, i = input.
valeurPrecedente = 1
print ' '
print '-----------------------------'
print ' Début de la démonstration'
print '-----------------------------'
while True:
valeur = pin5.read() # lecture de l'état (True ou False) de la pin
if valeur != valeurPrecedente:
if valeur == 1:
print 'Le bouton est enfoncé'
else:
print 'Le bouton est relâché'
valeurPrecedente = valeur

Deuxième script en python:  interface graphique

Ce deuxième programme est similaire mais, grâce à Tkinter, il affiche l'état de la pin numéro 5 dans une fenêtre.  En guise d'effet visuel supplémentaire, j'ai ajouté un carré qui est vert quand le bouton est enfoncé, et rouge quand le bouton est relâché. 





L'utilisation de la commande "after" permet de mettre à jour cette valeur de façon répétitive, sans que l'utilisateur soit obliger de cliquer sur un bouton.

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Indique dans une fenêtre l'état de la pin 5 de l'Arduino.
Interface graphique avec Tkinter.
Pour plus d'informations:
http://electroniqueamateur.blogspot.com/2015/07/firmata-et-arduino-4-lecture-de-letat.html
"""
import Tkinter as tk
import pyfirmata
#port = 'COM3' #windows
port = '/dev/ttyACM0' #linux
board = pyfirmata.Arduino(port)
it = pyfirmata.util.Iterator(board) # itérateur permettant de ne pas engorger la communication série
it.start()
pin5 = board.get_pin('d:5:i') # d = digital, 5 = numéro de la pin, i = input
valeur = 0
def valeur_label(label,canv, rect):
def mesure():
global valeur
valeur = pin5.read()
if valeur == 1:
label.config(fg="green")
label.config(text = "Le bouton est enfoncé")
canv.itemconfigure(rect, fill='green')
else:
label.config(fg="red")
label.config(text = "Le bouton est relâché")
canv.itemconfigure(rect, fill='red')
label.after(10, mesure) ## répétition dans 10 ms
mesure()
root = tk.Tk()
root.geometry("250x150+300+300")
root.title("Pin 5")
label1 = tk.Label(root, text = " ") # un peu d'espace
label1.pack()
label1 = tk.Label(root, text = "État de la pin numéro 5 de l'Arduino:")
label1.pack()
label1 = tk.Label(root, text = " ") # encore un peu d'espace
label1.pack()
label2 = tk.Label(root)
label2.pack()
canv = tk.Canvas(root, width=50, height=50) # canevas pour dessiner
rect=canv.create_rectangle(10, 10, 40, 40, fill="red") # rectangle
canv.pack()
valeur_label(label2,canv,rect)
root.mainloop()

Yves Pelletier   (TwitterFacebook)

Aucun commentaire:

Enregistrer un commentaire