Premiers pas avec le Elecfreaks Pico:ed

Elecfreaks Pico Ed Micro

Le Pico:ed est une carte de développement basée sur le Raspberry Pi RP2040 (la puce utilisée sur le Raspberry Pi Pico) mais avec le facteur de forme du très réussi BBC micro:bit. La partie « ed » du nom signifie éducation.

L’avant de la carte arbore deux boutons, une LED cachée dans le point du « i » de « Pico » et un grand écran lumineux à matrice de points 7×17. L’arrière a un petit haut-parleur pour les tonalités et les bips, un bouton de démarrage pour mettre à jour l’appareil avec un fichier UF2 plus récent et une prise d’alimentation pour une batterie permettant une utilisation loin de l’ordinateur.

Elecfreaks Pico Ed

Le connecteur de bord permet à l’utilisateur de s’interfacer, via des pinces crocodiles ou une carte de dérivation de connecteur de bord, avec une grande variété de capteurs, d’écrans, de modules complémentaires micro:bit et de kits de démarrage tels que le kit de démarrage Elecfreaks micro:bit ou le kit Kitronik Inventor.

Le microprocesseur RP2040 bien pris en charge peut être programmé avec le langage MicroPython facile à apprendre et très populaire à l’aide de l’éditeur Thonny gratuit. Cela en fait un tableau de départ idéal pour ceux qui ne sont pas intéressés par la programmation avec des blocs. Il y a suffisamment de mémoire fournie avec 256 Ko de SRAM et 2 Mo de mémoire Flash pour des projets assez gros !

Ce tutoriel couvrira

  • Mise à jour de la carte en ajoutant la bibliothèque de périphériques
  • Clignotement de la LED intégrée
  • Utilisation des boutons
  • Affichage du texte et des chiffres sur l’écran
  • Jouer un morceau
  • Apprendre à contrôler les pixels individuels sur l’écran
  • Distance de détection avec un capteur infrarouge externe et affichage graphique de la valeur sur l’écran.
  • Connexion de potentiomètres pour contrôler l’affichage
  • Ajout d’un écran SSD1306 pour une sortie plus avancée

Ce dont vous aurez besoin

Commencer

Le fabricant fournit une documentation de démarrage sur leur site Web.

Le schéma de brochage montre que :

  • La LED unique est allumée GP25
  • Le bouton A est activé GP21
  • Le bouton B est activé GP22
  • GP0 à GP3 et GP17 à GP25 ne sont pas sortis

Le connecteur de bord a moins de broches physiques car certaines seront nécessaires pour piloter le buzzer sur GP0 ​​et l’affichage matriciel sur GP18/GP19 via I2C avec une adresse de puce de 0x74.

Le site explique comment télécharger le fichier compressé et enregistrer le programme du pilote de périphérique dans le dossier lib de votre Pico:ed. Après avoir suivi les instructions en jouant avec les exemples, nous avons fini avec les fenêtres de fichiers de Thonny ressemblant à ceci (ne vous embêtez pas à créer et à enregistrer le fichier Main.py pour le moment) :
Pico:ed Fenêtre Thonny

Exemples de programmes

Il y a 4 exemples très simples fournis par Elecfreaks pour vous aider à démarrer. Vous pouvez les copier depuis le site Web, les coller dans de nouvelles fenêtres de code, enregistrer, exécuter et expérimenter :

  • Contrôlez la LED par les boutons – Allumer / éteindre
  • Faire défiler les lettres et les chiffres via les boutons
  • Jouez quelques tonalités comme une mélodie
  • Connectez une LED externe et contrôlez via des boutons.

Malheureusement, il n’y a pas d’exemple sur la façon de contrôler l’affichage ! Nous devons pouvoir activer et désactiver des pixels individuels et contrôler la luminosité. Ceci n’est pas couvert par les exemples du fabricant, nous vous montrerons donc comment faire plus tard dans ce tutoriel !

Explorer les exemples

Nous devons examiner en détail le code de la bibliothèque pour voir si nous pouvons déterminer ce qui se passe dans chaque exemple. Vous pouvez imprimer le code directement depuis Thonny ou depuis l’IDE Python 3. Ce dernier affiche quelques commentaires supplémentaires dans la section « Musique »…

Musique

Ceci est l’exemple fourni, avec quelques commentaires mystérieux #’d dans une langue que nous ne maîtrisons pas !

Pico: ed commentaires de code en chinois

