C’est un peu la version Pico du robot MOVE Motor que je vous ai présenté dans un article précédent. Le principe reste le même puisque le circuit imprimé sert toujours de châssis au robot. Mais comme nous le verrons, cette nouvelle version bénéficie également de nombreuses améliorations.

Le robot Autonomous Robotics Platform m’a été envoyé gratuitement par Kitronik pour que je puisse le tester. Toutefois je ne touche aucune forme de rémunération et bien sûr, je conserve une totale liberté pour écrire cet article.
Le robot est préassemblé, il suffit d’ajouter les bandes de caoutchouc aux roues et de mettre en place les différents éléments (bien sûr, le Raspberry Pico n’est pas fourni). Les capteurs de suivi de ligne et de détection d’obstacles sont amovibles. C’est plutôt une bonne chose puisque cela permet de modifier, réparer ou faire évoluer très facilement le robot.

Le montage ne présente aucune de difficultés, quelques instants plus tard vous obtenez un robot opérationnel.

Caractéristiques techniques
Le robot Autonomous Robotics Platform possède 4 LED RGD addressable, 2 moteurs, 1 interrupteur On/OFF, 1 bouton poussoir, 4 ports pour relier des servomoteurs 1 capteur de suivi de ligne et 2 emplacements pour le capteurs de distance à ultrasons (à l’avant et à l’arrière).

Le robot est alimenté par 4 piles AA. Vous pouvez bien sûr utiliser des piles rechargeables, mais j’aurai s préféré pouvoir utiliser une ou deux batteries de type 18650 (récupérées l’année dernière sur une batterie de trottinette).

J’ai aussi remarqué 3 emplacements qui acceptent des vis M3. Ils sont situés à l’avant et devraient permettre d’ajouter de futures extensions (par exemple un chassis ou une pince utilisant un servomoteur). Bien sûr, si vous êtes un peu bricoleur, vous pourrez très facilement concevoir vos propres accessoires…

Préparation du Raspberry Pico
Si vous n’êtes pas à l’aise avec les soudures, choisissez la version avec les connecteurs déjà soudé. Mais, ce n’est très difficile de le faire soi-même. C’est un peu moins cher et on peut choisir la couleur et le type de connecteur.

Téléchargez le dernier firmware MicroPython, que vous trouverez à cette adresse.
Pour l’installer connectez le Raspberry Pico à votre ordinateur en USB en laissant le doigt appuyé sur le bouton BOOTSEL. Déposez simplement le fichier téléchargé dans le lecteur USB RPI-RP2 qui apparait.
Téléchargez et installez Thonny (disponible à cette adresse), lancez le (sélectionnez le Mode Standard). Allez dans Outils – Options sélectionnez MicroPython (Raspberry Pi Pico) dans l’onglet Interpréteur.

Il faudra aussi installer la bibliothèque Kitronik. Il s’agit du fichier PicoAutonomousRobotics.py (que vous trouverez ici). Pour l’installer dans la mémoire du Raspberry Pico (depuis Thonny), allez dans Fichier – Ouvrir, sélectionnez Cet ordinateur ouvrez le fichier depuis son emplacement sur votre disque dur. Allez dans Fichier – Enregistrer sous… sélectionnez Raspberry Pi Pico, retapez le nom du fichier (PicoAutonomousRobotics.py) et cliquez sur OK pour lancer la copie.

