Ligne 1 : |
Ligne 1 : |
| {{RASP-PYGAME-GUI-NAV}} | | {{RASP-PYGAME-GUI-NAV}} |
− |
| |
− | {{traduction}}
| |
| | | |
| == Entrée Analogique == | | == Entrée Analogique == |
Ligne 7 : |
Ligne 5 : |
| {{ADFImage|RASP-PYGAME-GUI-Analogique-00.jpg}} | | {{ADFImage|RASP-PYGAME-GUI-Analogique-00.jpg}} |
| | | |
− | This example uses a 10K potentiometer to provide a varying voltage. For analog to digital I normally use an [http://jeremyblythe.blogspot.co.uk/2012/09/raspberry-pi-hardware-spi-analog-inputs.html MCP3008 over SPI]. That's not possible here though because the PiTFT uses both SPI channels on the Pi. So I've switched to an I2C ADC: [http://www.adafruit.com/product/1085 ADS1115 16-Bit ADC - 4 Channel with Programmable Gain Amplifier].
| + | 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]. |
| | | |
− | Get the Adafruit Python library:
| + | Pour obtenir la bibliothèque Python Adafruit: |
| | | |
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
Ligne 16 : |
Ligne 14 : |
| </syntaxhighlight> | | </syntaxhighlight> |
| | | |
− | If you need to enable i2c follow this guide: Configuring I2C
| + | Vous aurez besoin d'activer [[Rasp-Hack-GPIO_Configurer_I2C|le support I2C en suivant ce guide]] |
| | | |
| {{ADFImage|RASP-PYGAME-GUI-Analogique-01.jpg}} | | {{ADFImage|RASP-PYGAME-GUI-Analogique-01.jpg}} |
| | | |
| == Démarrage == | | == Démarrage == |
| + | Au tout début du script nous faisons quelques {{fname|import}} pour le support multitâche (''threading'') et la conversion ADC. |
| | | |
− | At the top of this script now we have some more imports for the threading and ADC.
| + | Le gain et le taux d'échantillonnage sont configurés et le convertisseur ADC est initialisé. |
− | | |
− | The gain and sample rate are configured and the ADC initialized.
| |
| | | |
| <syntaxhighlight lang="python"> | | <syntaxhighlight lang="python"> |
Ligne 43 : |
Ligne 40 : |
| ADS1115 = 0x01 # 16-bit ADC | | ADS1115 = 0x01 # 16-bit ADC |
| | | |
− | # Select the gain | + | # Sélectionner le gain |
| # gain = 6144 # +/- 6.144V | | # gain = 6144 # +/- 6.144V |
| gain = 4096 # +/- 4.096V | | gain = 4096 # +/- 4.096V |
Ligne 51 : |
Ligne 48 : |
| # gain = 256 # +/- 0.256V | | # gain = 256 # +/- 0.256V |
| | | |
− | # Select the sample rate | + | # Sélectionner le taux d'échantillonnage |
− | sps = 8 # 8 samples per second | + | sps = 8 # 8 échantillons par seconde |
− | # sps = 16 # 16 samples per second | + | # sps = 16 # 16 échantillons par seconde |
− | # sps = 32 # 32 samples per second | + | # sps = 32 # 32 échantillons par seconde |
− | # sps = 64 # 64 samples per second | + | # sps = 64 # 64 échantillons par seconde |
− | # sps = 128 # 128 samples per second | + | # sps = 128 # 128 échantillons par seconde |
− | # sps = 250 # 250 samples per second | + | # sps = 250 # 250 échantillons par seconde |
− | # sps = 475 # 475 samples per second | + | # sps = 475 # 475 échantillons par seconde |
− | # sps = 860 # 860 samples per second | + | # sps = 860 # 860 échantillons par seconde |
| | | |
− | # Initialise the ADC using the default mode (use default I2C address) | + | # Initialiser le convertisseur ADC en utilisant le mode par défaut (et adresse I2C par défaut) |
− | # Set this to ADS1015 or ADS1115 depending on the ADC you are using! | + | # Utilisez ADS1015 ou ADS1115 en fonction de l'ADC que vous utilisez! |
| adc = ADS1x15(ic=ADS1115) | | adc = ADS1x15(ic=ADS1115) |
| | | |
− | #Setup the GPIOs as outputs - only 4 and 17 are available | + | # Configurer les GPIOs en sortie (OUTPUT) - seuls 4 et 17 sont disponibles |
| GPIO.setmode(GPIO.BCM) | | GPIO.setmode(GPIO.BCM) |
| GPIO.setup(4, GPIO.OUT) | | GPIO.setup(4, GPIO.OUT) |
Ligne 85 : |
Ligne 82 : |
| | | |
| == Le thread du potentiomètre == | | == Le thread du potentiomètre == |
− | xxx
| + | 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}} |