[ Raspberry Pi ] Manette USB et GPIO

J’ai retrouvé une vieille manette USB dans mes affaires, j’en ai profité pour découvrir comment faire réagir les GPIO du Raspberry Pi aux boutons de la manette en Python. Etant donné qu’il y a plein de tuto sur internet de comment contrôler les GPIO en bash ou en python, je ne vais pas trop vous expliquer cette partie.

Si vous n’êtes pas familier avec les GPIO je vous recommande ce tuto qui vous permettra de réaliser un feu tricolore anglais : https://projects.drogon.net/raspberry-pi/gpio-examples/tux-crossing/
Je vous propose d’ailleurs le script pour transformer le feu en français avec le même montage : Feu tricolore Français

Donc pour préparer l’expérience on a besoin de sept LEDs et autant de résistances (j’ai pris des 220ohms). On les relie aux GPIO 17, 18, 22, 23, 24, 25, 27. (soit GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6). Chaque GPIO est branché comme pour le feu tricolore c’est à dire :

Pour Raspberry. (issue de https://projects.drogon.net/raspberry-pi/gpio-examples/tux-crossing/gpio-examples-1-a-single-led/)
Pour Raspberry. (issue de https://projects.drogon.net/raspberry-pi/gpio-examples/tux-crossing/gpio-examples-1-a-single-led/)

Le montage ressemble à la fin à ça :

Pour Raspberry Pi
Pour Raspberry Pi

Pour le code le voici à mettre dans un fichier manette.py, à télécharger ici : Script pour contrôler les GPIO depuis une manette USB

#!/usr/bin/env python

import pygame
from pygame.locals import *
import RPi.GPIO as GPIO
import time


class App:
    def __init__(self):
        self._running = True

    def on_init(self):
        pygame.init()
        joystick = pygame.joystick.Joystick(0)
        joystick.init()

        GPIO.setmode(GPIO.BCM)
        GPIO.setwarnings(False)

        self.outputs = [17, 18, 27, 22, 23, 24, 25]

        for i in self.outputs :
            print "Setup #",i
            GPIO.setup(i, GPIO.OUT)

        self._running = True
        print "En attente"

    def on_event(self, event):
        if event.type == pygame.JOYBUTTONDOWN:
            self.stop_leds()
            if event.button == 0 :
                print "LED ROUGE 1"
                GPIO.output(17, True)
            elif event.button == 1 :
                print "LED JAUNE 1"
                GPIO.output(18, True)
            elif event.button == 2 :
                print "LED VERTE 1"
                GPIO.output(27, True)
            elif event.button == 3 :
                print "LED ROUGE 2"
                GPIO.output(22, True)
            elif event.button == 4 :
                print "LED JAUNE 2"
                GPIO.output(23, True)
            elif event.button == 5 :
                print "LED VERTE 2"
                GPIO.output(24, True)
            elif event.button == 6 :
                print "LED ROUGES"
                GPIO.output(17, True)
                GPIO.output(22, True)
                GPIO.output(25, True)
            elif event.button == 7 :
                print "LED JAUNES"
                GPIO.output(18, True)
                GPIO.output(23, True)
            elif event.button == 8 :
                print "LED VERTES"
                GPIO.output(27, True)
                GPIO.output(24, True)
            elif event.button == 9 :
                print "TOUTES LED"
                for i in self.outputs :
                    GPIO.output(i, True)
            elif event.button == 10 :
                print "LED ROUGE 3"
                GPIO.output(25, True)
            elif event.button == 11 :
                print "AUCUNE LED"
        elif event.type == pygame.JOYAXISMOTION:
            print event.axis , " - " , event.value
            if event.axis == 0 and event.value > 0:
                self.switch_led("next")
            elif event.axis == 0 and event.value < 0:
                self.switch_led("prev")
            elif event.axis == 1 and event.value > 0:
                self.switch_led("next")
            elif event.axis == 1 and event.value < 0:
                self.switch_led("next")


    def on_loop(self):
        pass
    def on_render(self):
        pass
    def on_cleanup(self):
        GPIO.cleanup()
        pygame.quit()

    def on_execute(self):
        if self.on_init() == False:
            self._running = False

        while( self._running ):
            for event in pygame.event.get():
                self.on_event(event)
            self.on_loop()
            self.on_render()
        self.on_cleanup()

    def stop_leds(self):
        for i in self.outputs :
            GPIO.output(i, False)

    def switch_led(self, direction):
        index = 0
        for i in self.outputs :
            if GPIO.input(i) == 1 :
                GPIO.output(self.outputs[index], False)
                if direction == "next" :
                    index -= 1
                    if index < 0 :
                        index = 6
                elif direction == "prev" :
                    index += 1
                    if index > 6 :
                        index = 0
                GPIO.output(self.outputs[index], True)
                break
            index += 1


if __name__ == "__main__" :
    theApp = App()
    theApp.on_execute()

Pour l’exécuter :

sudo python manette.py

Et voici le résultat :