Cet article résume les bases de la programmation d’une carte Pyboard officielle en langage MicroPython.
IDE de développement
Thonny reste un des meilleurs outils de développement pour les cartes microcontrôleurs sous MicroPython.
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
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
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.
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
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 brochepin
. - 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 :
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
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.
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.
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 cycliqueduty
. - 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