Fortement inspiré des documents de JOËL RIVET.

1. Téléchargement, installation, connexion

  1. Téléchargez et installez la dernière version de Thymio Suite 2.4.0 : https://www.thymio.org/fr/telecharger-thymio-suite/
  2. Connectez le robot Thymio : Câble USB.
  3. Lancez Thymio Suite et sélectionnez l'icône Thonny à droite.
  4. Sélectionnez un robot en cliquant dessus.
  5. Sélectionnez le bouton en bas de la page.
  6. L'interface de Thonny apparaît.

2. Premiers pas avec Thymio

2.1. Variables

Taper dans la zone de script (en haut à gauche) le code :
motor_left_target = 500
motor_right_target = 500
puis cliquer sur le petit bouton "play" à droite dans la barre d'outils.
Pour arrêter le robot, cliquer sur le bouton "stop" .

Taper dans la zone de script (en haut à gauche) le code :
motor_left_target = 500
motor_right_target = -500

2.2. Fonctions

Taper dans la zone de script :
nf_leds_top(32, 16, 0)
Thymio se colore en orange. Le code est en RVB et les limites sont de 0 à 32 pour chaque couleur.

Colorer Thymio en cyan, violet (magenta à dominante bleue) puis en blanc.
Combiner un déplacement et des LEDS allumées.
Faire vérifier par le professeur.
Pour finir cette rapide introduction, déterminons si quelque chose se trouve davant le robot.
Taper dans la zone de script :
print(prox_horizontal[2])
Lancer l'exécution du programme. S'il n'y a rien devant le robot, dans la console en bas à gauche, doit s'afficher le nombre 0.
Placer votre main davant le robot et lancer à nouveau le programme précéent. Cette fois-ci, on devrait voir s'afficher un nombre aux alentours de 3000.

3. Capteurs de proximité et les moteurs : le piéton

On se propose de créer ce petit script qui évoque le comportement Mon véhicule autonome : S'il n'y a pas d'obstacle devant le robot, il avance. Sinon, il s'arrête. On peut imaginer que l'obstacle est un piéton qui passe devant le robot. Ce script utilise le capteur de proximité avant central de Thymio ainsi que les moteurs des 2 roues. Avant de détailler les propriétés des capteurs et moteurs, réalisons le script en python. La première des choses à faire est de définir une variable pour la vitesse. Elle peut aller de 0 à 500.
speed = 100 # ne pas mettre de valeur non entière
Pour une fonction liée aux capteurs de proximité :
@onevent
def prox():

3.1. Fonctionnement des capteurs de proximité

Chaque capteur émet un rayonnement infra-rouge. Si un obstacle se trouve devant, une partie du rayonnement revient dans le capteur, qui détecte alors un signal qui peut monter jusqu'à 5000 (unité arbitraire). S'il n'y a rien devant, le rayonnement ne revient pas et le signal vaut alors 0. Ce signal est stocké dans un tableau de 7 éléments nommé en python prox_horizontal. La figure montre que par exemple, le capteur avant central correspond à la variable prox_horizontal[2].
Le capteur arrière droit à la variable prox_horizontal[6.]
La limite de détection est d'environ 11 cm.
On traite le cas où le capteur central ne détecte rien, avec un seuil de détection fixé arbitrairement à 3500 (vous pouvez changer ce seuil pour tester). Le robot avance à la vitesse speed.
if prox_horizontal[2] < 3500:
 motor_left_target = speed
 motor_right_terget = speed
la variable motor_left_target fixe la vitesse de rotation du moteur gauche, motor_right_target celle du moteur droit. Puis on traite le cas où un obstacle est détecté (valeur du capteur >= 3500).
else:
 motor_left_target = 0
 motor_right_target = 0
La fréquence d'appel à la fonction prox, donc la fréquence à laquelle les vitesse sont ajuster est de 10Hz, soit toutes les 100ms.
Dernière étape :
On recense dans la fonction les variables qui sont en écriture (var = ...) et on les déclare globales au début de la fonction :
@onevent
def prox():
 global motor_left_target, motor_right_target
Détection d'obstacles
Reprendre le programme précédent en modifiant le comportement.
Si un objet se trouve devant, Thymio recule.
Si un objet se trouve plutôt d'un côté, Thymio l'évite en tournant de l'autre.
Si un obstacle est capté par un des 2 capteurs arrière, il avance. Dans le cas où il ne capte rien, il reste â l'arrêt.
Pour simplifier, on n'envisagera pas les cas où plusieurs de ces situations se présentent simultanément. Par exemple, s'il y a à la fois un objet devant et un derrière.
Faire vérifier par le professeur.

