P2E-DIE
Dé binaire
L'idée dans ce projet est de choisir un nombre au hasard entre 1 et 6 lorsque l'utilisateur presse sur un bouton (pour lancer le dé).
Depuis la plus tendre enfance, nous sommes tous habitué à utiliser la base 10. Ainsi, la lecture d'une valeur numérique quelconque n'est généralement pas un problème... et encore moins pour un dé offrant une valeur entre 1 et 6 en chiffre ou dé utilisant 1 à 6 points.
Malheureusement, le Pico-2-Explorer ne dispose pas de LEDs organisées sous la forme de dé ou afficheur numérique. Par contre la carte dispose de 3 LEDs qui peuvent être utilisée pour afficher des 1 (allumée) et des 0 (éteinte).
Il est possible d'utiliser les LEDs du Pico-2-explorer pour représenter une valeur numérique à l'aide d'un encodage binaire.
Nous pourrons ainsi produire une valeur numérique de 1 à 6 (celles d'un dé) qu'il sera possible de lire sur les 3 LEDs du Pico-2-Explorer.
La connaissance des premières représentations binaire peut s'avérer très utile dans les mondes de l'informatique et de l'électronique.
A propos de l'encodage binaire
Plutôt que d'aborder l'encodage binaire de front, je vais procéder par une approche détournée suivit d'une petite correction.
Une approche imparfaite
Admettons que l'on fixe une valeur prédéterminée à nos trois LEDs. Soit les valeurs 1, 2, 3 (en commençant la numérotation par la gauche).
Il est donc possible d'indiquer les valeurs suivantes en allumant la LED appropriée. On peu indiquer quelle LED est allumée à l'aide d'une suite de 1 et de 0. Par exemple 001 indique que seule la LED la plus a droite est allumée tandis que 110 indique que les deux LEDs les plus a gauches sont allumées.
Chacun de ces 1/0 sont des équivalents de marche/arret ou vrai/faux ou True/False. Chacune des positions, appelée bit, n'a que deux valeurs possibles.
- 000 = Aucune LED = 0
- 001 = LED verte = 1
- 010 = LED orange = 2
- 100 = LED rouge = 3
En allant un peu plus loin et en sommant les valeurs correspondantes, il est même possible d'atteindre la valeur 6.
Ainsi:
- 101 = LED rouge + LED verte = 3 + 1 = 4
- 110 = LED rouge + LED orange = 3 + 2 = 5
- 111 = LED rouge + LED orange + LED verte = 3 + 2 + 1 = 6
- Le bit le plus à droite à le poids le plus faible (une valeur de 1).
- Le bit le plus a gauche à le poids le plus fort (une valeur de 3).
Nous pouvons aussi donner des noms aux différents bits:
- Le bit de poids le plus faible (le plus à droite) porte le nom de bit 0 (ou b0),
- Le bit suivant, directement à gauche, porte le nom b1,
- le bit suivant, totalement a gauche dans notre exemple, porte le nom b2.
Le lecteur attentif aura noté qu'il y a deux façons de représenter la valeur 3 dans ce système.
- 100 = LED rouge = 3
- 011 = LED Orange + LED verte = 2+1 = 3
Cet encodage est équivoque! Il sera d'autant plus gênant et fréquent qu'il y a de bits pour codifier la valeur numérique.
Le codage binaire
Plutôt que d'utiliser une série numérique croissante (1,2,3), la codification binaire se propose d' utiliser la suite (1,2,4,8,16,32,64,128,...).
Cette suite de valeur est obtenue a partie de 2^0=1, 2^1=2, 2^2=4, 2^3=8 et ainsi de suite.
Ces nouveaux poids pour chacun des bits est visible sur l'image ci-dessous.
La lecture se fait de droite à gauche.
Cette fois, l'encodage évitera la redondance d'encodage pour la valeur 3 et permettra d'encoder une valeur allant jusque 7.
Valeur binaire | LEDs correspondantes | Valeur numérique |
000 | toutes LEDs éteintes | 0 |
001 | LED rouge = 1 | 1 |
010 | LED orange = 2 | 2 |
011 | LED orange + LED rouge = 2 + 1 | 3 |
100 | LED verte = 4 | 4 |
101 | LED verte + LED rouge = 4 + 1 | 5 |
110 | LED Verte + LED orange = 4 + 2 | 6 |
111 | LED Verte + LED orange + LED rouge = 4 + 2 + 1 | 7 |
A bit équivalent, l'encodage binaire permet d'encoder une gamme plus large de valeurs numériques.
Ainsi, sur 4 bits il est possible d'encoder 16 valeurs (0 à 15) en binaire là où l'encodage simple est limité à 11 valeurs (0 à 10).
Sur 5 bits, l'encodage binaire monte à 32 valeurs encodées là où l'encodage simple est limité à 16 valeurs.
Voici un petit résumé graphique du calcul sur base de la valeur binaire 01000110 (que l'on note 0b01000110 en Python)
A titre d'information, sur 8 bits, il est possible d'encoder les valeurs de 0 à 255 et sur 16 bits il sera possible de coder les nombres de 0 à 65535 (Le nombre de bits étant virtuellement illimités sous Python).
Et sous Python?
Jusqu'à maintenant, la notation binaire était assez spartiate avec seulement des 1 et des 0.
Cependant, dans un langage de programmation il est important d'indiquer si nous sommes face à une valeur binaire ou une valeur numérique.
Par défaut, Python considère un nombre comme étant encodé en base 10.
En saisissant l'instruction si dessous, il est possible de connaître la valeur correspondante d'un nombre binaire
print( 0b110 )
Ce qui affichera la valeur 6 dans la session REPL comme le démontre la capture Thonny IDE ci-dessous.
Il est également possible de transformer une valeur numérique en sa représentation binaire à l'aide de la fonction bin()
print( bin(3) )
print( bin(6) )
Comme le montre la capture d'écran ci-dessous, bin() n'utilise que le nombre de bit nécessaire pour encoder la valeur numérique.
C'est ainsi que seul 2 bits sont nécessaire pour l'encodage binaire de 3 là où il faut 3 bits pour encoder les valeurs de 4 à 7 (donc aussi pour 6).
Brancher
Pico | Pico-2-Explorer |
GP10 | Btn 1 |
GP22 | LED verte (bit 0, poids faible) |
GP26 | LED orange (bit 1) |
GP27 | LED rouge (bit 2, poids fort) |
Appuyer sur le bouton générera un nouveau nombre aléatoire qui sera affiché:
- En base 10 dans la session REPL.
- En binaire (base 2) sur les LEDs.
A cause de la disposition des LEDs, le décodage du nombre binaire ne se fait pas de gauche à droite (comme présenté dans l'introduction) mais de bas en haut.
Il est commun d'avoir les nombres les plus faible en bas... le poids le plus faible (valeur 1) se trouve donc en bas.
Il est possible de retrouver une lecture normale en faisant pivoter le Pico-2-Explorer de 90° dans le sens anti-horlogique.
Code
Le script die.py est disponible dans le dépôt dédié au Pico-2-Explorer.
1 import micropython, time
2 from random import randint
3 from machine import Pin
4 micropython.alloc_emergency_exception_buf(100)
5
6 counter = 0
7
8 def bouton_cb( obj ):
9 global counter
10 counter += 1
11
12 btn = Pin( Pin.board.GP10, Pin.IN, Pin.PULL_UP )
13 btn.irq( handler=bouton_cb, trigger=Pin.IRQ_FALLING )
14 LEDs = [ Pin(Pin.board.GP27, Pin.OUT), Pin(Pin.board.GP26, Pin.OUT),
15 Pin(Pin.board.GP22, Pin.OUT) ]
16 for led in LEDs:
17 led.value(0)
18
19 old_value = 0
20 while True:
21 if counter>0: # Button pressed?
22 new_value = randint(1,6)
23 while new_value == old_value:
24 new_value = randint(1,6)
25
26 old_value = new_value
27 print( 'Random = %i = %s' % (new_value,bin(new_value)) )
28
29 s = bin(new_value).replace( '0b','' )
30 s = '%3s' % s
31 s = s.replace(' ', '0')
32 # print( bin(new_value), '->', s )
33
34 for i in range(3): # 0..2
35 LEDs[i].value( int(s[i]) )
36
37 time.sleep_ms( 500 )
38 # Reset button detection
39 counter=0
40 else:
41 time.sleep_ms(200)
Cette exemple utilise le principe d'interruption pour détecter la pression du bouton. Ce principe est décrit dans sonnette.
- Ligne 2 : import de la fonction randint() qui permet de générer un nombre aléatoire entier borné en hait et en bas.
- Ligne 4 à 13 : mise en place de la détection du bouton (voir le projet sonnette).
- Ligne 14 : Déclaration de la liste LEDs contenant les instances de broches configurées en sortie. La première entrée de la liste LEDs[0] correspond au bit 2 (poids le plus fort). La deuxième entrée LEDs[1] correspond au bit 1. La troisième entrées LEDs[2] correspond au bit 0 (poids le plus faible). Il se fait que c'est aussi dans ce même ordre que bin() fournit les différents bits. En effet, bin(6) => "0b110" et si l'on retire le "0b" nous avons une chaîne de caractères "110" où "110"[0] est le bit de poids fort (bit 2) et "110"[2] est le bit de poids faible (bit 0).
Ressources
- Module random utilisé pour générer des valeurs aléatoires.
- Machine.Pin : cette ressource de MicroPython reprend, entre autre, la documentation sur les interruption et les broches.
- Développement avec interruption : cette ressource de MicroPython reprend de nombreuses recommandations concernant le développement de routines d'interruption avec MicroPython.
Traduction augmentée réalisée par Meurisse. D pour shop.MCHobby.be - Licence CC-BY-SA.