Aller au contenu

Chapitre 3.1 - Micro:bit⚓︎

0. Présentation de la carte BBC micro:bit⚓︎

BBC micro:bit est une carte à microcontrôleur conçue en 2015 au Royaume-Uni pour développer l'apprentissage de l'algorithmique et de la programmation.

La carte micro:bit dispose des spécificités techniques suivantes :

  • 25 LEDs programmables individuellement
  • 2 boutons programmables
  • Broches de connexion
  • Capteurs de lumière et de tempĂ©rature
  • Capteurs de mouvements (accĂ©lĂ©romètre et boussole)
  • Communication sans fil, via Radio et Bluetooth
  • Interface USB

1. "Hello world !", virtuellement ou IRL...⚓︎

1.1 À distance ? Pas de micro:bit ? le simulateur est là !⚓︎

Rendez-vous sur la page https://python.microbit.org/v/3

Effacez le code existant et collez-le code ci-dessous :

Python
from microbit import *

while True:
    display.scroll('Hello, World!')
    display.show(Image.HEART)
    sleep(2000)

Cliquez sur le bouton Play de la micro:bit virtuelle. C'est parti !

Pour Ă©viter des erreurs, fermez la fenĂŞtre de droite (le simulateur) Ă  chaque fois que vous modifiez votre code de la partie gauche.

1.2 Avec une micro:bit réelle⚓︎

Ouvrir le logiciel Mu. Au démarrage, choisir le mode BBC micro:bit. Brancher la carte Micro:bit sur un port USB.

2. Découverte des fonctionnalités⚓︎

2.1 Commandes de base de l'afficheur, matrice de 5x5 LEDs⚓︎

Voir vidéo explicative (en anglais)

LED signifie Light Emitting Diode, Diode Ă©lectroluminescente. La carte micro:bit en dispose de 25, toutes programmables individuellement, ce qui permet d'afficher du texte, des nombres et des images.

2.1.1 Afficher un texte "défilant" display.scroll(string, delay=400)⚓︎

Python
from microbit import *
display.scroll("NSI")
  • La première ligne de ce programme importe la bibliothèque de fonctions micro:bit. La deuxième ligne fait dĂ©filer un message Ă  l’écran. Cela n'arrive qu'une seule fois.

A faire

Exécuter le programme ci-dessus; Pour cela

  • Ecrire le programme ci-dessus puis flasher le programme sur la carte.

A faire

La vitesse de défilement peut être ralentie ou accélérée à l'aide du paramètre delay. L'unité est la milliseconde.

Python
from microbit import *
display.scroll("COROT", delay=20)

2.1.2 Afficher une "image" display.show(image)⚓︎

Exécuter le programme suivant:

Python
from microbit import *
display.show(Image.SAD)
Liste des images disponibles
Text Only
Image.HEART
Image.HEART_SMALL
Image.HAPPY
Image.SMILE
Image.SAD
Image.CONFUSED
Image.ANGRY
Image.ASLEEP
Image.SURPRISED
Image.SILLY
Image.FABULOUS
Image.MEH
Image.YES
Image.NO
Image.CLOCK12
Image.CLOCK11
Image.CLOCK10
Image.CLOCK9
Image.CLOCK8
Image.CLOCK7
Image.CLOCK6
Image.CLOCK5
Image.CLOCK4
Image.CLOCK3
Image.CLOCK2
Image.CLOCK1
Image.ARROW_N
Image.ARROW_NE
Image.ARROW_E
Image.ARROW_SE
Image.ARROW_S
Image.ARROW_SW
Image.ARROW_W
Image.ARROW_NW
Image.TRIANGLE
Image.TRIANGLE_LEFT
Image.CHESSBOARD
Image.DIAMOND
Image.DIAMOND_SMALL
Image.SQUARE
Image.SQUARE_SMALL
Image.RABBIT
Image.COW
Image.MUSIC_CROTCHET
Image.MUSIC_QUAVER
Image.MUSIC_QUAVERS
Image.PITCHFORK
Image.XMAS
Image.PACMAN
Image.TARGET
Image.TSHIRT
Image.ROLLERSKATE
Image.DUCK
Image.HOUSE
Image.TORTOISE
Image.BUTTERFLY
Image.STICKFIGURE
Image.GHOST
Image.SWORD
Image.GIRAFFE
Image.SKULL
Image.UMBRELLA
Image.SNAKE