4. Des boutons et des LEDs

4.1. Les boutons

Thymio dispose de 5 boutons.
  • bouton central (0 sur la figure) : button_center
  • bouton gauche (1 sur la figure) : button_left
  • bouton avant (2 sur la figure) : button_forward
  • bouton droit (3 sur la figure) : button_right
  • bouton arrière (4 sur la figure) : button_backward
Chaque variable peut prendre 2 valeurs :
  • la valeur 1 quand un doigt appuie sur un bouton,
  • la valeur 0 dans le cas contraire.

4.2. Les LEDs

Thymio possède :
  • 3 LEDS RVB (1 dessus, 2 dessous) dont la couleur est programmable.
  • 1 cercle de 8 LEDs jaunes autour des boutons.
  • d’autres LEDs liées aux capteurs et actionneurs, moins utiles pour le programmeur.

4.3. Programmation des LEDs : utiliser une fonction

On peut modifier une couleur avec la fonction nf_leds_top(r, v, b) qui prend en paramètres 3 antiers : r, v et b représentant les composantes rougre, verte ou blues. Ils varient entre 0 et 32 inclus.
Soit le script :
@onevent
def buttons():
 global nf_leds_top
 if button_left == 1:
 nf_leds_top(32, 0, 0)
La fonction buttons() étant parcourue 20 fois par seconde, si on appuie sur le bouton gauche if button_left == 1 est évalué à vrai et les LEDs du dessus s'allume en rouge.
Il est facile de compléter le script pour que :
  • Si on appuie sur le bouton avant, les LEDs du dessus s'allument en rouge en vert.
  • Si on appuie sur le bouton droit, les LEDs du dessus s'allument en rouge en bleu.
  • Si on appuie sur le bouton central, les 3 couleurs sont activées, sur le bouton arrière, les LEDs s’éteignent
Mais comment procéder si on veut utiliser d'autre couleurs ?
Chaque entier compris entre 0 et 32, représente une composante rouge, verte, bleu d'une couleur. Par exemple, si on désire produire la lumière orange, on écrira leds_top = [32, 16, 0].
ROUGE [32, 0, 0] VERT [0, 32, 0] BLEU [ 0, 0, 32] CYAN [ 0, 32, 32] MAGENTA[ 32, 0, 32] JAUNE [ 32, 32, 0] NOIR [ 0, 0, 0] BLANC [ 32, 32, 32]
Toutes les couleurs !
Nous souhaitons écrire un programme qui permette d'afficher les 32768 nuances de couleurs possibles.
Une approche consiste à partir du noir [0, 0, 0] et d'augmenter par par de 1 la valeur d'une composante en appuyant sur un bouton jusqu'à 32. Avec 3 buoutons, on couvre toutes les nuances.
Pour commencer, on initialise 3 variables à 0 :
r = 0
v = 0
b = 0
Assignons à chaque bouton un rôle :
  • En appuyant sur le bouton gauche, on augmente la composante rouge.
  • En appuyant sur le bouton avant, on augmente la composante verte.
  • En appuyant sur le bouton droit, on augmente la composante bleu.
  • En appuyant sur le bouton arrière, on réinitialise tout à 0.
Faire vérifier par le professeur.

5. Des minuteurs et des sons

5.1. Les sons de Thymio

Thymio a plusieurs moyens de produire des sons:
  • Comme pour les couleurs, il y a des sons système au nombre de 8.
  • Il y a aussi un générateur d'onde de synthèse qui peut jouer un son musical pour une durée donnée.
  • Le système peut aussi lire des sons enregistrés sur une carte micro SD logeable à l'arrière du Thymio. On peut même enregistrer de l'audio avec le micro et le rediffuser.
La qualité de l'ensemble reste modeste eu égard au microprocesseur et au système audio embarqué.
Les 8 sons systèmes :
  • -1 : arrête de jouer un son
  • 0 : son de démarrage
  • 1 : son d'arrêt (son non reconfiguration)
  • 2 : son des boutons fléchés
  • 3 : son du bouton central
  • 4 : son de chute libre (peureux)
  • 5 : son de choc
  • 6 : son de suivi d'objet
  • 7 : son de détection d'objet pour suivi
Tester les différents sons.
Le générateur peut jouer un son continu de fréquence et de durée variable.
La fréquence peut varier de 55 Hz environ à quelques milliers de Hz. Mais l'onde qui sert de source au générateur est très courte, ce qui fait que dans les aigus, le repliement de fréquence altère profondément le son.
La durée est exprimée en 1/60 de seconde.
Exemple :Produire la note la3 (440Hz) pendant 1/2 seconde (30/60) s'écrit : nf_sound_freq(440, 30)

