Mode d'emploi | Conrad Components 1225953 Raspberry Pi Course material Manuel utilisateur

Ajouter à Mes manuels
97 Des pages
Mode d'emploi | Conrad Components 1225953 Raspberry Pi Course material Manuel utilisateur | Fixfr
Sommaire
1
De l'installation du système d'exploitation au premier programme Python
1.1
De quoi avez-vous besoin ?
1.1.1
Chargeur pour téléphone portable à prise micro-USB
1.1.2
Carte mémoire
1.1.3
Clavier
1.1.4
Souris
1.1.5
Câble réseau
1.1.6
Câble HDMI
1.1.7
Câble audio
1.1.8
Câble vidéo composite jaune (FBAS)
1.2
Installer le système d'exploitation Raspbian
1.2.1
Préparer la carte mémoire sur l'ordinateur
1.2.2
Installateur de logiciel NOOBS
1.2.3
Les voyants LED sur le Raspberry Pi
1.2.4
Le premier démarrage sur le Raspberry Pi
1.3
Presque comme Windows – l'interface graphique LXDE
1.3.1
Enregistrer vos fichiers sur le Raspberry Pi
1.4.1
Deviner les chiffres avec Python
1.4.2
Voilà comment cela fonctionne
5
5
6
6
6
6
6
6
7
7
7
7
8
8
9
9
11
14
16
2
Le premier voyant LED s'allume sur le Raspberry Pi
2.1
Composants dans le kit
2.1.2
Câble de connexion
2.1.3
Résistances et leur code couleur
2.2
Brancher les LED
2.3
GPIO avec Python
2.4
Allumer et éteindre une LED
2.4.1
Voilà comment cela fonctionne
2.5
Lancer Python avec support GPIO sans terminal
18
19
20
21
22
26
27
28
29
3
Feu de signalisation
3.1.1
Voilà comment cela fonctionne
32
34
4
Feu pour piétons
4.1.1
Voilà comment cela fonctionne
4.2
Bouton sur la connexion GPIO
4.2.1
Voilà comment cela fonctionne
36
38
39
43
5
Motif à LED coloré et chenillard
5.1.1
Voilà comment cela fonctionne
45
48
6
Variation de l'intensité lumineuse des LED par modulation de la largeur des
impulsions
6.1.1
Voilà comment cela fonctionne
6.1.2
Faire varier l'intensité lumineuse de deux LED indépendamment l'une de l'autre
6.1.3
Voilà comment cela fonctionne
53
56
57
59
7
Indicateur à LED montrant l'espace disponible des cartes mémoires
7.1.1
Voilà comment cela fonctionne
60
63
8
Dé graphique
8.1.1
Voilà comment cela fonctionne
65
67
9
Horloge analogique sur l'écran
9.1.1
Voilà comment cela fonctionne
72
73
10
Boîte de dialogue graphique pour contrôler le programme
10.1.1 Voilà comment cela fonctionne
10.2.1 Voilà comment cela fonctionne
10.3
Régler la vitesse de clignotement
10.3.1
Voilà comment cela fonctionne
77
79
84
87
88
11
Pitance avec les LED
11.1.1
Voilà comment cela fonctionne
90
93
4
1 De l'installation du système d'exploitation au premier programme
Python
Quasiment aucun appareil électronique dans sa catégorie de prix n'a fait autant parler de lui ces derniers
mois que le Raspberry Pi. Le Raspberry Pi est, même si cela ne se voit pas à première vue, un ordinateur
complet de la taille d'une carte de crédit - disponible à un prix très raisonnable. Non seulement le matériel
informatique est bon marché mais également les logiciels nécessaires : Le système d'exploitation et toutes les
applications nécessaires pour l'utiliser et tous les jours sont téléchargeables gratuitement.
Fig. 1.1: Le Raspberry Pi – un PC de taille miniature
Grâce à son système Linux spécialement adapté avec une interface graphique, le Raspberry Pi est un
ordinateur de remplacement silencieux et consommant peu d'électricité. Son interface GPIO dont la
programmation est libre, rend le Raspberry Pi particulièrement intéressant pour les adeptes de la « culture
maker ».
1.1
De quoi avez-vous besoin ?
Malgré sa taille miniature, le Raspberry Pi est un ordinateur à part entière. Pour pouvoir l'utiliser, vous avez
besoin comme pour un ordinateur « normal » de nombreux autres accessoires – un système d'exploitation,
une alimentation électrique, un réseau, un écran/moniteur, un clavier et divers câbles de connexion.
5
1.1.1 Chargeur pour téléphone portable à prise micro-USB
Un chargeur moderne pour téléphone portable suffit pour faire fonctionner le Raspberry Pi. Les anciens
chargeurs construits avec les premières technologies de recharge via USB ne sont pas assez puissants. Si
vous utilisez un périphérique USB à forte consommation électrique comme un disque dur sans alimentation
externe, vous devrez utiliser un bloc d'alimentation plus puissant. Le bloc d'alimentation doit délivrer une
tension de 5 V et un courant d'au moins 700 mA, de préférence 1000 mA. Le régulateur de puissance intégré
empêche que les composants ne « grillent » si vous utilisez un bloc d'alimentation trop puissant.
Un bloc d'alimentation trop faible se manifeste ainsi.
Lorsque le Raspberry Pi démarre deux fois mais que le pointeur de la souris ne se bouge pas ou que le
système ne réagit pas aux commandes du clavier, cela indique que l'alimentation électrique n'est pas
suffisante. De même, si vous ne pouvez pas accéder aux données de votre clé USB ou des disques durs,
vous devrez utiliser un bloc d'alimentation plus puissant.
1.1.2 Carte mémoire
La carte mémoire sert de disque dur dans le Raspberry Pi. Elle contient le système d'exploitation. Les
données internes et les programmes installés y sont également conservés. La carte mémoire doit être d'au
moins 4 Go et prendre en charge la norme de classe 4 selon les indications du fabricant. Cette norme
indique la vitesse de la carte mémoire. Une carte mémoire de classe 10 récente présente des performances
remarquables.
1.1.3 Clavier
Tout clavier disposant d'une connexion USB peut être utilisé. Les claviers sans fil ne fonctionnent pas
toujours car ils ont besoin de beaucoup d'énergie ou de pilotes spéciaux. Si vous n'avez pas d'autre clavier,
vous devrez utiliser un concentrateur hub USB doté d'une alimentation électrique propre pour faire
fonctionner le clavier sans fil.
1.1.4 Souris
Une souris avec connexion USB n'est nécessaire que si vous utilisez un système d'exploitation avec interface
utilisateur graphique sur le Raspberry Pi. Certains claviers disposent de ports USB pour les souris de sorte
que vous n'avez pas à fournir d'autres ports de connexion. Vous pouvez ensuite les utiliser pour connecter
des clés USB p. ex.
1.1.5 Câble réseau
Pour vous connecter à un réseau local avec le routeur, un câble réseau est nécessaire. Il est nécessaire dans
tous les cas pour la configuration initiale. Vous pourrez également utiliser ultérieurement une connexion
WLAN. De nombreuses fonctions du Raspberry Pi ne sont pas utilisables sans accès à Internet.
1.1.6 Câble HDMI
Le Raspberry Pi peut être connecté à un écran/moniteur ou un téléviseur à l'aide d'un câble HDMI. Pour le
connecter à un moniteur d'ordinateur avec une prise DVI, il existe des câbles HDMI ou adaptateurs spéciaux.
6
1.1.7 Câble audio
Un casque audio ou des enceintes pour ordinateur peuvent être utilisées sur le Raspberry Pi via un câble
audio avec prises jack de 3,5 mm. Le signal audio est également disponible via le câble HDMI. Aucun câble
audio n'est nécessaire pour les téléviseurs ou moniteurs HDMI. Si un moniteur d'ordinateur est connecté via
un câble HMDI avec adaptateur DVI, le signal audio est en général perdu à ce point de sorte que vous avez
besoin d'utiliser à nouveau la sortie audio analogique.
1.1.8 Câble vidéo composite jaune (FBAS)
Si vous n'avez pas de moniteur HDMI, le Raspberry Pi peut être connecté à un téléviseur classique en
utilisant un câble vidéo composite analogique, avec les fiches jaunes caractéristiques. Cependant, la
résolution de l'écran sera très faible. Pour les téléviseurs sans entrée composite jaune, il existe un adaptateur
composite (FBAS) vers SCART. L'interface graphique peut être utilisée seulement avec des restrictions dans la
résolution analogique du téléviseur.
1.2 Installer le système d'exploitation Raspbian
Le Raspberry Pi est livré sans système d'exploitation. Contrairement aux autres ordinateurs qui utilisent
presque tous Windows, une version spécialement adaptée de Linux est recommandée pour le Raspberry Pi.
Windows ne fonctionnerait pas avec des équipements économes en énergie.
La version de Linux, que le fabricant du Raspberry Pi recommande et prend en charge, s'appelle Raspbian.
Raspbian repose sur la version Debian de Linux, une des versions les plus connues de Linux, qui est basée
entre autres sur les versions populaires Ubuntu et Knoppix de Linux. Dans les ordinateurs classiques, il y a
un disque dur. Dans Raspberry Pi, il y a une carte mémoire. Vous y trouverez le système d'exploitation et les
données, à partir desquelles le Raspberry Pi va également démarrer.
1.2.1 Préparer la carte mémoire sur l'ordinateur
Étant donné que le Raspberry Pi ne peut pas encore démarrer tout seul, nous devons préparer préalablement
la carte mémoire sur l'ordinateur. Pour ce faire, vous avez besoin d'un lecteur de cartes sur l'ordinateur. Ce
dernier peut être intégré de manière fixe ou connecté via un port USB.
Il est recommandé d'utiliser une carte mémoire neuve car elle est déjà préformatée de manière optimale par
le fabricant. Cependant, vous pouvez également utiliser une carte mémoire qui a déjà été utilisée dans un
appareil photo numérique ou un autre appareil. Ces cartes mémoires doivent être à nouveau formatées
avant d'être utilisée dans le Raspberry Pi. Pour ce faire, vous pouvez théoriquement utiliser les
fonctionnalités de formatage de Windows. Il est préférable d'utiliser le logiciel « SDFormatter » de la SD
Association. Il permet de formater les cartes mémoires pour une performance optimale. Vous pouvez
télécharger gratuitement cet outil à l'adresse www.sdcard.org/downloads/formatter_4.
Si la carte mémoire contient des partitions d'une installation précédente de système d'exploitation pour le
Raspberry Pi, sa capacité complète n'est pas affichée dans SDFormatter. Dans ce cas, utilisez l'option de
formatage FULL (Erase) et activez l'option Format Size Adjustment. La partition de la carte mémoire est
ensuite recréée.
7
La carte mémoire sera effacée
Nous vous recommandons d'utiliser une carte mémoire vide pour l'installation du système d'exploitation.
S'il y a des données sur la carte mémoire, elles seront effacées irréversiblement au cours du processus de
reformatage, pendant l'installation du système d'exploitation.
1.2.2 Installateur de logiciel NOOBS
Le « New Out Of Box Software » (NOOBS) est un installateur particulièrement simple pour le système
d'exploitation du Raspberry Pi. L'utilisateur n'a plus besoin de traiter avec des outils image et des blocs de
démarrage comme avant pour mettre en place une carte mémoire démarrable/amorçable. NOOBS propose
plusieurs systèmes d'exploitation au choix, à partir desquels vous pouvez choisir le système d'exploitation
souhaité lors du premier démarrage directement sur Raspberry Pi, qui est ensuite installé de manière
démarrable/amorçable sur la carte mémoire. Téléchargez le fichier compressé d'env. 1,2 Go pour installer
NOOBS, à partir du site officiel de téléchargement à l'adresse suivante www.raspberrypi.org/downloads, et
décompressez-le sur l'ordinateur sur une carte mémoire d'au moins 4 Go.
Démarrez maintenant le Raspberry Pi avec cette carte mémoire. Pour ce faire, insérez-la dans l'emplacement
dédié du Raspberry Pi puis branchez le clavier, la souris, le moniteur et le câble réseau. Connectez en
dernier l'alimentation USB. Cela met en marche le Raspberry Pi. Il n'y a pas de bouton d'alimentation séparé.
Après quelques secondes, un menu s'affiche à partir duquel vous pouvez choisir le système d'exploitation
souhaité. Nous utilisons le système d'exploitation Raspbian recommandé par la fondation Raspberry Pi.
Sélectionnez le [français] comme langue d'installation puis cochez le système d'exploitation Raspbian
présélectionné. Après avoir confirmé le message de sécurité indiquant que la carte mémoire sera écrasée,
l'installation se lance et est achevée en quelques minutes. Pendant l'installation, de courtes informations sur
Raspbian s'affichent à l'écran.
1.2.3 Les voyants LED sur le Raspberry Pi
Cinq voyants LED indiquant le statut de Raspberry Pi se trouvent dans un coin de l'appareil. Les noms sont en
partie différents sur les nouveaux et les anciens modèles de Raspberry Pi, mais les fonctions restent les mêmes.
Nouvelle carte de circuit
imprimé (Rev. 2)
Carte de circuit imprimé
(ancienne Rev. 1)
Couleur
Signification du voyant LED
ACT
OK
Vert
Accès sur la carte mémoire
PWR
PWR
Rouge
Connecté à l'alimentation électrique
FDX
FDX
Vert
LAN en mode duplex intégral
LNK
LNK
Vert
Accès sur le LAN
100
10M
Jaune.
LAN avec 100 Mo/s
Tableau 1.1: Voyants LED sur le Raspberry Pi
8
Fig. 1.2: Les voyants LED de statut sur le Raspberry Pi
1.2.4 Le premier démarrage sur le Raspberry Pi
À l'issue de l'installation, le Raspberry Pi redémarre et lance automatiquement l'outil de configuration
raspi-config. Vous devez ici choisir uniquement dans Enable Boot to Desktop l'option Desktop Log in as
user ‘pi’. La langue [française] et le clavier [français] sont automatiquement sélectionnés ainsi que d'autres
réglages importants. Après un redémarrage, le bureau graphique LXDE devient disponible.
1.3 Presque comme Windows – l'interface graphique LXDE
Le mot « Linux » fait peur à beaucoup de personnes, car elles craignent d'avoir à saisir des lignes de code
comme il y a 30 ans sous DOS. Ce n'est pas le cas, loin de là ! En tant que système d'exploitation ouvert,
Linux offre gratuitement aux développeurs un moyen de développer une interface graphique propre. Vous
n'êtes donc pas lié(e) à une interface en tant qu'utilisateur du système d'exploitation toujours basé sur des
lignes de commande dans le noyau.
9
Fig. 1.3: Le Desktop LXDE (bureau LXDE) sur Raspberry Pi ressemble beaucoup à celui de Windows XP.
La version Raspbian de Linux pour le Raspberry Pi utilise l'interface LXDE (Lightweight X11 Desktop
Environment), qui, d'une part, a besoin de très peu de ressource système et qui, d'autre part, ressemble
fortement au menu de démarrage et au gestionnaire de fichiers de votre interface habituelle de Windows.
Application Linux
Même la connexion utilisateur caractéristique de Linux s'effectue en arrière-plan. Cependant, si vous en
avez besoin : Le nom d’utilisateur est pi et le mot de passe raspberry.
Le symbole LXDE en bas à gauche ouvre le menu Démarrer, les symboles à côté ouvrent le gestionnaire de
fichiers et le navigateur Internet. Le menu Démarrer est structuré sur plusieurs niveaux comme sous
Windows. Les programmes fréquemment utilisés peuvent être sauvegardés avec un clic droit de souris sur le
Desktop (bureau). Voici quelques programmes déjà préinstallés : le navigateur Internet Midori,
l'environnement de développement Python et le Pi Store.
Mettre en arrêt le Raspberry Pi
On peut théoriquement débrancher simplement le Raspberry Pi pour qu'il s'éteigne. Il est cependant
recommandé d'arrêter proprement le système comme un ordinateur classique. Pour ce faire, doublecliquez sur le symbole Shutdown qui se trouve sur le bureau.
10
1.3.1 Enregistrer vos fichiers sur le Raspberry Pi
La gestion des fichiers est un peu différente sur Linux par rapport à Windows mais cela n'est pas plus
difficile. Raspbian offre un gestionnaire de fichiers qui ressemble beaucoup à l'explorateur de Windows.
Cependant, il y a une différence important par rapport à Windows : Linux ne sépare pas strictement en
fonction des lecteurs. Tous les fichiers se trouvent dans un seul système de fichier unique.
Sous Linux, vous mettez en principe tous vos fichiers seulement sous le répertoire Home. Il s'appelle ici
/home/pi pour le nom d'utilisateur pi. Linux utilise la barre oblique simple (/), pour séparer, et non la
célèbre barre oblique inversée de Windows (\). Vous mettrez également vos programmes Python dans ce
répertoire. Le gestionnaire de fichiers, qui peut être ouvert via le menu Démarrer ou avec la combinaison de
touche [Win] +[E] montre par défaut seulement ce répertoire Home. Certains programmes sont placés
automatiquement dans des sous-répertoires.
Les personnes qui souhaitent tout voir, même les fichiers qui ne concernent pas l'utilisateur normal,
changent le gestionnaire de fichiers en haut à gauche de la position Emplacement à Arborescence du
répertoire. Choisissez ensuite dans le menu sous Affichage l'option Affichage détaillé, l'affichage apparaît
comme l'on a préréglé sous Linux.
Fig. 1.4: Le gestionnaire de fichiers de Raspberry Pi peut ressembler à cela...
11
Fig. 1.5: ... ou à ceci.
Combien d'espace reste-t-il disponible sur la carte mémoire ?
Contrairement aux disques durs des ordinateurs qui sont en permanence pleins - grâce à sa carte mémoire,
le Raspberry Pi peut fonctionner beaucoup plus vite. Il est d'autant plus important d'avoir toujours de
l'espace libre et disponible sur la carte mémoire en un clin d'œil. La barre d'état du gestionnaire de
programme en bas de la fenêtre indique à droite l'espace libre et disponible de la carte mémoire.
1.4 Le premier programme avec Python
Pour faire ses premiers pas dans la programmation, le langage de programmation Python est préinstallé sur le
Raspberry Pi. Python se distingue par sa structure claire qui permet une introduction simple dans la
programmation. C'est également une langue idéale pour « automatiser rapidement des tâches répétitives » que
vous auriez pu autrement faire manuellement. Étant donné qu'aucune déclaration de variables, aucun type,
aucune classe ou aucune règle compliquée ne doit être respectée, programmer devient vraiment amusant.
Python 2.7.3 ou 3.3.0 ?
Les deux versions de Python sont préinstallées sur Raspberry Pi. La nouvelle version de Python 3.x utilise
malheureusement en partie une syntaxe différente par rapport à la version éprouvée 2.x, de sorte que les
programmes créés avec une version ne marchent pas avec l'autre. Certaines bibliothèques importantes
comme p. ex. la célèbre PyGame pour la programmation de jeux et de représentations graphiques
générales, ne sont pas disponibles pour Python 3.x. Par conséquent, et aussi parce que la plupart des
programmes disponibles sur Internet sont écrits pour Python 2.x, nous utilisons dans ce manuel la
version éprouvée 2.7.3 de Python. Si une version de Python plus ancienne, avec un numéro de version 2.x
est installée sur votre Raspberry Pi, nos exemples fonctionneront également.
12
Python 2.7.3 est lancé avec le symbole IDLE sur le bureau. En un clin d'œil, une fenêtre de
saisie avec une invite de commande s'affiche ici à l'écran.
Fig. 1.6: La fenêtre de saisie du Python-Shell.
Dans cette fenêtre, vous ouvrez les programmes Python existants, vous en écrivez de nouveaux ou vous
pouvez directement modifier les commandes Python de manière interactive, sans avoir à écrire un vrai
programme. Entrez p. ex. dans l'invite de commande ce qui suit :
>>> 1+2
La réponse correcte s'affiche ensuite immédiatement :
3
De cette façon, Python peut être utilisé comme une calculatrice pratique mais cela n'a rien à voir avec la
programmation. Le cours de programmation commence habituellement avec un programme Bonjour le
monde, qui écrit sur l'écran la phrase « Bonjour le monde ». Cela est si facile avec Python qu'il n'est même
pas nécessaire d'insérer son propre titre. Il vous suffit de taper dans l'écran du Python-Shell la phrase
suivante :
>>> print "Bonjour le monde"
Ce premier « programme » écrit ensuite Bonjour le monde dans la ligne suivante à l'écran.
Fig. 1.7: « Bonjour le monde » en Python (La réponse du calcul est encore visible au-dessus).
Vous voyez également ici que le Python-Shell utilise automatiquement différentes couleurs de texte à des fins
de clarification. Les commandes Python sont en orange, les chaînes de caractères en vert et les résultats en
bleu. Vous découvrez plus tard encore d'autres couleurs.
13
Cartes flash Python
Python est le langage de programmation idéal pour commencer à apprendre à programmer. Seule la
syntaxe et les règles de mises en page sont un peu étranges. Pour vous aider à programmer, les éléments
importants de la syntaxe du langage Python sont décrits brièvement sous la forme « d'antisèche ». Elle
repose sur les cartes flash de David Whale. Vous trouverez tout ce dont vous avez besoin à l'adresse
bit.ly/pythonflashcards. Ces cartes flash n'expliquent pas le contexte technique mais seulement décrivent
la syntaxe avec des exemples brefs et comment faire quelque chose.
1.4.1 Deviner les chiffres avec Python
Plutôt que de nous arrêter sur les principes de la programmation, les algorithmes et les types de données,
nous préférons écrire le premier petit jeu dans Python, une devinette simple, dans laquelle un chiffre choisi
aléatoirement par l'ordinateur doit être deviné par le joueur avec le moins d'étapes possibles.
1.
Choisissez dans le menu le Python-Shell File/New Window. Une nouvelle fenêtre s'ouvre ici, dans
laquelle vous entrez le code suivant :
import random
chiffre = random.randrange(1000); réponse = 0; i = 0
while réponse != chiffre:
réponse = input("Ta réponse :")
if chiffre < réponse:
print "Le chiffre cherché est plus petit que",réponse
if chiffre > réponse:
print "le chiffre cherché est plus grand que ",réponse
i += 1
print "Vous avec trouvé le chiffre à la ",i,"e
réponse"
2. Enregistrez le fichier avec File/Save As en tant que spiel1.py. Ou téléchargez le fichier fini du
programme à partir de www.buch.cd et ouvrez-le dans Python-Shell avec File/Open. Le code couleur
dans le code source apparaît automatiquement et aide à trouver les erreurs de saisie.
3. Avant de lancer le jeu, vous devez tenir compte d'une particularité de la langue [française], à savoir les
[accents]. Python fonctionne sur différentes plateformes informatiques qui codent les [accents]
différemment. Pour qu'ils soient correctement affichés, choisissez dans le menu Options/Configure IDLE
et activez sur l'onglet General l'option Locale-defined dans le champ Default Source Encoding.
14
Fig. 1.8: Le réglage correct pour afficher les [accents] dans Python.
4. Lancez maintenant le jeu avec la touche [F5] ou le point de menu Run/Run Module.
5. Par souci de simplicité, le jeu renonce à l'interface graphique, au texte explicatif ou aux questions de
plausibilité de la réponse. L'ordinateur génère en arrière-plan un chiffre aléatoire compris entre 0 et
1000. Il suffit d'entrer votre réponse et vous saurez si le chiffre cherché est plus grand ou plus petit. En
plusieurs réponses, vous vous approcherez du bon chiffre.
15
Fig. 1.9: Deviner le chiffre dans Python.
1.4.2 Voilà comment cela fonctionne
Comme le jeu fonctionne, vous pouvez l'essayer facilement. Vous vous posez naturellement quelques
questions maintenant : Qu'est-ce qu'il se passe en arrière-plan ? Qu'est-ce que ces lignes de programme
signifient ?
import random Pour
générer le chiffre aléatoire, un module de Python externe nommé random est importé. Il
contient différentes fonctions nécessaire pour générer le chiffre aléatoire.
chiffre = random.randrange(1000) La
fonction randrange du module random génère un chiffre aléatoire
dans la gamme délimitée par les paramètres, ici entre 0 et 999. Le paramètre de la fonction
random.randrange() spécifie le nombre de chiffres aléatoires possibles, commençant par 0 donc toujours
le premier chiffre qui n'est pas atteint. Il en est de même pour les boucles et les fonctions semblables dans
Python.
Ce chiffre aléatoire est enregistré dans les variables chiffre. Les variables sont les emplacements mémoires
dans Python, qui portent un nom donné et qui peuvent enregistrer des chiffres, des chaînes de caractères,
des listes ou d'autres types de données. Contrairement à d'autres langages de programmation, vous ne devez
pas les déclarer préalablement.
16
Comment les chiffres aléatoires sont-ils générés ?
On pense communément que rien ne peut se produire au hasard dans un programme. Alors, comment
est-ce qu'un programme peut générer un chiffre aléatoire ? Si l'on divise un grand nombre premier par
n'importe quel chiffre, on obtient des chiffres à x décimales qui peuvent être devinés difficilement. Ils
changent sans aucune régularité lorsque l'on augmente régulièrement le diviseur. Bien que ce résultat soit
apparemment dû au hasard, il peut être reproduit à tout moment par un programme identique ou en
appelant plusieurs fois le même programme. Si l'on prend maintenant un nombre obtenu à partir de
certains de ces chiffres et que l'on le divise à nouveau par un chiffe qui découle de la seconde du temps
actuel ou du contenu d'un emplacement mémoire donné de l'ordinateur, on obtient un résultat qui n'est
pas reproductible et qui est alors appelé un chiffre aléatoire.
réponse = 0 La
variable réponse contient le nombre que l'utilisateur a donné. Au début, elle est 0.
i = 0 La
variable i s'est établie chez les développeurs comme le compteur pour les cycles de boucles du
programme. Elle est utilisée ici pour compter le nombre de réponses que l'utilisateur a donné pour deviner le
chiffre secret. Cette variable est aussi égale à 0au début.
while réponse != chiffre: Le mot while (en anglais signifiant « tant que ») lance une boucle de
programme qui est répétée dans ce cas tant que la réponse, le chiffre que l'utilisateur donne n'est pas égal
au chiffre secret chiffre. Python utilise la combinaison de caractères != pour l'inégalité. La boucle de
programme s'exécute en fait après les deux points (:).
réponse = input("Ta réponse :") La fonction input écrit le texte Ta réponse : puis attend ensuite
une commande qui est enregistrée dans la variable réponse.
Les indentations sont importantes dans Python
Dans la plupart des langages de programmation, les boucles de programme ou les décisions utilisent
l'indentation [ajout de tabulation ou d'espaces dans un fichier texte] pour faciliter la lecture du code du
programme. Dans Python, cette indentation sert non seulement à des fins de clarification mais elle est
également absolument nécessaire pour la logique du programme. On n'a pas besoin ici de ponctuation
spéciale pour quitter les boucles ou les décisions.
if chiffre < réponse:
Si le chiffre secret chiffre est plus petit que le chiffre réponse donné par
l'utilisateur, alors...
print "Le chiffre cherché est plus petit que", réponse
... ce texte est délivré. À la fin, la variable réponse est utilisée pour que le chiffre donné apparaisse dans le
texte. Si cela ne répond pas à cette condition, la ligne indentée est simplement ignorée.
if réponse < chiffre:
Si le chiffre secret chiffre est plus grand que le chiffre réponse donné par
l'utilisateur, alors...
print "Le chiffre cherché est plus grand que", réponse
... un autre texte est délivré.
17
i += 1 Dans chaque cas – donc plus indenté – le compteur i, qui compte le nombre de tentatives, est
augmenté de 1. Cette ligne avec l'opérateur += veut dire la même chose que i = i + 1.
print "Vous avez trouvé le chiffre à la ",i,"e
réponse"
Cette ligne est plus indentée ce qui signifie que la boucle while est également quittée. Si la condition n'est
plus satisfaite, que le chiffre réponse donné par l'utilisation n'est plus inégal (mais égal) au chiffre secret
chiffre, ce texte est délivré, qui se compose des deux parties de la phrase et des variables i et qui indique
le nombre de tentatives nécessaires pour que l'utilisateur trouve la bonne réponse. Les programmes Python
n'ont besoin d'aucune instruction en particulier pour se terminer. Ils se terminent tout simplement après la
dernière ligne de commande ou après une boucle qui n'est plus exécutée et après laquelle il n'y a pas
d'autre instruction.
2 Le premier voyant LED s'allume sur le Raspberry Pi
La barrette à 26 broches dans le coin du Raspberry Pi permet de connecter directement des périphériques
pour p. ex. saisir des entrées via des boutons ou allumer les voyants LED contrôlés par un programme. Cette
barrette est également appelée GPIO. L'acronyme anglais de « General Purpose Input Output » signifie
simplement en [français] « Entrée et sortie d'usage général ».
17 de ces 26 broches peuvent être programmées comme des entrées ou des sorties comme vous le souhaitez,
et elles peuvent être utilisées pour de nombreuses extensions matérielles. Les autres broches sont dédiées à
l'alimentation électrique et à d'autres fins.
Fig. 2.1: Attribution des interfaces GPIO La ligne grise en haut et à gauche indique le bord de la carte de circuit imprimé. La broche
GPIO 2 se trouve complétement à l'extérieur, dans le coin du Raspberry Pi.
18
Attention !
En aucun cas, vous ne devez connecter les broches GPI entre elles et attendre la suite des événements.
Suivez impérativement les instructions suivantes :
Certaines broches GPIO sont directement connectées aux bornes du processeur et un court-circuit peut
endommager irréversiblement le Raspberry Pi. Si vous connectez deux broches ensemble via un
interrupteur ou une LED, il faut toujours intercaler une pré-résistance.
Utilisez toujours pour les signaux logistiques la broche 1 qui délivre une tension de + 3,3 V et qui peut
supporter jusqu'à 50 mA. La broche 6 est le fil de terre pour les signaux logistiques. Les autres broches,
14, 17, 20, 25 marquée par Ground ou 3V3 sont réservées aux extensions ultérieures. Vous pouvez
actuellement les utiliser comme indiqué. Cependant, vous ne devez pas le faire pour pouvoir les utiliser
pour vos projets aussi avec les versions à venir du Raspberry Pi.
Chaque broche GPIO peut être définie comme une sortie (p. ex. pour les LED) ou comme une entrée (p.
ex. pour les boutons). Les sorties GPIO délivrent en état logique 1 une tension de + 3,3 V, en état logique 0
0 volt. Les sorties GPIO délivrent sous une tension allant jusqu'à + 1,7 V le signal logique 0, sous une
tension comprise entre + 1,7 V et + 3,3 V le signal logique 1.
La broche 2 délivre une tension de + 5 V pour alimenter un périphérique externe. Le courant délivré peut
être aussi élevé que celui délivré par le bloc d'alimentation USB du Raspberry Pi. Cette broche ne doit
cependant pas être connectée avec une entrée GPIO.
2.1 Composants dans le kit
Le kit d'apprentissage contient différents composants électroniques, qui vous permettent de réaliser les
expériences décrites (et naturellement les vôtres). A ce stade, les composants sont décrits uniquement
brièvement. L'expérience pratique qui est nécessaire pour les utiliser est ensuite apportée par les expériences
réelles.
•
2x Cartes de circuit imprimé
•
1x LED rouge
•
1x LED jaune
•
1x LED verte
•
1x LED bleue
•
4x Boutons
•
4x Résistances de 10 kΩ (Marron-Noir-Orange)
•
4x Résistances de 1 kΩ (Marron-Noir-Rouge)
19
•
4x Résistances de 220 Ω (Rouge-Rouge-Marron)
•
12x Câbles de connexion (Circuit imprimé – Raspberry Pi)
•
fil de connexion d'env. 1 m
2.1.1 Cartes de circuits imprimés
Deux cartes de circuit imprimé sont incluses dans le kit pour construire rapidement des circuits
électroniques. Les composants électroniques peuvent être directement branchés sur une trame à perforation
avec des distances standard, sans avoir à les souder. Dans ces cartes, les rangées longitudinales extérieures
avec les contacts (X et Y) sont toutes interconnectées.
Fig. 2.2: La carte de circuit imprimé du kit avec quelques composants montrés pour l'exemple.
Ces rangées de contact sont souvent utilisées comme les pôles plus et moins pour l'alimentation électrique
des circuits. Dans les autres rangées de contact, 5 contacts sont interconnectés (A à E et F à J) là où il y a un
trou au centre de la carte. De grands composants peuvent être insérés au centre et câblés vers l'extérieur.
2.1.2 Câble de connexion
Les câbles de connexion de couleur ont tous sur l'un des côtés un petit connecteur de fils qui peut être inséré
sur la carte de circuit imprimé. De l'autre côté, il y a une prise qui s'adapte sur une broche GPIO du
Raspberry Pi.
En outre, le fil de connexion est inclus dans le kit d'apprentissage. Il permet de créer des ponts de jonction
courts pour connecter les rangées de contact sur la carte de circuit imprimé. Coupez la longueur appropriée
20
de fil avec un petit coupe-fil comme décrit dans chaque expérience. Pour pouvoir mieux insérer le fil dans la
carte de circuit imprimé, il est recommandé de couper le fil de manière légèrement oblique de sorte à créer
une sorte de pointe. Dénudez la gaine isolante aux deux extrémités sur une longueur d'environ un demicentimètre.
2.1.3 Résistances et leur code couleur
Les résistances sont utilisées dans l'électronique numérique essentiellement pour limiter le courant arrivant
au port d'un microcontrôleur mais également comme pré-résistance pour les LED. L'unité de mesure de la
résistance est l'ohm (Ω). 1000 ohms correspondent à un kiloohm, qui est abrégé par kΩ.
La valeur de la résistance est donnée sur la résistance par des anneaux de couleur. La plupart des résistances
ont quatre anneaux de couleur. Les deux premiers anneaux de couleur indiquent le chiffre, le troisième un
multiplicateur et le quatrième la tolérance. Cet anneau de tolérance est la plupart du temps de couleur or - ou
argent. Le premier anneau ne peut pas être de ces couleurs de sorte que le sens de lecture est clair. La valeur de
la tolérance ne joue en soi aucun rôle dans l'électronique numérique.
Couleur
Valeur de la résistance en ohm (Ω)
1. Anneau
(1er chiffre ;
dizaine)
2. Anneau
(2e chiffre)
Argent
3. Anneau
(Multiplicateur)
4. Anneau
(Tolérance)
10−2 = 0,01
± 10 %
−1
Or
10 = 0,1
Noir.
0
100 = 1
±5%
Marron
1
1
101 = 10
±1%
Rouge
2
2
102 = 100
±2%
3
Orange.
3
3
10 = 1 000
Jaune.
4
4
104 = 10 000
Vert
5
5
105 = 100 000
± 0,5 %
Bleu
6
6
106 = 1 000 000
± 0,25 %
Violet
7
7
107 = 10 000 000
± 0,1 %
Gris
8
8
108 = 100 000 000
± 0,05 %
Blanc
9
9
109 = 1 000 000 000
Tableau 2.1: Le tableau montre la signification des anneaux de couleur sur les résistances.
21
Le kit d'apprentissage contient des résistances de trois valeurs différentes :
Valeur
1. Anneau
(1er chiffre ;
dizaine)
2. Anneau
(2e chiffre)
3. Anneau
(Multiplicat
eur)
4. Anneau
(Toléranc
e)
Usage
220 Ω
Rouge
Rouge
Marron
Or
Pré-résistance pour LED
1 kΩ
Marron
Noir.
Rouge
Or
Résistance de protection
pour les entrées GPIO
10 kΩ
Marron
Noir.
Orange.
Or
Résistance Pull-Down
pour les entrées GPIO
Tableau 2.2: Codes couleur des résistances incluses dans le kit d'apprentissage
Faites particulièrement attention aux couleurs des résistances de 1 kΩ et de 10 kΩ. Il est facile de les
intervertir.
2.2 Brancher les LED
Les voyants LED (LED = Light Emitting Diode, soit en français = diode électroluminescente) pour les signaux
lumineux et les effets lumineux peuvent être branchés sur les ports GPIO. Pour ce faire, une pré-résistance de
220 Ω (Rouge-Rouge-Marron) doit être montée entre la broche GPIO utilisée et l'anode de la LED, pour limiter
le courant passant et éviter de griller la LED. En outre, la pré-résistance protège également la sortie GPIO du
Raspberry Pi. En effet, la LED n'offre quasiment aucune résistance dans le sens du courant et le port GPIO
peut donc être surchargé rapidement s'il est connecté à la masse. On branche la cathode de la LED avec le fil
de masse sur la broche 6.
Dans quel sens faut-il brancher la LED ?
Les deux conducteurs de connexion d'une LED ont des longueurs différentes. Le conducteur le plus long
des deux est le pôle plus, c.-à-d. l'anode, le plus court est la cathode. Astuce pour retenir facilement : Le
signe plus a un trait en plus par rapport au signe moins, ce qui fait que le fil est un peu plus long. En
outre, la plupart des LED sont aplaties du côté moins, ressemblant alors au signe moins. Astuce pour
retenir facilement : Cathode = bord court
En premier lieu, branchez comme sur la figure une LED via une pré-résistance de 220 Ω (Rouge-RougeMarron) sur la prise + 3,3 V (broche 1) et connectez le pôle moins de la LED à la ligne de terre (broche 6).
22
Fig. 2.3: Construction de la carte pour connecter une LED.
Composants nécessaires:
1x Carte de circuit imprimé
1x LED rouge
1x résistance de 220 Ω
2x Câbles de connexion
23
Fig. 2.4: Le premier voyant LED sur le Raspberry Pi
Dans cette première expérience, le Raspberry Pi est uniquement utilisé comme alimentation électrique de la
LED. La LED s'allume toujours sans avoir besoin de logiciel.
Dans l'expérience suivante, vous installerez un bouton dans la ligne d'alimentation de la LED. La LED
s'allume maintenant uniquement si vous appuyez sur le bouton. Aucun logiciel n'est également requis ici.
24
Fig. 2.5: Construction de la carte pour une LED qui est allumée avec un bouton
Composants nécessaires :
1x Carte de circuit imprimé
1x LED rouge
1x résistance de 220 Ω
1x Bouton
2x Câbles de connexion
25
Fig. 2.6: LED avec bouton sur le Raspberry Pi.
2.3 GPIO avec Python
Pour pouvoir utiliser les ports GPIO avec un programme Python, vous devez installer la bibliothèque PythonGPIO. Si vous n'êtes pas certain(e) si tous les modules nécessaires sont installés, installez une fois les
versions actuelles avec les commandes suivantes :
sudo apt-get update
sudo apt-get install python-dev
sudo apt-get install python-rpi.gpio
Comme d'habitude pour tous les périphériques sous Linux, les ports GPIO sont inclus comme des fichiers
dans la structure du répertoire. Vous avez besoin des privilèges Root pour accéder à ces fichiers. Lancez
également le Python-Shell avec les privilèges Root via un LXTerminal : sudo idle
26
2.4 Allumer et éteindre une LED
Branchez, comme indiqué sur la figure, une LED via une pré-résistance de 220 Ω (Rouge-Rouge-Marron) sur
le port GPIO 25 (broche 22) et non plus directement sur la prise de + 3,3 V. Connectez le pôle moins de la
LED au fil de terre du Raspberry Pi (broche 6) via le rail de masse de la carte de circuit imprimé.
Composants nécessaires :
1x Carte de circuit imprimé
1x LED rouge
1x résistance de 220 Ω
2x Câbles de connexion
Le programme suivant led.py allume la LED pendant 5 secondes puis l'éteint :
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.OUT)
GPIO.output(25, 1)
time.sleep(5)
GPIO.output(25, 0)
GPIO.cleanup()
27
Fig. 2.7: Une LED sur le port GPIO 25
2.4.1 Voilà comment cela fonctionne
L'exemple montre les fonctions de base les plus importantes de la bibliothèque RPi.GPIO.
import RPi.GPIO as GPIO La bibliothèque RPi.GPIO doit être importée dans chaque programme Python où
elle doit être utilisée. Cette manière d'écrire permet de consulter toutes les fonctions de la bibliothèque via le
préfixe GPIO.
import time La
fonction time couramment utilisée de la bibliothèque Python n'a rien à voir avec la
programmation de GPIO. Elle comprend des fonctions pour le calcul de l'heure et de la date, y compris une
fonction time.sleep, avec laquelle vous pouvez définir facilement des temps d'attente dans un programme.
Au début de chaque programme, il faut définir comment sont affectés les ports
GPIO. On utilise normalement la numérotation standard BCM.
GPIO.setmode(GPIO.BCM)
28
Numérotation des ports GPIO
La bibliothèque RPi.GPIO supporte différentes méthodes pour affecter les ports. Dans le mode BCM, les
numéros de port GPIO connus sont utilisés, qui peuvent également être utilisés à partir des lignes de
commande ou dans les scripts de Shell. Dans le mode alternatif BOARD, l'affectation des numéros de
broches de 1 à 26 correspondent à la carte Raspberry Pi.
GPIO.setup(25, GPIO.OUT) La
fonction GPIO.setup initialise un port GPIO comme une sortie ou une
entrée. Le premier paramètre affecte le port en fonction du mode prédéfini BCM ou BOARD avec son numéro
GPIO ou son numéro de broche. Le deuxième paramètre peut être soit GPIO.OUT pour une sortie soit
GPIO.IN pour une entrée.
GPIO.output(25, 1) Sur
un port qui vient être initialisé, un 1 est donné. La LED qui y est branchée,
s'allume. A la place de 1, les valeurs prédéfinies True ou GPIO.HIGH peuvent également être données.
time.sleep(5) Cette fonction entraîne un temps d'attente de 5 secondes à partir de la bibliothèque time
importée au début, avant que le programme ne se poursuive.
GPIO.output(25, 0) Pour
éteindre la LED, on transmet la valeur 0, False ou GPIO.LOW sur le port GPIO.
GPIO.cleanup() A
l'issue d'un programme, tous les ports GPIO doivent être réinitialisés. Cette ligne traite en
une fois tous les ports GPIO initialisés par le programme. Les ports qui sont initialisés par d'autres
programmes restent inchangés. À la fin, les autres programmes potentiellement exécutés en parallèle ne sont
pas affectés.
Intercepter les avertissements GPIO
Si un port GPIO doit être configuré sans avoir été réinitialisé correctement, mais qu'il a été ouvert par un
autre programme ou par un programme corrompu, il est possible que des messages d'alerte soit émis
sans interrompre cependant le déroulement du programme. Au cours du développement du programme,
ces avertissements peuvent être très utiles pour détecter les erreurs. Dans un programme fini, ils peuvent
déconcerter un utilisateur inexpérimenté. Par conséquent, la bibliothèque GPIO offre avec
GPIO.setwarnings(False) la possibilité de supprimer ces avertissements.
2.5 Lancer Python avec support GPIO sans terminal
Les personnes qui bricolent beaucoup avec Python et GPIO ne souhaitent pas ouvrir à chaque fois un
LXTerminal pour lancer l'IDLE. Il existe un moyen plus facile. Placez ce symbole sur le bureau qui peut ouvrir
l'IDE de Python avec les privilèges de super-utilisateur :
29
•
Créez une copie du symbole de bureau IDLE préinstallé. Pour ce faire, procédez comme suit :
•
Faites un clic droit de souris sur le symbole IDLE du bureau et sélectionnez Copier dans le menu
contextuel.
Fig. 2.8: Copier le symbole IDLE du bureau.
Ensuite faites un clic droit de souris sur le bureau et sélectionnez Coller dans le menu contextuel. Comme il
existe déjà un raccourci bureau avec le même nom, un message indiquant que vous essayez de faire une
copie s'affiche à l'écran.
Modifiez ici le nom de la copie de idle.desktop à idle_gpio.desktop. Rien ne change au premier abord au
niveau du symbole sur le bureau. Le nom affiché reste IDLE.
30
Fig. 2.9: Message affiché lors de la duplication d'un raccourci bureau
Faites maintenant un clic droit de souris sur la copie du symbole de bureau et sélectionnez Leafpad dans le
menu contextuel. Les raccourcis bureau sont des fichiers texte dans Linux, qui peuvent être modifiés à l'aide
d'un éditeur de texte.
Fig. 2.10: Le raccourci bureau dans l'éditeur de texte Leafpad
Effectuez ici les deux modifications montrées dans la figure :
•
Modifiez le champ Name en IDLE GPIO. Il s'agit du nom qui sera affiché à l'écran.
•
Insérez dans le champ Exec avant la commande le mot sudo.
Fermez l'éditeur et enregistrez le fichier. En double-cliquant sur le nouveau symbole de bureau, lancez l'IDE
de Python IDLE avec les privilèges de super-utilisateur. Vous pouvez maintenant utiliser les fonctions GPIO
sans ouvrir Python via un LXTerminal.
31
3 Feu de signalisation
Allumer et éteindre une seule LED peut être amusant au début mais cela ne nécessite pas vraiment un
ordinateur pour le faire. Un feu de signalisation avec son cycle de lumière typique passant du vert au jaune,
du jaune au rouge puis une combinaison de rouge-jaune pour revenir au vert, est facile à réaliser avec trois
LED et permet de montrer des techniques supplémentaires de programmation dans Python.
Montez le circuit montré dans la figure sur la carte de circuit imprimé. Pour contrôler les LED, trois ports
GPIO et un fil de terre commun sont utilisés. Les numéros de ports GPIO en mode BCM sont montrés sur le
Raspberry Pi dans la figure.
Fig. 3.1: Construction de la carte pour le feu de signalisation
Composants nécessaires :
1x Carte de circuit imprimé
1x LED rouge
1x LED jaune
1x LED verte
3x résistances de 220 Ω
4x Câbles de connexion
32
Fig. 3.2: Un feu de signalisation simple
Le programme ampel01.py contrôle le feu de circulation :
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
rouge
= 0; jaune
= 1; vert = 2
Feu_de_circulation=[4,18,23]
GPIO.setup(Feu_de_circulation[rouge], GPIO.OUT, initial=False)
GPIO.setup(Feu_de_circulation[jaune], GPIO.OUT, initial=False)
GPIO.setup(Feu_de_circulation[vert], GPIO.OUT, initial=True)
print ("Ctrl+C arrête le programme")
try:
while True:
time.sleep(2)
GPIO.output(Feu_de_circulation[vert],False);
33
GPIO.output(Feu_de_circulation[jaune],True)
time.sleep(0.6)
GPIO.output(Feu_de_circulation[jaune],False);
GPIO.output(Feu_de_circulation[rouge],True)
time.sleep(2)
GPIO.output(Feu_de_circulation[jaune],True)
time.sleep(0.6)
GPIO.output(Feu_de_circulation[rouge],False);
GPIO.output(Feu_de_circulation[jaune],False)
GPIO.output(Feu_de_circulation[vert],True)
except KeyboardInterrupt:
GPIO.cleanup()
3.1.1 Voilà comment cela fonctionne
Les premières lignes sont déjà connues. Elles importent les bibliothèques RPi.GPIO pour le contrôle des
ports GPIO et time pour les retards. La numérotation des ports GPIO est ensuite définie comme dans
l'exemple précédent sur BCM.
rouge = 0; jaune = 1; vert = 2 Ces lignes définissent les trois variables rouge, jaune et vert pour les trois
LED. Vous n'avez besoin dans le programme de rappeler aucun numéro ou de port GPIO. Vous pouvez
contrôler facilement les LED via leur couleur.
Feu_de_circulation=[4,18,23] Pour contrôler les trois LED, une liste est établie. Elle contient les
numéros GPIO dans l'ordre, dans lequel les LED sont montées sur la carte de circuit imprimé. Étant donné
que les ports GPIO apparaissent uniquement à ces endroits dans le programme, vous pouvez facilement
modifier le programme si vous souhaitez utiliser d'autres ports GPIO.
GPIO.setup(Feu_de_circulation[rouge], GPIO.OUT, initial=False)
GPIO.setup(Feu_de_circulation[jaune], GPIO.OUT, initial=False)
GPIO.setup(Feu_de_circulation[vert], GPIO.OUT, initial=True)
Les trois ports GPIO utilisés sont initialisés un par un comme des sorties. Nous n'utilisons cette fois aucun
numéro de port GPIO mais plutôt la liste précédemment définie. Dans une liste, chaque élément est indexé
par un numéro, en commençant par 0. Feu_de_circulation[0] est également le premier élément, dans ce
cas 4. Les variables rouge, jaune et vert contiennent les numéros 0, 1 et 2, qui sont nécessaires comme index
pour les éléments de la liste. De cette façon, les ports GPIO utilisés peuvent être traités par les couleurs :
•
Feu_de_circulation[rouge]
correspond au port GPIO 4 avec la LED rouge.
•
Feu_de_circulation[jaune]
correspond au port GPIO 18 avec la LED jaune.
•
Feu_de_circulation[vert]
correspond au port GPIO 23 avec la LED verte
L'instruction GPIO.setup peut contenir un paramètre initial facultatif, qui attribue déjà un statut logique
au port GPIO lors de l'initialisation. Dans ce programme, nous allumons la LED verte dès le début. Les deux
autres LED commencent le programme dans un état éteint.
print ("Ctrl+C arrête le programme") Un court mode d'emploi est maintenant affiché à l'écran. Le
programme s'exécute automatiquement. La combinaison de touches [Ctrl] +[C] doit l'arrêter. Pour vérifier
si l'utilisateur a arrêté le programme avec [Ctrl]+[C], nous utilisons une requête try...except. Le code
34
de programme associé sous try: est ensuite exécuté normalement. Si une exception système se provient
pendant ce temps – cela peut être une erreur ou également la combinaison de touche [Ctrl]+[C], le
programme est interrompu et l'instruction except à la fin du programme est exécutée.
except KeyboardInterrupt:
GPIO.cleanup()
Cette combinaison de touches déclenche un KeyboardInterrupt et la boucle est quittée automatiquement. La
dernière ligne ferme les ports GPIO utilisés et éteint toutes les LED. Le programme est terminé. Grâce à la
fermeture contrôlée des ports GPIO, aucun avertissement système ou message d'erreur, qui pourrait
déconcerter l'utilisateur, ne s'affiche à l'écran. Le cycle réel du feu de signalisation s'exécute dans une boucle
infinie :
while True : Ces boucles infinies nécessitent toujours une condition d'arrêt sinon le programme ne
s'arrêterait jamais.
time.sleep(2) Au début du programme mais également à chaque départ de la boucle, la LED verte
s'allume pendant 2 secondes.
GPIO.output(Feu_de_circulation[vert],False);
GPIO.output(Feu_de_circulation[jaune],True)
time.sleep(0.6)
La LED verte s'éteint maintenant et la LED jaune s'allume. Elle éclaire ensuite seule pendant 0,6 seconde.
GPIO.output(Feu_de_circulation[jaune],False);
GPIO.output(Feu_de_circulation[rouge],True)
time.sleep(2)
La LED jaune s'éteint maintenant à nouveau et la LED rouge s'allume. Elle éclaire ensuite seule pendant
2 secondes. La phase rouge d'un feu de signalisation est généralement beaucoup plus longue que la phase
jaune.
GPIO.output(Feu_de_circulation[jaune],True)
time.sleep(0.6)
Au début de la phase rouge-jaune, la LED jaune est également allumée sans qu'une autre LED soit éteinte.
Cette phase dure 0,6 seconde.
GPIO.output(Feu_de_circulation[rouge],False)
GPIO.output(Feu_de_circulation[jaune],False)
GPIO.output(Feu_de_circulation[vert],True)
À la fin de la boucle, le feu de signalisation repasse au vert. Les LED rouge et jaune sont éteintes et la LED
verte est allumée. La boucle recommence dans la phase verte du feu de signalisation avec un temps d'attente
de 2 secondes. Vous pouvez naturellement modifier tous les temps comme vous le souhaitez. En réalité, les
phases du feu de signalisation dépendent des dimensions du carrefour et du trafic routier. Les phases jaune
et rouge-jaune durent en général 2 secondes chacune.
35
4 Feu pour piétons
Dans l'expérience suivante, nous ajoutons un feu pour piéton au feu de signalisation, qui montre une lumière
clignotante pour les piétons pendant la phase rouge du feu de circulation, comme cela est utilisé dans
certains pays. Vous pouvez naturellement aussi installer dans le programme les feux pour piétons avec des
lumières rouge et verte que l'on trouve en Europe centrale mais ce kit d'apprentissage ne contient qu'une
LED en plus des LED déjà utilisées dans le feu de circulation.
Pour l'expérience suivante, montez une LED avec une pré-résistance comme montré dans le schéma du
circuit. Elle doit être branchée sur le port GPIO 24.
Fig. 4.1: Construction de la carte pour le feu de circulation et le feu clignotant pour piétons
Composants nécessaires :
1x Carte de circuit imprimé
1x LED rouge
1x LED jaune
1x LED verte
1x LED bleue
4x résistances de 220 Ω
5x câbles de connexion
36
Fig. 4.2: Feu de circulation avec feu clignotant pour piéton
Le programme ampel02.py contrôle le nouveau système de feu de signalisation : Le programme a été
légèrement développé par rapport à la version précédente.
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
rouge
= 0; jaune
= 1; vert = 2, bleu
= 3
Feu_de_circulation=[4,18,23,24]
GPIO.setup(Feu_de_circulation[rouge], GPIO.OUT, initial=False)
GPIO.setup(Feu_de_circulation[jaune], GPIO.OUT, initial=False)
GPIO.setup(Feu_de_circulation[vert], GPIO.OUT, initial=True)
GPIO.setup(Feu_de_circulation[bleu], GPIO.OUT, initial=False)
print ("Ctrl+C arrête le programme")
try:
while True:
37
time.sleep(2)
GPIO.output(Feu_de_circulation[vert],False);
GPIO.output(Feu_de_circulation[jaune],True)
time.sleep(0.6)
GPIO.output(Feu_de_circulation[jaune],False);
GPIO.output(Feu_de_circulation[rouge],True)
time.sleep(0.6)
for i in range(10):
GPIO.output(Feu_de_circulation[bleu],True); time.sleep(0.05)
GPIO.output(Feu_de_circulation[bleu],False); time.sleep(0.05)
time.sleep(0.6)
GPIO.output(Feu_de_circulation[jaune],True); time.sleep(0.6)
GPIO.output(Feu_de_circulation[rouge],False)
GPIO.output(Feu_de_circulation[jaune],False)
GPIO.output(Feu_de_circulation[vert],True)
except KeyboardInterrupt:
GPIO.cleanup()
4.1.1 Voilà comment cela fonctionne
Le déroulement du programme est déjà connu. Pendant la phase rouge longue, le feu pour piétons bleu doit
clignoter rapidement.
bleu = 4 Une
nouvelle variable définit la LED pour le feu pour piéton dans la liste
Feu_de_circulation=[4,18,23,24] La
liste a été élargie à quatre éléments pour pouvoir contrôler les
quatre LED.
GPIO.setup(Feu_de_circulation[bleu], GPIO.OUT, initial=False) La
nouvelle LED est initialisée et
est éteinte au début. C'est le réglage de base pendant la phase verte du feu de circulation.
time.sleep(0.6)
for i in range(10):
GPIO.output(Feu_de_circulation[bleu],True); time.sleep(0.05)
GPIO.output(Feu_de_circulation[bleu],False); time.sleep(0.05)
time.sleep(0.6)
Dans le cycle du feu de signalisation, une boucle qui permet à la LED bleue de clignoter, commence
0,6 seconde après le début de la phase rouge. Pour ce faire, nous utilisons ici une boucle for qui,
contrairement à la boucle while sera répétée un nombre défini de cycles de boucle, et qui ne n'exécute pas
tant qu'une certaine condition d'arrêt n'est pas satisfaite.
for i in range(10): Chaque
boucle for nécessite un compteur de boucle, une variable qui change de
valeur à chaque répétition de boucle. Pour un compteur de boucle simple, le nom de variable i s'est établi
dans tous les langages de programmation. Tout autre nom est naturellement possible. Cette valeur peut être
appelée comme toute autre variable dans la boucle, mais ce n'est pas nécessaire ici. Le paramètre range
dans la boucle indique le nombre de cycle de la boucle, et plus précisément, quelles sont les valeurs que le
compteur de boucle peut donner. Dans notre exemple, la boucle est répétée 10 fois. Le compteur de boucle i
passe de la valeur 0 à 9. Dans la boucle, la nouvelle LED bleue est allumée puis éteinte après 0,05 seconde.
Un cycle de boucle est terminé après 0,05 seconde supplémentaire, et le prochain cycle recommence avec
l'allumage de la LED. De cette façon, elle clignote dix fois, et la phase complète dure 1 seconde.
38
time.sleep(0.6) Avec
un retard de 0,6 seconde après le dernier cycle de boucle, le cycle de commutation
normal du feu de circulation est poursuivi par l'allumage simultané de la LED jaune et de la LED rouge (déjà
allumée). Rien de nouveau jusqu'à maintenant. Ce qui est vraiment intéressant, c'est le feu pour piéton,
lorsqu'il ne fonctionne pas automatiquement mais qu'il doit d'abord être activé en appuyant sur un bouton,
comme c'est le cas pour de nombreux feux pour piétons. Dans la prochaine expérience, un bouton connecté
à un port GPIO simulera le bouton-poussoir que l'on trouve sur un vrai feu pour piéton.
4.2 Bouton sur la connexion GPIO
Les ports GPIO peuvent non seulement être utilisés pour la sortie de données, par exemple via les LED, mais
également être utilisés pour l'entrée de données. Pour ce faire, vous devez les définir comme des entrées
dans le programme. Pour les entrées, nous utilisons dans le projet suivant un bouton qui est directement
inséré dans la carte de circuit imprimé. Le bouton a quatre broches de connexion et chaque paire de broches
opposées (les plus distantes) est interconnectée. Tant que vous appuyez sur le bouton, les quatre connexions
sont interconnectées. Contrairement à un interrupteur, un bouton ne se verrouille pas. La connexion est
interrompue immédiatement dès que vous relâchez le bouton. Si un signal de + 3,3 V est délivré sur le port
GPIO défini comme entrée, ce dernier est considéré comme un True ou 1 logique. Vous pouvez
théoriquement connecter le port GPO avec la connexion + 3,3 V du Raspberry Pi via le bouton. Cependant,
vous ne devez le faire en aucun cas ! Cela surchargerait le port GPIO. Connectez toujours une résistance de
protection de 1 kΩ entre une entrée GPIO et la connexion de + 3,3 V pour éviter que trop de courant n'arrive
sur le port GPIO et par conséquent sur le processeur.
Fig. 4.3: Touche avec résistance de protection sur une entrée GPIO
Dans la plupart des cas, ce circuit simple fonctionne déjà. Cependant, le port GPIO n'a pas d'état clairement
défini lorsque le bouton est ouvert. Si un programme appelle ce port, il est possible d'obtenir des résultats
aléatoires. Pour éviter cela, connectez une résistance relativement très élevée - généralement 10 kΩ - à la
masse. Cette résistance dite Pull-down tire le statut du port GPIO vers le bas à 0 V lorsque le bouton est
ouvert. Étant donné que la résistance est très élevée, il n'y a pas de risque de court-circuit tant que vous
appuyez sur le bouton. Lorsque vous appuyez sur le bouton, + 3,3 V et le fil de terre sont directement
connectés via cette résistance.
39
Fig. 4.4: Touche avec résistance de protection et résistance Pull-Down sur une entrée GPIO
Montez un bouton selon la figure suivante en utilisant les deux résistances dans le circuit.
Fig. 4.5: Construction de la carte pour le feu pour piéton « activé sur demande ».
40
Composants nécessaires :
1x Carte de circuit imprimé
1x LED rouge
1x LED jaune
1x LED verte
1x LED bleue
4x résistances de 220 Ω
1x Bouton
1x résistance de 1 kΩ
1x résistance de 10 kΩ
7x câbles de connexion
1x cavalier court
La barre de contact en bas de la figure du bouton est connectée avec le fil + 3,3 V du Raspberry Pi (broche 1)
via le rail plus de la carte de circuit imprimé. Pour connecter le bouton avec le rail plus, nous utilisons un
cavalier court pour garder le dessin clair. Sinon, vous pouvez également connecter un des contacts inférieurs
du bouton directement avec la broche 1 du Raspberry Pi en utilisant un câble de connexion.
La barre de contact supérieure dans la figure du bouton est connectée au port GPIO 25 via une résistance de
protection de 1 kΩ (Marron-Noir-Rouge) et au fil de terre via une résistance Pull-Down de 10 kΩ (MarronNoir-Orange).
41
Fig. 4.6: Feu clignotant pour piéton avec bouton
Le programme ampel03.py contrôle le nouveau système de feu de signalisation avec le bouton pour le feu
clignotant pour piéton
# -*- coding: utf-8 -*import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
rouge
= 0; jaune
= 1; vert
= 2; bleu
= 3; bouton = 4
Feu_de_circulation=[4,18,23,24,25]
GPIO.setup(Feu_de_circulation[rouge], GPIO.OUT, initial=False)
GPIO.setup(Feu_de_circulation[jaune], GPIO.OUT, initial=False)
GPIO.setup(Feu_de_circulation[vert], GPIO.OUT, initial=True)
42
GPIO.setup(Feu_de_circulation[bleu], GPIO.OUT, initial=False)
GPIO.setup(Feu_de_circulation[bouton], GPIO.IN)
print ("Appuyer sur le bouton pour activer le feu clignotant pour piétons
, Ctrl+C arrête le programme")
try:
while True:
if GPIO.input(Feu_de_circulation[bouton])==True:
GPIO.output(Feu_de_circulation[vert],False)
GPIO.output(Feu_de_circulation[jaune],True)
time.sleep(0.6)
GPIO.output(Feu_de_circulation[jaune],False)
GPIO.output(Feu_de_circulation[rouge],True)
time.sleep(0.6)
for i in range(10):
GPIO.output(Feu_de_circulation[bleu],True); time.sleep(0.05)
GPIO.output(Feu_de_circulation[bleu],False); time.sleep(0.05)
time.sleep(0.6)
GPIO.output(Feu_de_circulation[jaune],True)
time.sleep(0.6)
GPIO.output(Feu_de_circulation[rouge],False);
GPIO.output(Feu_de_circulation[jaune],False)
GPIO.output(Feu_de_circulation[vert],True); time.sleep(2)
except KeyboardInterrupt:
GPIO.cleanup()
4.2.1 Voilà comment cela fonctionne
Le programme est légèrement développé par rapport à la dernière version.
# -*- coding: utf-8 -*- Afin
d'afficher correctement les [accents français] du feu clignotant pour
dans la sortie de programme – indépendamment des paramètres de l'interface IDLE définis par
l'utilisateur, un code pour afficher les caractères spéciaux est défini dès le début. Cette ligne doit être incluse
dans tous les programmes qui affichent des textes, dans lesquels il y a des [accents] ou d'autres caractères
spéciaux propres à chaque pays.
piétons
ASCII, ANSI et Unicode
Un alphabet normal contient 26 lettres plus quelques caractères spéciaux, tous en majuscules et en
minuscules, ainsi que 10 chiffres et quelques signes de ponctuation ; l'ensemble s'élève à environ
100 signes différents. Un octet permet d'afficher 256 signes différents. Cela devrait être suffisant – pensez
au début de l'histoire des ordinateurs, lorsque les bases importantes des techniques actuelles ont été
définies.
Il est apparu très rapidement que l'inventeur du jeu de caractère ASCII (American Standard Code for
Information Interchange) basé sur 256 signes s'était trompé. C'était un américain qui n'avait pas pensé
au-delà du monde anglophone. Dans toutes les langues importantes dans le monde, sans compter les
langues asiatiques et arabes avec leur propre système d'écriture, il existe des centaines de lettres qui
doivent être représentées. Elles ne peuvent pas toutes tenir dans l'espace libre disponible de la liste
étendue des 256 caractères.
43
Plus tard, le jeu de caractères ANSI a été introduit parallèlement au jeu de caractère ASCII. Il est utilisé
par les anciennes versions de Windows et présente encore une fois les mêmes erreurs. Pour parfaire la
confusion des langues, les [accents français] et les autres lettres avec des accents ont été classés dans un
autre endroit du jeu de caractères dans la norme ASCII.
Pour résoudre ce problème, l'Unicode a été introduit dans les années 1990. Il représente toutes les
langues, y compris les hiéroglyphes égyptiens, l'écriture cunéiforme et le sanskrit védique, l'écriture la
plus ancienne dans le monde. Pour coder les caractères Unicode de la forme la plus commune dans les
fichiers de texte bruts, il y a UTF-8 un code qui fonctionne sur plusieurs plateformes, qui correspond aux
128 premiers caractères de l'ASCII et qui est rétrocompatible avec quasiment tous les systèmes affichant
des textes. Le codage est représenté dans une ligne de commentaire. Toutes les lignes qui commencent avec un
signe #, ne sont pas prise en compte par l'interpréteur Python. Le codage, qui doit toujours figurer au début d'un
programme, informe le Python-Shell des caractères à afficher sans qu'il y ait de réelle instruction de
programmation. De cette façon, vous pouvez également entrer vos commentaires dans le code du programme.
Commentaires dans le programme
Lorsque l'on écrit un programme, il est possible que l'on ne se souvienne pas plus tard ce que l'on avait
en tête pour certaines instructions du programme. La programmation est l'une des activités les plus
créatives car l'on crée quelque chose uniquement et exclusivement à partir de ses idées sans limite posée
par le matériel et les outils. Les commentaires sont particulièrement important lorsque l'on programme,
pour qu'une autre personne comprenne ce que l'on faut ou pour modifier le programme. Aucun
commentaire n'est inclus dans les exemples de programme pour maintenir un code de programme clair.
Toutes les instructions du programme sont décrites dans le détail.
Lorsque l'on publie son propre programme, il faut toujours se poser la question : les commentaires en
[français] ou en anglais ? En cas de commentaires en [français], les allemands se plaignent de ne pas
comprendre la langue. Avec des commentaires en anglais, on se comprend parfois plus et les Anglais se
moquent du mauvais anglais utilisé.
bouton = 4
Feu_de_circulation=[4,18,23,24,25]
Par souci de simplicité, pour le bouton, un seul élément supplémentaire avec le numéro 4 et le port GPIO 25
a été inséré dans la liste. De cette façon, vous pouvez également choisir un autre port GPIO pour le bouton,
dont le numéro comme le port GPIO de la LED est inscrit seulement à cet endroit du programme.
GPIO.setup(Feu_de_circulation[bouton], GPIO.IN) Le port GPIO du bouton est défini comme une
entrée. Cette définition s'effectue également via GPIO.setup, mais cette fois avec le paramètre GPIO.IN.
print ("Appuyer sur le bouton pour activer le feu clignotant pour piétons, Ctrl+C
arrête le programme")
Lors du démarrage, le programme affiche un long message qui informe l'utilisateur qu'il doit appuyer sur le
bouton.
44
while True:
if GPIO.input(Feu_de_circulation[bouton])==True:
Dans la boucle infinie, une requête est maintenant intégrée. Les instructions suivantes sont d'abord exécutées
lorsque le port GPIO 25 donne la valeur True et que l'utilisateur appuie également sur le bouton. Jusqu'à ce
moment, le feu de circulation reste dans sa phase verte. La poursuite de la boucle correspond
essentiellement au déroulement du dernier programme. Le feu de circulation passe du jaune au rouge et la
lumière clignotante clignote dix fois. Ensuite, le feu de circulation repasse au rouge-jaune, puis au vert.
time.sleep(2) Il
y a une petite différence dans ce programme. La phase verte de 2 secondes est intégrée
maintenant à la fin de la boucle et n'est plus au début de la boucle. Elle est néanmoins appliquée une fois
par cycle de boucle, avec comme différence que le cycle du feu de circulation commence immédiatement et
sans retard lorsque vous appuyez sur le bouton. Pour éviter que la phase verte n'échoue lorsque vous
réappuyez sur le bouton immédiatement après la phase jaune, ce retard est maintenant intégré à la fin de la
boucle.
5 Motif à LED coloré et chenillard
Les chenillards sont toujours des effets populaires pour attirer l'attention, que ce soit dans une salle de jeux
ou dans les enseignes lumineuses professionnelles. Grâce au Raspberry Pi et à quelques LED, vous pouvez
réaliser facilement quelque chose de ressemblant.
Montez pour l'expérience suivante quatre LED avec des pré-résistances comme indiqué sur la figure. Ce
circuit correspond au feu pour piétons sans le bouton de l'expérience précédente.
Fig. 5.1: Construction de carte pour le motif et le chenillard.
45
Composants nécessaires :
1x Carte de circuit imprimé
1x LED rouge
1x LED jaune
1x LED verte
1x LED bleue
4x résistances de 220 Ω
5x câbles de connexion
Fig. 5.2: Quatre LED avec pré-résistances.
Grâce à différents motifs clignotants à LED, nous expliquons plusieurs boucles et méthodes de
programmation en Python. Le programme suivant propose différents motifs à LED qui peuvent être choisis
par l'utilisateur en utilisant le clavier.
46
Le programme ledmuster.py permet de faire clignoter les LED de différentes façons.
# -*- coding: utf-8 -*import RPi.GPIO as GPIO
import time
import random
GPIO.setmode(GPIO.BCM)
LED = [4,18,23,24]
for i in LED:
GPIO.setup(i, GPIO.OUT, initial=0)
z = len(LED); w = 5; t = 0.2
print ("Choix de l'effet lumineux"); print ("1 – chenillard cyclique")
print ("2 – chenillard aller-retour"); print ("3 – montées et descentes")
print ("4 – Tous clignotent simultanément"); print ("5 – tous clignotent
aléatoirement")
print ("Ctrl+C arrête le programme")
try:
while True:
e = raw_input ("Veuillez choisir le motif : ")
if e == "1":
for i in range(w):
for j in range(z):
GPIO.output(LED[j], True); time.sleep(t)
GPIO.output(LED[j], False)
elif e == "2":
for i in range(w):
for j in range(z):
GPIO.output(LED[j], True); time.sleep(t)
GPIO.output(LED[j], False)
for j in range(z-1, -1, -1):
GPIO.output(LED[j], True); time.sleep(t)
GPIO.output(LED[j], False)
elif e == "3":
for i in range(w):
for j in range(z):
GPIO.output(LED[j], True); time.sleep(t)
time.sleep(2*t)
for j in range(z-1, -1, -1):
GPIO.output(LED[j], False)
time.sleep(t)
time.sleep(2*t)
elif e == "4":
for i in range(w):
for j in range(z):
GPIO.output(LED[j], True)
time.sleep(2*t)
for j in range(z):
GPIO.output(LED[j], False)
time.sleep(t)
elif e == "5":
47
for i in range(w*z):
j = random.randint(0,z-1)
GPIO.output(LED[j], True); time.sleep(t)
GPIO.output(LED[j], False)
else:
print ("Entrée invalide")
except KeyboardInterrupt:
GPIO.cleanup()
5.1.1 Voilà comment cela fonctionne
La première ligne du programme avec la définition du codage UTF-8 et l'importation des bibliothèques
requises sont déjà connues grâce aux expériences précédentes. La bibliothèque random est importée en plus
pour générer un motif clignotant aléatoire.
Lorsque ce programme a été développé, on a veillé à ce qu'il soit possible de l'utiliser de différentes façons. Il
peut donc être utilisé sans problème avec plus de quatre LED. Cette flexibilité fait aujourd'hui partie d'un bon
style de programmation. En prenant l'exemple du Raspberry Pi, ce type de programmes permet non
seulement de s'étendre vers de nouveaux ports GPIO, mais également de modifier facilement d'autres ports
GPIO lorsqu'ils sont nécessaires au niveau matériel.
LED = [4,18,23,24] Pour
les LED, une liste avec les numéros de port GPIO est à nouveau définie pour que
ces ports soient établis seulement à un endroit dans le programme.
for i in LED:
GPIO.setup(i, GPIO.OUT, initial=0)
Au lieu d'initialiser les ports GPIO de chaque LED comme dans les programmes précédents, une boucle for
s'exécute cette fois pour la liste LED. Le compteur de boucle i prend successivement chaque valeur dans la
liste, p. ex les numéros de port GPIO des LED, et n'est pas simplement incrémenté comme dans les boucles
for précédemment utilisées. De longues listes de votre choix peuvent être traitées de cette façon. La
longueur de la liste doit être ignorée lors du développement du programme.
Les quatre ports GPIO pour les LED sont définis comme des sorties et mis sur 0 pour éteindre les LED
éventuellement allumées lors des expériences précédentes.
z = len(LED); w = 5; t = 0.2
48
Pour garder le programme universel et facile à modifier, trois autres variables sont maintenant définies :
z
Nombre de LED
Le nombre de LED est automatiquement repris à l'aide de la fonction len() à
partir de la liste LED.
w
Répétitions
Chaque motif doit être répété cinq fois par défaut pour être mieux reconnu. Ce
nombre peut être modifié selon vos souhaits et s'applique ensuite à tous les
motifs.
t
Temps
Cette variable indique la durée de l'allumage de la LED lorsqu'elle clignote. La
pause qui suit est aussi longue. Le nom t s'est établi pour les variables qui
enregistrent les périodes de temps dans les programmes, dans presque tous les
langages de programmation.
Les valeurs définies comme variables sont non seulement intégrées de manière fixe à cet endroit dans le
programme mais peuvent également être facilement modifiées. Le vrai programme commence après ces
définitions.
print ("Choix de l'effet lumineux"); print ("1 – chenillard cyclique")
print ("2 – chenillard aller-retour"); print ("3 – montées et descentes")
print ("4 – Tous clignotent simultanément"); print ("5 – tous clignotent
aléatoirement")
print ("Ctrl+C arrête le programme")
Ces lignes affichent à l'écran des instructions pour l'utilisateur pour la correspondance des touches
numériques et des différents motifs présentés.
Fig. 5.3: Le programme sur l'écran
Après que la sélection a été affichée, la boucle principale du programme se lance. Pour ce faire, nous
utilisons ici également une boucle infinie while True: qui est intégrée dans une instruction try...except.
e = raw_input ("Veuillez choisir le motif : ") Dès le début de la boucle, le programme attend
une entrée de l'utilisateur, qui est enregistrée dans la variable e. La fonction raw_input() prend l'entrée
dans le texte en clair sans l'interpréter. En revanche, les opérations mathématiques entrées avec input() ou
49
les noms de variables sont directement interprétés. Dans la plupart de cas, raw_input() est également le
meilleur choix car vous n'avez pas besoin de vous occuper des nombreuses entrées possibles.
Le programme attend jusqu'à ce que l'utilisateur entre une lettre et appuie sur le bouton [Enter]. Selon le
chiffre que l'utilisateur a entré, un motif donné doit maintenant être affiché avec les LED. Pour le vérifier,
nous utilisons une construction if...elif...else.
Motif 1
Si l'entrée était un 1, la partie du programme indentée derrière cette ligne est exécutée.
if e == "1": Notez
que l'indentation dans Python ne sert pas seulement d'aide visuelle. Comme avec les
boucles, les requêtes sont également initiées avec une indentation.
Égal n'est pas égal égal
Python utilise deux types de signe pour l'égalité. Le signe = simple est utilisé pour attribuer une valeur
donnée à une variable. Le double signe égal égal == est utilisé dans les requêtes et vérifie si deux valeurs
sont vraiment identiques.
Si l'utilisateur a également entré un 1 avec le clavier, une boucle est lancée, qui génère un chenillard
cyclique. Ces boucles sont construites en principe de la même façon pour tous les motifs à LED utilisés.
for i in range(w): La boucle externe répète le motif aussi souvent que spécifié dans les variables w définies
dans l'entrée. Il y a une autre boucle dans cette boucle, qui génère chaque motif. Elle diffère avec chaque
motif.
for j in range(z):
GPIO.output(LED[j], True); time.sleep(t)
GPIO.output(LED[j], False)
Dans le cas d'un simple chenillard cyclique, cette boucle s'exécute une fois pour chaque LED de la liste, les
unes après les autres. Le nombre de LED est enregistré au début du programme dans la variable z. La LED
avec le numéro correspondant à l'état actuel du compteur de cycle est allumée. Ensuite, le programme
attend l'entrée pendant le temps enregistré dans la variable t puis éteint à nouveau la LED. Le cycle suivant
de boucle commence ensuite avec la LED suivante. La boucle externe répète la même boucle interne cinq
fois.
Motif 2
Si l'utilisateur a entré un 2, une boucle semblable est lancée. Ici, les LED sont non seulement comptées dans
un sens mais également dans le sens inverse à la fin du chenillard. La lumière avance et recule en
alternance.
elif e == "2": Les autres requêtes après la première utilisent la requête elif, ce qui signifie qu'elles ne
peuvent être exécutées que si la requête précédente a retourné un résultat False.
50
for i in range(w):
for j in range(z):
GPIO.output(LED[j],
GPIO.output(LED[j],
for j in range(z-1, -1,
GPIO.output(LED[j],
GPIO.output(LED[j],
True); time.sleep(t)
False)
-1):
True); time.sleep(t)
False)
Des boucles imbriquées les unes dans les autres sont également utilisées ici. Après la première boucle
interne, qui correspond à la partie du programme décrite ci-dessus, après que la LED avec le numéro 3 s'est
allumée, une autre boucle pour le chenillard allant à contresens commence. Les éléments de la liste sont
toujours numérotés à partir de 0. La quatrième LED a donc le numéro 3.
Pour qu'une boucle puisse s'exécuter en arrière, nous utilisons la syntaxe étendue de for...range(). A la
place de spécifier seulement une valeur finale, trois paramètres peuvent également être définis : la valeur
initiale, l'incrément et la valeur finale. Dans notre exemple, ils étaient :
Valeur initiale
z-1
La variable z contient le nombre de LED. Étant donné que la numérotation des
éléments de la liste commence avec 0, la dernière LED a le numéro z-1.
Incrément
-1
Avec un incrément égal à -1. Chaque cycle de boucle décompte un nombre en
arrière.
-1
La valeur finale dans une boucle est toujours la première valeur qui n'est pas
atteinte. Dans la première boucle comptée en avant, le compteur de boucle
commence à 0 et atteint la valeur 0, 1, 2, 3 dans notre exemple pour adresser les
LED. Le 4 n'est pas atteint en quatre cycles de boucles. La boucle décomptée en
arrière doit finir avec 0 et la valeur -1 ne doit donc pas être atteinte.
Valeur finale
La deuxième boucle décrite permet de faire clignoter les quatre LED successivement dans le sens inverse.
Après cela, la boucle externe recommence le cycle dans son ensemble qui dure ici deux fois plus longtemps
que la première partie du programme parce que chaque LED clignote deux fois.
Motif 3
Si l'utilisateur a entré un 3, une boucle semblable est lancée. Ici, les LED sont également comptées dans les
deux sens mais pas immédiatement après l'allumage puis l'extinction.
elif e == "3":
for i in range(w):
for j in range(z):
GPIO.output(LED[j], True); time.sleep(t)
time.sleep(2*t)
for j in range(z-1, -1, -1):
GPIO.output(LED[j], False); time.sleep(t)
time.sleep(2*t)
51
La première boucle interne allume les LED les unes après les autres avec un retard. À la fin de la boucle qui est
reconnaissable par l'indentation de la ligne time.sleep(2*t), on attend pendant deux fois le temps de retard.
Pendant ce temps, toutes les LED sont allumées. Après cela, une nouvelle boucle commence, qui décompte en
arrière et qui éteint les LED, une par une. On attend également à la fin deux fois le temps de retard, lorsque
toutes les LED sont éteintes, avant que la boucle externe recommence encore une fois le cycle en entier.
Motif 4
Si l'utilisateur a entré un 4, un autre motif clignotant commence, avec lequel toutes les LED clignotent en
même temps et ne s'allument pas les unes après les autres.
elif e == "4":
for i in range(w):
for j in range(z):
GPIO.output(LED[j], True)
time.sleep(2*t)
for j in range(z):
GPIO.output(LED[j], False)
time.sleep(t)
Étant donné que plusieurs ports GPIO ne peuvent pas être activés ou inactivés avec une seule instruction, des
boucles sont également utilisées ici, cependant sans retard dans la boucle. Les quatre LED sont
immédiatement allumées les unes après les autres. Cela semble au même moment pour l'œil humain. À la
fin de la première boucle interne, le programme attend deux fois le temps de retard avant que toutes les LED
sont éteintes à nouveau.
Les différents temps d'éclairage et d'extinction permettent de créer différents effets avec les lumières
clignotantes. Le clignotement est plutôt perçu quand le temps d'éclairage est plus long que le temps
d'extinction. Des temps d'éclairage très courts associés avec des temps d'extinction relativement longs
génèrent un effet de flash.
Motif 5
Si l'utilisateur a entré un 5, les LED clignotent complétement aléatoirement.
elif e == "5":
for i in range(w*z):
j = random.randint(0,z-1)
GPIO.output(LED[j], True); time.sleep(t)
GPIO.output(LED[j], False)
Comme aucune boucle imbriquée n'est utilisée ici, nous laissons la boucle se répéter plus souvent. Grâce à
la multiplication des variables w et z, chaque LED clignote en moyenne autant que dans le premier motif.
La fonction random.randint() écrit un chiffre aléatoire dans la variable j. Ce chiffre aléatoire est supérieur
ou égal au premier paramètre et inférieur ou égal au deuxième paramètre. Dans notre cas la valeur peut
également être 0, 1, 2, 3.
La LED sélectionnée aléatoirement est allumée puis éteinte à nouveau après un temps de retard. Après cela,
la boucle redémarre et une nouvelle LED est choisie aléatoirement.
52
Entrée invalide
Pour tous les programmes qui nécessitent une entrée de l'utilisateur, on doit intercepter les entrées
incorrectes. Si l'utilisateur entre une réponse imprévue, le programme doit y répondre.
else:
print ("Entrée invalide")
Si l'utilisateur a entré quelque chose d'autre, l'instruction donnée sous else est exécutée. On rencontre
toujours cette partie de requête si aucune des autres requêtes ne fournit de véritable résultat. Dans notre cas,
le programme affiche un message à l'écran.
Comme dans les expériences précédentes, le programme est quitté avec un KeyboardInterrupt, dans
lequel l'utilisateur appuie sur la combinaison de touches [Ctrl]+[C]. La dernière ligne ferme les ports GPIO
utilisés et éteint toutes les LED.
6 Variation de l'intensité lumineuse des LED par modulation de la largeur
des impulsions
Les LED sont des composants typiques pour émettre des signaux dans l'électronique numérique. Elles
peuvent être dans deux états différents, marche et arrêt, 0 et 1 ou True et False. Il en est de même pour les
ports GPIO définis comme des sorties numériques. Par conséquent, il n'est théoriquement pas possible de
faire varier l'intensité lumineuse d'une LED.
Une astuce permet cependant de réguler la luminosité d'une LED sur un port GPIO numérique. Si l'on fait
clignoter assez rapidement une LED, l'œil humain ne l'interprète pas comme un clignotement. La technique
désignée comme la modulation de la largeur des impulsions génère un signal pulsé qui s’active et se
désactive à des intervalles très courts. La tension du signal reste toujours constante, seul le rapport entre le
niveau False (0 V) et le niveau True (+ 3,3 V) est changé. Le rapport cyclique donne le rapport de la
longueur de l'état activé sur la durée totale d'un cycle de commutation.
Fig. 6.1: A gauche : Rapport cyclique : 50 % – à droite : Rapport cyclique : 20 %
Plus le rapport cyclique est cyclique, plus le temps d'éclairage de la LED est court dans un cycle de
commutation. De cette façon, une LED semble sombre comme une LED éteinte en permanence.
Pour l'expérience suivante, branchez une LED via une pré-résistance sur le port GPIO 18.
53
Fig. 6.2: Construction de la carte avec une LED
Composants nécessaires :
1x Carte de circuit imprimé
1x LED jaune
1x résistance de 220 Ω
2x Câbles de connexion
54
Fig. 6.3: Une LED sur le port GPIO 18
Le programme leddimmen01.py fait varier l'intensité lumineuse de la LED cycliquement et utilise pour ce
faire une fonctionnalité propre PWM de la bibliothèque GPIO. Le signal PWM est généré comme un
processus spécifique. De cette façon, une LED dont l'intensité lumineuse varie (presque) peut être utilisée
comme une source lumineuse normale dans un programme.
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM); LED = 18
GPIO.setup(LED, GPIO.OUT)
print ("Ctrl+C arrête le programme")
p = GPIO.PWM(LED, 50); p.start(0)
try:
while True:
for c in range(0, 101, 2):
p.ChangeDutyCycle(c); time.sleep(0.1)
for c in range(100, -1, -2):
p.ChangeDutyCycle(c); time.sleep(0.1)
except KeyboardInterrupt:
p.stop(); GPIO.cleanup()
55
6.1.1 Voilà comment cela fonctionne
Une partie de ce programme vous est familière, certains éléments ne vous disent rien car nous faisons ici
une petit tour dans la programmation orientée objet. Les bibliothèques sont importées au début, comme
vous le savez déjà. Cette fois, une seule variable, LED, est fixée pour le port GPIO 18, qui est initialisé comme
une sortie.
print ("Ctrl+C arrête le programme") Étant
donné que ce programme avec une construction
s'exécute et doit être arrêté par l'utilisateur, des informations correspondantes s'affichent à
l'écran pour l'utilisateur.
try...except
p = GPIO.PWM(LED, 50) La fonction GPIO.PWM() de la bibliothèque GPIO est essentielle pour la sortie des
signaux PWM. Cette fonction nécessite deux paramètres, le port GPIO et la fréquence du signal PWM. Dans
notre cas, le port GPIO est fixé avec la variable LED et la fréquence est de 50 hertz (Hz) (oscillations par
seconde).
Pourquoi est-ce que la fréquence de 50 Hz est idéale pour PWM ?
L'œil humain ne perçoit pas bien les changements de lumière plus rapides que 20 Hz. Étant donné que le
courant alternatif en Europe utilise une fréquence de 50 Hz, de nombreuses sources lumineuses
clignotent à cette fréquence et ce clignotement n'est pas perceptible pour l'œil humain. Si une LED
clignote à plus de 20 Hz mais moins de 50 Hz, des interférences avec d'autres sources lumineuses
peuvent se produire et perturber l'effet perçu de variation d'intensité lumineuse.
GPIO.PWM() génère un soi-disant objet qui est enregistré dans la variable p. Ces objets sont davantage que
de simples variables. Les objets peuvent avoir des propriétés différentes et sont influencés par des soi-disant
méthodes. Les méthodes, séparées par un point, sont spécifiées directement après le nom de l'objet.
p.start(0) La méthode start() lance la génération du signal PWM. Pour ce faire, un rapport cyclique doit
encore être spécifié. Dans notre cas, le rapport cyclique est 0 et la LED est toujours éteinte. La boucle infinie
commence maintenant dans laquelle deux boucles sont imbriquées directement successivement, ce qui
permet de faire varier l'intensité de la LED alternativement entre une intensité forte et une intensité faible.
for c in range(0, 101, 2): La boucle compte par incrément de 2 depuis 0 jusqu'à 100. La valeur est
toujours spécifiée pour arrêter une boucle for, qui n'est pas atteinte en pratique, dans notre cas : 101.
p.ChangeDutyCycle(c) La méthode ChangeDutyCycle() définit à chaque cycle de boucle le rapport
cyclique de l'objet PWM sur la valeur du compteur de boucle, également augmenté de 2 % à chaque fois,
jusqu'à ce que dernier cycle soit à 100 % et que la LED éclaire avec sa pleine luminosité.
time.sleep(0.1) On attend 0,1 seconde à chaque cycle de boucle avant que le cycle suivant n'augmente le
rapport de cycle de 2 %.
for c in range(100, -1, -2):
p.ChangeDutyCycle(c); time.sleep(0.1)
56
Après que la LED a atteint sa pleine luminosité, une deuxième boucle régule son intensité dans le sens
inverse selon le même schéma. Cette boucle compte à rebours à partir de 100, avec des décréments de -2.
Ce cycle se répète jusqu'à ce que l'utilisateur appuie sur la combinaison de touches [Ctrl]+[C].
except KeyboardInterrupt:
p.stop(); GPIO.cleanup()
Le KeyboardInterrupt déclenche immédiatement la méthode stop() de l'objet PWM. Cette méthode arrête
la génération du signal PWM. Après cela, les ports GPIO sont réinitialisés, comme nous le savons déjà avec
les programmes précédents.
6.1.2 Faire varier l'intensité lumineuse de deux LED indépendamment l'une de l'autre
Étant donné qu'aucun temps de programmation dans le script Python n'est nécessaire pour programmer le
signal PWM, il est possible de faire varier l'intensité de plusieurs LED indépendamment les unes des autres,
comme le montre l'expérience suivante. Pour ce faire, branchez une autre LED via une pré-résistance sur le
port GPIO 25.
Fig. 6.4: Construction de la carte pour faire varier l'intensité lumineuse de deux LED.
57
Composants nécessaires :
1x Carte de circuit imprimé
1x LED jaune
1x LED rouge
2x Résistances de 220 Ω
3x Câbles de connexion
Fig. 6.5: Une deuxième LED sur le port GPIO 25
Le programme leddimmen02.py fait varier cycliquement l'intensité d'une LED pendant que l'autre LED
éclaire avec une forte intensité avec la première LED, puis ne diminue pas d'intensité dans un autre cycle,
éclaire de nouveau avec 0 et clignote rapidement.
import RPi.GPIO as GPIO
import time
58
GPIO.setmode(GPIO.BCM); LED = [18,25]
GPIO.setup(LED[0], GPIO.OUT); GPIO.setup(LED[1], GPIO.OUT)
print ("Ctrl+C arrête le programme")
p = GPIO.PWM(LED[0], 50); q = GPIO.PWM(LED[1], 50)
p.start(0)
q.start(0)
try:
while True:
for c in range(0, 101, 2):
p.ChangeDutyCycle(c); q.ChangeDutyCycle(c)
time.sleep(0.1)
q.ChangeFrequency(10)
for c in range(0, 101, 2):
p.ChangeDutyCycle(100-c); q.ChangeDutyCycle(c)
time.sleep(0.1)
q.ChangeFrequency(50)
except KeyboardInterrupt:
p.stop(); GPIO.cleanup()
6.1.3 Voilà comment cela fonctionne
La structure de base du programme correspond à celle de l'expérience précédente avec quelques petites
améliorations.
LED = [18,25]; GPIO.setup(LED[0], GPIO.OUT); GPIO.setup(LED[1], GPIO.OUT)
A la place d'un variable pour le port GPIO, une liste est maintenant définie avec deux variables et les deux
ports GPIO 18 et 25 sont initialisés comme des sorties pour les LED.
p = GPIO.PWM(LED[0], 50); q = GPIO.PWM(LED[1], 50); p.start(0); q.start(0)
Ensuite les deux objets p et q sont également créés pour générer les signaux PWM pour les deux LED avec
une fréquence de 50 Hz pour chacune.
for c in range(0, 101, 2):
p.ChangeDutyCycle(c); q.ChangeDutyCycle(c)
time.sleep(0.1)
Dans la première boucle, le rapport cyclique des deux objets PWM est augmenté simultanément, incrément
par incrément. Les deux LED se comportent de la même façon dans cette phase.
q.ChangeFrequency(10) A
la fin de cette boucle, lorsque les deux LED ont atteint la pleine luminosité, la
fréquence du signal PWM est réduite de 10 Hz par la méthode ChangeFrequency(). Cette fréquence est
encore perçue comme un clignotement pour l'œil humain.
for c in range(0, 101, 2):
p.ChangeDutyCycle(100-c); q.ChangeDutyCycle(c)
time.sleep(0.1)
59
La deuxième boucle commence maintenant, par souci de simplicité, cette fois également avec un comptage
croissant. Pour la première LED, à partir de l'objet PWM p, dont l'intensité doit être réduite pas à pas dans ce
cycle, la valeur correspondante pour le rapport cyclique est calculée à chaque cycle. Pour la deuxième LED,
à partir de l'objet PWM q, le rapport cyclique est simplement augmenté à nouveau. L'effet de clignotement
est causé par le changement de fréquence.
q.ChangeFrequency(50) A la fin de cette deuxième boucle, la fréquence de cette LED revient à 50 Hz pour
qu'elle soit dans le cycle suivant à nouveau aussi lumineux progressivement que la première LED.
7 Indicateur à LED montrant l'espace disponible des cartes mémoires
Les cartes mémoires sont toujours pleine trop rapidement comme les disques durs. C'est pourquoi on
souhaite avoir une indicateur visuel du remplissage de la carte mémoire pour pouvoir savoir en un clin d'œil
s'il y reste peu d'espace disponible. Vous pouvez réaliser cela très simplement avec trois LED sur le
Raspberry Pi. Pour ce faire, des fonctions du système d'exploitation sont utilisées et elles sont appelées par
Python.
Fig. 7.1: L’espace mémoire libre peut évidemment être affiché directement dans le gestionnaire de fichiers sur le Raspberry Pi.
Pour afficher l'espace mémoire disponible, nous utilisons les trois LED du feu de signalisation qui s'allument
avec différentes combinaisons de couleurs.
60
Fig. 7.2: Construction de la carte pour l'indicateur à LED montrant l'espace disponible dans les cartes mémoires.
Composants nécessaires :
1x Carte de circuit imprimé
1x LED rouge
1x LED jaune
1x LED verte
3x résistances de 220 Ω
4x Câbles de connexion
61
Fig. 7.3: Les trois LED indiquent l'espace mémoire disponible sur la carte mémoire.
Le programme speicheranzeige.py fournit différents affichages par LED en fonction de l'espace mémoire
libre sur la carte mémoire :
Espace mémoire libre
Affichage par LED
< 1 Mo
Rouge
De 1 Mo à 10 Mo
Rouge-Jaune
De 10 Mo à 100 Mo
Jaune
De 100 Mo à 500 Mo
Jaune-Vert
> 500 Mo
Vert
Tableau 7.1: L’état de remplissage de la carte mémoire est ainsi affiché.
62
import RPi.GPIO as GPIO
import time
import os
g1 = 1; g2 = 10; g3 = 100; g4 = 500
GPIO.setmode(GPIO.BCM)
LED = [4,18,23]
for i in range(3):
GPIO.setup(LED[i], GPIO.OUT, initial=False)
print ("Ctrl+C arrête le programme")
try:
while True :
s = os.statvfs('/')
f = s.f_bsize * s.f_bavail / 1000000
if f < g1:
x = "100"
elif f < g2:
x = "110"
elif f < g3:
x = "010"
elif f < g4:
x = "011"
else:
x = "001"
for i in range(3):
GPIO.output(LED[i], int(x[i]))
time.sleep(1.0)
except KeyboardInterrupt:
GPIO.cleanup()
Si vous exécutez le programme, les LED indiquent en permanence l'espace mémoire libre qui reste
disponible sur la carte mémoire. Testez-le en copiant et supprimant de gros fichiers sur la carte mémoire via
le réseau. L'affichage se met à jour automatiquement.
7.1.1 Voilà comment cela fonctionne
Le programme utilise le module os de Python pour calculer l'espace mémoire libre qui est disponible à partir
des fonctions du système d'exploitation.
import os Le
module os doit être importé au début du programme, comme les autres modules.
g1 = 1; g2 = 10; g3 = 100; g4 = 500 Ces
lignes définissent les limites de la plage disponible pour l'espace
mémoire, entre lesquelles l'affichage doit changer. Par souci de simplicité, le programme utilise des
mégaoctets et non des octets car l'on imagine mieux ces chiffres. Vous pouvez à tout moment modifier les
limites. Les quatre valeurs doivent seulement être placées dans un ordre croissant.
63
GPIO.setmode(GPIO.BCM)
LED = [4,18,23]
for i in range(3):
GPIO.setup(LED[i], GPIO.OUT, initial=False)
Une liste définit le numéro de port GPIO des trois LED. Après cela, une boucle initialise les trois ports GPIO
comme des sorties et toutes les LEDS sont éteintes.
Également dans cette expérience, nous utilisons une construction try...except et une boucle infinie pour
que le programme s'exécute et se répète toujours automatiquement, jusqu'à ce que l'utilisateur l'arrête en
appuyant sur [Ctrl]+[C]. Les fonctions vraiment intéressantes suivent ensuite. Elles accèdent au système
d'exploitation et vérifient l'espace mémoire libre disponible.
s = os.statvfs('/') Le
module statistique os.statvfs() à partir de la bibliothèque os fournit différentes
informations statistiques sur le système de fichiers qui sont écrites ici dans la boucle infinie à chaque cycle
de boucle à nouveau comme un objet dans la variables.
f = s.f_bsize * s.f_bavail / 1048576 La méthode s.f_bsizefournit ici la taille d'un bloc mémoire en
octet. s.f_bavail donne le nombre de blocs libres. Le produit à partir des deux valeurs donne donc le
nombre d'octets libres, qui est divisé ici par 1 048 576, pour obtenir le nombre de mégaoctets libres. Le
résultat est enregistré dans la variable f.
if f < g1:
x = "100"
Si l'espace mémoire libre est inférieur à la première valeur limite (1 Mo), la chaîne de caractères x, qui
indique le motif des LED allumées, est spécifiée égale à "100". La première LED rouge doit s'allumer. Le
motif est une chaîne de caractères simple composée des chiffres 0 et 1.
elif f < g2:
x = "110"
elif f < g3:
x = "010"
elif f < g4:
x = "011"
À l'aide de la requête elif, les autres limites sont vérifiées et le motif des LED est fixé en conséquence.
Lorsque la première question n'a pas de réponse/objet, il y a également plus de 1 Mo d'espace libre
disponible.
else:
x = "001"
Si aucune requête n'est satisfaite, alors il y a encore plus d'espace libre que la limite supérieure spécifiée et
le motif des LED est fixé à "001". La dernière LED verte doit s'allumer.
for i in range(3):
GPIO.output(LED[i], int(x[i]))
64
Une boucle définit/fixe les valeurs de sortie pour les trois LED. Toutes les LED obtiennent successivement la
valeur numérique de chaque chiffre à partir de la chaîne de caractères 0 ou 1. Les valeurs 0 et 1 peuvent
également être utilisées comme False et True pour activer ou inactiver les sorties GPIO. La fonction int()
calcule à partir d'un chiffre de ces valeurs numériques. Le chiffre est lu par le compteur de boucle i à partir
d'une certaine position de la chaîne de caractères du motif.
time.sleep(1.0) Le programme attend 1 seconde jusqu'au cycle suivant de boucle. Pour économiser les
performances, vous pouvez également spécifier des temps d'attente plus long jusqu'à ce que le calcul de
l'espace mémoire libre doive se répéter.
À cet endroit, la boucle while...True recommence depuis le début. Si l'utilisateur doit appuyer entre temps
sur la combinaison de touches [Ctrl]+[C], un KeyboardInterrupt est déclenché et la boucle est quittée.
Après cela, les ports GPIO sont fermés et les LED éteintes.
8 Dé graphique
Un jeu sympathique offre des graphismes et pas seulement une réponse textuelle comme à l'époque des
premiers ordinateurs DOS. La bibliothèque PyGame fournit des fonctions et des objets prédéfinis pour
l'affichage graphique et la programmation de jeux. Ainsi, vous n'avez pas à tout créer à partir de zéro.
On a besoin d'un dé pour jouer à de nombreux jeux mais il est fréquent de ne pas en avoir sous la main.
L'exemple suivant de programme montre combien il est facile d'utiliser le Raspberry Pi comme un dé à l'aide
de Python et PyGame.
Fig. 8.1: Utiliser le Raspberry Pi comme un dé
Le dé doit être aussi simple que possible et être utilisé avec une seule touche, et le résultat aléatoire du
lancer de dé doit être affiché graphiquement comme un « vrai » dé. Le programme suivant wuerfel.py
simule un tel dé sur l'écran.
65
# -*- coding: utf-8 -*import pygame, sys, random
from pygame.locals import *
pygame.init()
FELD = pygame.display.set_mode((320, 320))
pygame.display.set_caption("Dé")
BLEU = (0, 0, 255); BLANC = (255, 255, 255)
P1 = ((160, 160)); P2 = ((60, 60)); P3 = ((160, 60));
P4 = ((260, 60))
P5 = ((60, 260)); P6 = ((160, 260)); P7 = ((260, 260))
mainloop = True
print "Appuyer sur n'importe quelle touche pour lancer le dé, sur [échap]
pour quitter le jeu"
while mainloop:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYUP
and event.key == K_ESCAPE):
mainloop = False
if event.type == KEYDOWN:
CHAMP.fill(BLEU)
CHIFFRE = random.randrange (1, 7); print CHIFFRE
if CHIFFRE == 1:
pygame.draw.circle(CHAMP, BLANC, P1, 40)
if CHIFFRE == 2:
pygame.draw.circle(CHAMP, BLANC, P2, 40)
pygame.draw.circle(CHAMP, BLANC, P7, 40)
if CHIFFRE == 3:
pygame.draw.circle(CHAMP, BLANC, P1, 40)
pygame.draw.circle(CHAMP, BLANC, P4, 40)
pygame.draw.circle(CHAMP, BLANC, P5, 40)
if CHIFFRE == 4:
pygame.draw.circle(CHAMP, BLANC, P2, 40)
pygame.draw.circle(CHAMP, BLANC, P4, 40)
pygame.draw.circle(CHAMP, BLANC, P5, 40)
pygame.draw.circle(CHAMP, BLANC, P7, 40)
if CHIFFRE == 5:
pygame.draw.circle(CHAMP, BLANC, P1, 40)
pygame.draw.circle(CHAMP, BLANC, P2, 40)
pygame.draw.circle(CHAMP, BLANC, P4, 40)
pygame.draw.circle(CHAMP, BLANC, P5, 40)
pygame.draw.circle(CHAMP, BLANC, P7, 40)
if CHIFFRE == 6:
pygame.draw.circle(CHAMP, BLANC, P2, 40)
pygame.draw.circle(CHAMP, BLANC, P3, 40)
pygame.draw.circle(CHAMP, BLANC, P4, 40)
pygame.draw.circle(CHAMP, BLANC, P5, 40)
pygame.draw.circle(CHAMP, BLANC, P6, 40)
pygame.draw.circle(CHAMP, BLANC, P7, 40)
pygame.display.update()
pygame.quit()
66
Fonctionne sans sudo
Étant donné que ce programme n'a besoin d'aucun port GPIO, il fonctionne aussi sans privilège de superutilisateur. Vous pouvez facilement lancer l'IDE de Python via le symbole de bureau IDLE.
8.1.1 Voilà comment cela fonctionne
Ce programme affiche de nombreuses nouvelles fonctions, en particulier pour les affichages graphiques avec
la bibliothèque PyGame qui peut être évidemment utilisée pour les jeux mais également pour afficher
d'autres graphismes à l'écran.
import pygame, sys, random
from pygame.locals import *
pygame.init()
Ces trois lignes de programme sont placées au début de presque tous les programmes qui utilisent PyGame.
En plus du module random que vous connaissez déjà pour générer un chiffre aléatoire, le module pygame et
le module sys sont chargés, car ils contiennent des fonctions système importants de PyGame, comme p. ex.
l'ouverture et la fermeture de fenêtres. Toutes les fonctions de la bibliothèque PyGame sont importées puis le
vrai module PyGame est initialisé.
CHAMP = pygame.display.set_mode((320, 320))
Cette fonction importante dans chaque programme qui utilise un affichage graphique, définit une zone de
dessin, une dite surface, qui fait la taille de 320 x 320 pixels dans notre exemple et qui reçoit le nom CHAMP.
Notez que l'écriture entre les doubles crochets est utilisée essentiellement pour les coordonnées graphiques
de l'écran. Cette surface est affichée dans une nouvelle fenêtre à l'écran.
pygame.display.set_caption("Dé")
Cette ligne présente le nom de la fenêtre.
BLEU = (0, 0, 255); BLANC = (255, 255, 255)
Ces lignes définissent les deux couleurs utilisées, le bleu et le blanc. Vous pouvez également spécifier à
chaque fois dans le programme les valeurs de couleurs, ce qui ne contribue cependant pas directement à
l'aperçu.
Affichage des couleurs à l'écran
Les couleurs sont définies dans Python comme dans la plupart des autres langages de programmation, avec
trois chiffres compris entre 0 et 255, qui spécifient chacun la composante rouge, verte et bleu de la couleur. Les
écrans utilisent un mélange de couleurs qui s'additionnent, et les trois composantes de couleur donnent
ensemble du blanc à pleine saturation.
P1 = ((160, 160)); P2 = ((60, 60)); P3 = ((160, 60)); P4 = ((260, 60)); P5 = ((60,
260)); P6 = ((160, 260)); P7 = ((260, 260))
67
Ces lignes définissent le centre du point du dé. Les trois axes du point du dé sont placés sur la zone de
dessin de 320 x 320 pixels avec les coordonnées 60, 160 et 260.
Le système de coordonnées pour l'infographie
Chaque point dans une fenêtre ou sur un objet-surface est représenté par ses coordonnées x et y. L'origine
du système de coordonnées n'est pas à gauche en bas comme on l'apprend à l'école mais à gauche en haut.
Exactement comme on lit un texte de gauche à droite et du haut vers le bas, l'axe des x va de gauche à
droite et l'axe des y de haut en bas.
Les sept points P1 à P7 désignent les centres du dé indiqués dans le graphique. Chaque point du dé a un
rayon de 40 pixels. Avec un écart axial de 80 pixels, il reste 20 pixels entre les points du dé et 20 pixels
jusqu'au bord de la fenêtre.
Fig. 8.2: Les points du dé et leurs coordonnées
À cet endroit, une variable nommée mainloop est encore spécifiée sur True avec les autres variables. Cette
variable sera nécessaire plus tard pour la boucle principale du jeu.
68
mainloop = True Les
bases sont ainsi créées et le vrai jeu peut commencer.
print "Appuyer sur n'importe quelle touche pour lancer le dé, sur [échap]
pour quitter le jeu"
Cette ligne explique brièvement à l'utilisateur ce qu'il faut faire. Chaque fois que vous appuyez sur une
touche du clavier, vous relancez le dé. print écrit toujours dans la fenêtre Python-Shell, et non dans la
nouvelle fenêtre graphique.
while mainloop: La boucle principale du jeu commence maintenant. Dans de nombreux jeux, une boucle
infinie est utilisée. Elle est toujours répétée et vérifie en permanence l'activité de l'utilisateur. Une condition
d'arrêt doit être définie quelque part dans la boucle pour s'assurer que le jeu puisse être arrêté.
La variable mainloop est utilisée ici et elle prend en compte uniquement les deux valeurs booléennes True
et False (vrai et faux, marche et arrêt). Elle est spécifiée comme True au début et est vérifiée à chaque cycle
de boucle. Si, pendant une boucle, elle prend la valeur False, la boucle est quittée avant le cycle suivant.
for event in pygame.event.get(): Cette
ligne lit la dernière activité de l'utilisateur et s'enregistre sous
Dans le jeu, il y a uniquement deux types d'activité de l'utilisateur qui comptent pour le jeu :
l'utilisateur appuie sur une touche et lance ainsi le dé, ou l'utilisateur souhaite quitter le jeu.
event.
if event.type == QUIT or (event.type == KEYUP
and event.key == K_ESCAPE):
mainloop = False
Il existe deux façons de quitter le jeu : on peut cliquer sur le signe x en haut à droite de la fenêtre ou
appuyer sur le bouton [échap]. Si l'on clique sur le signe x, event.type == QUIT fourni par le système
d'exploitation est exécuté. Si l'on appuie sur un bouton puis qu'on le relâche, event.type == KEYUP est
exécuté. En outre, le bouton enfoncé est enregistré dans event.key dans ce cas.
La requête if déjà décrite vérifie si l'utilisateur veut fermer la fenêtre ou (or) s'il a appuyé sur un bouton
puis l'a relâché et (and) si ce bouton est le bouton avec la désignation interne K_ESCAPE. Si c'est le cas, la
variable mainloop est spécifiée sur False, ce qui arrête la boucle principale du jeu avant le cycle suivant.
if event.type == KEYDOWN: Le
deuxième type d'activité de l'utilisateur qui se produit toujours plusieurs fois
pendant le jeu (et jamais une seule fois), est le fait que l'utilisateur appuie sur une touche. Cela peut être
n'importe quelle touche à l'exception de la touche [échap]. Dès que vous appuyez sur une touche
(KEYDOWN), une partie importante du programme est lancée pour générer et afficher le résultat du lancer de
dé.
Tout d'abord, l'objet-surface appelé CHAMP, la fenêtre de programme, prend la couleur
définie comme BLEU au début, pour effacer le résultat du lancer de dé précédent.
CHAMP.fill(BLEU)
CHIFFRE = random.randrange (1, 7)
La fonction aléatoire random génère maintenant un chiffre aléatoire compris entre 1 et 6 et l'enregistre dans
la variable CHIFFRE.
69
Cette ligne écrit seulement pour contrôler le résultat du lancer de dé dans la fenêtre du
Python-Shell. Vous pouvez également omettre cette ligne si vous souhaitez renoncer à l'affichage textuel.
print CHIFFRE
if CHIFFRE == 1:
pygame.draw.circle(CHAMP, BLANC, P1, 40)
Les six requêtes suivent maintenant le même schéma. Lorsque le chiffre aléatoire du lancer de dé a une
certaine valeur, un à six points de dé sont dessinés en conséquence. La fonction pygame.draw.circle()
utilisée à cette fin a besoin de quatre ou cinq paramètres :
•
Surface donne la surface de dessin sur laquelle est dessiné par exemple la CHAMP.
•
Couleur donne la couleur du cercle, par exemple la couleur BLANC précédemment définie.
•
Centre donne le centre du cercle.
•
Rayon donne le rayon du cercle.
•
Épaisseur donne l'épaisseur de la ligne du cercle. Si ces paramètres sont omis ou spécifiés égaux à 0, le
cercle est plein.
Si une des conditions if est satisfaite, les points de dé sont d'abord enregistrés uniquement sur une surface
de dessin virtuelle.
pygame.display.update() Cette
ligne à la fin de la boucle met à jour le graphique à l'écran.Les points du
dé sont maintenant vraiment visibles.
70
Fig. 8.3: Les six résultats possibles du lancer de dé.
71
La boucle recommence immédiatement et attend que l'utilisateur appuie sur une touche. Si pendant la
boucle mainloop est spécifiée sur False, parce que l'utilisateur a arrêté le jeu, la boucle ne continue plus et
la ligne suivante est exécutée à la place :
pygame.quit() Cette ligne arrête le module PyGame, ce qui ferme également la fenêtre graphique et par
conséquent l'ensemble du programme.
9 Horloge analogique sur l'écran
L'affichage numérique de l'heure auquel nous nous sommes habitués aujourd'hui avec les ordinateurs, n'est
devenu à la mode que dans les années 1970. On a lu l'heure pendant des siècles sur des horloges
analogiques avec des aiguilles tournant dans un cadran. L'engouement pour l'horloge numérique a quelque
peu diminué ces dernières années car on a reconnu que les horloges analogiques étaient lues plus
rapidement et clairement en cas de mauvaises conditions météorologiques ou lorsqu'elles sont loin comme
par exemple dans les gares. L'œil humain saisit un graphique plus rapidement que des chiffres ou des lettres.
L'image d'une horloge analogique marque la mémoire à court terme de sorte que l'on peut l'interpréter
correctement même lorsque l'on ne l'a vu de manière incomplète ou floue.Si l'on regarde une horloge
numérique de manière imprécise, on ne peut pas tirer de conclusions fiables à propos de l'heure affichée.
Fig. 9.1: Horloge analogique programmée avec PyGame.
Ce programme doit montrer non seulement comme on programme une horloge mais également expliquer les
principes de base pour les affichages analogiques, comme ils peuvent être utilisés non seulement pour lire
l'heure mais également peur afficher différentes valeurs mesurées ou données statistiques.
Trois aiguilles tournent au centre du cadran rond pour indiquer les heures, les minutes et les secondes. En
haut, dans le titre de la fenêtre, vous trouverez en outre une horloge numérique qui affiche simultanément
l'heure.
72
Le programme uhr01.py affiche une horloge analogique à l'écran :
import pygame, time
from pygame.locals import *
from math import sin, cos, radians
pygame.init()
ROUGE = (255, 0, 0); BLANC = (255, 255, 255); NOIR = (0, 0, 0)
CHAMP = pygame.display.set_mode((400, 400))
CHAMP.fill(BLANC)
MX = 200; MY = 200; MP = ((MX, MY))
def point(A, W):
w1 = radians(W * 6 – 90); x1 = int(MX + A * cos(w1))
y1 = int(MY + A * sin(w1)); return((x1, y1))
for i in range(60):
pygame.draw.circle(CHAMP, NOIR, point(190, i), 2)
for i in range(12):
pygame.draw.circle(CHAMP, NOIR, point(190, i * 5), 4)
mainloop = True; s1 = 0
while mainloop:
temps = time.localtime()
s = temps.tm_sec; m = temps.tm_min; h = temps.tm_hour
if h > 12:
h = h – 12
hm = (h + m / 60.0) * 5
if s1 <> s:
pygame.draw.circle(CHAMP, BLANC, MP, 182)
pygame.draw.line(CHAMP, NOIR, MP, point(120, hm), 6)
pygame.draw.line(CHAMP, NOIR, MP, point(170, m), 4)
pygame.draw.line(CHAMP, ROUGE, MP, point(180, s), 2)
s1 = s
pygame.display.set_caption("Heure actuelle : " +
time.asctime())
pygame.display.update()
for event in pygame.event.get():
if event.type == QUIT or (event.type ==
KEYUP and event.key == K_ESCAPE):
mainloop = False
pygame.quit()
9.1.1 Voilà comment cela fonctionne
Ce programme montre d’autres fonctions de la bibliothèque PyGame et la bibliothèque time ainsi que des
fonctions trigonométriques simples, qui sont utilisées pour les affichages analogiques.
import pygame, time
from pygame.locals import *
from math import sin, cos, radians
pygame.init()
Au début, la bibliothèque PyGame est initialisée comme dans le dernier programme. En outre, la bibliothèque
time et trois fonctions de la très vaste bibliothèque math sont importées pour la détermination du temps.
ROUGE = (255, 0, 0); BLANC = (255, 255, 255); NOIR = (0, 0, 0)
Les trois couleurs utilisées dans le graphisme sont enregistrées dans trois variables.
73
CHAMP = pygame.display.set_mode((400, 400)); CHAMP.fill(BLANC)
Une fenêtre de 400 x 400 pixel est ouverte et complétement colorée en blanc.
MX = 200; MY = 200; MP = ((MX, MY))
Trois variables déterminent les coordonnées du point central(centre)à partir duquel tous les autres éléments
graphiques, le cadran et les aiguilles sont placés. Les variables MX et MY contiennent les coordonnées x et y
du point central, la variable MP le point central comme point, tel qu'il est utilisé pour les fonctions
graphiques.
La définition d'une fonction vient ensuite. Elle calcule la distance entre le centre et un des points d'angle
dans le système de coordonnées. Cette fonction est appelée plusieurs fois dans le programme pour
représenter à la fois le cadran et les aiguilles.
def point(A, W):
w1 = radians(W * 6 – 90); x1 = int(MX + A * cos(w1))
y1 = int(MY + A * sin(w1)); return((x1, y1))
La fonction utilise deux paramètres : A est la distance entre le point souhaité et le centre W est l'angle formé
par rapport au centre. Pour simplifier la représentation dans le cas de l'horloge, nous prenons l'angle formé
dans le sens antihoraire par rapport à l'axe vertical de 12 heures. L'angle n'est pas exprimé en degré mais en
minutes, 1/60 d'un tour complet, dans la fonction. Ces hypothèses permettent de ne pas faire de nombreux
calculs intermédiaires.
Comme la plupart des langages de programmation, Python calcule les unités angulaires en radian et non en
degré. La fonction radian() de la bibliothèque math convertit les degrés en radians. Pour ce faire, l'angle
utilisé dans le programme en minute est multiplié par 6 pour obtenir des degrés puis on soustrait 90 degrés
pour que l'axe vertical 0 pointe vers le haut, comme la minute 0 de chaque heure. Cet angle converti en
radians est enregistré à l'intérieur de fonction dans la variable w1 pour les calculs ultérieurs.
L'affichage d'une horloge analogique repose sur les fonctions trigonométriques sinus et cosinus. Elles
déterminent les coordonnées à partir de l'angle d'un point en radian par rapport au point central (w1) dans le
système de coordonnées rectangulaire (x1 et y1). Les coordonnées du point central sont prises à partir des
variables MX et MY qui sont définies en dehors de la fonction et appliquées globalement. La distance du point
par rapport au point central est obtenue via le paramètre A de la fonction. La fonction int() est dérivée du
résultat de la valeur entière, car les coordonnées de pixel peuvent être données seulement avec des entiers.
La valeur de retour de la fonction est un point géométrique avec les coordonnées calculées x1 et y1, qui sont
définies comme tous les points entre des parenthèses.
Le cadran est dessiné selon la définition de cette fonction.
for i in range(60):
pygame.draw.circle(CHAMP, NOIR, point(190, i), 2)
74
Une boucle dessine successivement les 60 points-minutes sur un cercle. Tous les points sont déterminés avec
la fonction point(). Ils sont à la même distance du point central, qui est toujours éloigné de 10 pixels du
bord de la fenêtre avec 190 pixels en quatre quadrants. Les points ont un rayon de 2 pixels.
for i in range(12):
pygame.draw.circle(CHAMP, NOIR, point(190, i * 5), 4)
Une deuxième boucle dessine 12 cercles plus grands qui marquent les heures sur le cadran. Ils ont un rayon
de 4 pixels, sont simplement dessinés sur le cercle précédent et les recouvrent complétement. Le symbole
des heures se suivent à une distance angulaire de cinq unités-minutes que l'on peut obtenir en multipliant
par 5 les données angulaires, qui sont données dans la fonction.
mainloop = True; s1 = 0 Avant
que la boucle principale du programme ne commence, deux variables
auxiliaires sont encore définies. Elles sont nécessaires dans les processus suivants. mainloop indique
comme dans le dernier exemple de programme si la boucle doit se répéter ou si l'utilisateur souhaite quitter
le programme. s1 enregistre la dernière seconde affichée.
while mainloop:
temps = time.localtime()
La boucle principale du programme commence maintenant. Elle écrit à chaque cycle, indépendamment de
sa durée, l'heure actuelle dans l'objet temps. Pour ce faire, la fonction time.localtime() de la
bibliothèque time est utilisée. Le résultat est une structure de données qui est composée de différentes
valeurs individuelles.
s = temps.tm_sec; m = temps.tm_min; h = temps.tm_hour
Les trois valeurs importantes pour les aiguilles, secondes, minutes et heures, sont écrites à partir de la
structure dans trois variables s, m et h.
if h > 12:
h = h – 12
L’horloge analogique ne montre que douze heures. La fonction time.localtime() fournit toutes les
données de temps en format 24 heures. Pour afficher l'heure de l'après-midi, il suffit de soustraire 12 heures.
Affichage de l'heure avec une horloge analogique
Selon le mécanisme utilisé, il existe deux affichages différents pour les horloges analogiques. Dans une
vraie montre analogique, l'aiguille des minutes effectue un mouvement circulaire uniforme. Dans une
montre à commande numérique, comme par exemple les horloges de gare, une minute complète passe à
la minute suivante. Cette dernière méthode a l'avantage de pouvoir lire l'heure en un clin d'œil, à la
minute près. Les fractions de minutes ne sont pas importantes normalement pour la vie de tous les jours.
Nous utilisons également cette méthode pour notre programme d'horloge. L'aiguille des heures doit
cependant effectuer un mouvement circulaire uniforme. Il serait très étrange et déroutant si chaque heure
écoulée pleinement sautait directement à l'heure suivante.
75
hm = (h + m / 60.0) * 5 La variable hm enregistre l'angle de l'aiguille des heures en unité-minute telle qu'elle
est utilisée dans l'ensemble du programme. Pour ce faire, 1/60 de la valeur des minutes est ajoutée à l'heure
actuelle. À chaque minute, l'aiguille de l'heure se déplace 1/60 d'une heure. La valeur calculée est multipliée
par 5 parce que l'aiguille des heures avance de 5 unités-minutes sur le cadran en une heure.
if s1 <> s: La durée d'un cycle de boucle n'est pas connue dans le programme. Pour l'horloge analogique,
cela signifie que le graphisme ne doit pas être mis à jour à chaque cycle de boucle mais uniquement lorsque
la seconde actuelle est différente de la dernière affichée. Pour ce faire, la seconde affichée est enregistrée
plus tard dans le programme dans la variable s1, la seconde actuelle reste toujours dans la variable s.
Si la seconde a changé par rapport à la dernière seconde affichée, les graphismes de l'horloge sont mis à
jour avec les instructions qui suivent. Si elle n'a pas changé, le graphisme n'a pas besoin d'être mis à jour et
la boucle recommence avec une autre requête de l'heure système actuelle.
pygame.draw.circle(CHAMP, BLANC, MP, 182)
Une surface circulaire blanche est d'abord dessinée en couvrant complétement les aiguilles. Le rayon de
182 pixels est légèrement plus grand que l'aiguille la plus longue de sorte qu'il ne reste plus rien. Il est
beaucoup plus facile de dessiner un cercle complet, que de recouvrir au pixel près la dernière aiguille
dessinée.
pygame.draw.line(CHAMP, NOIR, MP, point(120, hm), 6)
La ligne dessine l'aiguille des heures comme une ligne d'une largeur de 6 pixels et d'une longueur de 120
pixels à partir du point central avec un angle qui est spécifié par la variable hm. La fonction
pygame.draw.line() n'a pas été utilisée jusqu'à présent. Elle a besoin de cinq paramètres :
•
Surface donne la surface de dessin sur laquelle est dessiné par exemple le CHAMP.
•
Couleur donne la couleur du cercle, par exemple la couleur NOIR précédemment définie.
•
Point de départ indique le point de départ de la ligne ; dans cet exemple, il s'agit du centre de l'horloge.
•
Point final indique le point final de la ligne ; dans l'exemple, il est calculé avec la fonction point() à
partir de l'angle de l'aiguille des heures.
•
Épaisseur donne l'épaisseur de la ligne.
La même fonction dessine également les deux autres aiguilles de l'horloge.
pygame.draw.line(CHAMP, NOIR, MP, point(170, m), 4)
Cette ligne dessine l'aiguille des minutes avec une ligne large de 4 pixels et longue de 170 pixels à partir du
point central, avec un angle qui est donné par la valeur des minutes.
pygame.draw.line(CHAMP, ROUGE, MP, point(180, s), 2)
76
Cette ligne dessine l'aiguille des secondes comme une ligne rouge large de 2 pixels et longue de 180 pixels à
partir du point central, avec un angle qui est donné par la valeur des secondes.
s1 = s La seconde qui vient d'être affichée est maintenant dans la variable s1, pour comparer cette valeur et
la seconde actuelle dans le prochain cycle de boucle.
pygame.display.set_caption("Heure actuelle : " +
time.asctime())
Cette ligne écrit l'heure actuelle sous forme numérique dans le titre de la fenêtre. Pour ce faire, la fonction
time.asctime() de la bibliothèque time est utilisée. Elle donne l'heure comme une chaîne de caractères
entièrement formatée.
pygame.display.update() Les éléments graphiques sont dessinés seulement virtuellement jusqu'à présent.
En premier lieu, cette ligne reconstruit vraiment l'affichage graphique. La mise à jour s'effectue en même
temps. Par conséquent, on ne voit aucun vacillement lorsque les aiguilles sont dessinées les unes après
autres.
for event in pygame.event.get():
if event.type == QUIT or (event.type ==
KEYUP and event.key == K_ESCAPE):
mainloop = False
Toujours dans la requête if et également seulement une fois dans la seconde, la requête relativement
gourmande en ressources exécute les événements du système pour déterminer ici si l'utilisateur veut fermer
la fenêtre de l'horloge dans la dernière seconde ou s'il a appuyé sur la touche [échap]. Si c'est le cas, la
variable mainloop est spécifiée sur False et la boucle n'est plus répétée.
pygame.quit() Cette dernière ligne arrête d'abord le module PyGame, ce qui ferme également la fenêtre
graphique et par conséquent, l'ensemble du programme.
10 Boîte de dialogue graphique pour contrôler le programme
Aucun programme moderne qui requiert une interaction avec l'utilisateur, ne fonctionne en mode textuel
pur. Il y a partout des interfaces graphiques sur lesquelles l'on peut cliquer sur des boutons au lieu d'avoir à
entrer des données via le clavier.
Python n'offre pas lui-même d'interface graphique pour le programme. Il existe cependant plusieurs modules
externes semblables à PyGame déjà décrit, qui sont spécialement conçus pour créer des interfaces
graphiques. Un des modules les plus connus est Tkinter, qui offre à Python l'interface graphique Tk, qui peut
également être utilisé pour divers autres langages de programmation.
Les structures de la boîte à outils graphiques Tk diffèrent légèrement de Python et peuvent sembler
inhabituelles de prime abord. Par conséquent, nous commençons par un exemple très simple : Une LED doit
être allumée et éteinte dans une boîte de dialogue.
77
Composants nécessaires :
1x Carte de circuit imprimé
1x LED rouge
1x Résistance de 220 Ω
2x Câbles de connexion
Fig. 10.1: Une LED unique sur le port GPIO 4
Branchez une LED via une pré-résistance sur le port GPIO 4. Le programme ledtk01.py va allumer cette
LED.
import RPi.GPIO as GPIO
from Tkinter import *
LED = 4; GPIO.setmode(GPIO.BCM); GPIO.setup(LED,GPIO.OUT)
78
def LedAllumée():
GPIO.output(LED,True)
def LedÉteinte():
GPIO.output(LED,False)
root = Tk(); root.title("LED")
Label(root,
text="Veuillez cliquer sur le bouton, pour allumer et
éteindre la LED").pack()
Button(root, text="Allumée", command=LedAllumée).pack(side=LEFT)
Button(root, text="Éteinte", command=LedÉteinte).pack(side=LEFT)
root.mainloop()
GPIO.cleanup()
Fig. 10.2: Voilà à quoi la boîte de dialogue ressemble.
10.1.1 Voilà comment cela fonctionne
Ce programme présente les fonctions de base de la bibliothèque Tkinter pour construire la boîte de dialogue
graphique. Contrairement à la bibliothèque graphique PyGame, qui construit les graphiques au pixel près, la
taille de la boîte de dialogue et les éléments de contrôle dans Tkinter découlent automatiquement de la taille
requise mais peuvent également être modifiés manuellement ultérieurement si nécessaire.
import RPi.GPIO as GPIO
from Tkinter import *
Après l'importation de la bibliothèque GPIO, les éléments de la bibliothèque Tkinter sont également
importés.
LED = 4
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED,GPIO.OUT)
Ces lignes ne montrent rien de nouveau. Le port GPIO 4 est défini comme port de sortie pour une LED et
désigné avec la variable LED.
def LedAllumée():
GPIO.output(LED,True)
Une fonction LedAllumée() est maintenant définie. Elle allume la LED.
def LedÉteinte():
GPIO.output(LED,False)
Une fonction semblable, LedÉteinte(), éteint la LED. Ces deux fonctions sont appelées plus tard à l'aide de
deux boutons dans la boîte de dialogue.
Jusqu'à ce point, tout était en Python pur. Nous continuons maintenant avec T et des particularités.
79
root = Tk() Tkinter
travaille avec ce qu'on appelle des widgets. Il s'agit d'éléments d'écran indépendants
dans la plupart de cas pour contenir différents éléments de la boîte de dialogue. Chaque programme a
besoin d'un widget root à partir duquel tous les autres objets sont appelés. Ce widget root est toujours
nommé Tk(),génère automatiquement une fenêtre et initialise la bibliothèque Tkinter.
L'objet root.title("LED") dans Tkinter fournit différentes méthodes pour différentes fins. La méthode
title() dans un widget fixe le titre de la fenêtre, écrit également dans ce cas le mot LED dans la ligne de
titre de la nouvelle fenêtre.
Chaque widget peut contenir plusieurs objets qui sont définis séparément. Pour ce faire, Tkinter connaît
différents types d'objet dont chacun des différents paramètres permettent d'écrire les propriétés de l'objet.
Les paramètres sont spécifiés entre parenthèse, séparés par des virgules, derrière le type de l'objet. Étant
donné que cette liste peut être très longue, on écrit généralement chaque paramètre sur une ligne distincte
de sorte que tous les paramètres soient alignés les uns sous les autres. Contrairement à l'indentation des
boucles et des requêtes dans Python, ces indentations ne sont pas obligatoires pour les objets Tkinter.
Label(root, text="Veuillez cliquer sur le bouton pour allumer et
éteindre la LED").pack()
Les objets de type Label sont des textes bruts dans un widget. Ils peuvent être modifiés par le programme
mais n'offrent aucune interaction avec l'utilisateur. Le premier paramètre dans chaque objet Tkinter est le
nom du widget supérieur, la plupart du temps le nom de la fenêtre dans laquelle l'objet se trouve. Dans
notre cas, il s'agit de la seule fenêtre dans le programme, le widget root.
Le paramètre text contient le texte qui doit être affiché sur le Label. À la fin de la définition de l'objet, le dit
Conditionneur est inclus comme la méthode .pack(). Ce conditionneur intègre l'objet dans la boîte de
dialogue et génère la géométrie du widget.
Button(root,
text="Allumé",
command=LedAllumée).pack(side=LEFT)
Les objets de type Button sont les boutons sur lesquels l'utilisateur clique pour déclencher une action
donnée. Le paramètre text contient ici également le texte qui doit être affiché sur le bouton.
Le paramètre command contient une fonction qui appelle le bouton lorsque vous cliquez dessus. Aucun
paramètre ne peut être passé et le nom de la fonction doit être donné sans parenthèse. Ce bouton appelle la
fonction LedÉteinte() qui éteint la LED.
La méthode .pack() peut également contenir un autre paramètre qui spécifie comme un objet doit être
disposé dans la boîte de dialogue. side=LEFT signifie que le bouton est aligné à gauche et non centré.
Button(root, text="Éteinte", command=LedÉteinte).pack(side=LEFT)
Un deuxième bouton est appliqué en suivant le même schéma. Il éteint la LED via la fonction LedÉteinte().
Toutes les fonctions et tous les objets sont maintenant définis et le vrai programme peut être commencé.
80
root.mainloop() Le programme principal se compose uniquement d'une seule ligne. Elle lance la boucle
principale mainloop(), une méthode du widget root. Cette boucle du programme attend que l'utilisateur
actionne un des widget et déclenche ainsi une action.
Le symbole en haut à droite pour fermer la fenêtre n'a pas besoin d'être spécialement défini avec Tkinter. Si
l'utilisateur ferme la fenêtre principale root, la boucle principale mainloop() est automatiquement quittée.
GPIO.cleanup() Le
programme se poursuit jusqu'à la dernière ligne et ferme le port GPIO ouvert.
Après le démarrage du programme, une boîte de dialogue s'affiche à l'écran. Cliquez sur le bouton Allumée,
pour allumer la LED, puis sur Éteinte pour l'éteindre à nouveau.
10.2 Contrôler le chenillard avec l'interface graphique
La bibliothèque Tkinter de Python met à disposition plusieurs éléments de commandes autres que les
simples boutons. Les boutons radio permettent de construire les menus de sélection dans lesquels
l'utilisateur peut choisir parmi plusieurs options données.
Qu'est-ce qu'un bouton radio ?
Le nom « bouton radio » vient en fait des vieilles radios où il y avait des boutons pour choisir parmi des
stations de radio prédéfinies. À chaque fois que l'on appuyait sur l'un de ces boutons, le dernier bouton
enfoncé était libéré automatiquement grâce à un mécanisme ingénieux. Les boutons radio se comportent
de la même façon. Si l'utilisateur choisit une option, les autres sont automatiquement inactivées.
L'expérience suivante montre différents motifs clignotants de LED qui sont semblables à l'expérience « Motif
à LED coloré et chenillard ». Contrairement à l'expérience précédente, l'utilisateur n'a pas besoin d'entrer
son choix sur un écran textuel mais il peut choisir facilement le motif souhaité à partir d'une liste simple.
Fig. 10.3: La boîte de dialogue propose trois motifs à LED.
La construction du circuit est la même que dans l'expérience « Motif à LED coloré et chenillard ».
81
Fig. 10.4: Construction de la carte pour l'expérience 10.2
Composants nécessaires :
1x Carte de circuit imprimé
1x LED rouge
1x LED jaune
1x LED verte
1x LED bleue
4x Résistances de 220 Ω
5x Câbles de connexion
82
Fig. 10.5: Quatre LED clignotent avec des motifs différents.
Le programme ledtk02.py est basé sur le programme précédent mais les boutons radio et les fonctions
pour le chenillard à LED et les motifs clignotant sont étendues.
import RPi.GPIO as GPIO
import time
from Tkinter import *
GPIO.setmode(GPIO.BCM)
LED = [4,18,23,24]
for i in LED:
GPIO.setup(i, GPIO.OUT, initial=0)
w = 5; t = 0.2
motif = [
("Chenillard vers la gauche",1),
("Clignoter",2),
("Chenillard vers la droite",3)
83
]
root = Tk(); root.title("LED"); v = IntVar(); v.set(1)
def LedEin():
e = v.get()
if e == 1:
for i in range(w):
for j in range(4):
GPIO.output(LED[j], True)
time.sleep(t)
GPIO.output(LED[j], False)
elif e == 2:
for i in range(w):
for j in range(4):
GPIO.output(LED[j], True)
time.sleep(t)
for j in range(4):
GPIO.output(LED[j], False)
time.sleep(t)
else:
for i in range(w):
for j in range(4):
GPIO.output(LED[3-j], True); time.sleep(t)
GPIO.output(LED[3-j], False)
Label(root,
text="Veuillez cliquer sur le bouton pour démarrer le
chenillard").pack()
for txt, m in motif:
Bouton_radio(root, text = txt,
variable = v, value = m).pack(anchor=W)
Button(root, text="Démarrer", command=LedAllumée).pack(side=LEFT)
root.mainloop()
GPIO.cleanup()
10.2.1
Voilà comment cela fonctionne
Les bibliothèques requises sont importées encore une fois au début. En outre par rapport au dernier
programme, la bibliothèque time est également importée. Elle est nécessaire pour les temps d'attente des
effets à LED clignotants.
GPIO.setmode(GPIO.BCM); LED = [4,18,23,24]
for i in LED:
GPIO.setup(i, GPIO.OUT, initial=0)
Une liste est ensuite définie pour les quatre LED. Les ports GPIO correspondants sont définis comme des
sorties et spécifiés sur 0 de sorte que toutes les LED soient éteintes au début.
w = 5; t = 0.2
Deux variables spécifient deux valeurs dans le programme : le nombre de répétition w d'un motif et le temps
de clignotement t. Les deux valeurs peuvent être aussi inscrites à chaque occurrence dans le programme. De
cette façon, elles peuvent s'ajuster plus facilement étant donné qu'elles ne sont définies qu'à un seul endroit.
84
motif = [
("Chenillard vers la gauche",1), ("Clignoter",2), ("Chenillard vers la droite",3)
]
Les textes des trois motifs disponibles sont définis sous forme de liste spécifique. Chacun des trois éléments
de la liste consiste en quelques valeurs, chacun comprenant le texte affiché et la valeur numérique qui doit
être retournée plus tard lors du choix du bouton radio.
root = Tk(); root.title("LED")
L'initialisation du widget root correspond encore une fois au programme précédent, ne différant qu'au
niveau du contenu de la boîte de dialogue.
v = IntVar(); v.set(1)
Les variables qui sont utilisées dans la boîte de dialogue Tk, doivent être déclarées avant la première
utilisation, contrairement aux variables normales de Python. Ces deux lignes déclarent une variable v comme
un nombre entier et la spécifie comme 1 au début.
def LedAllumée():
e = v.get()
Une fonction qui s'appelle LedAllumée() comme dans le dernier exemple est maintenant définie à nouveau.
Mais cette fois, elle n'allume pas qu'une seule LED mais démarre un motif de LED. La deuxième fonction
LedÉteinte() du dernier exemple n'est pas nécessaire ici. La première ligne de la nouvelle fonction lit
l'entrée de l'utilisateur à partir de la variable tk v et écrit la valeur dans la variable Python e. Comme la
valeur arrive exactement dans la variable v, apprenez davantage ci-dessous avec l'explication des boutons
radio.
Selon le choix de l'utilisateur, trois différentes boucles de programme peuvent être lancées :
if e == 1:
for i in range(w):
for j in range(4):
GPIO.output(LED[j], True); time.sleep(t)
GPIO.output(LED[j], False)
Dans le premier cas, une boucle est exécutée cinq fois. Elle allume successivement chacune des quatre LED,
les laisse allumées pendant 0,2 seconde puis les éteint. Les cinq répétitions et le temps de clignotement de
0,2 seconde sont définis par les variables w et t au début du programme.
elif e == 2:
for i in range(w):
for j in range(4):
GPIO.output(LED[j], True)
time.sleep(t)
for j in range(4):
GPIO.output(LED[j], False)
time.sleep(t)
85
Dans le deuxième cas, toutes les quatre LED sont allumées à la suite simultanément, elles éclairent ensuite
pendant 0,2 secondes puis sont éteintes en même temps.
else:
for i in range(w):
for j in range(4):
GPIO.output(LED[3-j], True); time.sleep(t)
GPIO.output(LED[3-j], False)
Le troisième cas ressemble au premier sauf que les LED sont comptées à l'envers et que, par conséquent, le
chenillard court dans le sens inverse.
Après avoir défini la fonction, les éléments de l'interface graphique sont créés.
Label(root,
text="Veuillez cliquer sur le bouton, pour démarrer le
chenillard").pack()
Le texte de la boîte de dialogue est à nouveau défini comme un objet Label. La définition des trois boutons
radio est nouvelle.
for txt, m in motif:
Bouton_radio(root, text = txt, variable = v, value = m).pack(anchor=W)
Les boutons radio sont définis par une forme spéciale de la boucle for. A la place d'un compteur de boucle,
il y a ici deux variables qui sont comptées en parallèle. Les deux compteurs passent successivement par les
éléments de la liste motif. La première variable de comptage txt assume la première valeur de la paire de
valeurs : le texte affiché à côté du bouton radio. La deuxième variable de comptage m assume le numéro de
chaque motif à partir de la deuxième valeur de la paire de valeur.
La boucle crée de cette façon trois boutons radio dont le premier paramètre est toujours le widget root où
se trouvent les boutons radio. Le paramètre text d’un bouton radio donne le texte à afficher qui est dans ce
cas lu à partir de la variable txt. Le paramètre variable spécifie une variable Tk précédemment déclarée,
dans laquelle la valeur du bouton radio choisi par l'utilisateur est enregistrée.
Le paramètre value spécifie une valeur numérique pour chaque bouton radio, qui est lue dans ce cas à
partir de la variable m. Si un utilisateur clique sur ce bouton radio, la valeur du paramètre value dans la
variable enregistrée sous variable est écrite. Chacun des trois boutons radio est construit selon sa définition
de manière similaire à la méthode .pack() dans la boîte de dialogue. Le paramètre anchor=W assure que
les boutons radio soient alignées à gauche les uns sous les autres.
Button(root, text="Démarrer", command=LedEin).pack(side=LEFT)
Le bouton est défini comme dans le dernier exemple.
root.mainloop(); GPIO.cleanup()
La boucle principale et la fin du programme correspondent à l'exemple précédent.
86
Lancez le programme et choisissez un motif de LED via une des boutons radio. Le premier choix est
présélectionné via la variable v. Si vous utilisez les boutons radio dans une boîte de dialogue, vous devez
toujours définir une pré-sélection judicieuse pour ne jamais obtenir de résultat indéfini si l'utilisateur ne fait
aucun choix. En cliquant sur Start, vous lancez le motif choisi et il s'exécute cinq fois. Vous pouvez ensuite
choisir un autre motif.
10.3 Régler la vitesse de clignotement
La boîte de dialogue est étendue dans la troisième étape. L'utilisateur peut maintenant régler la vitesse du
clignotement à l'aide d'un curseur.
Fig. 10.6: Trois motifs de LED au choix
et vitesse de clignotement réglable
Utilisation du curseur
Le curseur offre une manière très intuitive d'enter des valeurs numériques comprises dans une certaine
gamme. De cette façon, on économise une requête de plausibilité qui détermine si l'utilisateur a donné
une valeur que le programme peut appliquer judicieusement, étant donné que les valeurs en dehors de la
gamme prédéfinie du curseur ne sont pas possibles. Réglez toujours le curseur de sorte que la valeur soit
concevable pour l'utilisateur. Cela n'a aucun sens de pouvoir régler les valeurs dans une fourchette de
plusieurs millions. Si la valeur numérique absolue ne joue aucun rôle réel, il vous suffit de donner à
l'utilisateur une échelle de 1 à 10 ou de 1 à 100 et de calculer la valeur dans le programme. La valeur doit
être augmentée de gauche à droite. Si cela se fait dans le sens inverse, cela sera étrange pour la plupart
des utilisateurs. En outre, prédéfinissez toujours une valeur judicieuse qui est appliquée si l'utilisateur ne
change pas le curseur.
Le programme ledtk03.py correspond en grande partie à l'exemple précédent. Seule la régulation de la
vitesse est ajoutée.
import RPi.GPIO as GPIO
import time
from Tkinter import *
GPIO.setmode(GPIO.BCM); LED = [4,18,23,24]
for i in LED:
GPIO.setup(i, GPIO.OUT, initial=0)
w = 5
motif = [
("Chenillard vers la gauche",1), ("Clignoter",2), ("Chenillard vers la droite",3)
87
]
root = Tk(); root.title("LED"); v = IntVar(); v.set(1); g = IntVar(); g.set(5)
def LedEin():
e = v.get()
t = 1.0/g.get()
if e == 1:
for i in range(w):
for j in range(4):
GPIO.output(LED[j], True); time.sleep(t)
GPIO.output(LED[j], False)
elif e == 2:
for i in range(w):
for j in range(4):
GPIO.output(LED[j], True)
time.sleep(t)
for j in range(4):
GPIO.output(LED[j], False)
time.sleep(t)
else:
for i in range(w):
for j in range(4):
GPIO.output(LED[3-j], True): time.sleep(t)
GPIO.output(LED[3-j], False)
Label(root,
text="Veuillez cliquer sur le bouton pour démarrer le
chenillard").pack()
for txt, m in motif:
Bouton_radio(root, text = txt, variable = v, value = m).pack(anchor=W)
Label(root, text="Vitesse").pack()
Scale(root, orient=HORIZONTAL, from_ = 1, to = 10, variable = g).pack()
Button(root, text="Démarrer", command=LedAllumée).pack(side=LEFT)
root.mainloop()
GPIO.cleanup()
10.3.1
Voilà comment cela fonctionne
L'initialisation des bibliothèques et des ports GPIO, ainsi que la définition de la liste pour les trois motifs
clignotants de LED correspondent au programme précédent. La définition de la variable t pour le temps de
clignotement disparaît puisqu'elle est lue ultérieurement sur le curseur.
g = IntVar(); g.set(5) En plus de la variable Tk v, dans laquelle le motif clignotante choisi est enregistré,
une autre variable entière g est déclarée pour la vitesse. Elle contient une valeur de départ de5, qui
correspond à la valeur centrale du curseur.
def LedAllumée():
e = v.get(); t = 1.0/g.get()
88
La fonction qui permet de faire clignoter les LED correspond aussi à l'exemple précédent, avec cependant
une différence. La variable t pour la durée de clignotement est déterminée à partir de la valeur g du
curseur.
Étant donné qu'un utilisateur fait le lien intuitivement en un clin d'œil avec une vitesse plus élevée, le curseur
placé à droite retourne une valeur plus élevée. Cependant, dans le programme, un temps d'attente plus court
(donc une valeur plus petite) est nécessaire avec une vitesse plus élevée. Cela est obtenu par un calcul inverse,
qui détermine à partir des valeurs 1 à 10 du curseur la valeur 1,0 à 0,1 pour la variable t. Dans la formule, on
doit écrire 1,0 et non 1 pour que le résultat soit un chiffre à virgule et non un chiffre entier.
Convertir les chiffres entiers en chiffre à virgule
Le résultat d'un calcul est automatiquement enregistré comme un chiffre à virgule si au moins une des
valeurs est un chiffre à virgule. Si toutes les valeurs sont exprimées en nombres entiers (Integer), le
résultat est alors un nombre entier.
La définition du label et des boutons radio dans la boîte de dialogue sont reprises à partir de l'exemple
précédent.
Label(root,
text="Vitesse").pack()
Pour expliquer le curseur; un autre label est écrit dans la boîte de dialogue. Étant donné qu'il ne contient
aucun paramètre dans la méthode pack(), il est centré horizontalement sous le bouton radio.
Scale(root, orient=HORIZONTAL, from_ = 1, to = 10, variable = g).pack()
Le curseur est un objet de type Scale, qui a comme premier paramètre root comme tous les objets dans
cette boîte de dialogue. Le paramètre orient=HORIZONTAL indique que le curseur est placé à l'horizontale. Il
serait placé à la verticale sans ce paramètre. Les paramètres from_ et to indiquent le début et la fin du
curseur. Faites attention à l'écriture de from_, car from sans tiret bas est un mot réservé dans Python pour
l'importation des bibliothèques. Le paramètre variable spécifie une variable Tk précédemment déclarée,
dans laquelle la valeur actuellement réglée sur le curseur est enregistrée. La valeur de départ est reprise à
partir de la valeur fixée par la déclaration des variables, dans ce cas 5.
Le curseur est également centré horizontalement dans la boîte de dialogue avec la méthode pack().
Les autres parties du programme – le bouton Start, la boucle principale et la fin du programme – ne changent
pas par rapport à l'exemple précédent.
Démarrez le programme, choisissez un motif clignotant et réglez la vitesse. Plus la valeur est élevée, plus le
motif clignote rapidement. En cliquant sur le bouton Start, la fonction LedAllumée() détermine le motif
clignotant choisi à partir des boutons radio ainsi que la vitesse à partir de la position du curseur.
89
11 Pitance avec les LED
À la fin des années 1970, avant la vraie époque des jeux informatiques, il y avait un jeu électronique avec
quatre ampoules de couleur, qui a même été nominé pour le jeu de l'année en 1979. Le jeu était vendu en
Allemagne sous le nom Senso. Atari l'a reproduit avec un jeu nommé Touch Me de la taille d'une grosse
calculatrice. Un autre jeu semblable est sorti sous le nom Einstein. Senso a été commercialisé sous le nom
Simon pour sa version anglophone.
Raspbian fournit une version graphique de ce jeu avec les Python Games, sous le nom Simulate.
Fig. 11.1: Le jeu Simulate tiré des Python Games.
Notre jeu PiDance est également basé sur ce principe de jeu. Les LED clignotent dans un ordre aléatoire.
L'utilisateur doit ensuite appuyer sur les boutons dans le même ordre. À chaque tour, une LED
supplémentaire s'allume de sorte qu'il soit toujours plus difficile de se rappeler la séquence des LED. Dès
que l'on fait une erreur, le jeu est terminé.
Le jeu est construit à partir de deux cartes de circuit imprimé, de sorte que les touches soient sur le bord et
faciles à utiliser, sans que des câble ne soient débranchés accidentellement des cartes de circuit imprimé.
Pour une meilleure stabilité, les cartes de circuit imprimé peuvent être interconnectées longitudinalement.
En plus des câbles de connexion que vous connaissez déjà, quatre cavaliers courts sont également
nécessaires. Pour ce faire, coupez avec un pince coupante ou un coupe-fil le fil de connexion en des
morceaux longs de 2,5 centimètres environ et dénudez 7 millimètres de gaine isolantes au niveau des deux
90
extrémités à l'aide d'une lame coupante. Pliez ces morceaux de fil pour obtenir une forme en U. Vous pouvez
ensuite connecter deux rangées sur une carte de circuit imprimé.
Fig. 11.2: Construction de la carte pour l'expérience 11
Composants nécessaires :
2x Cartes de circuit imprimé
1x LED rouge
1x LED jaune
1x LED verte
1x LED bleue
4x Résistances de 220 Ω
4x Résistances de 1 kΩ
4x Résistances de 10 kΩ
4x Boutons
10x Câbles de connexion
4x Cavaliers courts
91
Fig. 11.3: PiDance avec LED et des boutons sur les deux cartes de circuit imprimé
Les boutons sont montés à côté des LED associées. Les deux rangées longitudinales centrales des cartes de
circuit imprimé des deux côté du point de jonction servent de conducteur 0 V et + 3,3 V pour le circuit.
Le programme pidance01.py contient le jeu terminé.
# -*- coding: utf-8 -*import time, random
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
rchiffre = 10; couleur = []
for i in range(rchiffre):
Couleur.append(random.randrange(4))
LED = [23,24,25,8]
for i in LED:
GPIO.setup(i, GPIO.OUT, initial=False)
BOUT = [4,17,21,22]
for i in BOUT:
GPIO.setup(i, GPIO.IN)
def LEDAllumée(n, z):
GPIO.output(LED[n], True); time.sleep(z)
GPIO.output(LED[n], False); time.sleep(0.15)
def Appuyer():
while True:
if(GPIO.input(BOUT[0])):
return 0
if(GPIO.input(BOUT[1])):
return 1
if(GPIO.input(BOUT[2])):
92
return 2
if(GPIO.input(BOUT[3])):
return 3
ok = True
for tour in range(1, rchiffre +1):
print "Tour", tour
for i in range(tour):
LEDallumée(couleur[i], 1)
for i in range(tour):
bouton = Appuyer()
LEDallumée(bouton, 0.2)
if(bouton != couleur[i]):
print "Perdu !"
print "Vous avez réussi jusqu'au tour ", tour – 1, "."
for j in range(4):
GPIO.output(LED[j], True)
for j in range(4):
time.sleep(0.5)
GPIO.output(LED[j], False)
ok = False
break
if(ok == False):
break
time.sleep(0.5)
if(ok == True):
print "Bien joué !"
for i in range(5):
for j in range(4):
GPIO.output(LED[j], True)
time.sleep(0.05)
for j in range(4):
GPIO.output(LED[j], False)
time.sleep(0.05)
GPIO.cleanup()
11.1.1 Voilà comment cela fonctionne
Le programme propose de nombreuses nouveautés. Les bases du contrôle GPIO sont cependant déjà
connues.
rchiffre = 10 Après l'importation des modules time, random et RPi.GPIO, une variable rchiffre est
créée. Elle spécifie le nombre de tours du jeu. Vous pouvez évidemment jouer à plus de dix tours – plus il y a
de tours, plus il est difficile de se rappeler de la séquence de clignotement.
couleur = []
for i in range(rchiffre):
couleur.append(random.randrange(4))
La liste couleur est remplie avec une boucle avec autant de nombres aléatoires compris entre 0 et 3 que de
tours joués. Pour ce faire, la méthode append() est utilisée. Elle indique ce qui est disponible dans chaque
liste. Elle dépend des éléments définis comme paramètre sur la liste.
93
LED = [23,24,25,8]
for i in LED:
GPIO.setup(i, GPIO.OUT, initial=False)
Les ports GPIO pour les LED sont configurés comme des sorties selon le schéma connu dans une liste LED et
ils sont tous inactivés.
BOUT = [4,17,21,22]
for i in BOUT:
GPIO.setup(i, GPIO.IN)
Suivant le même principe, les ports GPIO sont configurés comme des entrées pour les quatre boutons dans
une liste BOUT.
Les bases sont ainsi créées et elles définissent encore deux fonctions qui sont nécessaires plusieurs fois dans
le programme.
def LEDallumée(n, z):
GPIO.output(LED[n], True); time.sleep(z)
GPIO.output(LED[n], False); time.sleep(0.15)
La fonction LEDallumée() allume une LED qui éclaire alors pendant un certain temps. La fonction utilise
deux paramètres. Le premier paramètre n donne le numéro de la LED compris entre 0 et 3, le deuxième
paramètre z donne le temps pendant lequel la LED doit rester allumée. Après que la LED est éteinte à
nouveau, la fonction attend encore que 0,15 seconde se soit écoulée, pour voir les pauses courtes entre les
allumages des LED en cas d'appels multiples. Cela est particulièrement important lorsqu'une LED est allumée
plusieurs fois à la suite. Autrement, on ne pourrait pas s'en apercevoir.
def Appuyer():
while True:
if(GPIO.input(BOUT[0])):
return 0
if(GPIO.input(BOUT[1])):
return 1
if(GPIO.input(BOUT[2])):
return 2
if(GPIO.input(BOUT[3])):
return 3
La fonction Appuyer() se compose d'une boucle infinie qui attend que l'utilisateur appuie sur un des
boutons. Le numéro du bouton est ensuite transmis au programme principal.
ok = True Après la définition des fonctions, le vrai programme principal démarre et spécifie en premier une
variable ok sur True. Dès que le joueur fait une erreur, ok passe à False. Si la variable est toujours True
après le nombre de tour prédéfini, le joueur a gagné la partie.
for tour in range(1, rchiffre +1):
Le jeu exécute le nombre de tours fixé dans la variable rzahl. Le compteur de tours est décalé de 1 vers le
haut pour que le jeu commence au tour 1 et non au tour 0.
94
print "Tour", tour
Le tour actuel est indiqué dans la fenêtre Python-Shell.
for i in range(tour):
LEDallumée(couleur[i], 1)
Le programme exécute maintenant le motif que le joueur doit se rappeler. Selon le nombre actuel de tours,
plusieurs LED s'allument successivement en fonction de la liste couleur spécifiée au début du programme,
avec des couleurs choisies aléatoirement. Comme le compteur tour commence à 1, une seule LED s'allume
déjà pendant le premier tour. Pour allumer les LED, la fonction LEDallumée() est utilisée. Son premier
paramètre est la couleur à partir de la position correspondante dans la liste. Son deuxième paramètre laisse
chaque LED allumée pendant une seconde.
for i in range(tour): Après
l'exécution du motif de couleur, une nouvelle boucle démarre dans laquelle le
joueur doit entrer le même motif de mémoire, à l'aide des boutons.
bouton = Appuyer() Pour ce faire, la fonction Appuyer() est appelée. Elle attend jusqu'à ce que le joueur
appuie un des boutons. Le numéro des boutons appuyés est enregistré dans la variable bouton.
LEDallumée(bouton, 0.2) Après que vous avez appuyé sur un bouton, la LED correspondante s'allume
brièvement pendant 0,2 seconde.
if(bouton != couleur[i]): Si le dernier bouton enfoncé ne correspond pas à la couleur de la position
correspondante dans la liste, le joueur a perdu. L'opérateur != signifie non égal. L'opérateur <> peut aussi
être utilisé ici.
print "Perdu !"
print "Vous avez réussi jusqu'au tour ", tour – 1, "."
Le programme affiche sur l'écran que le joueur a perdu et combien de tours il a gagnés. Le nombre de tours
passés est plus petit de 1 comme le compteur de tours actuel.
for j in range(4):
GPIO.output(LED[j], True)
Toutes les LED sont allumées comme signal visuel ...
for j in range(4):
time.sleep(0.5); GPIO.output(LED[j], False)
... puis elles sont éteintes les unes après les autres avec un intervalle de 0,5 secondes. Cela donne un effet de
réduction visible.
ok = False
La variable ok, qui indique si le joueur joue encore, est spécifié sur False ...
break ...
et la boucle est interrompue. Le joueur ne peut plus appuyer sur un autre bouton. Le jeu est quitté
immédiatement à la première erreur.
95
if(ok == False):
break
si ok est sur False, la boucle externe est également interrompue et il n'y a pas de tours supplémentaires.
time.sleep(0.5) Si les entrées ont répété correctement la séquence, le programme attend pendant
0,5 seconde jusqu'à ce que le tour suivant commence.
if(ok == True): Le programme arrive à cet endroit si les boucles se sont toutes exécutées, si le joueur a entré
correctement toutes les séquences, ou si la boucle précédente a été interrompue par une erreur du jeu. Si ok
reste sur True, la remise des prix a lieu. Sinon ce bloc est ignoré et le jeu exécute seulement la dernière ligne du
programme.
print "Bien joué !"
for i in range(5):
for j in range(4):
GPIO.output(LED[j], True)
time.sleep(0.05)
for j in range(4):
GPIO.output(LED[j], False)
time.sleep(0.05)
En cas de victoire, un affichage apparaît dans la fenêtre Python-Shell. Après cela toutes les LED clignotent
brièvement cinq fois à la suite.
GPIO.cleanup()
fermés.
96
La dernière ligne est exécutée dans tous les cas. Tous les ports GPIO utilisés sont ici
Mentions légales
© 2014 Franzis Verlag GmbH, Richard-Reitzner-Allee 2, 85540 Haar bei München
www.elo-web.de
Auteur : Christian Immler
ISBN 978-3-645-10145-5
Tous droits réservés, y compris en ce qui concerne la reproduction photomécanique et le stockage sur les supports électroniques. La création
et la distribution de copies sur papier, sur des supports de données ou sur Internet, en particulier dans le format PDF, n'est autorisée qu'avec
la permission expresse de l'éditeur, sous peine de poursuites.
La plupart des noms de produits du matériel informatique et des logiciels, ainsi que les noms de marque et logos de société, qui sont
mentionnés dans ce document, sont également et généralement des marques déposées et ils doivent être traités comme tels. Lorsque l'éditeur
mentionne des noms de produits, il respecte en principe la graphie du fabricant.
Tous les circuits et programmes présentés dans ce livre ont été développés, vérifié et testés avec le plus grand soin. Néanmoins, nous ne
pouvons pas exclure complétement la présence d'erreur dans ce livre et dans le logiciel. L'éditeur et l'auteur sont responsables en cas
d'intention délictueuse ou de négligence grave conformément aux dispositions légales. Par ailleurs, l'éditeur et l'auteur dans le cadre de la loi
sur la responsabilité civile du producteur, en cas d'atteinte à la vie, à l'intégrité physique ou à la santé de la personne, ainsi qu'en cas de
manquement fautif et essentiel aux obligations du contrat. Le droit aux dommages et intérêts pour avoir manqué aux obligations contractuelles
importantes est cependant limités aux dommages spécifiques au contrat, sauf dans les cas où une responsabilité légale est fournie
conformément à la loi sur la responsabilité du produit.
Les appareils électriques et électroniques ne doivent pas être jetés avec les ordures ménagères !
Il convient de procéder à l'élimination du produit au terme de sa durée de vie conformément aux prescriptions légales en vigueur. Il existe des
points de collecte où vous pouvez déposer
gratuitement vos appareils électriques usagés. Contactez votre commune pour savoir où se trouvent ces points de collecte.
Ce produit est conforme aux directives CE pertinents, tant que vous l'utilisez en respectant les instructions fournies. Ce mode d'emploi fait
partie du produit et doit être transmis avec le produit si vous le cédez.
Attention ! Protection des yeux et LED.
Ne regardez jamais directement dans une LED car cela peut endommager la rétine ! Cela est particulièrement vrai pour les LED lumineuses
dans des boîtiers clairs et en particulier pour les LED très puissantes. La luminosité apparente des LED blanches, bleues, violettes et à
ultraviolets donne une fausse impression du risque réelle que faites prendre à vos yeux. Faites particulièrement attention si vous utilisez des
lentilles convergentes. Utilisez les LED comme prévu dans les instructions mais pas avec des courants plus élevés.

Manuels associés