Exercice 1

Créer un code qui permet d'afficher la totalité des images, pendant une demi-seconde chacune (grâce à l'instruction sleep(500) ). On utilisera la liste

Python
lst = [Image.HEART, Image.HEART_SMALL, Image.HAPPY, Image.SMILE,
    Image.SAD, Image.CONFUSED, Image.ANGRY, Image.ASLEEP, Image.SURPRISED, Image.SILLY,
    Image.FABULOUS, Image.MEH, Image.YES, Image.NO, Image.CLOCK12,
    Image.CLOCK11, Image.CLOCK10, Image.CLOCK9, Image.CLOCK8, Image.CLOCK7,
    Image.CLOCK6, Image.CLOCK5, Image.CLOCK4, Image.CLOCK3, Image.CLOCK2,
    Image.CLOCK1, Image.ARROW_N, Image.ARROW_NE, Image.ARROW_E, Image.ARROW_SE,
    Image.ARROW_S, Image.ARROW_SW, Image.ARROW_W, Image.ARROW_NW, Image.TRIANGLE,
    Image.TRIANGLE_LEFT, Image.CHESSBOARD, Image.DIAMOND, Image.DIAMOND_SMALL, Image.SQUARE,
    Image.SQUARE_SMALL, Image.RABBIT, Image.COW, Image.MUSIC_CROTCHET, Image.MUSIC_QUAVER,
    Image.MUSIC_QUAVERS, Image.PITCHFORK, Image.XMAS, Image.PACMAN, Image.TARGET, Image.TSHIRT,
    Image.ROLLERSKATE, Image.DUCK, Image.HOUSE, Image.TORTOISE, Image.BUTTERFLY, Image.STICKFIGURE,
    Image.GHOST, Image.SWORD, Image.GIRAFFE, Image.SKULL, Image.UMBRELLA, Image.SNAKE]

Correction
Python
from microbit import *

lst = [Image.HEART, Image.HEART_SMALL, Image.HAPPY, Image.SMILE,
    Image.SAD, Image.CONFUSED, Image.ANGRY, Image.ASLEEP, Image.SURPRISED, Image.SILLY,
    Image.FABULOUS, Image.MEH, Image.YES, Image.NO, Image.CLOCK12,
    Image.CLOCK11, Image.CLOCK10, Image.CLOCK9, Image.CLOCK8, Image.CLOCK7,
    Image.CLOCK6, Image.CLOCK5, Image.CLOCK4, Image.CLOCK3, Image.CLOCK2,
    Image.CLOCK1, Image.ARROW_N, Image.ARROW_NE, Image.ARROW_E, Image.ARROW_SE,
    Image.ARROW_S, Image.ARROW_SW, Image.ARROW_W, Image.ARROW_NW, Image.TRIANGLE,
    Image.TRIANGLE_LEFT, Image.CHESSBOARD, Image.DIAMOND, Image.DIAMOND_SMALL, Image.SQUARE,
    Image.SQUARE_SMALL, Image.RABBIT, Image.COW, Image.MUSIC_CROTCHET, Image.MUSIC_QUAVER,
    Image.MUSIC_QUAVERS, Image.PITCHFORK, Image.XMAS, Image.PACMAN, Image.TARGET, Image.TSHIRT,
    Image.ROLLERSKATE, Image.DUCK, Image.HOUSE, Image.TORTOISE, Image.BUTTERFLY, Image.STICKFIGURE,
    Image.GHOST, Image.SWORD, Image.GIRAFFE, Image.SKULL, Image.UMBRELLA, Image.SNAKE]

for img in lst:
    display.show(img)
    sleep(500)

Créer sa propre image⚓︎