Il est temps pour Google de sauver la situation et de traduire les commentaires pour nous. Voici ce que nous avons trouvé :

  • self.buzzer.duty_u16(1000) #Ajustez la fréquence du PWM pour qu’il émette la tonalité spécifiée
  • self.buzzer.duty_u16(0) #Pas de mise sous tension lors de la prise de vue à vide
  • #Pause (deux tons par seconde en quatre ou quatre temps, avec une légère pause au milieu de chaque syllabe)
  • self.buzzer.duty_u16(0) #Le rapport cyclique de l’appareil est de 0, c’est-à-dire qu’il n’est pas sous tension
  • self.buzzer.deinit() #release PWM

Cela explique que la modulation d’onde d’impulsion (PWM) est utilisée pour générer une onde carrée pour produire des tonalités sur le haut-parleur. En regardant les fréquences données dans le dictionnaire des tonalités, nous voyons qu’il y a 7 notes en do majeur – commençant par le « do médian ».

self.tones = {'1': 262, '2': 294, '3': 330, '4': 349, '5': 392, '6': 440, '7': 494, '-': 0}

Le symbole ‘–’ fournit le silence. Il serait facile d’ajouter des tonalités/notes supplémentaires. Consultez les liens ci-dessous pour les fréquences requises :

Texte et chiffres pour l’affichage

Ici, nous remarquons que seuls les lettres, les caractères numériques et ‘l’espace’ sont définis dans un autre dictionnaire. La liste pour chaque caractère est les coordonnées des pixels composant cette lettre, en commençant par le haut :

"i":[[2,0], [1,2], [2,2], [2,3], [2,4], [2,5], [1,6], [2,6], [3,6]],
"j":[[3,0], [2,2], [3,2], [3,3], [3,4], [0,5], [3,5], [1,6], [2,6]],

Essayez de tracer ces coordonnées pour voir comment elles fonctionnent.

pixels

Voici le bloc de code dans le fichier d’exemple pour les pixels :

def pixel(self, x, y, color=None, blink=None, frame=None):
    if not 0 <= x <= self.width:
        return
    if not 0 <= y <= self.height:
        return
    pixel = self._pixel_addr(x, y)

La ligne du haut nous donne l’indice de l’instruction de base des pixels. Où (x, y) est la position du pixel par rapport au coin supérieur gauche de l’écran (0, 0) et c est la couleur/luminosité dans la plage de 0 à 255.

Notez que la procédure reviendra sans rien faire si la position donnée ne se rapporte pas à une LED physique sur l’affichage. Ceci est très utile – une instruction de pixel hors affichage ne provoquera pas d’erreur.

display.pixel(-3, 12, 5)

Cette instruction ne fera rien. La détection d’erreurs facilite grandement la programmation.

Un exemple de programme testant nos résultats

Nous vous suggérons de copier le programme ci-dessous et de le coller dans Thonny. Enregistrez-le sous GFX.py et exécutez-le. Le script comporte de nombreux commentaires pour vous aider à comprendre ce qui se passe.

Dans la section ‘bounce’, appuyer sur le bouton ‘A’ arrête la boucle en réinitialisant la variable en cours d’exécution sur False.

# Pico:ed GFX demonstration in 17x7 pixels
# By Thomas 30 April 2022 for raspberryme.com
from Pico_ed import *     #import Driver library
import utime
delay = 0.1

#Brightness
display.fill(1)  # Fill display with pale pixels
utime.sleep(2)
display.fill(10) # Fill display with brighter pixels
utime.sleep(2)

# Lines
display.fill(0) # clear the screen to BLACK
for i in range(7):  # Vertical line in column 0
    display.pixel(0,i, 10) # pixel ON
    utime.sleep(delay)
for i in range(7):  
    display.pixel(0,i, 0) # pixel OFF 
    utime.sleep(delay)
for i in range(17): # Horizontal line
    display.pixel(i,3, 10) # pixel ON
    utime.sleep(delay)
for i in range(17):
    display.pixel(i,3, 0) # pixel OFF
    utime.sleep(delay)

# Brightness 2
# Single pixel getting brighter
for i in range(255):
    display.pixel(3,3, i) 
    utime.sleep(0.01)
# Line of pixels getting brighter
step = int(255/16)
for i in range(i):
    display.pixel(i,5, i * step)
display.pixel(16,5, 255)
utime.sleep(2.5)
display.fill(0)

# Pretty edge - Some pixels off the screen without error
c = 10 # colour/brightness
for i in range(17):
    display.pixel(i,0, c)
    display.pixel(17-i,6, c)
    display.pixel(0,i, c)  
    display.pixel(16,7-i, c) 
    utime.sleep(0.1)
utime.sleep(1)

