CentraleSupélec LMF, UMR CNRS 9021
Département informatique Laboratoire Méthodes Formelles
Bât Breguet, 3 rue Joliot-Curie Bât 650 Ada Lovelace, Université Paris Sud
91190 Gif-sur-Yvette, France Rue Noetzlin, 91190 Gif-sur-Yvette, France
Tutoriel Pyboard

Table des matières

La pyboard est une carte équipée d'un processeur STM32F4 et conçue pour le développement sous Micropython.

Elle est très facile à utiliser grâce à son système de fichiers (elle se comporte comme une clef USB quand on la branche) et son interpréteur python (accessible sur un port série) qui permet de prototyper très rapidement.

Premier contact

Pour programmer la pyboard, il suffit de disposer d'un éditeur de texte. Une fois la pyboard connectée à votre ordinateur, ouvrez le volume qui a dû apparaître (probablement sous le nom PYBFLASH). Vous devriez y trouver :

  • boot.py, qui contient le code exécuté au démarrage de la carte
  • main.py, qui contient le code exécuté après le démarrage
  • pybcdc.inf, driver de port série pour Windows
  • README.txt

Pour exécuter du code sur la pyboard, il suffit de le placer dans le fichier main.py d'éjecter le volume et de redémarrer la carte en appuyant sur son bouton RST.

Écrivez le code suivant dans le fichier main.py, enregistrez le fichier, éjectez le volume et faites redémarrer la pyboard :

Vous devriez voir les 4 LEDs de la carte s’allumer successivement.

La ligne 1 importe le module pyb qui permet d'accéder aux fonctionnalités de la pyboard. À la ligne 3, on utilise la classe pyb.LED qui gère les 4 LEDs de la pyboard. On construit notamment la liste de ces 4 LEDs (qui sont numérotées à partir de 1, d'où le +1 dans le constructeur de LED).

Ligne 4, on initialise la variable i, qui indique quelle LED doit être allumée, à 0 (ce qui correspond à la LED 1, qui est rouge). Les lignes 5 à 13 vont faire s'allumer successivement chacune des LEDs, i variant de 0 à 3 grâce à l'addition modulo 4 de la ligne 13. Les lignes 6 à 10 ont pour rôle d'allumer la LED choisie (celle qui correspond à i) et d'éteindre les 3 autres. La ligne 12 fait attendre 100ms, la ligne 13 fait passer à la LED suivante, en revenant à 0 si on dépasse 3.

%

Dans un terminal

Il est assez fastidieux de devoir éjecter le volume et de redémarrer la carte à chaque modification du code. De plus, pour expérimenter, il est plus agréable de pouvoir interagir avec l'interpréteur python. On va pour cela utiliser le port série de la carte.

Voyez les instructions du site officiel (en anglais) pour référence. Je donne ci-dessous ma version en français.

Ceci n'est plus nécessaire sous Windows X

Il faut tout d'abord installer le driver qui va permettre d'utiliser le port série USB de la pyboard. Ce driver se trouve sur le volume USB de la pyboard, c'est le fichier pybcdc.inf.

Pour l'installer, ouvrez le gestionnaire de périphériques et trouvez la pyboard dans la liste de périphériques (elle devrait être annotée par un symbole indiquant qu'elle ne fonctionne pas encore). Faites un clic droit, choisissez "Propriétés" et installez le driver en le choisissant manuellement (ne laissez pas Windows le rechercher automatiquement). Une fois l'installation terminée, regardez dans le gestionnaire de périphérique à quel port est associée la pyboard (par exemple COM4 ou COM12).

Pour vous connecter à la pyboard, il vous faut un émulateur de terminal. Le mieux est de télécharger PuTTY.

Vous n'avez plus qu'à vous connecter au port COM de la pyboard avec votre émulateur de terminal. Avec PuTTY, cliquez sur "Session" dans le panneau de gauche, puis sélectionnez "Serial" dans le panneau de droite, saisissez le port COM de la pyboard dans le champ "Serial Line", et finalement, cliquez sur "Open".