Chaque pixel LED sur l’affichage physique peut prendre une parmi dix valeurs. Si un pixel prend la valeur 0 c’est qu’il est éteint. Littéralement, il a une luminosité de zéro. En revanche, s’il prend la valeur 9 il est à la luminosité maximale. Les valeurs de 1 à 8 représentent des niveaux de luminosité entre éteint (0) et « au maximum » (9).

Python
from microbit import *

bateau = Image("05050:"
               "05050:"
               "05050:"
               "99999:"
               "09990")

display.show(bateau)

2.1.3 Les pixels (display.set_pixel(x, y, val))⚓︎

Vous pouvez régler la luminosité des pixels de l'affichage individuellement de 0 (désactivé) à 9 (luminosité maximale). Pour des informations sur les coordonnées de l'affichage, voir le guide pour matrice à LED.

Exécuter le programme suivant:

Python
from microbit import *
display.set_pixel(1, 4, 9)

Exercice 2

Faire clignoter le pixel central.

Correction
Python
1
2
3
4
5
6
7
from microbit import *

while True:
    display.set_pixel(2, 2, 9)
    sleep(200)
    display.set_pixel(2, 2, 0)
    sleep(200)

Exercice 3

Faire afficher en boucle un pixel aléatoire pendant 200 ms.

Pour obtenir un entier pseudo-aléatoire, on utilisera la fonction randint du module random. Par exemple, l'instruction randint(2, 8) va renvoyer un nombre (pseudo-)aléatoire entre 2 et 8 inclus.

On pourra aussi utiliser l'instruction display.clear() pour Ă©teindre tout l'affichage.

Correction
Python
1
2
3
4
5
6
7
8
9
from microbit import *
from random import randint

while True:
    x = randint(0,4)
    y = randint(0,4)
    display.set_pixel(x, y, 9)
    sleep(200)
    display.clear()

2.4 Les entrées boutons A, B et A+B - programmation événementielle (vidéo explicative)⚓︎

image

Il y a deux boutons sur la face avant du micro:bit (étiquetés A et B). On peut détecter quand ces boutons sont pressés, ce qui permet de déclencher des instructions sur l'appareil.

Exemples avec le boutton A:

  • button_a.is_pressed(): renvoie True si le bouton spĂ©cifiĂ© est actuellement enfoncĂ© et False sinon.
  • button_a.was_pressed(): renvoie True ou False pour indiquer si le bouton a Ă©tĂ© appuyĂ© depuis le dĂ©marrage de l'appareil ou la dernière fois que cette mĂ©thode a Ă©tĂ© appelĂ©e.

Exemple : Essayer le programme suivant qui fait défiler le texte "NSI" indéfiniment. Dès qu'un bouton est pressé, on sort de la boucle break et le programme s'achève.

Python
from microbit import *
while True:
    display.scroll("NSI")
    sleep(200)
    if button_a.was_pressed():
        break
display.clear()
display.show(Image.SAD)

Exercice 4

Créer le code permettant de basculer d'un visage triste à un visage heureux suivant qu'on appuie sur A ou sur B.

Correction
Python
from microbit import *
while True:
    if button_a.was_pressed():
        display.show(Image.SAD)
    if button_b.was_pressed():
        display.show(Image.HAPPY)

Exercice 5

Créer le code permettant de déplacer un point vers la gauche ou vers la droite en appuyant sur A ou sur B.

Correction
Python
1
2
3
4
5
6
7
8
9
from microbit import *
x = 2
while True:
    display.clear()
    display.set_pixel(x, 2, 9)
    if button_a.was_pressed():
        x = x - 1
    if button_b.was_pressed():
        x = x + 1

Exercice 6

Même énoncé que l'exercice précédent, mais en faisant parcourir tout l'écran au pixel :

  • si on sort Ă  droite, on se dĂ©cale d'une ligne vers le bas et on revient tout Ă  gauche.
  • si on sort Ă  gauche, on se dĂ©cale d'une ligne vers le haut et on revient tout Ă  droite.
  • arrivĂ© tout en bas Ă  droite, on rĂ©apparaĂ®t en haut Ă  gauche (et rĂ©ciproquement).