# Pixel Bounce
display.show("Pixel Bounce")
display.show("Press A to Halt")
dx = 1
dy = 1
running = True
x = 3
y = 3
while running:
    display.pixel(x,y, 10) # Current pixel ON
    utime.sleep(.05)
    oldx = x
    oldy = y
#    print(x,y) # Old debug help - slows down bouncing
# Update pixel position - not displayed yet
    x = x + dx
    if x  == 17:
        x = 15
        dx = -1
    if x == -1:
        x = 1
        dx = 1
    y = y + dy
    if y  == 7:
        y = 5
        dy = -1
    if y == -1:
        y = 1
        dy = 1
    display.pixel(oldx,oldy, 0) # Turn pixel OFF
    # Press button A to stop
    if ButtonA.is_pressed(): 
        running = False
display.fill(0)

display.show("Bye")
utime.sleep(2)
display.fill(0) # clear display

Remarques supplémentaires

  • La couleur est vraiment luminosité – tous les pixels sont ROUGES. 1 est un peu trop faible et 10 nous apparaît comme une norme utile. 255 est trop lumineux.
  • Le piégeage d’erreur pour les pixels hors écran fonctionne très bien – voir le Joli bord section.
  • Notez que dans la section de rebond, nous éclairons le pixel et enregistrons sa position actuelle dans vieuxx et vieux. Nous mettons ensuite à jour x et y et ne désactivons le pixel qu’au bas de la boucle. Le nouveau pixel est alors allumé au début de la boucle suivante. Un pixel est allumé plus longtemps qu’éteint.
  • Une instruction d’impression dans la fenêtre Shell de Thonny est très lente lors de l’exécution d’une boucle graphique. Essayez de décommenter : # print(x,y) # Ancienne aide de débogage – ralentit le rebond
  • L’affichage d’une chaîne de texte sur l’écran défile s’il y a plus de 3 caractères mais reste immobile avec 3 caractères ou moins

Exemple pratique – Capteur de distance IR

Ce capteur infrarouge simple est disponible à l’achat seul ou dans le cadre du pack de capteurs Waveshare.

Capteur IR Waveshare
Ce capteur a une LED Infra-Rouge comme émetteur et un récepteur Infra-Rouge dans l’extension noire de la carte. La tension sur la broche AOUT varie avec la quantité de lumière réfléchie dans le récepteur.

Si nous connectons AOUT à l’une des broches du convertisseur analogique-numérique sur la carte, nous obtenons une lecture qui change lorsque nous rapprochons et éloignons un morceau de papier blanc du capteur. La broche DOUT fournit une sortie 0/1 et le seuil est réglable avec le petit potentiomètre intégré. La LED bascule lorsque le seuil est dépassé. L’autre LED est un indicateur d’alimentation.

Nous avons utilisé une carte de dérivation Edge Connector pour faciliter le raccordement, mais vous pouvez utiliser des pinces crocodiles ou similaires. Projet de capteur infrarouge Pico:ed Le programme court ci-dessous nous a permis d’afficher un pixel se déplaçant sur l’écran pour représenter la distance entre le capteur et la feuille de papier :

# Pico:ed Infra Red  Sensor and GFX demonstration in 17x7 pixels
# By Thomas 30 April 2022 for raspberryme.com
from Pico_ed import *     #import Driver library
import utime
import machine
# Connections
#   VCC - 3.3V
#   GND - GND
#   AOUT - 0 = GP26 = ADC 0
adc = machine.ADC(26)
old_ir = 0
while True:
    ir = int(adc.read_u16()/3500)-1
    display.pixel(old_ir,3, 0) # pixel OFF
    display.pixel(ir,3, 10) # pixel ON
    old_ir = ir

Connexion de potentiomètres pour contrôler l’affichage Pico:ed

Essayez de connecter des potentiomètres 10k à votre carte Pico:ed pour contrôler les pixels ! Vous trouverez ci-dessous un schéma de câblage montrant comment les brancher.

Les couleurs sont les suivantes :

  • Rouge à ADC0
  • Vert à ADC1
  • Noir à GND
  • Orange à 3,3 volts

Connexions du potentiomètre Pico:ed

Choses à essayer