Vous pouvez également utiliser le script Powershell pyterm.ps1 disponible sur ce dépôt Github.

Si vous avez installé PuTTY et rshell (avec pip3 install rshell), cette video vous montre comment utiliser pyload et pyterm sous Windows X.

Notez bien que je ne suis pas un utilisateur régulier de Windows et que ces informations comportent peut-être des erreurs. Merci de me les signaler afin que je puisse corriger cette page.

Le port série apparaît automatiquement sur Mac comme /dev/tty.usbmodem<xyz>, où <xyz> est un entier, et comme /dev/ttyACM0 sous Linux. Vous pouvez utiliser screen, minicom ou picocom pour vous y connecter. Sous MacOS, picocom est le plus facile à utiliser et fonctionne également avec les cartes ESP32 sous Micropython.

Pour éviter de devoir chercher le nom du périphérique, j'utilise un script nommé pyterm qui me connecte à la première pyboard qu'il trouve.

pyterm est disponible sur ce dépôt Github

Exemple de session :

~ $ pyterm 
picocom v3.1

port is        : /dev/tty.usbmodem345D355133332
flowcontrol    : none
baudrate is    : 115200
parity is      : none
databits are   : 8
stopbits are   : 1
escape is      : C-a

... autres informations supprimées ...

Type [C-a] [C-h] to see available commands
Terminal ready

>>> 
ici, j'ai tapé Ctrl-D pour redémarrer la carte
MPY: sync filesystems
MPY: soft reboot
MicroPython v1.11 on 2019-05-29; PYBv1.0 with STM32F405RG
Type "help()" for more information.
>>> import pyb
>>> led = pyb.LED(1)
>>> led.on()
>>> led.off()
>>> 
ici, j'ai tapé Ctrl-A suivi de Ctrl-X pour quitter picocom
Terminating...
Thanks for using picocom
~ $ 

Ceci fonctionne également avec une carte ESP32 sous Micropython.

Executer un fichier Python

Plutôt que de taper directement du code Python dans l'interpréteur de la carte, il est souvent plus pratique d'éditer son code dans un fichier et de le faire exécuter ensuite par l'interpréteur de la carte.

Il existe pour cela une commande pyboard, mais il faut lui donner explicitement le périphérique sur lequel on souhaite exécuter le fichier. Par exemple pyboard --device /dev/cu.usbmodem3472354933332 mon_programme.py

De même que pour pyterm (voir plus haut), j'utilise un script pyload qui détecte les pyboards disponibles et utilise la première si aucune n'est précisée :

pyload est disponible sur ce dépôt Github

Ceci fonctionne également avec une carte ESP32 sous Micropython.

Une alternative, quand on programme une pyboard, est de copier le fichier sur la pyboard (elle apparaît comme un volume nommé PYBFLASH), puis de se connecter au REPL de la carte (avec pyterm par exemple) et de taper :

import moncode

si le fichier est moncode.py.

rshell

Rshell est un environnement de développement en ligne de commande pour MicroPython. Une traduction en français de sa documentation est disponible sur le wiki de MC Hobby

De même que pour les commandes picocom et pyboard, j'utilise un script pyrshell qui détecte les pyboards présentes et s'y connecte automatiquement.

pyrshell est disponible sur ce dépôt Github

Ceci fonctionne également avec une carte ESP32 sous Micropython. C'est d'ailleurs une manière simple d'accéder au système de fichier sur ESP32, car il n'apparaît pas comme un disque externe, contrairement à ce qui se passe avec la pyboard.

Pour installer Micropython sur une ESP32, consultez le tutoriel (en anglais).

Autres environnements

L'éditeur Mu Editor a un mode spécial pour MicroPython que vous pouvez essayer.

Quelques exemples

Je propose ici quelques exemple de code pour pyboard ou pour ESP32 sous MicroPython, qui ne font appel qu'au matériel disponible sur la carte. Vous n'aurez pas besoin d'accessoires, à part le cable USB pour connecter la carte à votre ordinateur.

