Pages d'index

Pages d'index

vendredi 31 juillet 2015

Firmata et Arduino 5: lecture d'une entrée analogique (python)

Récapitulons:  pour une raison ou pour une autre, vous souhaitez contrôler un Arduino grâce à un programme en python exécuté par l'ordinateur auquel est branché l'Arduino.

Dans les articles précédents, nous avons constaté que le protocole Firmata est particulièrement approprié pour cette situation; nous avons vu comment contrôler les sorties de l'Arduino (incluant la création d'un signal PWM) et comment lire ses entrées numériques.

Aujourd'hui, nous lisons les entrées analogiques de l'Arduino en utilisant pyFirmata.

Circuit

Pour tester le principe, le plus simple est de brancher un potentiomètre à l'entrée A0 de l'Arduino.  Bien sûr, ce potentiomètre peut être remplacé par n'importe quel capteur analogique (photorésistance, thermistance, etc.).



Sketch StandardFirmata et bibliothèque PyFirmata

Pour que tout fonctionne correctement, il est essentiel que le sketch "StandardFirmata" ait été téléversé dans votre Arduino, et que la bibliothèque "pyFirmata" soit 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).

Codage

Avec pyFirmata, la lecture d'une pin analogique est presque identique à la lecture d'une pin numérique.  La principale différence réside dans la définition de la pin:

        pinA0 = board.get_pin('a:0:i')

...nous utiliserions "i" à la place de "a" s'il s'agissait d'un signal numérique.

Ensuite, on utilise la fonction "read()" pour lire la valeur.  Attention:  "read()" retourne une valeur décimale entre 0 et 1 (alors qu'en langage Arduino, "analogRead()" retourne un entier entre 0 et 1023).

       pinA0.read()

Il faut également utiliser un itérateur afin d'éviter d'engorger la communication série entre l'Arduino et l'ordinateur hôte:

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


Script classique (mode texte)

Ce programme plutôt minimaliste se contente de lire la valeur de l'entrée A0 une fois par seconde et de l'afficher à l'écran.


#!/usr/bin/env python
# -*- coding: latin-1 -*-
'''
Lecture de l'état de la pin A0 de l'Arduino au moyen de Firmata
Version en lignes de commandes
Pour plus d'informations:
http://electroniqueamateur.blogspot.com/2015/07/firmata-et-arduino-5-lecture-dune.html
'''
import pyfirmata
import time
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()
pinA0 = board.get_pin('a:0:i') # a = analogique, 0 = numéro de la pin, i = input.
print ' '
print '-----------------------------'
print " Lecture de l'entrée analogique A0 de l'Arduino "
print '-----------------------------'
while True:
print pinA0.read() # la valeur varie entre 0 et 1.
time.sleep(1) # Pause d'une seconde avant la prochaine mesure

Script utilisant Tkinter (interface graphique)

Et voici un autre script en python qui, cette fois, utilise la bibliothèque Tkinter afin de présenter le résultat dans une fenêtre; en plus de la valeur numérique, une jauge offre une indication visuelle de l'état de l'entrée A0 de l'Arduino (l'illustration ci-dessous montre le résultat dans Linux Mint).



#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Indique dans une fenêtre l'état de la pin A0 de l'Arduino:
valeur numérique et jauge graphique.
Pour plus d'informations:
http://electroniqueamateur.blogspot.com/2015/07/firmata-et-arduino-5-lecture-dune.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()
pinA0 = board.get_pin('a:0:i') # a = analogique, 0 = numéro de la pin, i = input
valeur = 0
def valeur_label(label,canv, rect1, rect2):
def mesure():
global valeur
valeur = pinA0.read()
label.config(text = valeur)
canv.itemconfigure(rect1, fill = 'white') ## on redessine le fond, ça efface l'ancienne jauge
canv.itemconfigure(rect2, width = 500*valeur) ## nouvelle jauge, en fonction de la valeur actuelle
label.after(10, mesure) ## répétition dans 10 ms
mesure()
root = tk.Tk()
root.geometry("300x150+300+300") ##taille et position initiale de la fenêtre
root.title("Pin A0") #titre de la fenêtre
label1 = tk.Label(root, text = " ") # un peu d'espace
label1.pack()
label1 = tk.Label(root, text = "État de l'entrée analogique A0 de l'Arduino:")
label1.pack()
label1 = tk.Label(root, text = " ") # encore un peu d'espace
label1.pack()
label2 = tk.Label(root)
label2.pack()
label3 = tk.Label(root, text = " ") # encore un peu d'espace
label3.pack()
canv = tk.Canvas(root, width=250, height=20) # canevas pour dessiner
rect1=canv.create_rectangle(0, 0, 250, 20, fill = 'white') # fond blanc de la jauge
rect2=canv.create_rectangle(0, 0, 1, 20) # jauge
canv.pack()
valeur_label(label2,canv,rect1, rect2)
root.mainloop()

Yves Pelletier   (TwitterFacebook)

2 commentaires:

  1. Bonjour,
    Est ce que c'est possible de faire la même chose avec une plateforme grove, c'est à dire avec un ce genre de produits : http://www.lextronic.fr/P36222-capteur-de-force.html
    http://www.lextronic.fr/P37830-module-grove---moteur-haptic.html
    A la limite on peut peut-être introduire les fils blancs noir jaune rouge directement dans l'Arduino?
    Merci
    GT

    RépondreSupprimer
  2. pour le capteur de force, ce dernier est connecté sur l'analogique 1(A1).
    donc oui ça doit fonctionner en changeant :
    pinA1 = board.get_pin('a:1:i')

    RépondreSupprimer