Démarrer sous Linux

Dans cette section figurent les instructions pour installer installer les firmwares disponibles en téléchargement sur le site officiel de la fondation MicroPython pour n’importe quelle carte (supportée) de STMicroelectronics. La cible principale des exemples et tutoriels disponibles sur ce site reste cependant la carte NUCLEO-WB55.

Outils nécessaires à l’installation de MicroPython : Il est nécessaire d’utiliser un ordinateur Windows avec une machine virtuelle Linux installée ou un ordinateur exécutant Linux directement.

Pour obtenir une machine virtuelle : Vous trouverez une machine virtuelle « Polytech » en suivant ce lien. Allez dans la catégorie « Ressources pour programmer le STM32 sur un ordinateur personnel », puis en cliquant sur « Avec VirtualBox ».

Installation de MicroPython sur une carte à microcontrôleur de ST à l’aide d’un ordinateur Linux

Depuis le bureau Linux, ouvrez un terminal en faisant Clic Droit puis « Ouvrir un terminal ici ». Entrez ensuite les commandes suivantes, une par une, afin d’installer les logiciels pré-requis.

sudo apt-get install git
sudo apt-get install make
sudo apt-get install gcc
sudo apt-get install gcc-arm-none-eabi

Entrez votre mot de passe lorsque celui-ci vous est demandé. Appuyez sur la touche « o » pour accepter l’installation lorsque cela vous sera demandé. Une fois les logiciels pré-requis installés, il est nécessaire de récupérer le projet MicroPython depuis l’outil Git en écrivant dans un terminal (ouvert depuis un dossier où sera placé l’utilitaire pour MicroPython) les commandes suivantes :

git clone https://GitHub.com/Micropython/MicroPython
cd ~/MicroPython
git submodule update --init
cd mpy-cross
make
cd ../ports/stm32

Vous pouvez maintenant effectuer la commande suivante :

make BOARD={your-board-model}

Il est nécessaire de remplacer {your-board-model} par le nom de la carte STM32 utilisée. Par exemple, si vous utilisez une carte NUCLEO-WB55, il sera nécessaire d’écrire la commande :

make BOARD=NUCLEO_WB55

Une liste des cartes de STMicroelectronics pour lesquelles un firmware MicroPython a été développé est disponible ici.

  • Il est possible que la commande make ne fonctionne pas comme voulu, dans ce cas il faut ajouter :
make BOARD={your-board-model} PYTHON=python3
  • Vous avez réussi cette étape si le terminal affiche :

make-board.png

Les commandes précédentes ont permis de générer un dossier nommé build-{your– board–model} disponible dans /Micropython/ports/stm32 (le dossier MicroPython se trouve là où vous avez ouvert le terminal).

Ouvrez l’explorateur de fichier pour récupérer ce dossier. Il contient un fichier avec une extension .hex, il s’agit du moteur MicroPython que nous allons flasher dans le STM32.

Pour cela, nous utiliserons STM32CubeProgrammer téléchargeable ici et choisir STM32CubePrg-Lin pour Linux. Vous devrez vous créer un compte myST.

Ouvrez un terminal et entrez les commandes suivantes :

sudo apt-get install libusb-1.0.0-dev

Extrayez l’archive téléchargée, puis exécutez SetupSTM32CubeProgrammer-x.y.z.linux (x,y,z varient selon la version) Laissez-vous guider par l’installeur.

Entrez ensuite dans un terminal la commande :