Je ne vais par réexpliquer ici les bases de la programmation du Raspberry Pico sous MicroPython. Si vous n’êtes pas familiarisé avec l’utilisation de cette carte, je vous conseille de lire mon article de mon article de présentation du Raspberry Pico (ainsi que les autres articles consacrés au Pico). Jetez aussi un œil aux liens qui se trouvent à la fin de l’article, cela vous aidera à comprendre les exemples de code qui vont suivre.
LED RGB
Les LED sont numérotées de 0 à 3. Vous pouvez utiliser une des couleurs prédéfinies (RED, YELLOW, GREEN, CYAN, BLUE, PURPLE ou WHITE) ou la définir vous-même en indiquant la proportion de rouge, vert et bleu (RGB). Voilà par exemple comment allumer et éteindre les phares :
# Appel des bibliothèques
from PicoAutonomousRobotics import KitronikPicoRobotBuggy
from time import sleep
robot = KitronikPicoRobotBuggy()
# Fonctions
def eteindreTout():
for i in range(0, 4):
robot.clear(i)
robot.show()
def phares():
robot.setLED(0, (50, 50, 50)) # Blanc
robot.setLED(1, (50, 50, 50)) # Blanc
robot.setLED(2, (50, 0, 0)) # Rouge
robot.setLED(3, (50, 0, 0)) # Rouge
robot.show()
# Boucle infinie
while True:
phares()
sleep(1)
eteindreTout()
sleep(1)
Bouton poussoir
Le boutoir poussoir est programmable, vous pouvez par exemple l’utiliser pour allumer ou éteindre les phares.
# Appel des bibliothèques
from PicoAutonomousRobotics import KitronikPicoRobotBuggy
from time import sleep
robot = KitronikPicoRobotBuggy()
etatPhares = False
# Fonctions
def eteindreTout():
for i in range(0, 4):
robot.clear(i)
robot.show()
def phares():
robot.setLED(0, (50, 50, 50)) # Blanc
robot.setLED(1, (50, 50, 50)) # Blanc
robot.setLED(2, (50, 0, 0)) # Rouge
robot.setLED(3, (50, 0, 0)) # Rouge
robot.show()
# Boucle infinie
while True:
if robot.button.value() == True:
etatPhares = not etatPhares
sleep(0.300)
if etatPhares ==True:
phares()
else:
eteindreTout()
sleep(0.1)
Buzzer
Il est possible de klaxonner avec le Buzzer, mais aussi jouer un petit morceau de musique.
# Appel des bibliothèques
from PicoAutonomousRobotics import KitronikPicoRobotBuggy
from time import sleep
robot = KitronikPicoRobotBuggy()
# Fréquences des notes
re3 = 294
mi3 = 330
solb3 = 370
sol3 = 392
la3 = 440
si3 = 494
do4 = 523
re4 = 587
temps = 0.3
# Fonctions
def note(frequence, duree):
robot.soundFrequency(frequence)
sleep(duree)
robot.silence()
sleep(temps/16)
def marseillaise(): # Musique
note(re3, temps / 2)
note(re3, temps)
note(re3, temps / 2)
note(sol3, temps)
note(sol3, temps)
note(la3, temps)
note(la3, temps)
note(re4, temps * 2)
note(si3, temps / 2)
note(sol3, temps)
sleep(temps / 2)
note(sol3, temps / 2)
note(si3, temps)
note(sol3, temps / 2)
note(mi3, temps)
note(do4, temps * 2)
note(la3, temps)
note(solb3, temps / 2)
note(sol3, temps * 2)
robot.beepHorn() # Klaxon
# Boucle infinie
while True:
if robot.button.value() == True:
marseillaise()
sleep(0.1)
Moteurs
Vous pouvez très facilement contrôler les déplacements du robot en modifiant la vitesse et le sens de rotation des moteurs. En ajoutant un stylo au centre du robot, vous pouvez même dessiner des figures géométriques. Voilà par exemple comment faire un carré.
# Appel des bibliothèques
from PicoAutonomousRobotics import KitronikPicoRobotBuggy
from time import sleep
robot = KitronikPicoRobotBuggy()
# Fonctions
def phares():
robot.setLED(0, (50, 50, 50)) # Blanc
robot.setLED(1, (50, 50, 50)) # Blanc
robot.setLED(2, (50, 0, 0)) # Rouge
robot.setLED(3, (50, 0, 0)) # Rouge
robot.show()
def stop():
robot.motorOff("l") # Arret moteur gauche
robot.motorOff("r") # Arret moteur droit
def avant(vitesse, duree):
robot.motorOn("l", "f", vitesse) # Moteur gauche
robot.motorOn("r", "f", vitesse) # Moteur droit
sleep(duree)
stop()
def tourneGauche(vitesse, duree):
robot.motorOff("l") # Arret moteur gauche
robot.motorOn("r", "f", vitesse) # Moteur droit
sleep(duree)
stop()
def tourneDroite(vitesse, duree):
robot.motorOn("l", "f", vitesse) # Moteur gauche
robot.motorOff("r") # Arret moteur droit
sleep(duree)
stop()
def arriere(vitesse, duree):
robot.motorOn("l", "r", vitesse) # Moteur gauche
robot.motorOn("r", "r", vitesse) # Moteur droit
sleep(duree)
stop()
phares()
# Boucle infinie
while True:
if robot.button.value() == True:
# Carre
avant(80, 0.4)
tourneDroite(80, 0.32)
avant(80, 0.4)
tourneDroite(80, 0.32)
avant(80, 0.4)
tourneDroite(80, 0.32)
avant(80, 0.4)
tourneDroite(80, 0.32)
sleep(0.1)
Malheureusement, les moteurs ne possède pas suffisamment de force pour propulser le robot à vitesse réduite. Lorsqu’il est à l’arrêt, le robot est incapable de démarrer à une vitesse de 60 % (il émet un sifflement aigu). Cela réduit la vitesse de fonctionnement à une plage comprise entre 65 et 100 %.
A mon avis, le problème se situe au niveau du motoréducteur (le système d’engrenage relié au moteur), il faudrait jouer sur la démultiplication pour réduire la vitesse de rotation des roues. Ce qui permettrait d’augmenter leurs puissance (comme quand on change de vitesse sur un vélo).

