Voici les objectifs :
- animer les bonhommes de neige
- animer le père-noël dans la cheminée
- éclairer l'étoile de neige du sapin
- et passer de la musique de Noël pendant l'animation.
Avant cela, nous allons construire un petit coffre contenant toute l'informatique. Le fichier PDF sera bientôt disponible.
1.Le choix du micrologiciel
Nous aurions pu choisir MicroPython pour notre montage. Mais, je n'ai pas trouvé de module son satisfaisant pour jouer du mp3. Je me suis rapproché de la société Adafruit qui a développé son propre micrologiciel pour ses modules. J'utilise le module son Adafruit MAX98357 I2S Class-D Mono Amp. C'est un petit amplificateur mono.
2.Installation de CircuitPython
Il existe plusieurs méthodes pour installer CircuitPython. Nous allons voir les deux méthodes.
2a.Téléchargement du fichier uf2
Utilisez le lien suivant https://circuitpython.org/downloads . Vous avez deux types Pi Pico, le Pico sans Wifi et le Pico avec le module Wifi. Nous utiliserons le premier.
Cliquez sur Pico et télécharger le fichier UF2 de la dernière version stable.
Pour installer CircuitPython, brancher le Pi Pico sur un port USB de votre ordinateur et appuyer en même temps sur le bouton BOOTSEL. Normalement, une fenêtre s'affiche comme ci-dessous.
Il suffira de copier le fichier dans le dossier qui a été ouvert lors de la connexion en USB.
Une fois le fichier copié, le Pi Pico redémarre automatiquement avec CircuitPython. Si vous utilisez Thonny, l'invite de commande a changé, c'est celui de CircuitPython.
Il faudra indiquer à Thonny que vous utiliser CircuitPython. Cliquez sur le menu Tools -> Options. Cliquez sur l'onglet Interpreter et sélectionnez CircuitPython (generic)
Le Pi Pico fonctionne comme une clé USB, il se monte automatiquement et le nom du média s'appelle CIRCUITPY. Contrairement à MicroPython qui nous offre 1,4 Mo de stockage, nous n'aurons qu' 1 Mo de stockage.
2b.Utilisation du logiciel Thonny
Avant de lancer le logiciel Thonny, brancher le Pi Pico sur un port USB de votre ordinateur et appuyer en même temps sur le bouton BOOTSEL. Normalement, une fenêtre s'affiche comme ci-dessous.
Lancez le programme Thonny et cliquez sur le menu en bas à droite
Choisissez Install CircuitPython
Une boîte de dialogue s'affiche et choisissez le modèle de Pi Pico. Dans notre exemple, nous prenons le Pi Pico sans Wifi : le Raspberry Pi * Pico/Pico H version 1.21.0
Une fois le système, cliquez sur Close. Une fois le fichier copié, le Pi Pico redémarre automatiquement avec CircuitPython. Pour vérifier le bon fonctionnement du Pi Pico, cliquez sur le bouton rouge qui va redémarrer le système.
En bas de la fenêtre console, vous devriez voir ce message :
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
Press any key to enter the REPL. Use CTRL-D to reload.
Adafruit CircuitPython 8.2.9 on 2023-12-06; Raspberry Pi Pico with rp2040
soft reboot
]0;🐍REPL | 8.2.9\
Adafruit CircuitPython 8.2.9 on 2023-12-06; Raspberry Pi Pico with rp2040
>>>
Comme précédemment, il faudra modifier l'interpreter de Thonny pour CircuitPython.
3.Le programme pas à pas
3a. les servomoteurs des bonhommes de neige
Premier montage avec une platine d'essai et des fils jumper permettant des modifications rapides. Le bouton et la LED sont réunis dans un bouton confectionné en Lego.
le schéma
Nous devrons installer la librairie adafruit_motor pour utiliser les servomoteurs. Téléchargez le bundle des librairies CircuitPython avec ce lien https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/latest. Récupérez le dossier adafruit_motor et le copiez-le dans le Pi Pico dans le dossier lib comme ci-dessous.
Voici le premier code. Il diffère un peu de MicroPython. Le programme principal est composé d'une boucle infinie. La led du bouton clignote tant que l'on n'a pas appuyé sur le bouton. Une fois le bouton appuyé, on déclenche un scénario parmi les trois proposés grâce à la fonction random. A la fin du scénario, on revient à la boucle après une tempo de 3 secondes.
"""
CircuitPython diorama Noel 2023
deux servos bonhommes de neige
19/12/2023
"""
import board
import digitalio
import pwmio
from time import sleep
from adafruit_motor import servo
import time
import random
# create a PWMOut object on Pin GP4 and GP5
pwm1 = pwmio.PWMOut(board.GP4, duty_cycle=2 ** 15, frequency=50)
pwm2 = pwmio.PWMOut(board.GP5, duty_cycle=2 ** 15, frequency=50)
# Create servo object
# initialisation servo
my1_servo = servo.Servo(pwm1)o
my2_servo = servo.Servo(pwm2)
# initialisation LED Bouton
led_button = digitalio.DigitalInOut(board.GP16)
led_button.direction = digitalio.Direction.OUTPUT
# initialisation bouton
button = digitalio.DigitalInOut(board.GP17)
button.switch_to_input(pull=digitalio.Pull.DOWN)
# LED bouton allumé
led_button.value = True
# Positionnement des servos
my2_servo.angle = 1
my1_servo.angle = 6
# Boucle principale
while True:
if button.value:
led_button.value = False
choix = random.randint(0, 2)
if choix == 0:
j = 0
for i in range(35):
my1_servo.angle = 58
sleep(0.25)
my2_servo.angle = 1
sleep(0.25)
my1_servo.angle = 6
sleep(0.25)
my2_servo.angle = 50
sleep(0.25)
elif choix == 1:
for i in range(35):
my1_servo.angle = 58
sleep(0.25)
my1_servo.angle = 6
sleep(0.25)
my2_servo.angle = 1
sleep(0.25)
my2_servo.angle = 50
sleep(0.25)
else:
for i in range(35):
my1_servo.angle = 58
my2_servo.angle = 1
sleep(0.5)
my1_servo.angle = 6
my2_servo.angle = 50
sleep(0.5)
#temporisation de 3 secondes
sleep(3)
else:
led_button.value = True
sleep(0.2)
led_button.value = False
sleep(0.2)
3b. Le Père Noël et le sapin
Continuons avec le troisième servomoteur qui actionne le Père Noël dans la cheminée et l'éclairage de l'étoile dans le sapin. On rajoute quelques connexions à notre montage
le schéma
Première modification du code, on rajoute le troisième servo et l'on active la fonction PWM pour la LED du sapin.
"""
CircuitPython diorama Noel 2023
deux servos bonhommes de neige
un servo pour le Père Noël
Lumière sapin de Noël
19/12/2023
"""
import board
import digitalio
import pwmio
from time import sleep
from adafruit_motor import servo
import time
import random
# create a PWMOut object on Pin GP4 and GP5
pwm1 = pwmio.PWMOut(board.GP4, duty_cycle=2 ** 15, frequency=50)
pwm2 = pwmio.PWMOut(board.GP5, duty_cycle=2 ** 15, frequency=50)
pwm3 = pwmio.PWMOut(board.GP8, duty_cycle=2 ** 15, frequency=50)
# Create servo object
# initialisation servo
my1_servo = servo.Servo(pwm1)
my2_servo = servo.Servo(pwm2)
my3_servo = servo.Servo(pwm3)
# led sapin
ledsapin = pwmio.PWMOut(board.GP6, frequency=1000, duty_cycle=0, variable_frequency=True)
# initialisation LED Bouton
led_button = digitalio.DigitalInOut(board.GP16)
led_button.direction = digitalio.Direction.OUTPUT
# initialisation bouton
button = digitalio.DigitalInOut(board.GP17)
button.switch_to_input(pull=digitalio.Pull.DOWN)
# LED bouton allumé
led_button.value = True
# Positionnement des servos
my2_servo.angle = 1
my1_servo.angle = 6
my3_servo.angle = 0
# Extinction du sapin
ledsapin.duty_cycle = 0
# Boucle principale
while True:
if button.value:
led_button.value = False
choix = random.randint(0, 2)
if choix == 0:
j = 0
for i in range(35):
my3_servo.angle = 51
ledsapin.duty_cycle = i * 1870
my1_servo.angle = 58
sleep(0.25)
my2_servo.angle = 1
sleep(0.25)
my1_servo.angle = 6
sleep(0.25)
my2_servo.angle = 50
my3_servo.angle = 0
sleep(0.25)
elif choix == 1:
for i in range(35):
my3_servo.angle = 51
ledsapin.duty_cycle = 65535
my1_servo.angle = 58
sleep(0.25)
ledsapin.duty_cycle = 0
my1_servo.angle = 6
sleep(0.25)
ledsapin.duty_cycle = 65535
my2_servo.angle = 1
sleep(0.25)
ledsapin.duty_cycle = 0
my2_servo.angle = 50
my3_servo.angle = 0
sleep(0.25)
else:
for i in range(35):
my3_servo.angle = 51
duty = random.randint(0, 100)
ledsapin.duty_cycle = int((duty/100)*65535)
my1_servo.angle = 58
my2_servo.angle = 1
sleep(0.5)
duty = random.randint(0, 100)
ledsapin.duty_cycle = int((duty/100)*65535)
my1_servo.angle = 6
my2_servo.angle = 50
my3_servo.angle = 0
sleep(0.5)
ledsapin.duty_cycle = 0
#temporisation de 3 secondes
sleep(3)
else:
led_button.value = True
sleep(0.2)
led_button.value = False
sleep(0.2)
3c. Le son
Nous ajoutons le module son MAX98357. C'est un petit module ampli alimenté en 5 v. Nous ajouterons un mini haut-parleur.
le schéma
Nous rajouterons un fichier mp3 dans le Pi Pico comme ci-dessous
Voici la deuxième modification du code. J'ai ajouté une fonction playmp3, simple à première vue, mais qui servira surtout pour le dernier montage.
"""
CircuitPython diorama Noel 2023
deux servos bonhommes de neige
un servo pour le Père Noël
Lumière sapin de Noël
gestion du son
19/12/2023
"""
import board
import digitalio
import pwmio
from time import sleep
from adafruit_motor import servo
import time
import random
# bibliotèque son
import audiomp3
import audiobusio
# create a PWMOut object on Pin GP4 and GP5
pwm1 = pwmio.PWMOut(board.GP4, duty_cycle=2 ** 15, frequency=50)
pwm2 = pwmio.PWMOut(board.GP5, duty_cycle=2 ** 15, frequency=50)
pwm3 = pwmio.PWMOut(board.GP8, duty_cycle=2 ** 15, frequency=50)
# Create servo object
# initialisation servo
my1_servo = servo.Servo(pwm1)
my2_servo = servo.Servo(pwm2)
my3_servo = servo.Servo(pwm3)
# led sapin
ledsapin = pwmio.PWMOut(board.GP6, frequency=1000, duty_cycle=0, variable_frequency=True)
# initialisation LED Bouton
led_button = digitalio.DigitalInOut(board.GP16)
led_button.direction = digitalio.Direction.OUTPUT
# initialisation bouton
button = digitalio.DigitalInOut(board.GP17)
button.switch_to_input(pull=digitalio.Pull.DOWN)
# LED bouton allumé
led_button.value = True
# Positionnement des servos
my2_servo.angle = 1
my1_servo.angle = 6
my3_servo.angle = 0
# Extinction du sapin
ledsapin.duty_cycle = 0
#initialisation carte audio
audio = audiobusio.I2SOut(board.GP0, board.GP1, board.GP2)
def playmp3():
name_mp3 = audiomp3.MP3Decoder(open("son.mp3", "rb"))
audio.play(name_mp3)
# Boucle principale
while True:
if button.value:
led_button.value = False
playmp3()
choix = random.randint(0, 2)
if choix == 0:
j = 0
for i in range(35):
my3_servo.angle = 51
ledsapin.duty_cycle = i * 1870
my1_servo.angle = 58
sleep(0.25)
my2_servo.angle = 1
sleep(0.25)
my1_servo.angle = 6
sleep(0.25)
my2_servo.angle = 50
my3_servo.angle = 0
sleep(0.25)
elif choix == 1:
for i in range(35):
my3_servo.angle = 51
ledsapin.duty_cycle = 65535
my1_servo.angle = 58
sleep(0.25)
ledsapin.duty_cycle = 0
my1_servo.angle = 6
sleep(0.25)
ledsapin.duty_cycle = 65535
my2_servo.angle = 1
sleep(0.25)
ledsapin.duty_cycle = 0
my2_servo.angle = 50
my3_servo.angle = 0
sleep(0.25)
else:
for i in range(35):
my3_servo.angle = 51
duty = random.randint(0, 100)
ledsapin.duty_cycle = int((duty/100)*65535)
my1_servo.angle = 58
my2_servo.angle = 1
sleep(0.5)
duty = random.randint(0, 100)
ledsapin.duty_cycle = int((duty/100)*65535)
my1_servo.angle = 6
my2_servo.angle = 50
my3_servo.angle = 0
sleep(0.5)
ledsapin.duty_cycle = 0
#temporisation de 3 secondes
sleep(3)
else:
led_button.value = True
sleep(0.2)
led_button.value = False
sleep(0.2)
3d. La banque son avec le module SD
Le Pi Pico permet de stocker des fichiers, mais le stockage devient vite insuffisant lorsque l'on veut utiliser de nombreux fichiers sons. Nous allons ajouter un module lecteur de carte SDRam comme ci-dessous.
le schéma complet
Et voici le code complet. On a ajouté l'initialisation du module SD ainsi que le montage du système de fichier. La fonction playmp3 s'est enrichie de 13 sons choisis aléatoirement.
"""
CircuitPython diorama Noel 2023
deux servos bonhommes de neige
un servo pour le Père Noël
Lumière sapin de Noël
gestion du son
gestion carte SD
19/12/2023
"""
import board
import digitalio
import pwmio
from time import sleep
from adafruit_motor import servo
import time
import random
# bibliothèque son
import audiomp3
import audiobusio
# bibliothèque storage
import busio
import sdcardio
import storage
# create objet sdcardio
MOSI = board.GP11
MISO = board.GP12
clk = board.GP10
cs = board.GP15
spi = busio.SPI(clk, MOSI=MOSI, MISO=MISO)
sd = sdcardio.SDCard(spi, cs)
# montage carte SD
vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')
# create a PWMOut object on Pin GP4 and GP5
pwm1 = pwmio.PWMOut(board.GP4, duty_cycle=2 ** 15, frequency=50)
pwm2 = pwmio.PWMOut(board.GP5, duty_cycle=2 ** 15, frequency=50)
pwm3 = pwmio.PWMOut(board.GP8, duty_cycle=2 ** 15, frequency=50)
# Create servo object
# initialisation servo
my1_servo = servo.Servo(pwm1)
my2_servo = servo.Servo(pwm2)
my3_servo = servo.Servo(pwm3)
# led sapin
ledsapin = pwmio.PWMOut(board.GP6, frequency=1000, duty_cycle=0, variable_frequency=True)
# initialisation LED Bouton
led_button = digitalio.DigitalInOut(board.GP16)
led_button.direction = digitalio.Direction.OUTPUT
# initialisation bouton
button = digitalio.DigitalInOut(board.GP17)
button.switch_to_input(pull=digitalio.Pull.DOWN)
# LED bouton allumé
led_button.value = True
# Positionnement des servos
my2_servo.angle = 1
my1_servo.angle = 6
my3_servo.angle = 0
# Extinction du sapin
ledsapin.duty_cycle = 0
#initialisation carte audio
audio = audiobusio.I2SOut(board.GP0, board.GP1, board.GP2)
def playmp3():
choix = random.randint(0, 12)
if choix == 0:
name_mp3 = audiomp3.MP3Decoder(open("/sd/son01.mp3", "rb"))
elif choix == 1:
name_mp3 = audiomp3.MP3Decoder(open("/sd/son02.mp3", "rb"))
elif choix == 2:
name_mp3 = audiomp3.MP3Decoder(open("/sd/son03.mp3", "rb"))
elif choix == 3:
name_mp3 = audiomp3.MP3Decoder(open("/sd/son04.mp3", "rb"))
elif choix == 4:
name_mp3 = audiomp3.MP3Decoder(open("/sd/son05.mp3", "rb"))
elif choix == 5:
name_mp3 = audiomp3.MP3Decoder(open("/sd/son06.mp3", "rb"))
elif choix == 6:
name_mp3 = audiomp3.MP3Decoder(open("/sd/son07.mp3", "rb"))
elif choix == 7:
name_mp3 = audiomp3.MP3Decoder(open("/sd/son08.mp3", "rb"))
elif choix == 8:
name_mp3 = audiomp3.MP3Decoder(open("/sd/son09.mp3", "rb"))
elif choix == 9:
name_mp3 = audiomp3.MP3Decoder(open("/sd/son10.mp3", "rb"))
elif choix == 10:
name_mp3 = audiomp3.MP3Decoder(open("/sd/son11.mp3", "rb"))
elif choix == 11:
name_mp3 = audiomp3.MP3Decoder(open("/sd/son12.mp3", "rb"))
elif choix == 12:
name_mp3 = audiomp3.MP3Decoder(open("/sd/son13.mp3", "rb"))
audio.play(name_mp3)
# Boucle principale
while True:
if button.value:
led_button.value = False
playmp3()
choix = random.randint(0, 2)
if choix == 0:
j = 0
for i in range(35):
my3_servo.angle = 51
ledsapin.duty_cycle = i * 1870
my1_servo.angle = 58
sleep(0.25)
my2_servo.angle = 1
sleep(0.25)
my1_servo.angle = 6
sleep(0.25)
my2_servo.angle = 50
my3_servo.angle = 0
sleep(0.25)
elif choix == 1:
for i in range(35):
my3_servo.angle = 51
ledsapin.duty_cycle = 65535
my1_servo.angle = 58
sleep(0.25)
ledsapin.duty_cycle = 0
my1_servo.angle = 6
sleep(0.25)
ledsapin.duty_cycle = 65535
my2_servo.angle = 1
sleep(0.25)
ledsapin.duty_cycle = 0
my2_servo.angle = 50
my3_servo.angle = 0
sleep(0.25)
else:
for i in range(35):
my3_servo.angle = 51
duty = random.randint(0, 100)
ledsapin.duty_cycle = int((duty/100)*65535)
my1_servo.angle = 58
my2_servo.angle = 1
sleep(0.5)
duty = random.randint(0, 100)
ledsapin.duty_cycle = int((duty/100)*65535)
my1_servo.angle = 6
my2_servo.angle = 50
my3_servo.angle = 0
sleep(0.5)
ledsapin.duty_cycle = 0
#temporisation de 3 secondes
sleep(3)
else:
led_button.value = True
sleep(0.2)
led_button.value = False
sleep(0.2)
Ce tuto est terminé, j'espère qu'il vous a plu.