sudo cp ~/STMicroelectronics/STM32Cube/STM32CubeProgrammer/Drivers/rules/*.* /etc/udev/rules.d

STM32CubeProgrammer est maintenant installé.

Ouvrez alors le fichier .hex (1) dans STM32CubeProgrammer et connectez la carte Nucleo à l’ordinateur. Sur le logiciel, cliquez sur connect (2) puis download (3) et enfin verify (3). Si vous rencontrez une erreur lors de la connexion, essayez de rebrancher le câble ou changez de port USB.

cube-programmer.png

Le code est flashé sur la carte si on observe un message de succès de vérification. Vous avez alors réussi à installer MicroPython sur une carte STM32.

Premiers codes en MicroPython

Ouvrez un terminal série comme gtkterm ou PuTTY. Choisissez le port série correspondant à votre carte STM32 (/dev/ttyACM0 sur Linux), avec une vitesse de 115200. Vous devriez alors observer après avoir appuyé sur le bouton RESET noir un message similaire :

reset-button.png

Il est alors possible d’utiliser le terminal comme un interpréteur Python, il s’agit de l’interpréteur interactif MicroPython nommé REPL. Entrez maintenant les lignes suivantes pour tester le langage Python :

print(« Hello World »)
for i in range (10) :

Vous remarquerez que les inscriptions >>> sont devenues ... après la seconde commande, cela est normal car la notion d’indentation est très importante dans le langage Python contrairement à d’autres langages comme le C par exemple. Entrez alors par la suite print(i) puis appuyez sur la touche Entrée trois fois vous observez alors :

print-i.png

Nous avons alors créé une variable nommée i et nous l’avons incrémentée jusqu’à la valeur 9. Entrez help() pour avoir quelques commandes propres au langage MicroPython.

Utilisation du logiciel Geany pour lire un programme MicroPython

Nous savons maintenant comment programmer en MicroPython sur un STM32 à partir d’un terminal série. Cela peut alors devenir contraignant dans le cas d’un programme de plusieurs dizaines de lignes car il faut alors écrire ligne après ligne en prenant compte de l’indentation du langage Python. Nous allons alors « automatiser » l’outil de développement Geany de manière à « compiler » un programme écrit en MicroPython.

Dans un premier temps, il est nécessaire d’installer le logiciel Geany ; entrez cette commande sur un terminal :

sudo apt-get install geany

Récupérez ensuite le fichier pyboard.py. Il se trouve dans le dossier téléchargé MicroPython/tools/. Ce fichier contient un programme écrit en langage Python permettant d’envoyer les programmes MicroPython à la carte Nucleo depuis un poste fixe. Créez un répertoire sur votre ordinateur et déposez le fichier pyboard.py dedans. Il faut alors configurer le logiciel Geany. Après avoir ouvert le logiciel, allez dans le menu Construire > Définir les commandes de construction pour ajouter un nouveau bouton nommé MicroPython dans la partie Commandes d'exécution. Dans le champ suivant, écrivez :

python pyboard.py --device '/dev/ttyACM0' "%f"**

Vous devez obtenir :

geany-compilateur.png

Vous pouvez à présent créer un fichier du nom de votre choix avec une extension .py (créez un document texte et ajoutez manuellement .py) et le placer dans le répertoire que vous venez de créer. Ouvrez-le avec Geany puis exécuter ce programme avec Construire > MicroPython.

Ce tutoriel est terminé, vous pouvez écrire un script et l’exécuter depuis Geany !

Travaux pratiques avec MicroPython

Dans un premier temps nous allons voir comment allumer une LED. Pour cela, écrivez le code ci-dessous directement sur un émulateur série ou sur l’IDE Geany :

from pyb import LED
led = LED(1)
led.on()

Ce code permet d’allumer la LED utilisateur de votre microcontrôleur, cette LED est généralement de couleur verte.

  • Il est très important de commencer un programme MicroPython pour STM32 avec l’importation de la bibliothèque pyb ou d’une de ces composantes (LED, Pin, ExtInt, Timer .Etc). Ajouter en début (première ligne) de votre programme :
import pyb

Introduction aux entrées/sorties :

from pyb import Pin

p_out = Pin('PA5', Pin.OUT_PP) # LED verte correspondant à LED(1)
p_out.high() # p_out.low() pour éteindre la LED

p_in = Pin('PC13', Pin.IN, Pin.PULL_UP)
p_in.value() # prend la valeur 0 ou 1

La LED utilisateur doit s’allumer ici aussi. La fonction p_in.value() doit retourner et afficher un bit prenant la valeur 0 ou 1 suivant l’état de PC13 (généralement le bouton poussoir utilisateur).

Nous avons appris à allumer une pin en sortie et à lire la valeur d’une pin en entrée, nous allons à présent voir comment générer une PWM. On utilise la modulation de largeur d’impulsion (MLI) ou Pulse Width Modulation (PWM) lorsque l’on veut générer un signal pseudo-analogique depuis une source numérique. Les signaux PWM ont pour caractéristique :

  • Une fréquence, qui désigne la vitesse à laquelle le signal a effectué un cycle complet (10Hz → 10 cycles par seconde).
  • Un rapport cyclique (Duty Cycle) qui correspond à la durée à l’état haut sur la période du signal

duty-cycle-examples.png

Illustration : Wikipedia

Avant de générer une PWM, il est impératif de savoir si la broche du microcontrôleur STM32 que nous voulons utiliser est compatible avec cette modulation et également le numéro du timer (ainsi que son canal) utilisé pour la modulation. Par exemple, la pin PA5 généralement reliée à la LED utilisateur sur une majorité de cartes Nucleo peut être relié électriquement au Timer 2 canal 1 sur d’autres cartes.

Dans ce cas, le code pour faire clignoter cette LED avec une PWM de fréquence 1Hz et avec un rapport cyclique de 50% sera :

from pyb import Pin, Timer
LED = Pin('PA5') # PA5 --> TIM2, CH1
tim = Timer(2, freq=1)
ch = tim.channel(1, Timer.PWM, pin=LED)
ch.pulse_width_percent(50) # DutyCycle de 50%

Le rapport cyclique est de 0,5 sur une fréquence de PWM de 1Hz, la LED est donc allumé durant 500 millisecondes et éteinte durant 500 millisecondes également.

Une liste de bouts de codes MicroPython est disponible ici.

Attention : Ces codes ne sont pas encore tous compatibles avec les microcontrôleurs STM32, ils sont destinés à la carte Pyboard (une carte d’expérimentation programmable nativement en MicroPython).

Pour la carte NUCLEO-WB55 qui nous intéresse en particulier et pour le firmware distribué sur ce site, la liste des broches PWM disponibles, et les Timers / Channels associés pour le firmware distribué est la suivante :

  • A3 : TIM2_CH1
  • A2 : TIM2_CH2
  • D0 : TIM2_CH4
  • D1 : TIM2_CH3
  • D3 : TIM1_CH3
  • D5 : TIM2_CH1
  • D6 : TIM1_CH1
  • D9 : TIM1_CH2
  • D11 : TIM17_CH1
  • D12 : TIM16_CH1
  • D13 : TIM2_CH1
  • D14 : TIM17_CH1
  • D15 : TIM16_CH1

Voici un exemple de code adapté mettant en œuvre la PWM pour la carte NUCLEO-WB55 et toujours pour le firmware distribué sur ce site :

# Objet du Script :
# L'intensité de la LED cesse de varier après un premier appui sur le bouton sw1
# Elle recommence à varier après un second appui sur sw1.
# Utilisation des interruptions externes pour gérer le bouton.
# Matériel (en plus de la carte NUCLEO-WB55) : une LED connectée sur D6 et GND

from pyb import Pin, Timer, ExtInt
import time

# Initialisation du bouton SW1
sw1 = pyb.Pin( 'SW1' , pyb.Pin.IN)
sw1.init(pyb.Pin.IN, pyb.Pin.PULL_UP, af=-1)

# gestion interruption du bouton
button_pressed = False

def callback(line):
#    print("line =", line)
    global button_pressed
    button_pressed = not button_pressed

ext = ExtInt(Pin('SW1'), ExtInt.IRQ_RISING, Pin.PULL_UP, callback)

# initialisation de la PWM
p = Pin('D6')
ti = 1
ch = 1
tim = Timer(ti, freq=1000)
ch = tim.channel(ch, Timer.PWM, pin=p)
i=0

while True:
    if button_pressed :
        while i < 101: # augmente l'intensité de la LED par pas de 1%
            ch.pulse_width_percent(i)
            i=i+1
            time.sleep_ms(10) # pause de 10 ms

        while i > 0: # réduit l'intensité de la LED par pas de 1%
            ch.pulse_width_percent(i)
            i=i-1
            time.sleep_ms(10) # pause de 10 ms

Références