Suivi ligne
Le module de suivi de ligne possède 3 capteurs (à gauche, au centre et à droite). Ils renvoient une valeur faible si le sol est clair et une valeur élevée si le le sol est foncé). Vous pouvez utiliser le code suivant pour pour tester les capteurs.
# Appel des bibliothèques
from PicoAutonomousRobotics import KitronikPicoRobotBuggy
from time import sleep
robot = KitronikPicoRobotBuggy()
# Boucle infinie
while True:
capteurGauche = robot.getRawLFValue("l")
capteurDroit = robot.getRawLFValue("r")
capteurCentral = robot.getRawLFValue("c")
print("Centre:", capteurCentral, " Gauche :",capteurGauche," Droit:",capteurDroit)
sleep(1)
Comme vous pouvez le voir dans cet exemple où les 3 capteurs sont situés au dessus d’une ligne noire, le capteur central renvoie des valeurs beaucoup plus faibles (apparemment ce serait dû à la lumière parasite des 2 autres capteurs).

À cause du problème de démultiplication (dont j’ai parlé un peu plus haut), le programme de suivi de ligne n’est pas facile à mettre au point. Le robot va un peu trop vite et il a parfois tendance à quitter la ligne. Le programme ci dessous est inspiré de la documentation de Kitronik. Il fonctionne, mais ne laissez jamais le robot sans surveillance parce qu’une sortie de piste reste quand même possible.
# Appel des bibliothèques
from PicoAutonomousRobotics import KitronikPicoRobotBuggy
from time import sleep
robot = KitronikPicoRobotBuggy()
# Fonctions
def phares():
robot.setLED(0, (50, 50, 50)) # Blanc
robot.setLED(1, (50, 50, 50)) # Blanc
robot.setLED(2, (50, 0, 0)) # Rouge
robot.setLED(3, (50, 0, 0)) # Rouge
robot.show()
def avant(vitesse):
robot.motorOn("l", "f", vitesse) # Moteur gauche
robot.motorOn("r", "f", vitesse) # Moteur droit
def tourneGauche(vitesse):
robot.motorOn("l", "r", vitesse)
robot.motorOn("r", "f", vitesse) # Moteur droit
def tourneDroite(vitesse):
robot.motorOn("l", "f", vitesse) # Moteur gauche
robot.motorOn("r", "r", vitesse)
phares()
# Boucle infinie
while True:
capteurGauche = robot.getRawLFValue("l")
capteurDroit = robot.getRawLFValue("r")
capteurCentral = robot.getRawLFValue("c")
if(capteurCentral < 20000):
if(capteurGauche < (capteurDroit)): #turn right
tourneDroite(75)
elif (capteurDroit < (capteurGauche)): #turn left
tourneGauche(75)
else:
avant(75)
sleep(0.01)