Allumer et éteindre une LED LED

On utilise ici le bouton disponible sur la carte (USR sur la pyboard, BOOT sur l'ESP32) pour allumer la LED intégrée à la carte. La LED ne reste allumée que tant que l'on maintient le bouton enfoncé.

Cet exemple montre comment configurer les ports, lire et modifier leur état, sur la pyboard et l'ESP32 :

Allumer et éteindre une LED, autre version LED 2

On utilise ici le bouton disponible sur la carte (USR sur la pyboard, BOOT sur l'ESP32) pour allumer ou éteindre la LED intégrée à la carte à chaque fois que l'on appuie sur le bouton.

On fait ici simplement clignoter la LED intégrée à la carte. Cet exemple montre comment attendre l'écoulement d'une durée.

Faire clignoter une LED avec un timer LED et timer

On fait ici clignoter la LED intégrée à la carte à l'aide d'un timer. Cet exemple montre comment configurer un timer pour exécuter une tâche périodiquement.

Choisir la luminosité d'une LED avec la PWM LED et PWM

La modulation de largeur d'impulsion (Pulse Width Modulation en anglais) est une technique qui permet de faire varier la tension moyenne d'un signal binaire. Elle évite de recourir à un convertisseur numérique-analogique pour faire varier la puissance transmise à une LED ou à un moteur à courant continu.

Le principe est de faire varier le rapport cyclique (rapport du temps passé au niveau haut sur la période du signal) d'un signal de fréquence suffisamment élevée pour être imperceptible. Par exemple, à 5kHz, le clignotement d'une LED alimentée en PWM n'est pas perçu par l'œil. En faisant varier le rapport cyclique de 0% à 100%, on passe d'une LED éteinte à une LED allumée à sa luminosité maximale. Dans la réalité, la LED est allumée et éteinte 5000 fois par seconde, mais on ne perçoit que la luminosité moyenne, qui est proportionnelle au rapport cyclique. Il est d'ailleurs plus facile de choisir la luminosité de la LED en PWM qu'en réglant sa tension d'alimentation avec un convertisseur numérique-analogique, car la réponse de la luminosité en fonction de la tension n'est pas linéaire.

On fait ici varier périodiquement la luminosité de la LED intégrée en modifiant progressivement le rapport cyclique du signal PWM.

Allumer et éteindre la LED intégrée avec des interruptions Interruptions

Nous avons vu plus haut comment allumer et éteindre la LED intégrée à chaque fois qu'on appuie sur le bouton poussoir de la carte. Cette solution monopolise le processeur qui passe son temps à scruter l'état du bouton poussoir pour détecter les appuis. Elle peut être déléguée au matériel, qui peut nous prévenir automatiquement lorsque le signal d'une patte d'entrée passe de 1 à 0 (ou de 0 à 1, il suffit de choisir ce qui nous intéresse). Le processeur est alors déchargé de ce travail de scrutation et peut faire des choses plus utiles.

Le problème est de savoir comment le processeur est prévenu lorsque le matériel détecte un changement de valeur du signal sur une patte. C'est le mécanisme de traitement des interruptions qui va permettre au matériel de signaler un changement. Quand un changement de valeur pour lequel on a demandé à être prévenu se produit, le traitement que fait le processeur est interrompu, et il va exécuter le code d'une fonction que l'on aura indiquée.

Il y a des limites à ce que l'on peut faire dans cette fonction, et on ne peut notamment pas créer de nouveaux objets car il est possible que nous ayons interrompu le processeur alors qu'il était justement en train de créer un objet, et que la mémoire soit dans un état transitoire où le marquage des espaces libres et des espaces occupés n'est pas à jour. Il est malheureusement assez facile de créer des objets sans s'en rendre compte en Python, par exemple en faisant une division qui crée un flottant, on en ajoutant un élement à une liste ou un dictionnaire qui se redimensionne.

On se limitera donc à du code court qui fait peu de calculs et qui se contente de mettre à jour des variables globales.