Les bases de Micropython pour la Pyboard

Cet article résume les bases de la programmation d’une carte Pyboard officielle en langage MicroPython.

Pyboard v1.1

Image : micropython.org

IDE de développement

Thonny reste un des meilleurs outils de développement pour les cartes microcontrôleurs sous MicroPython.

Thonny + Pyboard

Noms des broches

Sur la Pyboard, les broches de GPIO sont divisées en deux groupes symétriques de X1 à X12 et de Y1 à Y12. Un groupement supplémentaire est défini de X16 à X24.

En langage MicroPython, c’est la classe Pin  du module pyb qui a la charge de la gestion des broches d’entrée/sortie. Il est possible de lister le nom des broches de la carte de la manière suivante :

>>> dir(Pin.board)
['__class__', '__name__', '__bases__', 'LED_BLUE', 'LED_GREEN', 'LED_RED', 'LED_YELLOW', 'MMA_AVDD', 'MMA_INT',
'SD', 'SD_CK', 'SD_CMD', 'SD_D0', 'SD_D1', 'SD_D2', 'SD_D3', 'SD_SW', 'SW', 'USB_DM', 'USB_DP', 'USB_ID', 'USB_VBUS',
'X1', 'X10', 'X11', 'X12', 'X17', 'X18', 'X19', 'X2', 'X20', 'X21', 'X22', 'X3', 'X4', 'X5', 'X6', 'X7', 'X8', 'X9',
'Y1', 'Y10', 'Y11', 'Y12', 'Y2', 'Y3', 'Y4', 'Y5', 'Y6', 'Y7', 'Y8', 'Y9']

En résumé :

CPU Digitale Analogique Communication Timer
X1 PA0 Entrée/Sortie Entrée UART4 (TX) Timer 2 – CH1
X2 PA1 Entrée/Sortie Entrée UART4 (RX) Timer 2 – CH2
X3 PA2 Entrée/Sortie Entrée UART2 (TX) Timer 2 – CH3
X4 PA3 Entrée/Sortie Entrée UART2 (RX) Timer 2 – CH4
X5 PA4 Entrée/Sortie Entrée/Sortie SPI1 (/SS)
X6 PA5 Entrée/Sortie Entrée/Sortie SPI1 (SCK) Timer 2 – CH1
X7 PA6 Entrée/Sortie Entrée SPI1 (MISO)
X8 PA7 Entrée/Sortie Entrée SPI1 (MOSI) Timer 1 – CH1N
X9 PB6 Entrée/Sortie UART1 (TX) , I2C1 (SCL) Timer 4 – CH1
X10 PB7 Entrée/Sortie UART1 (RX) , I2C1 (SDA) Timer 4 – CH2
X11 PC4 Entrée/Sortie Entrée
X12 PC5 Entrée/Sortie Entrée

LED utilisateur

La carte intègre quatre LED utilisateur respectivement de couleurs rouge (LED(1)), verte (LED(2)),  jaune (LED(3)) et bleu (LED(4)).

from pyb import LED

led = LED(2)     # Déclaration de la LED Verte
led.on()         # Allume la LED
led.off()        # Etteint la LED
led.toggle()     # Change l'état de la LED

Sorties digitales

Schéma Pyboard + LED

L’exemple ci-dessous allume ou éteint une LED connectée à la broche X5.

from pyb import Pin

pin = Pin('X5', Pin.OUT)  # Pin.OUT = sortie "classique" (push-pull)
pin.on()                  # Impose un état haut (3,3 V)
pin.off()                 # Impose un état bas (0 V)

Entrées digitales

Lecture directe d’un niveau logique

Schéma Pyboard + Résistance tirage externe

Cet exemple utilise un bouton poussoir et une résistance de tirage vers le haut pour imposer un niveau logique (0 ou 1) sur l’entrée X5.

from pyb import Pin

pin = Pin('X5', Pin.IN) # Pin.IN = entrée
val = pin.value()       # Lecture état
print(val)              # Affichage

La méthode value() retourne le niveau logique (0 ou 1) de la broche en question.

Activer la résistance de tirage interne

Sur toutes les entrées digitales, deux résistances internes de tirage respectivement vers le haut (PULL_UP) et le bas (PULL_DOWN) sont activables. Ce qui simplifie, par exemple, la connexion d’un interrupteur ou d’un bouton poussoir.

Schéma Pyboard + Résistance tirage interne

from pyb import Pin

pin = Pin('X5', Pin.IN, Pin.PULL_UP) # D5 en entrée avec tirage vers le haut
val = pin.value()                    # Lecture état de D5
print(val)

Mesurer une durée d’impulsion

La programme ci-dessous montre comment mesurer la durée d’une impulsion à l’état haut sur l’entrée D13.

from machine import Pin, time_pulse_us

pin = Pin('X5', Pin.IN)      # Implusion sur entrée X5
duree = time_pulse_us(pin,1) # 0 = état bas et 1 = état haut
print(duree,"µs")            # Affichage

Entrées analogiques (12 bits)

Les entrées analogiques sont accessibles entre autres sur les broches X1 à X8.

Lecture directe

Schéma Pyboard + Potentiomètre

Une montage potentiométrique applique une tension réglable (de 0 à 3,3 V) sur l’entrée analogique X5.

