Modifications

Sauter à la navigation Sauter à la recherche
7 774 octets ajoutés ,  15 août 2016 à 15:41
aucun résumé de modification
Ligne 1 : Ligne 1 :  
{{RASP-PYGAME-GUI-NAV}}
 
{{RASP-PYGAME-GUI-NAV}}
 +
 +
== Entrée Analogique ==
 +
 +
{{ADFImage|RASP-PYGAME-GUI-Analogique-00.jpg}}
 +
 +
Cet exemple utilise un potentiomètre de 10K pour fournir une tension variable. Pour la conversion analogique vers digital nous utilisons habituellement un [http://jeremyblythe.blogspot.co.uk/2012/09/raspberry-pi-hardware-spi-analog-inputs.html MCP3008 via SPI]. Mais cela n'est pas possible ici puisque le PiTFT utilise les deux canaux SPI disponibles sur le Pi. Par conséquant, nous optons pour un convertisseur ADC I2C: [http://www.adafruit.com/product/1085 ADC 16-Bit ADS1115 - 4 canaux avec un gain programmable].
 +
 +
Pour obtenir la bibliothèque Python Adafruit:
 +
 +
<syntaxhighlight lang="bash">
 +
cd /home/pi
 +
git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git
 +
</syntaxhighlight>
 +
 +
Vous aurez besoin d'activer  [[Rasp-Hack-GPIO_Configurer_I2C|le support I2C en suivant ce guide]]
 +
 +
{{ADFImage|RASP-PYGAME-GUI-Analogique-01.jpg}}
 +
 +
== Démarrage ==
 +
Au tout début du script nous faisons quelques {{fname|import}} pour le support multitâche (''threading'') et la conversion ADC.
 +
 +
Le gain et le taux d'échantillonnage sont configurés et le convertisseur ADC est initialisé.
 +
 +
<syntaxhighlight lang="python">
 +
import sys
 +
sys.path.append('/home/pi/Adafruit-Raspberry-Pi-Python-Code/Adafruit_ADS1x15')
 +
 +
import pygame
 +
import os
 +
import pygameui as ui
 +
import logging
 +
import RPi.GPIO as GPIO
 +
import signal
 +
from Adafruit_ADS1x15 import ADS1x15
 +
import threading
 +
import time
 +
 +
ADS1015 = 0x00  # 12-bit ADC
 +
ADS1115 = 0x01  # 16-bit ADC
 +
 +
# Sélectionner le gain
 +
# gain = 6144  # +/- 6.144V
 +
gain = 4096  # +/- 4.096V
 +
# gain = 2048  # +/- 2.048V
 +
# gain = 1024  # +/- 1.024V
 +
# gain = 512  # +/- 0.512V
 +
# gain = 256  # +/- 0.256V
 +
 +
# Sélectionner le taux d'échantillonnage
 +
sps = 8    # 8 échantillons par seconde
 +
# sps = 16  # 16 échantillons par seconde
 +
# sps = 32  # 32 échantillons par seconde
 +
# sps = 64  # 64 échantillons par seconde
 +
# sps = 128  # 128 échantillons par seconde
 +
# sps = 250  # 250 échantillons par seconde
 +
# sps = 475  # 475 échantillons par seconde
 +
# sps = 860  # 860 échantillons par seconde
 +
 +
# Initialiser le convertisseur ADC en utilisant le mode par défaut (et adresse I2C par défaut)
 +
# Utilisez ADS1015 ou ADS1115 en fonction de l'ADC que vous utilisez!
 +
adc = ADS1x15(ic=ADS1115)
 +
 +
# Configurer les GPIOs en sortie (OUTPUT) - seuls 4 et 17 sont disponibles
 +
GPIO.setmode(GPIO.BCM)
 +
GPIO.setup(4, GPIO.OUT)
 +
GPIO.setup(17, GPIO.OUT)
 +
 +
log_format = '%(asctime)-6s: %(name)s - %(levelname)s - %(message)s'
 +
console_handler = logging.StreamHandler()
 +
console_handler.setFormatter(logging.Formatter(log_format))
 +
logger = logging.getLogger()
 +
logger.setLevel(logging.DEBUG)
 +
logger.addHandler(console_handler)
 +
 +
os.putenv('SDL_FBDEV', '/dev/fb1')
 +
os.putenv('SDL_MOUSEDRV', 'TSLIB')
 +
os.putenv('SDL_MOUSEDEV', '/dev/input/touchscreen')
 +
 +
MARGIN = 20
 +
</syntaxhighlight>
 +
 +
== Le thread du potentiomètre ==
 +
Un thread est utilisé pour lire continuellement la valeur du potentiomètre. Si l'on fait la lecture du potentiomètre dans la mise-à-jour de la Scene alors le taux de rafraîchissement de l'écran diminuera de façon importante.
 +
 +
Ce thread séparé permet à l'écran d'être redessiné en même temps (en parallèle) que la lecture de la valeur depuis l'ADC.
 +
 +
La classe est définie comme {{fname|callable}} appela - d'où la méthode {{fname|__call__}}. Il prend une référence vers la classe pitft de sorte qu'il est possible d'y mettre les valeurs à-jour. Il y a un schéma d'arrêt relativement simple basé sur la vérification d'un variable (un ''flag''/''drapeau'') à chaque tour de boucle. Nous verrons plus tard comment terminer proprement le programme en modifiant la variable ''flag''.
 +
 +
Donc, nous lisons simplement la valeur depuis l'ADC et modifie la valeur du libellé et la position de la barre de progression (visible sur le pitft).
 +
 +
<syntaxhighlight lang="python">
 +
class PotReader():
 +
    def __init__(self, pitft):
 +
        self.pitft = pitft
 +
        self.terminated = False
 +
       
 +
    def terminate(self):
 +
        self.terminated = True
 +
       
 +
    def __call__(self):
 +
        while not self.terminated:
 +
            # Lecture du canal 0 en mode single-ended en utilisant la configuration ci-avant
 +
            volts = adc.readADCSingleEnded(0, gain, sps) / 1000
 +
            self.pitft.set_volts_label(volts)
 +
            self.pitft.set_progress(volts / 3.3)
 +
</syntaxhighlight>
 +
 +
== Définition de l'interface utilisateur ==
 +
Nous avons ajouté quelques widget supplémentaires sur la Scene et modifié la taille des boutons (pour que tout se présente correctement).
 +
 +
Nous allons afficher la tension sur un widget label (''libellé'') et un widget progress (''barre de progression'').
 +
 +
Les méthodes {{fname|set_progress}} et {{fname|set_volts_label}} sont appelées depuis le thread PotReader pour faire la mise-à-jour des valeurs dans ces Widgets.
 +
 +
<syntaxhighlight lang="python">
 +
class PiTft(ui.Scene):
 +
    def __init__(self):
 +
        ui.Scene.__init__(self)
 +
 +
        self.on17_button = ui.Button(ui.Rect(MARGIN, MARGIN, 130, 60), '17 on')
 +
        self.on17_button.on_clicked.connect(self.gpi_button)
 +
        self.add_child(self.on17_button)
 +
 +
        self.on4_button = ui.Button(ui.Rect(170, MARGIN, 130, 60), '4 on')
 +
        self.on4_button.on_clicked.connect(self.gpi_button)
 +
        self.add_child(self.on4_button)
 +
 +
        self.off17_button = ui.Button(ui.Rect(MARGIN, 100, 130, 60), '17 off')
 +
        self.off17_button.on_clicked.connect(self.gpi_button)
 +
        self.add_child(self.off17_button)
 +
 +
        self.off4_button = ui.Button(ui.Rect(170, 100, 130, 60), '4 off')
 +
        self.off4_button.on_clicked.connect(self.gpi_button)
 +
        self.add_child(self.off4_button)
 +
 +
        self.progress_view = ui.ProgressView(ui.Rect(MARGIN, 200, 280, 40))
 +
        self.add_child(self.progress_view)
 +
 +
        self.volts_value = ui.Label(ui.Rect(135, 170, 50, 30), '')
 +
        self.add_child(self.volts_value)
 +
 +
    def gpi_button(self, btn, mbtn):
 +
        logger.info(btn.text)
 +
       
 +
        if btn.text == '17 on':
 +
            GPIO.output(17, False)
 +
        elif btn.text == '4 on':
 +
            GPIO.output(4, False)
 +
        elif btn.text == '17 off':
 +
            GPIO.output(17, True)
 +
        elif btn.text == '4 off':
 +
            GPIO.output(4, True)
 +
 +
    def set_progress(self, percent):
 +
        self.progress_view.progress = percent
 +
       
 +
    def set_volts_label(self, volts):
 +
        self.volts_value.text = '%.2f' % volts
 +
 +
    def update(self, dt):
 +
        ui.Scene.update(self, dt)
 +
</syntaxhighlight>
 +
 +
== Et pour finir... ==
 +
Pour démarrer le programme nous initialisons pygameui, construisons la classe pitft class et démarrons le thread potreader avec le pitft en référence.
 +
 +
Puisque nous exécutons un thread supplémentaire, nous avons également besoin d'une '''méthode propre''' pour terminer le programme.
 +
 +
Un gestionnaire de signal (''signal handler'') est utilisé pour capturer ctrl+c et terminer le thread PotReader avant d'appeler sys.exit - sinon le programme ne se fermera pas.
 +
 +
<syntaxhighlight lang="python">
 +
ui.init('Raspberry Pi UI', (320, 240))
 +
pygame.mouse.set_visible(False)
 +
 +
pitft = PiTft()
 +
 +
# démarrer le thread exécutant le ''callable''
 +
potreader = PotReader(pitft)
 +
threading.Thread(target=potreader).start()
 +
 +
def signal_handler(signal, frame):
 +
    print 'Vous avez pressé Ctrl+C!'
 +
    potreader.terminate()
 +
    sys.exit(0)
 +
       
 +
# Enregister le gesionnaire signal_handler pour le lignal SIGINT (interruption)
 +
signal.signal(signal.SIGINT, signal_handler)
 +
 +
ui.scene.push(pitft)
 +
ui.run()
 +
</syntaxhighlight>
 +
 +
== Exécuter ==
 +
Vous pouvez exécuter cet exemple final depuis le projet pygamelcd:
 +
 +
<syntaxhighlight lang="bash">
 +
sudo python test5.py
 +
</syntaxhighlight>
 +
    
{{RASP-PYGAME-GUI-TRAILER}}
 
{{RASP-PYGAME-GUI-TRAILER}}
29 918

modifications

Menu de navigation