5.2. Les minuteurs

Un paramètre que n'avons pas encore abordé, très important dans la programmation événementielle est le temps.
Pour gérer le temps, nous avons 2 minuteurs appelés timer0 et timer1 accessibles grâce à :
  • une variable (élément d'un tableau) : timer_period[0] ou timer_period[1]
  • une fonction liée à un événement : timer0() ou timer1()
On commence par définir la durée du compte à rebours du minuteur.
Soit par exemple timer_period[0] = 2000 # en ms. Cette affectation peut être placée n'importe où dans le code.
A partir du moment où le code lit cette instruction, le compte à rebours commence, indépendamment du reste du code qui poursuit son exécution de son côté. On parle de mode asynchrone.
Quand le compte à rebours se termine (ici au bout de 2000 ms soit 2s), le code va déclencher un événement et exécuter la fonction timer0() (qui devra être précédée par un décorateur). ll faut garder à l'esprit, qu'étant en mode asynchrone, cet appel de fonction interrompra toute exécution du code, quel qu'elle soit.
@onevent
def timer0():
 code à exécuter
Camion de pompier
Transformons le robot Thymio en camion de pompier avec son famaux "pin pon" en 440Hz et 394Hz. Le cahier des charges est simple : Thymio doit avancer en émettent sa sirène.

6. Détecter un choc

Un choc n'est rien de plus qu'une brutale variation d'accélération et donc l'accéléromètre y est sensible.
La fonction correspondante à cet évènement est :
@onevent
def tap():
Contrairement aux autres fonctions qui sont appelées en boucle, cette fonction est exécutée seulement en cas de choc.
Exemple : Le robot s'allumine en orange en cas de choc avec le code :
@onevent
def tap():
 nf_leds_top(32, 16, 0)

Ecrire un script qui fait démarrer le robot avec une petite tape. Le robot émet également le son système de démarrage et se colore en jaune.
Une nouvelle tape doit l'arrêter en éteignant les LEDs et en émettant le son système d'arrêt du robot.
Faire vérifier par le professeur.

7. Capteur de sol

Thymio possède en plus de ses capteurs horizontaux 2 capteurs situés dessous à l'avant.
On accède à leur mesures par 2 variables prox_ground_delta[0] (capteur gauche) et prox_ground_delta[1] (capteur droite). Ce sont les 2 éléments du tableau prox_ground_delta.

Leur domaine de valeurs est un peu plus restreint : [0, 1000]. Ils fonctionnent comme les autres par réflexion d'un rayon infra-rouge. Donc :
  • Si le sol du dessous du robot est blanc, réflexion maximale, prox_ground_delta[0 ou 1] prend une valeur proche de 1000.
  • Si le sol du dessous du robot est très noir ou absent (on tient le robot retourné en l'air), réflexion minimale ou nulle, prox_ground_delta[0 ou 1] prend une valeur proche de 0.
Suivi de ligne
On suppose que Thymio se trouve sur une ligne courbe noire de 4cm de largeur environ. L'état des capteurs sol va conditionner les actions à effectuer :
capteur
gauche
capteur
droit
situationaction
noirnoirle robot est sur la lignetout droit
noirblancle reobot sort de la ligne par la droite tourner légèrement à gauche
blancnoir le robot sort de la ligne par la gauchetourner légèrement à droite
blanc blanc le robot est complètement sorti de la ligne pivoter pour reprendre la ligne
Voici le code à compléter en changeant les variables afin d'optimiser le temps mis pour effectuer le parcours:
speed = 150
@onevent
def prox():
 global motor_left_target, motor_right_target
 if prox_ground_delta[0] < 400 and prox_ground_delta[1] < 400: # les 2 capteurs sont sur la ligne noire
 motor_right_target =speed
 motor_left_target =speed
 elif prox_ground_delta[0] < 400 and prox_ground_delta[1] >400:# le capteur gauche est sur la ligne mais pas le droit
 motor_left_target = -speed//5
 motor_right_target = speed
 elif prox_ground_delta[0] > 400 and prox_ground_delta[1] < 400:# le capteur droit est sur la ligne mais pas le gauche
 motor_left_target = ............
 motor_right_target = ...........
 elif prox_ground_delta[0] > 400 and prox_ground_delta[1] > 400:# aucun capteur sur la ligne
 motor_left_target = speed
 motor_right_target = -speed