Utilisez les informations de ce didacticiel et d’autres ressources pour essayer de coder les suggestions suivantes. N’oubliez pas que vous avez un MCU Raspberry Pi Pico RP2040 standard sur la carte Pico:ed, donc la plupart des documents publiés (dans les livres et sur Internet) pour le Pico fonctionneront avec :

  • Contrôlez la position d’un pixel lumineux sur l’écran avec les deux potentiomètres. Utilisez-en un pour les valeurs horizontales (0-16) et l’autre pour les valeurs verticales (0-6).
  • Ajoutez au programme précédent pour créer un jeu. Dirigez le pixel pour « heurter » un pixel cible positionné au hasard avec une luminosité différente. Bip en cas de choc !
  • Chronométrez le temps que cela prend et affichez le temps.
  • Écrivez quelques airs supplémentaires.
  • Ajoutez des tonalités/notes supplémentaires dans le dictionnaire de la bibliothèque si nécessaire, comme des dièses et des bémols ou une portée accrue.
  • Afficher les nombres négatifs à l’écran. Comptez de – 20 à +20.
    • Méthode 1 : affichez un espace avant les chiffres puis dessinez le moins si nécessaire
    • Méthode 2 : ajouter un caractère moins au dictionnaire de caractères de la bibliothèque

Utilisation d’un écran graphique OLED SSD1306 avec le Pico:ed

Le populaire écran SSD1306 est disponible en deux tailles, 128×32 et 128×64 pixels et en plusieurs formats. Ils utilisent tous la même connexion i2c, avec seulement quatre fils.

  • VCC-3.3V
  • GND-GND
  • SDA-GP8
  • SCL-GP9

Nous devons installer une bibliothèque de pilotes. La page GitHub est iciou vous pouvez simplement téléchargez le fichier Python de la bibliothèque ici.

Ouvrez-le dans Thonny et enregistrez-le dans le dossier lib sur le Pico:ed en l’appelant ssd1306A.py afin qu’il n’entre pas en conflit avec l’autre pilote qui mai être là (car vous pourriez en avoir besoin pour un autre kit)

Python ssd1306 Thonny

Copiez maintenant le code ci-dessous et collez-le dans Thonny :

# ssd1306 OLED display on Pico:ed
# Thomas 2 May 2022 for raspberryme.com
# Code adapted from Pi Pico Micropython SDK
from machine import Pin, I2C
from ssd1306A import SSD1306_I2C
import framebuf

WIDTH  = 128   # oled display width
HEIGHT = 64    # oled display height

# Explicit Method
sda=machine.Pin(8)
scl=machine.Pin(9)
i2cA=machine.I2C(0,sda=sda, scl=scl, freq=2000000)

oled = SSD1306_I2C(128, 64, i2cA) # Adjust 64 to 32 if small display

# Raspberry Pi logo as 32x32 bytearray
buffer = bytearray(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|?\x00\x01\x86@\x80\x01\x01\x80\x80\x01\x11\x88\x80\x01\x05\xa0\x80\x00\x83\xc1\x00\x00C\xe3\x00\x00~\xfc\x00\x00L'\x00\x00\x9c\x11\x00\x00\xbf\xfd\x00\x00\xe1\x87\x00\x01\xc1\x83\x80\x02A\x82@\x02A\x82@\x02\xc1\xc2@\x02\xf6>\xc0\x01\xfc=\x80\x01\x18\x18\x80\x01\x88\x10\x80\x00\x8c!\x00\x00\x87\xf1\x00\x00\x7f\xf6\x00\x008\x1c\x00\x00\x0c \x00\x00\x03\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")

# Load the raspberry pi logo into the framebuffer (the image is 32x32)
fb = framebuf.FrameBuffer(buffer, 32, 32, framebuf.MONO_HLSB)

oled.fill(0) # Clear display
oled.blit(fb, 96, 15) # Blit raspberry to screeen

# Write some text to the screen
oled.text("Raspberry Pi",5,5)
oled.text("RP2040",29,15)
oled.text("Pico:ed",5,35)
oled.text("raspberryme.com",5,50)

oled.show()  # Update the screen

Tout est prêt ? Exécutez le code et vous devriez voir ceci :

Exemples OLED Pico:ed

Il existe une foule d’exemples de Raspberry Pi Pico utilisant ce petit écran sur le Web – il suffit de rechercher « Exemples de Pi Pico ssd1306 » et vous trouverez de nombreuses vidéos et projets.

Nous espérons que ce tutoriel vous a donné un aperçu de l’utilité de ce petit tableau ; à la fois pour un amateur novice et pour un usage éducatif dans les écoles. Si vous souhaitez passer du codage avec des blocs à MicroPython, cela pourrait être un excellent point de départ !

A propos de l’auteur

Cet article a été écrit par Thomas. Thomas est un professeur d’informatique à la retraite qui a commencé à écrire du code en 1968 alors que cela s’appelait programmation – il a commencé avec FORTRAN IV sur un IBM 1130 ! Membre actif de la communauté Raspberry Pi, ses principaux centres d’intérêt sont désormais le codage en MicroPython, les voyages et la photographie.