Détection d’obstacles
Le capteur de distance peut être placé à l’avant ou à l’arrière du robot, il renvoie la distance (en cm) qui le sépare d’un obstacle. Vous pouvez tester son fonctionnement avec le code suivant :
# Appel des bibliothèques
from PicoAutonomousRobotics import KitronikPicoRobotBuggy
from time import sleep
robot = KitronikPicoRobotBuggy()
# Boucle infinie
while True:
distanceAvant = robot.getDistance("f")
print("Distance:", distanceAvant)
sleep(1)
Si vous souhaitez brancher le capteur à l’arrière il faudra simplement utiliser le paramètre « r » à la place du « f« .

Voilà un petit exemple d’évitement d’obstacles :
# Appel des bibliothèques
from PicoAutonomousRobotics import KitronikPicoRobotBuggy
from time import sleep
from random import randint
robot = KitronikPicoRobotBuggy()
# Fonctions
def phares():
robot.setLED(0, (50, 50, 50)) # Blanc
robot.setLED(1, (50, 50, 50)) # Blanc
robot.setLED(2, (50, 0, 0)) # Rouge
robot.setLED(3, (50, 0, 0)) # Rouge
robot.show()
def avant(vitesse):
robot.motorOn("l", "f", vitesse) # Moteur gauche
robot.motorOn("r", "f", vitesse) # Moteur droit
def tourneGauche(vitesse):
robot.motorOn("l", "r", vitesse)
robot.motorOn("r", "f", vitesse) # Moteur droit
def tourneDroite(vitesse):
robot.motorOn("l", "f", vitesse) # Moteur gauche
robot.motorOn("r", "r", vitesse)
phares()
# Boucle infinie
while True:
distance = robot.getDistance("f")
if(distance < 10):
if (randint(0,1) == 0):
tourneDroite(70)
sleep(0.2)
else:
tourneGauche(70)
sleep(0.2)
else:
avant(70)
sleep(0.01)
Servomoteurs
Le robot possède aussi 4 ports destinés à accueillir des servomoteurs. Le pilotage est très simple, les ports sont numérotés de 0 à 3, il suffit donc d’indiquer leur numéro et l’angle que le servomoteur doit prendre.
Voilà par exemple comment contrôler le servomoteur SV0 :
# Appel des bibliothèques
from PicoAutonomousRobotics import KitronikPicoRobotBuggy
from time import sleep
robot = KitronikPicoRobotBuggy()
robot.goToPosition(0, 0) # Servomoteur n°0, angle 0°
sleep(0.5)
# Boucle infinie
while True:
if robot.button.value() == True:
for i in range(0,180):
robot.goToPosition(0, i)
sleep(0.01)
for i in range(180,0,-1):
robot.goToPosition(0, i)
sleep(0.01)

Vidéo de présentation du robot
Conclusion
Un très bon petit robot qui permet d’apprendre le MicroPython en s’amusant. Il manquerait simplement des batteries rechargeables et des moteurs qui fonctionnent à vitesse réduite, pour qu’il soit parfait. Espérons que ce problème soit corrigé dans une prochaine version…
Où l’acheter ?
- Autonomous Robotics Platform (Fiche produit Kitronik)
- Raspberry Pi Pico (Fiche produit Kitronik)
- Piste de suivi de ligne (Fiche produit Kitronik)
- Autonomous Robotics Platform (Fiche produit MCHobby)
- Raspberry Pi Pico (Fiche produit MCHobby)
- Raspberry Pi Pico Wireless (Fiche produit MCHobby)
Sources et liens utiles
- Documentation en français (traduite par MCHobby)
- Using the Motors (Documentation officielle Kitronik)
- Buzzer, Button and Lights (Documentation officielle Kitronik)
- Using the Line Following Sensors (Documentation officielle Kitronik)
- Using the Ultrasonic Sensor (Documentation officielle Kitronik)
- Using the Servo connections (Documentation officielle Kitronik)
- Bibliothèque Pico Autonomous Robotics (GitHub)
- Présentation du Raspberry Pico (Arduiblog)
- Getting started with Raspberry Pi Pico (Raspberry Pi Foundation)
- Firmware Raspberry Pico (MicroPython)