Correction
Python
from microbit import *
x = 2
y = 2
while True:
    display.clear()
    display.set_pixel(x, y, 9)
    if button_a.was_pressed():
        x = x - 1
    if button_b.was_pressed():
        x = x + 1
    if x == 5:
        x = 0
        y = y + 1
    if x == -1:
        x = 4
        y = y - 1
    if y == 5:
        x = 0
        y = 0
    if y == -1:
        x = 4
        y = 4       

Exercice 7

On veut créer le jeu suivant :

  • au dĂ©marrage, un pixel alĂ©atoire est placĂ© sur l'Ă©cran.
  • il faut ensuite se dĂ©placer un point vers la gauche ou vers la droite en appuyant sur A ou sur B.
  • lorsque qu'on a rejoint le point alĂ©atoire, un emoji HAPPY apparait.

Correction
Python
from microbit import *
from random import randint

n = randint(0,4)
p = randint(0,4)

x = 2
y = 2

while True:
    display.clear()
    display.set_pixel(n, p, 9)
    display.set_pixel(x, y, 9)

    if button_a.was_pressed():
        x = x - 1

    if button_b.was_pressed():
        x = x + 1

    if x == 5:
        x = 0
        y = y + 1

    if x == -1:
        x = 4
        y = y - 1

    if y == 5:
        y = 0

    if y == -1:
        y = 4

    if x == n and y == p:
      display.show(Image.HAPPY)  
      break

Exercice 8

Rajout d'un temps limité

La fonction tick_ms du module utime renvoie le nombre de millisecondes écoulées depuis le démarrage de la carte. Pour mesurer le temps écoulé dans un programme, on fixe le temps du début du programme dans une variable t0. Il suffit d'observer ensuite la valeur de tick_ms() - t0 pour savoir combien de temps (en millisecondes) s'est écoulé depuis le début du programme.

Exemple (à exécuter pour comprendre !) :

Python
from microbit import *
from utime import *

display.show(Image.HAPPY)
t0 = ticks_ms()

while True:
    if ticks_ms() - t0 > 5000:
        display.show(Image.SAD)
        break

➡ Reprendre l'exercice précédent en rajoutant une difficulté supplémentaire avec un temps limité.

Correction
Python
from microbit import *
from random import randint
from utime import *

n = randint(0,4)
p = randint(0,4)

x = 2
y = 2

t0 = ticks_ms()

while True:
    if ticks_ms() - t0 > 5000:
    display.show(Image.SAD)
    break

    display.clear()
    display.set_pixel(n, p, 9)
    display.set_pixel(x, y, 9)

    if button_a.was_pressed():
        x = x - 1

    if button_b.was_pressed():
        x = x + 1

    if x == 5:
        x = 0
        y = y + 1

    if x == -1:
        x = 4
        y = y - 1

    if y == 5:
        y = 0

    if y == -1:
        y = 4

    if x == n and y == p:
    display.show(Image.HAPPY)
    break

Exercice 10

Créer un jeu de Pierre-Feuille-Ciseaux qui se déclenchera lorsqu'on secoue la Microbit. (Vous pouvez créer vos propres images de pierre, de feuille et de ciseaux)

La détection du "secouage" de la carte se fera avec l'instruction suivante :

Python
if accelerometer.was_gesture('shake'):
    ...

Correction
Python
from microbit import *
from random import randint

pierre = Image('09990:'
               '09009:'
               '09990:'
               '09000:'
               '09000')

feuille = Image('09999:'
               '09000:'
               '09990:'
               '09000:'
               '09000')

ciseaux = Image('00999:'
               '09000:'
               '09000:'
               '09000:'
               '00999')


while True:
    if accelerometer.was_gesture('shake'):
        v = randint(1,3)
        if v == 1:
            display.show(pierre)
        if v == 2:
            display.show(feuille)
        if v == 3:
            display.show(ciseaux)

Exercice 11

