Cours:MiniQ v2 : Différence entre versions
m (→Travail à faire : exercice 3) |
(→Travail à faire : Exercice 1 (arduino)) |
||
(21 révisions intermédiaires par 2 utilisateurs non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
[[Cours:miniq_v2_Correctionprof|{{Vert|'''Corrections uniquement accessibles aux enseignants'''}}]] | [[Cours:miniq_v2_Correctionprof|{{Vert|'''Corrections uniquement accessibles aux enseignants'''}}]] | ||
− | + | ||
− | = | + | =Programmation avec arduino= |
Le robot miniQ est architecturé autour d'un processeur ATMega32U4. C'est le processeur qui équipe les cartes Leonardo et il est d'ailleurs complètement compatible. Il faut donc changer de board qui est par défaut "Arduino UNO" qui est essentiellement utilisé pour les TPs. | Le robot miniQ est architecturé autour d'un processeur ATMega32U4. C'est le processeur qui équipe les cartes Leonardo et il est d'ailleurs complètement compatible. Il faut donc changer de board qui est par défaut "Arduino UNO" qui est essentiellement utilisé pour les TPs. | ||
− | Le processeur 32U4 est capable de gérer une liaison série USB sans l'aide d'un circuit spécialisé (FTDI par exemple) | + | Le processeur 32U4 est capable de gérer une liaison série USB sans l'aide d'un circuit spécialisé (FTDI par exemple). |
Le schéma peut être trouvé sur [http://www.dfrobot.com/index.php?route=product/product&product_id=555#.VnvPFF64AW1 cette page commerciale] avec des exemples de code et des exercices en anglais. | Le schéma peut être trouvé sur [http://www.dfrobot.com/index.php?route=product/product&product_id=555#.VnvPFF64AW1 cette page commerciale] avec des exemples de code et des exercices en anglais. | ||
Ligne 11 : | Ligne 11 : | ||
En résumé : | En résumé : | ||
* La carte Arduino équivalente est la : Arduino Leonardo | * La carte Arduino équivalente est la : Arduino Leonardo | ||
− | * Le programmateur d'origine est : AVR ISP | + | * Le programmateur d'origine est : AVR ISP |
− | * | + | |
+ | ********************************************** | ||
+ | ********************************************** | ||
+ | Attention : pour programmer aller dans le menu | ||
+ | {{Rouge|Croquis : Téléverser avec un programmateur}} | ||
+ | ********************************************** | ||
+ | ********************************************** | ||
+ | |||
+ | =Utilisation de analogWrite() pour la MLI= | ||
+ | ==Commande d'un moteur== | ||
+ | [https://zestedesavoir.com/tutoriels/686/arduino-premiers-pas-en-informatique-embarquee/747_le-mouvement-grace-aux-moteurs/3437_le-moteur-a-courant-continu/ Vous trouverez des détails sur le moteur à courant continu et sa commande sur cette page] | ||
+ | |||
+ | [https://electrotoile.eu/c-est-quoi-la-PWM-avec-arduino.php Vous pourrez consulter plus tard cette page pour comprendre le signal PWM/MLI] | ||
+ | |||
+ | |||
+ | Pour faire varier la vitesse d'un moteur il suffit de faire varier sa tension de commande. En général ceci est réalisé avec un signal MLI ou PWM (signal à rapport cyclique variable), nous n'entrerons pas dans le détail dans ce TP. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
Tout ceci se fait dans le monde Arduino avec une commande "analogWrite()" | Tout ceci se fait dans le monde Arduino avec une commande "analogWrite()" | ||
+ | *analogWrite(broche,255); => tension moyenne de 5v sur la broche | ||
+ | *analogWrite(broche,127); => tension moyenne de 2.5v sur la broche | ||
+ | *analogWrite(broche,0); => tension moyenne de 0v sur la broche | ||
− | |||
− | ''' | + | |
− | * Il y a deux sorties de commandes du moteur gauche (il faudra donc les positionner en sortie) : | + | '''Commande d'un moteur :''' : |
− | ** broche 5 Arduino (PC6) pour la commande rapport cyclique variable | + | *Il y a deux sorties de commandes du moteur gauche (il faudra donc les positionner en sortie) : |
− | ** broche 12 Arduino (PD6) pour le sens de rotation | + | **broche 5 Arduino (PC6) pour la commande rapport cyclique variable : vitesse de rotation |
− | * On vous donne | + | **broche 12 Arduino (PD6) pour le sens de rotation |
− | + | *On vous donne la fonction ci-dessous qu'il faudra utiliser pour changer la vitesse du moteur : | |
− | + | *Le paramètre est une valeur entre -255 et 255 qui indique la valeur souhaitée pour la vitesse du moteur | |
<source lang=C> | <source lang=C> | ||
− | void MotorG( | + | void MotorG(int vitesse)//control the motor |
{ | { | ||
− | + | if (vitesse<0) | |
− | if( | + | { |
− | + | vitesse=-vitesse; | |
+ | digitalWrite(12,1); | ||
+ | } | ||
else | else | ||
− | + | { | |
− | if( | + | digitalWrite(12,0); |
− | + | } | |
− | + | if (vitesse>255) vitesse=255; | |
− | + | analogWrite(5,vitesse); | |
} | } | ||
</source> | </source> | ||
− | ' | + | |
+ | Exemple d'utilisation | ||
+ | <source lang=C> | ||
+ | void setup() | ||
+ | { | ||
+ | MoteurG(0); | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | |||
+ | On complète la commande du moteur gauche par celle du moteur droit. | ||
* Il y a deux sorties de commandes du moteur droit (il faudra donc les positionner en sortie) : | * Il y a deux sorties de commandes du moteur droit (il faudra donc les positionner en sortie) : | ||
** broche 6 Arduino (PD7) pour la commande rapport cyclique variable | ** broche 6 Arduino (PD7) pour la commande rapport cyclique variable | ||
** broche 7 Arduino (PE6) pour le sens de rotation | ** broche 7 Arduino (PE6) pour le sens de rotation | ||
− | * | + | *La fonction suivante permet de changer la vitesse du 2ème moteur |
− | |||
− | |||
− | |||
<source lang=C> | <source lang=C> | ||
− | void MotorD( | + | void MotorD(int vitesse)//control the motor |
{ | { | ||
− | + | if (vitesse<0) | |
− | if( | + | { |
− | + | vitesse=-vitesse; | |
+ | digitalWrite(7,1); | ||
+ | } | ||
else | else | ||
− | + | { | |
− | if( | + | digitalWrite(7,0); |
− | + | } | |
− | + | if (vitesse>255) vitesse=255; | |
− | + | analogWrite(6,vitesse); | |
} | } | ||
</source> | </source> | ||
− | + | ||
+ | {{Question|Travail à faire}} | ||
Vous devez réaliser une commande du robot pour qu'il réalise un huit (deux cercles connectés par un point). Vous choisirez le rayon de vos cercles en jouant sur les rapports cycliques. Puis vous jouerez sur les temporisations pour gérer tout cela. Bien entendu, le fait qu'il n'y ait pas d'information de retour sur l'endroit où vous êtes complique un peu la mise au point. | Vous devez réaliser une commande du robot pour qu'il réalise un huit (deux cercles connectés par un point). Vous choisirez le rayon de vos cercles en jouant sur les rapports cycliques. Puis vous jouerez sur les temporisations pour gérer tout cela. Bien entendu, le fait qu'il n'y ait pas d'information de retour sur l'endroit où vous êtes complique un peu la mise au point. | ||
Ligne 73 : | Ligne 96 : | ||
==Suivre une source de lumière par Conversion Analogique Numérique== | ==Suivre une source de lumière par Conversion Analogique Numérique== | ||
− | Le travail demandé dans cette section utilise encore la conversion analogique numérique. La différence est que maintenant c'est la position d'une source de lumière qui va faire changer les valeurs analogiques. | + | Le travail demandé dans cette section utilise encore la conversion analogique numérique. |
+ | |||
+ | La différence est que maintenant c'est la position d'une source de lumière qui va faire changer les valeurs analogiques. | ||
+ | |||
+ | Le capteur est connecté sur la broche A5 | ||
+ | |||
===Étalonnage des capteurs=== | ===Étalonnage des capteurs=== | ||
Ligne 80 : | Ligne 108 : | ||
Vous disposez de deux capteurs de lumière monté comme dans le schéma ci-contre. Utilisez une liaison série pour trouver les zones pour : | Vous disposez de deux capteurs de lumière monté comme dans le schéma ci-contre. Utilisez une liaison série pour trouver les zones pour : | ||
* lumière au centre | * lumière au centre | ||
− | * lumière | + | * lumière à droite |
− | * lumière | + | * lumière à gauche |
− | * | + | |
− | * lumière | + | {{Question|Ecrire un programme qui permet d'orienter le robot face à la lumière en utilisant l'information droite/centre/gauche}} |
+ | |||
+ | ===Correcteur proportionnel=== | ||
+ | |||
+ | Pour le moment, nous n'utilisons que 3 valeurs différentes pour faire le suivi de lumière. Afin de faire un suivi plus performant, nous allons calculer la vitesse de rotation du robot en fonction de la position de la lumière par rapport au robot : | ||
+ | |||
+ | {{Question|Trouver une équation permettant de donner l'angle entre l'axe du robot et la source de lumière, en fonction de la valeur du CAN.}} On considérera qu'il s'agit d'une relation affine : | ||
+ | *relever les valeurs de l'entrée analogique pour : | ||
+ | **angle -45° | ||
+ | **angle 0° | ||
+ | **angle +45° | ||
+ | *tracer la caractéristique angle en fonction de la valeur de l'entrée analogique | ||
+ | *donner l'équation de la droite | ||
+ | |||
+ | |||
+ | La vitesse du robot peut être décomposée en une translation et une rotation. On aura donc : | ||
+ | *vt : vitesse de translation (ex 20) | ||
+ | *wr : vitesse de rotation | ||
+ | *vitMoteurD = vt + wr | ||
+ | *vitMoteurG = vt - wr | ||
+ | * wr = k * positionAngulaireLumiere | ||
+ | |||
+ | {{Question|Ecrire un programme permettant de faire le suivi de la lumière d'après ce principe.}} | ||
+ | |||
+ | =Utilisation de l'infra-rouge pour suivre une ligne= | ||
+ | |||
+ | On souhaite maintenant programmer un robot suiveur de ligne, qui sera de couleur noire. | ||
+ | |||
+ | ==Principe== | ||
− | + | 5 capteurs photoréflectifs sont disposés sur le robot tel que résumé dans le tableau ci-dessous. | |
− | |||
− | + | {| class="wikitable" | |
− | + | |- | |
− | + | | Position du capteur || extrême gauche || gauche || centre || droite || extrême droite | |
− | + | |- | |
+ | | broche arduino || A0 || A1 || A2 || A3 || A4 | ||
+ | |- | ||
+ | | entrée CAN || ADC7 || ADC6 || ADC5 || ADC4 || ADC1 | ||
+ | |} | ||
− | + | On peut considérer dans un premier temps que la valeur lue sur le CAN est : | |
− | + | *inférieure à 300 sur du noir | |
− | + | *supérieur à 300 pour le blanc | |
− | + | ||
− | + | On décomposera la vitesse du robot de la même façon que précédemment : | |
− | + | *vt : vitesse de translation, constante par ex 30 | |
− | + | *wr : vitesse de rotation, dépendra de la position du robot par rapport à la ligne | |
− | + | *vitMoteurD = vt + wr | |
− | + | *vitMoteurG = vt - wr | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | == | + | =={{Bleu|Position de la ligne}}== |
− | |||
− | |||
− | |||
− | { | ||
− | |||
− | |||
− | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Le plus important est de trouver la position du robot par rapport à la ligne, que l'on notera pos. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Le principe est d'attribuer un poids à chaque capteur, d'autant plus grand que le capteur est excentré. Le signe donne le côté du capteur : | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | {| class="wikitable" | |
− | + | |- | |
− | + | | Position du capteur || extrême gauche || gauche || centre || droite || extrême droite | |
− | + | |- | |
− | + | | poids du capteur || 24 || 12 || 0 || -12 || -24 | |
− | + | |} | |
− | } | ||
− | |||
− | |||
− | |||
− | + | L'algorithme est le suivant : | |
+ | *initialiser pos à 0 | ||
+ | *initialiser nbCaptOnLine à 0 | ||
+ | *pour chaque capteur | ||
+ | **si le capteur est sur la ligne | ||
+ | ***incrémenter nbCaptOnLine | ||
+ | ***ajouter le poids du capteur à pos : pos <- pos + poids[numeroCapteur] | ||
+ | *normaliser pos : pos <- pos / nbCaptOnLine | ||
− | |||
− | |||
− | ''' | + | '''Exemples''' : |
− | + | {| class="wikitable" | |
− | + | |- | |
− | + | | | |
− | + | {| class="wikitable" | |
+ | |- | ||
+ | | Position du capteur || ex gauche || gauche || centre || droite || ex droite | ||
+ | |- | ||
+ | | poids du capteur || 24 || 12 || 0 || -12 || -24 | ||
+ | |- | ||
+ | | Valeur CAN || 100 || 100 || 10 || 20 || 100 | ||
+ | |- | ||
+ | | Capteur sur la ligne || N || N || O || O || N | ||
+ | |} | ||
− | + | pos = (0 + (-12))/2 = -6 | |
− | + | || | |
+ | {| class="wikitable" | ||
+ | |- | ||
+ | | Position du capteur || ex gauche || gauche || centre || droite || ex droite | ||
+ | |- | ||
+ | | poids du capteur || 24 || 12 || 0 || -12 || -24 | ||
+ | |- | ||
+ | | Valeur CAN || 100 || 15 || 10 || 20 || 100 | ||
+ | |- | ||
+ | | Capteur sur la ligne || N || O || O || O || N | ||
+ | |} | ||
− | + | pos = (12 + 0 + (-12))/3 = 0 | |
− | + | || | |
+ | {| class="wikitable" | ||
+ | |- | ||
+ | | Position du capteur || ex gauche || gauche || centre || droite || ex droite | ||
+ | |- | ||
+ | | poids du capteur || 24 || 12 || 0 || -12 || -24 | ||
+ | |- | ||
+ | | Valeur CAN || 5 || 150 || 100 || 200 || 100 | ||
+ | |- | ||
+ | | Capteur sur la ligne || O || N || N || N || N | ||
+ | |} | ||
− | + | pos = (24)/1 = 24 | |
− | + | |} | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | ==Vérification des capteurs== | |
− | + | La première étape dans la conception du programme va consister à vérifier le {{CAN}}, en utilisant la led. | |
− | + | Ceci peut être réalisé par un programme affichant les données sur la liaison série : | |
− | + | <source lang=c> | |
− | + | const uint8_t pinCapteur[5]={A0,A1,A2,A3,A4}; | |
− | |||
− | |||
− | void setup(){ | + | void setup() { |
+ | // put your setup code here, to run once: | ||
Serial.begin(9600); | Serial.begin(9600); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | void loop(){ | + | void loop() { |
− | + | int valeurCapteur[5]; | |
− | for ( | + | uint8_t i; |
− | + | // put your main code here, to run repeatedly: | |
− | + | for (i=0;i<5;i++) | |
− | + | { | |
− | Serial.println( | + | valeurCapteur[i]=analogRead( pinCapteur[i] );//store the value read from the sensors |
− | delay( | + | Serial.print(valeurCapteur[i]); |
+ | Serial.print(" - "); | ||
+ | } | ||
+ | Serial.println(); | ||
+ | delay(500); | ||
} | } | ||
</source> | </source> | ||
− | |||
− | |||
− | |||
− | |||
− | + | Un essai avec un Robot a donné les résultats suivants. | |
− | + | {| class="wikitable" | |
− | + | |- | |
− | + | | Position du capteur || extrême gauche || gauche || centre || droite || extrême droite | |
− | + | |- | |
− | + | | broche µc || 36 || 37 || 38 || 39 || 40 | |
− | + | |- | |
− | + | | entrée CAN || ADC7 || ADC6 || ADC5 || ADC4 || ADC1 | |
− | + | |- | |
− | + | | entrée Arduino || A0 || A1 || A2 || A3 || A4 | |
− | + | |- | |
+ | | BLANC ||836 || 982 || 980 || 974 || 970 | ||
+ | |- | ||
+ | | NOIR || 210 || 390 || 338 || 305 || 305 | ||
+ | |- | ||
+ | | Seuil || 523 || 686 || 659 || 639 || 637 | ||
+ | |} | ||
− | {{ | + | =={{Bleu|Position de la ligne}}== |
− | ' | + | Il est temps maintenant de calculer la variable {{rouge|pos}} tel qu'indiqué ci-dessus. |
− | + | {{Question|Calculer la valeur pos et l'afficher sur la liaison série}} | |
− | |||
− | |||
− | |||
− | |||
− | + | =={{Bleu|Marche}}== | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | {{Question| | + | {{Question|Il ne reste qu'à modifier la vitesse angulaire du robot (wr) en fonction de la variable pos}} |
− | ''' | + | '''Remarque''' : attention au signe, sinon la correction se fait dans le mauvais sens ! |
Version actuelle datée du 24 octobre 2022 à 17:00
Corrections uniquement accessibles aux enseignants
Sommaire
Programmation avec arduino
Le robot miniQ est architecturé autour d'un processeur ATMega32U4. C'est le processeur qui équipe les cartes Leonardo et il est d'ailleurs complètement compatible. Il faut donc changer de board qui est par défaut "Arduino UNO" qui est essentiellement utilisé pour les TPs.
Le processeur 32U4 est capable de gérer une liaison série USB sans l'aide d'un circuit spécialisé (FTDI par exemple).
Le schéma peut être trouvé sur cette page commerciale avec des exemples de code et des exercices en anglais.
En résumé :
- La carte Arduino équivalente est la : Arduino Leonardo
- Le programmateur d'origine est : AVR ISP
**********************************************
**********************************************
Attention : pour programmer aller dans le menu
Croquis : Téléverser avec un programmateur
**********************************************
**********************************************
Utilisation de analogWrite() pour la MLI
Commande d'un moteur
Vous trouverez des détails sur le moteur à courant continu et sa commande sur cette page
Vous pourrez consulter plus tard cette page pour comprendre le signal PWM/MLI
Pour faire varier la vitesse d'un moteur il suffit de faire varier sa tension de commande. En général ceci est réalisé avec un signal MLI ou PWM (signal à rapport cyclique variable), nous n'entrerons pas dans le détail dans ce TP.
Tout ceci se fait dans le monde Arduino avec une commande "analogWrite()"
- analogWrite(broche,255); => tension moyenne de 5v sur la broche
- analogWrite(broche,127); => tension moyenne de 2.5v sur la broche
- analogWrite(broche,0); => tension moyenne de 0v sur la broche
Commande d'un moteur : :
- Il y a deux sorties de commandes du moteur gauche (il faudra donc les positionner en sortie) :
- broche 5 Arduino (PC6) pour la commande rapport cyclique variable : vitesse de rotation
- broche 12 Arduino (PD6) pour le sens de rotation
- On vous donne la fonction ci-dessous qu'il faudra utiliser pour changer la vitesse du moteur :
- Le paramètre est une valeur entre -255 et 255 qui indique la valeur souhaitée pour la vitesse du moteur
void MotorG(int vitesse)//control the motor
{
if (vitesse<0)
{
vitesse=-vitesse;
digitalWrite(12,1);
}
else
{
digitalWrite(12,0);
}
if (vitesse>255) vitesse=255;
analogWrite(5,vitesse);
}
Exemple d'utilisation
void setup()
{
MoteurG(0);
}
On complète la commande du moteur gauche par celle du moteur droit.
- Il y a deux sorties de commandes du moteur droit (il faudra donc les positionner en sortie) :
- broche 6 Arduino (PD7) pour la commande rapport cyclique variable
- broche 7 Arduino (PE6) pour le sens de rotation
- La fonction suivante permet de changer la vitesse du 2ème moteur
void MotorD(int vitesse)//control the motor
{
if (vitesse<0)
{
vitesse=-vitesse;
digitalWrite(7,1);
}
else
{
digitalWrite(7,0);
}
if (vitesse>255) vitesse=255;
analogWrite(6,vitesse);
}
Travail à faire Vous devez réaliser une commande du robot pour qu'il réalise un huit (deux cercles connectés par un point). Vous choisirez le rayon de vos cercles en jouant sur les rapports cycliques. Puis vous jouerez sur les temporisations pour gérer tout cela. Bien entendu, le fait qu'il n'y ait pas d'information de retour sur l'endroit où vous êtes complique un peu la mise au point.
Vous pouvez chercher à innover sur les trajectoires. Des étudiants, par exemple, ont mis deux obstacles et cherché à réaliser un créneau entre ces deux obstacles. Faites-vous plaisir. Il vous faut à tout prix comprendre comment on va en ligne droite et comment on tourne.
Suivre une source de lumière par Conversion Analogique Numérique
Le travail demandé dans cette section utilise encore la conversion analogique numérique.
La différence est que maintenant c'est la position d'une source de lumière qui va faire changer les valeurs analogiques.
Le capteur est connecté sur la broche A5
Étalonnage des capteurs
Vous disposez de deux capteurs de lumière monté comme dans le schéma ci-contre. Utilisez une liaison série pour trouver les zones pour :
- lumière au centre
- lumière à droite
- lumière à gauche
Ecrire un programme qui permet d'orienter le robot face à la lumière en utilisant l'information droite/centre/gauche
Correcteur proportionnel
Pour le moment, nous n'utilisons que 3 valeurs différentes pour faire le suivi de lumière. Afin de faire un suivi plus performant, nous allons calculer la vitesse de rotation du robot en fonction de la position de la lumière par rapport au robot :
Trouver une équation permettant de donner l'angle entre l'axe du robot et la source de lumière, en fonction de la valeur du CAN. On considérera qu'il s'agit d'une relation affine :
- relever les valeurs de l'entrée analogique pour :
- angle -45°
- angle 0°
- angle +45°
- tracer la caractéristique angle en fonction de la valeur de l'entrée analogique
- donner l'équation de la droite
La vitesse du robot peut être décomposée en une translation et une rotation. On aura donc :
- vt : vitesse de translation (ex 20)
- wr : vitesse de rotation
- vitMoteurD = vt + wr
- vitMoteurG = vt - wr
- wr = k * positionAngulaireLumiere
Ecrire un programme permettant de faire le suivi de la lumière d'après ce principe.
Utilisation de l'infra-rouge pour suivre une ligne
On souhaite maintenant programmer un robot suiveur de ligne, qui sera de couleur noire.
Principe
5 capteurs photoréflectifs sont disposés sur le robot tel que résumé dans le tableau ci-dessous.
Position du capteur | extrême gauche | gauche | centre | droite | extrême droite |
broche arduino | A0 | A1 | A2 | A3 | A4 |
entrée CAN | ADC7 | ADC6 | ADC5 | ADC4 | ADC1 |
On peut considérer dans un premier temps que la valeur lue sur le CAN est :
- inférieure à 300 sur du noir
- supérieur à 300 pour le blanc
On décomposera la vitesse du robot de la même façon que précédemment :
- vt : vitesse de translation, constante par ex 30
- wr : vitesse de rotation, dépendra de la position du robot par rapport à la ligne
- vitMoteurD = vt + wr
- vitMoteurG = vt - wr
Position de la ligne
Le plus important est de trouver la position du robot par rapport à la ligne, que l'on notera pos.
Le principe est d'attribuer un poids à chaque capteur, d'autant plus grand que le capteur est excentré. Le signe donne le côté du capteur :
Position du capteur | extrême gauche | gauche | centre | droite | extrême droite |
poids du capteur | 24 | 12 | 0 | -12 | -24 |
L'algorithme est le suivant :
- initialiser pos à 0
- initialiser nbCaptOnLine à 0
- pour chaque capteur
- si le capteur est sur la ligne
- incrémenter nbCaptOnLine
- ajouter le poids du capteur à pos : pos <- pos + poids[numeroCapteur]
- si le capteur est sur la ligne
- normaliser pos : pos <- pos / nbCaptOnLine
Exemples :
pos = (0 + (-12))/2 = -6 |
pos = (12 + 0 + (-12))/3 = 0 |
pos = (24)/1 = 24 |
Vérification des capteurs
La première étape dans la conception du programme va consister à vérifier le Convertisseur Analogique Numérique, en utilisant la led.
Ceci peut être réalisé par un programme affichant les données sur la liaison série :
const uint8_t pinCapteur[5]={A0,A1,A2,A3,A4};
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
int valeurCapteur[5];
uint8_t i;
// put your main code here, to run repeatedly:
for (i=0;i<5;i++)
{
valeurCapteur[i]=analogRead( pinCapteur[i] );//store the value read from the sensors
Serial.print(valeurCapteur[i]);
Serial.print(" - ");
}
Serial.println();
delay(500);
}
Un essai avec un Robot a donné les résultats suivants.
Position du capteur | extrême gauche | gauche | centre | droite | extrême droite |
broche µc | 36 | 37 | 38 | 39 | 40 |
entrée CAN | ADC7 | ADC6 | ADC5 | ADC4 | ADC1 |
entrée Arduino | A0 | A1 | A2 | A3 | A4 |
BLANC | 836 | 982 | 980 | 974 | 970 |
NOIR | 210 | 390 | 338 | 305 | 305 |
Seuil | 523 | 686 | 659 | 639 | 637 |
Position de la ligne
Il est temps maintenant de calculer la variable pos tel qu'indiqué ci-dessus.
Calculer la valeur pos et l'afficher sur la liaison série
Marche
Il ne reste qu'à modifier la vitesse angulaire du robot (wr) en fonction de la variable pos
Remarque : attention au signe, sinon la correction se fait dans le mauvais sens !