Pour aller plus loin avec les IHM
Matériels nécessaires :
1 module micro:bit
1 câble USB
Pré-requis :
Prendre connaissance de la création d'une page avec la librairie tkinter
Question 1 : Lister les différents composants présent à l'intérieur d'un servo-moteur ?
Question 2 : Quelles sont les différences entre les 3 servo-moteur 9g, Futuba S3003 et le AX-12A ?
Question 3 : Quel angle peut-on piloter ?
Question 4 : Quel est le signal que l'on doit envoyer au servomoteur pour qu'il tourne ? Expliquer si l'on veut un angle de 90° et un de 180°.
Question 5 : Imaginez que vous devez utiliser un servo-moteur Futuba S3003, quelle application/usage en feriez-vous ? Votre projet doit être original et présenter un intérêt évident pour son usage.
Pilotage d'un servo-moteur avec un Arduino
Matériels nécessaires :
1 Servo-moteur
1 platine Arduino
1 oscilloscope
des fils mâles-mâles
Activités pratiques
Etape 1 : Câblage

Etape 2 : Le code + commentaire
Pour faire bouger notre servomoteur, nous allons devoir utiliser une bibliothèque de code, nommée "Servo". Celle-ci est fournie de base avec l'environnement de développement Arduino.
La bibliothèque Servo permet de contrôler jusqu'à 12 servomoteurs simultanément avec une carte Arduino UNO et 48 avec une carte Arduino Mega.
Avec une carte Arduino UNO, l'utilisation de la bibliothèque Servo rend inutilisable les broches D9 et D10 en PWM avec analogWrite().
Avec une carte Arduino Mega, 11 servomoteurs peuvent être utilisés simultanément sans poser de problèmes particuliers. A partir de 12 servomoteurs, les broches D11 et D12 ne pourront plus être utilisées en PWM avec analogWrite().
Mise en oeuvre de la bibliothèque Servo
La bibliothèque Servo est fournie de base avec l'environnement de développement Arduino. Il n'y a donc pas d'installation à prévoir.
Il suffit d'importer la bibliothèque en ajoutant cette ligne en début de programme pour l'utiliser :
|
1 |
#include <Servo.h> |
La bibliothèque Servo est une bibliothèque orientée object, cela signifie qu'elle fonctionne en assignant une variable (un objet) à chaque servomoteur que l'on souhaite utiliser.
Pour créer un objet Servo, il suffit de déclarer une variable (globale) de type "Servo", exemple :
|
1 |
Servo monServomoteur; |
Si vous souhaitez utiliser plusieurs servomoteurs simultanément, il faut créer plusieurs variables, une par servomoteur.
Initialisation de la bibliothèque Servo
L'initialisation de la bibliothèque Servo se fait au moyen de la fonction attach() de chaque objet de type Servo. Exemple :
|
1 2 3 |
void setup() { monServomoteur.attach(9); } |
|
|
|
|
|
|
1 |
Servo.attach(int broche); |
|
La fonction attach() prend en argument un unique paramètre obligatoire correspond au numéro de broche sur laquelle le servomoteur est câblé.
|
1 |
Servo.attach(int broche, unsigned long min, unsigned long max); |
La fonction attach() peut prendre en plus deux paramètres optionnels, "min" et "max", correspondant respectivement à la durée minimum et maximum en microsecondes de l'impulsion de contrôle vu en début d'article.
Les durées par défaut sont de 544µs pour 0° ~ 240µs pour 180°. Ces valeurs par défaut sont conçues pour fonctionner avec la grande majorité des servomoteurs du commerce.
Compatibilité avec les versions Arduino 0016 et inférieure
Si vous utilisez une vieille version du logiciel Arduino, version 0016 ou inférieur, la bibliothèque Servo ne permet dans ce cas que d'utiliser 2 servomoteurs, sur les broches D9 et D10 uniquement.
Cette limitation (assez contraignante) n'existe que dans ces versions. Il suffit d'utiliser une version plus récente pour ne plus avoir de problème.
Si plus tard dans votre code vous souhaitez vérifier qu'un objet Servo est bien attaché à une broche, vous pouvez utiliser la fonction attached().
|
1 |
bool Servo.attached(); |
La fonction attached() retourne un booléen, Vrai (true = 1) si l'objet Servo est attaché à une broche, Faux (false = 0) dans le cas contraire.
Et si vous souhaitez détacher un objet Servo d'une broche, il suffit d'appeler la fonction detach().
|
1 |
Servo.detach(); |
La fonction detach() ne prend aucun paramètre et ne retourne aucune valeur. Il suffit de l'appeler pour détacher l'objet Servo de sa broche.
N.B. Si vous détachez tous les objets Servo de leurs broches respectives, la bibliothèque Servo libère automatiquement les broches D9 et D10 (ou D11 et D12 sur Mega) qui redeviennent utilisables avec analogWrite().
Modification de l'angle du servomoteur
Pour modifier l'angle du bras du servomoteur, il existe deux solutions : write() et writeMicroseconds().
|
1 |
Servo.write(int angle); |
La fonction write() permet de modifier l'angle du bras du servomoteur en donnant en paramètre l'angle en question, sous la forme d'un nombre entier compris entre 0° et 180°.
|
1 |
int Servo.read(); |
Si par la suite, vous voulez récupérer la dernière valeur d'angle affectée avec la fonction write(), il suffit d'appeler la fonction read() qui retourne la dernière valeur connue.
N.B. L'amplitude de rotation disponible dépend du modèle de servomoteur. Certains servomoteurs peuvent faire un 0° ~ 180° sans problème, quand d'autre arrive à peine à tourner de 60°. Pensez à bien lire les spécifications techniques
|
1 |
Servo.writeMicroseconds(unsigned long us); |
La fonction writeMicroseconds() permet de modifier l'angle du bras du servomoteur en donnant en paramètre la durée de l'impulsion à transmettre au servomoteur.
Avec un servomoteur standard, une valeur de 1000µs donnera un angle de 0° et une valeur de 2000µs donnera un angle de 180°. Cependant, avec certains servomoteurs, ces valeurs peuvent aller jusqu'à une plage de l'ordre de 700 ~ 2300µs pour 0 ~ 180°.
Cette fonction permet de choisir précisément l'angle du bras en fonction du servomoteur utilisé. Il est cependant nécessaire de faire des tests aux préalables pour déterminer les limites du bras.
C'est quoi ce bruit ?
Quand on demande à un servomoteur d'aller au-delà de ses limites fonctionnelles (en lui demandant de faire un 360° par exemple), on entend en général un bruit aigu.
Si le servomoteur émet un bruit aigu / inhabituel, c'est que vous lui demandez l'impossible
Bloquer le bras d'un servomoteur dans une position "en force" n'est pas très bon et finira par le tuer. Cela induit aussi une très forte consommation de courant.
Exemple : Sweep
Pour illustrer l'utilisation des fonctions décrites ci-dessus, voici un petit exemple de code nommé "Sweep".
Son but est simple : faire tourner le bras du servomoteur dans un sens puis dans l'autre, indéfiniment.
Exemple Sweep utilisant Servo.write() avec commentaires :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
/** * Exemple de code pour un servomoteur, il fait faire des va-et-vient au servomoteur. */ /* Inclut la lib Servo pour manipuler le servomoteur */ #include <Servo.h> /* Créer un objet Servo pour contrôler le servomoteur */ Servo monServomoteur; void setup() {
// Attache le servomoteur à la broche D9 monServomoteur.attach(9); } void loop() { // Fait bouger le bras de 0° à 180° for (int position = 0; position <= 180; position++) { monServomoteur.write(position); delay(15); }
// Fait bouger le bras de 180° à 10° for (int position = 180; position >= 0; position--) { monServomoteur.write(position); delay(15); } } |
Etape 3 : Questions
On souhaite ajouter deux boutons pour gérer la rotation horaire et anti-horaire.
Le premier bouton permet de faire une rotation dans le sens horaire. Tant que ce bouton est appuyé, le second bouton va dans l'autre sens.
Question 6 : Téléverser et tester le code en visualisant le signal sur un oscilloscope. Faites une capture de la sortie à différents moments de la rotation.
Question 7 : Quel est la nature de l'information provenant du bouton ? est-ce que c'est une entrée ou une sortie ?
Question 8 : Définir le nombre de variables nécessaires ainsi que leur types pour gérer les deux boutons.
Question 9 : Définir la/les entrée(s)/sortie(s) utilisée ainsi que leur numéro. Donner l'instruction qui sera utilisée dans le setup pour initialiser ces boutons.
Question 10 : Ajouter le code pour gérer un bouton que l'on a vu dans l'activité découverte d'Arduino. Ajouter une sortie série et afficher l'état du bouton en fonction de l'appui. N'oubliez pas de mettre un delay(100).
Question 11 : Que faut-il faire lorsque l'on appuie sur le bouton rotation horaire ? Décrivez ce que doit faire ce code à l'aide d'un pseudo-code.
Si (je fais cela......) alors
mon moteur bouge dans le sens ....
sinon
je fais autre chose
fin de si
Question 12 : Implémentez (utiliser obligatoirement une fonction pour "ranger" votre code) et tester votre code à l'aide d'un cahier de recette (jeu de test sous la forme d'un tableau).
Si vous ne savez pas ce qu'est une fonction, vérifier cela dans l'activité "Découverte Arduino". Faites valider par le professeur.
Question 13 : Que faut-il faire lorsque l'on appuie sur le bouton rotation anti-horaire ? Décrivez ce que doit faire ce code à l'aide d'un pseudo-code.
Question 14 : Implémentez et tester votre code à l'aide d'un cahier de recette.
Question 15 : Ajouter un bouton Remise à zéro du servo-moteur pour qu'il revienne en position centrale.
Pour aller plus loin :
Question 11 : cf. question 5 : Réfléchissez à une autre utilisation du servo-moteur dans un projet arduino (défi jeu Arduino, utilisation ludique ou éducative, autre.). Expliquez votre idée à l'aide de schéma, phrase explicative, algorigramme.
IHM pour interagir entre un ordinateur et une carte Micro:bit
Ci-dessous vous trouverez les scripts à transférer sur votre carte Micro:bit et à exécuter sur votre PC à l'aide de Mu.
Ouvrir Mu, passer le en mode Micro:bit, copier/coller le code correspondant ci-dessous, enregistrer puis flashez (transférer le script sur) votre carte Micro:bit.
Ensuite, vous pouvez utiliser votre éditeur Python favori ou encore Mu en mode Python3.
Codes python du projet
Script à transférer vers la carte micro:bit :
Attention
Dans cette partie, on utilise Mu en mode micro:bit.
CTRL+C pour copier, CTRL+V pour coller
from microbit import *
uart.init(baudrate=115200)
display.scroll('Pret')
while True:
#print(temperature())
if uart.any():
#display.scroll('Recu')
msg_bytes = uart.read()
if msg_bytes == b'temperature':
temp = temperature()
print(temp)
display.scroll(temp)
else:
if msg_bytes == b'11':
display.set_pixel(1, 1, 9)
else:
msg_str = str(msg_bytes, 'UTF-8')
display.scroll(msg_str)
sleep(1000)
Script à exécuter sur le PC :
Attention
Dans cette partie, on utilise Mu en mode Python.
CTRL+C pour copier, CTRL+V pour coller
# coding: utf-8
import serial, time
import tkinter as tk
port = "COM3"
baud = 115200
s = serial.Serial(port)
s.baudrate = baud
def demande_temperature():
s.write(b'temperature')
data = s.readline()
data = int(data[0:4])
print(data)
texte_temperature.set("Température : "+str(data))
def envoie_message():
message_bytes = bytes(texte_message.get(), 'utf-8')
s.write(message_bytes)
def quitter():
s.close()
ma_fenetre.destroy()
# Fenêtre principale
ma_fenetre = tk.Tk()
ma_fenetre.title("Titre de la fenetre")
ma_fenetre.geometry("300x200")
# Création d'un bouton pour recuperer la temperature
button_temperature = tk.Button(ma_fenetre, text="Temperature", command=demande_temperature)
button_temperature.grid(row=1, column=0, padx=5, pady=5)
# Creation d'un label pour afficher la temperature
texte_temperature = tk.StringVar()
texte_temperature.set("Température : ")
label_temperature = tk.Label(ma_fenetre, textvariable=texte_temperature , bg="grey")
label_temperature.grid(row=1, column=1, padx=5, pady=5)
# Création d'un bouton pour envoyer un message
button_message = tk.Button(ma_fenetre, text ="Envoyer", command=envoie_message)
button_message.grid(row=2, column=1, padx=5, pady=50)
# Création d'un champ de saisie d'un message
texte_message = tk.StringVar()
texte_message.set('coucou')
champ_message = tk.Entry(ma_fenetre, textvariable=texte_message, bg="bisque", fg="maroon", width="20")
champ_message.focus_set()
champ_message.grid(row=2, column=0, padx=5, pady=5)
# Création d'un bouton Quitter
button_quitter = tk.Button(ma_fenetre, text="Quitter", command=quitter)
button_quitter.grid(row=3,column=0, padx=5, pady=5)
ma_fenetre.mainloop()
Créé avec HelpNDoc Personal Edition: Créer des documents d'aide PDF facilement