En utilisant les fonctions accelerometer.get_x() et accelerometer.get_y() de l'accéléromètre, créer un code qui allumera la LED du centre lorsque la carte est à l'horizontale, puis qui fera bouger cette LED en fonction de l'inclinaison de la carte.

Python
from microbit import *

def move(x, y):
    incx = accelerometer.get_x()
    if incx > 500:
        x += 1
        x = min(..., ...)
    if incx < -500:
        x -= 1
        x = max(..., ...)
    incy = accelerometer.get_y()
    if incy > 500:
        y += 1
        y = min(..., ...)
    if incy < -500:
        y -= 1
        y = max(..., ...)
    return x, y

x = 2
y = 2
while True:
    display.clear()
    ..., ...  = move(..., ...)
    display.set_pixel(..., ..., 9)
    sleep(200)    
Correction
Python
from microbit import *

def move(x, y):
    incx = accelerometer.get_x()
    if incx > 500:
        x += 1
        x = min(x,4)
    if incx < -500:
        x -= 1
        x = max(0,x)
    incy = accelerometer.get_y()
    if incy > 500:
        y += 1
        y = min(y,4)
    if incy < -500:
        y -= 1
        y = max(0,y)
    return x, y

x = 2
y = 2
while True:
    display.clear()
    x, y  = move(x, y)
    display.set_pixel(x,y,9)
    sleep(200)  

Exercice 12

Communication radio

Voici un code proposant une communication radio entre deux cartes. Inspirez-vous de ce code pour (par exemple) faire un «vrai» Pierre-Feuille-Ciseaux entre deux cartes.

Python
from microbit import *
import radio

radio.on()
radio.config(channel=12)
radio.config(power=7)

while True:
    message = radio.receive()
    if message:
        if message == 'yes':
            display.show(Image.YES)
            sleep(500)
            display.clear()
        elif message == 'no':
            display.show(Image.NO)
            sleep(500)
            display.clear()
    if button_a.was_pressed():
        radio.send('yes')
        display.show(Image.YES)
        sleep(500)
        display.clear()
    if button_b.was_pressed():
        radio.send('no')
        display.show(Image.NO)
        sleep(500)
        display.clear()

Plus de renseignements ici

Exercice 13

En utilisant l'exercice 10 et la communication radio, faire «passer» une led d'une carte à l'autre en inclinant la carte.

video

Correction

Carte 1

Python
from microbit import *
import radio

radio.on()
radio.config(channel=12)
radio.config(power=7)
hasBall = True
x = 2
y = 2

def move(x, y):
    incx = accelerometer.get_x()
    if incx > 500:
        x += 1
        x = min(x,5)
    if incx <-500:
        x -= 1
        x = max(0,x)
    incy = accelerometer.get_y()
    if incy > 500:
        y += 1
        y = min(y,4)
    if incy <-500:
        y -= 1
        y = max(0,y)
    return x, y

while True:
    if not hasBall:
        message = radio.receive()
        if message: 
            y = int(message)
            x = 4
            hasBall = True
    if hasBall:
        x, y = move(x, y)
        if x <= 4:
            display.clear()
            display.set_pixel(x, y, 9)
        if x == 5:
            radio.send(str(y))
            display.clear()
            hasBall = False         

    sleep(100)

Carte 2

Python
from microbit import *
import radio

radio.on()
radio.config(channel=12)
radio.config(power=7)
hasBall = False
x = 2
y = 2

def move(x, y):
    incx = accelerometer.get_x()
    if incx > 500:
        x += 1
        x = min(x,4)
    if incx <-500:
        x -= 1
        x = max(-1,x)
    incy = accelerometer.get_y()
    if incy > 500:
        y += 1
        y = min(y,4)
    if incy <-500:
        y -= 1
        y = max(0,y)
    return x, y

while True:
    if not hasBall:
        message = radio.receive()
        if message:     
            y = int(message)
            x = 0
            hasBall = True
    if hasBall:
        x, y = move(x, y)
        if x >= 0 :
            display.clear()
            display.set_pixel(x, y, 9)
        if x == -1:
            radio.send(str(y))
            display.clear()
            hasBall = False         

    sleep(100)