from pyb import Pin, ADC

adc = ADC(Pin("X5")) # Déclaration d'un ADC sur la broche X5
N = adc.read()       # Lecture de la conversion de 0 à 4095 (12 bits)
print(N)             # Affichage
  • C’est la classe ADC qui gère les entrées analogiques.
  • Le constructeur ADC(pin) active une entrée analogique sur la broche pin.
  • La méthode read() retourne la valeur de la tension (entier entre 0 et 4095) sur l’entrée analogique concernée.

Affichage en volt

La tension correspondante s’obtient par la relation :

    \[U = N \times\dfrac{ V_{Ref}}{N_{max}}= N \times\dfrac{ 3,3 V}{4095}\]

from pyb import Pin, ADC

adc = ADC(Pin("X5")) # Déclaration de l'ADC sur la broche X5
Vcc = 3.288          # Valeur de la tension d'alimentation (3.3 V)
N = adc.read()       # Lecture de la conversion de 0 à 4095 (12 bits)
U = N*Vcc/4095       # Calcul de la tension
print(N, U)          # Affichage

Pour plus de précision, la tension Vcc a été mesurée au voltmètre.

Acquisition d’une série de mesures en fonction du temps

Seules les cartes Pyboard implémentent la méthode read_timed pour une lecture de plusieurs valeurs à une fréquence d’échantillonnage pouvant aller jusqu’à 750 kHz ! Cette mesure est cadencée par le timer 6 qui est réservé à la conversion analogique numérique.

from pyb import Pin, ADC, Timer
from array import array

f = 500                          # Fréquence d'échantillonnage (750 kHz max.)
N = 20                           # Nombre de points
mesures = array("h", N*[0xFFFF]) # Tableau de N x 16 bit pour stocker les mesures
                                 # "h" pour signed short (int 2 octets)

adc = ADC(Pin('X5'))             # Déclaration du CAN sur la broche X5

tim = Timer(6, freq=f)           # Le timer 6 fixe la fréquence d'échantillonnage f

adc.read_timed(mesures, tim)     # Lancement des mesures

print(mesures)                   # Affichage des mesures

A noter que la fréquence d’échantillonnage est calculée au plus proche de celle disponible par le timer. La méthode freq() de la classe Timer renvoie la fréquence réelle du timer.

Les lignes suivantes calculent les instants et les tensions mesurées dans deux listes respectives.

f = tim.freq()                     # Fréquence réelle du timer
t = [i*1/f for i in range(N)]      # liste des instants
u = [mesures[i] for i in range(N)] # liste des mesures de tension

print(t)                           # Affichage temps
print(u)                           # Affichage tension
Pyboard + Décharge condensateur

Exemple : décharge d’un condensateur à travers une résistance.

Sorties analogiques (12 bits)

La Pyboard compte deux convertisseurs numérique-analogique (CNA ou DAC) sur les broches X5 et X6. La tension est délivrée sur 8 bit (par défaut) ou 12 bit varie de 0 à 3,3 V.

Schéma Pyboard + CNA + Voltmètre

from pyb import DAC

dac = DAC(1)           # DAC 1 sur la broche X5
dac.write(128)         # Ecriture d'une valeur sur 8 bit

dac = DAC(1, bits=12)  # DAC 1 en 12 bit
dac.write(4095)        # Ecriture de la valeur maximale

Sortie PWM

La Pyboard ne dispose pas de fonction spécifique pour générer un signal PWM. Il faut donc le construire à partir d’un timer.

Schéma Pyboard + LED

Le programme suivant règle l’intensité d’une LED sur la broche X6. Il n’y a pas de timer sur X5 !

from pyb import Pin, Timer

led = Pin('X6', Pin.OUT_PP)              # X6 en sortie
tim = Timer(2, freq=500)                 # Timer 2 fixé à 500 Hz 
pwm = tim.channel(1, Timer.PWM, pin=led) # PWM sur la CH1 du timer 2
pwm.pulse_width_percent(33)              # Lancement du signal - Rapport cyclique = 33%
tim.freq(400)                            # Modification de la fréquence
  • La méthode pulse_width_percent(duty) génère le signal avec un rapport cyclique duty.
  • Contrairement à l’Arduino, il est possible ici de régler la fréquence du signal avec la méthode freq(value) appliquée sur le timer !

Port I2C

Bien que le module pyb dispose de sa propre classe I2C (plus évoluée), il est préférable d’utiliser le module machine qui est compatible avec toutes les cartes microcontrôleur fonctionnant sous MycroPython.

I2C matériel

Le premier port I2C est présent sur les broches SCL et SDA.

from machine import I2C

i2c = I2C(1)     # Port I2C sur X9 (SCL) et X10 (SDA)
rep = i2c.scan() # Recherche de périphériques
print(rep)       # Affichage des adresses trouvées

I2C logiciel

Il est possible mettre en oeuvre un bus I2C logiciel à partir de deux broches quelconques.

from machine import I2C

i2c = I2C(scl="X1", sda="X2") # Port I2C logiciel sur X1 et X2
rep = i2c.scan()              # Recherche de périphériques
print(rep)                    # Affichage des adresses trouvées
Pour marque-pages : Permaliens.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *