dimanche 11 janvier 2015

    

17/04/2013

Trois robots de grande taille à construire et à programmer : Troisième robot "Spider" (Deuxième partie)

Nous terminons cette fois la description du troisième et dernier de nos robots : Spider, l’araignée à 6 pattes ! Dans cette dernière partie, nous analyserons ensemble tous les secrets des logiciels lui permettant de se déplacer et de reconnaître les obstacles.


Dans cette dernière partie nous étudierons ensemble les programmes logiciels gouvernant les périphériques et les dispositifs montés sur Spider et permettant au robot de se déplacer, de reconnaître la présence d’éventuels obstacles et de réagir correctement aux événements extérieurs.
Nous analyserons deux exemples de “listings”, toujours écrits en Basic : tous deux permettent à Spider de se déplacer dans son environnement, mais le premier utilise des “antennes” (ou “moustaches”, les insectes ayant plutôt des antennes, non ?) reliées à des micro-interrupteurs pour détecter les obstacles, alors que le second a recours aux détecteurs à infrarouges (lire la chronique Robotique dans les articles du blog) pour identifier d’éventuels empêchements à la progression du robot. Comme pour les articles consacrés aux logiciels des deux autres robots, pour Spider aussi le but du présent article est moins de vous montrer tout ce que notre robot est capable de faire que d’expliquer simplement quels sont les concepts de base qui sous-tendent sa programmation : ainsi, vous pourrez, quand vous le souhaiterez, réaliser la programmation de vos propres applications ou développer de nouvelles fonctionnalités, même si vous vous êtes contentés, dans un premier temps, de nos exemples.
Rappelons à ce propos que la carte-mère située sur le robot est munie de deux connecteurs d’extension (le premier, SV1, constitué de vingt broches, amène à l’extérieur les dix-neuf ports d’I/O plus la masse, le second, JP11, JP14, JP15, constitué de huit broches, met à disposition trois masses, trois niveaux +5 V et deux niveaux de tension provenant directement des batteries d’alimentation), de façon à pouvoir superposer une platine supplémentaire sur laquelle ajouter d’autres composants ou circuits (par exemple, des détecteurs, des mini-caméras vidéo ou des afficheurs LCD, etc.).
Avant d’entrer dans le vif des logiciels, revoyons rapidement quelques caractéristiques matérielles de Spider : toute la mécanique et l’électronique sont gérées par la carte-mère où trône le microcontrôleur PIC16F876 fonctionnant à la fréquence d’horloge de 20 MHz.
Le PIC dispose de trois ports d’I/O A, B et C, pour un total de vingt-deux broches.
Certaines de ces dernières sont utilisées chez Spider pour commander les dispositifs externes : par exemple, à la broche 1 du port A est relié le “speaker” (buzzer), aux broches 2, 1 et 0 du port B sont reliés les servomoteurs, respectivement de droite, de gauche et central, aux broches 4 et 5 du port A sont reliées les antennes, respectivement de gauche et de droite, etc. Pour une liste complète et détaillée, voyez les figures 1 et 2.
Nous pouvons maintenant analyser la génération du mouvement de Spider.
Il est obtenu au moyen de trois servomoteurs : le premier commande la marche en avant ou en arrière des pattes antérieures et postérieures droites, le deuxième gère la marche en avant ou en arrière des pattes antérieures et postérieures gauches, enfin la troisième commande l’abaissement ou le soulèvement d’une des deux pattes centrales tour à tour. Pour ces dernières, notez que les deux pattes centrales bougent en opposition mutuelle ou, si vous préférez, de façon différentielle : elles sont reliées par deux axes de renvoi de telle façon que, lorsqu’une patte se soulève (par exemple la gauche), l’autre s’abaisse (celle de droite) et vice versa. La marche en avant est donc obtenue ainsi :
- la patte centrale gauche s’abaisse, de telle façon que les deux autres pattes gauches se soulèvent,
- les pattes avant et arrière gauches avancent, tandis que les pattes avant et arrière droites reculent,
- la patte centrale droite s’abaisse, de telle façon que les deux autres pattes droites se soulèvent,
- les pattes avant et arrière droites avancent, tandis que les pattes avant et arrière gauches reculent.

En exécutant cycliquement ces quatre opérations, on obtient le mouvement en avant désiré. Si l’on veut en revanche faire reculer Spider, les opérations sont substantiellement les mêmes : une fois soulevées ou abaissées les pattes centrales, il faut alors bouger inversement, par rapport au cas précédent, les pattes avant et arrière. Pour faire varier la direction de son mouvement, Spider est en outre capable d’exécuter des rotations autour de son axe vertical : par exemple, pour tourner à gauche il est nécessaire de faire les pas suivants :
- abaisser la patte centrale gauche, de façon à soulever les deux autres pattes gauches,
- reculer les pattes avant et arrière droites ou gauches,
- abaisser la patte centrale droite, de façon à soulever les deux autres pattes droites,
- avancer les pattes avant et arrière droites ou gauches.
Si, en revanche, on veut que Spider tourne à droite, les premier et troisième points restent les mêmes, mais il faut inverser l’ordre d’exécution des deuxième et quatrième points.
Pour Spider aussi, les servomoteurs utilisés sont des Futuba S3003. Ils sont commandés par des trains d’impulsions dont la durée détermine le positionnement de l’axe. Rappelons que pour une durée de 1,5 ms l’axe se met en position centrale, pour 1,2 ou 1,8 ms il se met complètement dans une direction ou dans la direction opposée.
Comme pour les logiciels des deux autres robots, dans les programmes que nous allons analyser ici, la production des impulsions se fait par l’instruction PulseOut Pin,Period produisant sur la broche spéciale Pin une impulsion de durée égale à 2.10_6.Period. On l’a dit en introduction, le second logiciel utilise les émetteurs et le récepteur à infrarouges pour détecter la présence des obstacles. Rappelons brièvement leur logique de fonctionnement :
- on habilite l’émission sur le seul Emetteur à infrarouges IR1 (Emetteur droit), - si un obstacle est présent, il réfléchit la lumière émise vers le récepteur à infrarouges qui en identifie donc la présence,
- on habilite l’émission sur le seul Emetteur à infrarouges IR2 (Emetteur gauche),
- dans ce cas aussi, si un obstacle est présent, il réfléchit la lumière émise vers le récepteur à infrarouges qui en identifie donc la présence.

En exécutant les contrôles logiciels voulus de l’état du récepteur à infrarouges, il est donc possible de vérifier la présence des obstacles à droite, à gauche ou des deux côtés (dans ce dernier cas l’obstacle est frontal).

Figure 1 : Connexion des dispositifs externes.
Table de vérité.
Pin            Port           Etat logique       Signification
IR_1         Port C.1              1             Aucun obstacle détecté
IR_1         Port C.1              0             Obstacle détecté
IFR_1        Port C.5              1             Active trx IR de dx
IFR_1        Port C.5              0             Désactive trx IR de dx
IFR_2        Port C.2              1             Active trx IR de sx
IFR_2        Port C.2              0             Désactive trx IR de sx
Speaker      Port A.1              0             Aucun son émis
Speaker      Port A.1              1             Emission d’un son
Servo1       Port B.2              -             Servomoteur Droit
Servo2       Port B.1              -             Servomoteur Gauche
Servo3       Port B.0              -             Servomoteur Centre
Antenne_1    Port A.4              0             Obstacle détecté à sx
Antenne_1    Port A.4              1             Aucun obstacle à sx
Antenne_2    Port A.5              0             Obstacle détecté à dx
Antenne_2    Port A.5              1             Aucun obstacle à dx
LED_1        Port C.3              0             LED Gauche éteinte
LED_1        Port C.3              1             LED Gauche allumée
LED_2        Port C.4              0             LED Droite éteinte
LED_2        Port C.4              1             LED Droite allumée

Variable                  Valeur                   Opération exécutée
 Servo1                    600                  Jambes Droites en arrière
 Servo1                    750                  Jambes Droites centrées
 Servo1                    900                  Jambes Droites en avant
 Servo2                    600                  Jambes Gauches en avant
 Servo2                    750                  Jambes Gauches centrées
 Servo2                    900                  Jambes Gauches en arrière
 Servo3                    600                  Lève Jambe centrale de sx
 Servo3                    750                  Jambes centrales égales
 Servo3                    900                  Lève Jambe centrale de dx


Figure 2 : Connecteurs d’extension.

Pour vous permettre d’étendre les fonctionnalités du robot, la carte-mère qui le constitue est munie de deux connecteurs d’extension (SV1 e JP13, JP14, JP15), dans les schémas publiés ici on en montre des détails.

Figure 3 : Emetteurs et récepteur à infrarouges.

La figure montre la logique de fonctionnement du détecteur à infrarouges.
Les deux émetteurs à infrarouges (droit et gauche) envoient alternativement le signal lumineux : si un obstacle est présent, le cône de lumière est réfléchi et donc détecté par le récepteur placé en position centrale.
En allant lire le récepteur, on peut donc savoir si des obstacles ont été détectés et s’ils sont sur le côté droit ou sur le côté gauche ou en face du robot.

Premier logiciel : mouvement avec contrôle des obstacles au moyen des antennes
C’est celui de la figure 4. On l’a dit, ce programme permet à Spider de se déplacer et d’identifier les obstacles éventuels grâce à ses antennes (reliées à des micro-interrupteurs). Le cycle principal gère la marche en avant du robot et teste la présence d’un empêchement éventuel à cette progression : si un obstacle est détecté du côté droit, le robot recule de trois pas, tourne de 90° environ vers la gauche puis continue sa marche. Si à l’inverse l’obstacle est du côté gauche, Spider recule encore de trois pas, mais tourne vers la droite. Enfin, si l’obstacle est détecté par les deux antennes, après avoir reculé de trois pas, il tourne de 180° de façon à inverser la direction de sa marche.
Analysons maintenant le “listing” : le programme débute par la déclaration de certains paramètres de caractère général, du sens des ports (“input” ou “output”), des liaisons entre broches des ports et dispositifs externes et de certaines variables et constantes de commodité utilisées au sein du logiciel.
Ensuite commence l’exécution proprement dite : tout d’abord les trois servomoteurs sont réglés en position centrale, le positionnement est réalisé par la subroutine Mise à zéro utilisant les paramètres relatifs aux servomoteurs mémorisés dans les trois variables Pos_Servo1, Pos_Servo2 et Pos_Servo3.
On entre ensuite dans le cycle principal du programme : le premier mouvement du pas en avant est exécuté, on teste la présence des obstacles en appelant la subroutine Antennes, le pas en avant est complété, on teste à nouveau la présence des obstacles et enfin on revient au début du cycle principal, lequel se déroule indéfiniment.
La gestion du mouvement est exécutée par la subroutine Marche laquelle se contente de positionner les trois servomoteurs dans les positions qui lui sont indiquées par les trois variables Pos_Servo1, Pos_Servo2 et Pos_Servo3. A noter qu’à l’intérieur de cette subroutine la première opération consiste à positionner les pattes centrales, c’est seulement ensuite que les pattes avant et arrière bougent.
Si, au contraire, les trois servomoteurs étaient positionnés en même temps, on aurait un mouvement incorrect du robot.
Voyons à présent la subroutine Antennes : on le voit, à l’intérieur de celle-ci sont testés les états assumés par les deux micro-interrupteurs reliés aux deux antennes (rappelons que la condition Antenne=0 indique que le micro-interrupteur correspondant est fermé et que donc un obstacle est présent) et éventuellement les subroutines notées Gauche, Droite et Inverse sont appelées.
Dans le cas où c’est la première qui est appelée, cela implique la présence d’un obstacle à gauche : il faut alors reculer de quelques pas (trois dans notre exemple) et tourner à droite. Le premier point est exécuté en appelant la subroutine En arrière. La rotation est en revanche obtenue à l’intérieur d’un cycle “for” dans lequel sont paramétrées les positions des trois servomoteurs selon la logique expliquée en introduction de cet article.
La subroutine Droite travaille en symétrique de la Gauche vue ci-dessus : après avoir reculé de trois pas (géré encore par la subroutine En arrière) on exécute une rotation vers la gauche, rotation exécutée à l’intérieur d’un cycle “for” travaillant de façon absolument identique à la précédente.
Quant à la subroutine Inverse, elle gère la possibilité où seraient détectés des obstacles situés en même temps à droite et à gauche : là, après avoir reculé de trois pas (appel de En arrière), on tourne de 180°. La subroutine travaille comme la procédure Droite, dans ce cas cependant le cycle “for” est exécuté un nombre supérieur de fois, de façon à exécuter une rotation plus ample.
Avant de conclure l’analyse, notons deux choses. La première touche, à l’intérieur du “listing”, à la présence de deux variables, LED_1 et LED_2, utilisées pour allumer ou éteindre deux LED, montées respectivement sur les côtés gauche et droit, utilisées comme “yeux” du robot. La seconde concerne la subroutine Son et ses appels positionnés dans le “listing”.
Cette procédure, déjà amplement analysée à propos des logiciels pour CarBot et Filippo, fait émettre un signal sonore au “speaker” (buzzer) installé sur la carte-mère. L’émission du son est gérée par l’instruction Sound Speaker, [Note,Durée], produisant sur la broche indiquée Speaker une onde caractérisée par les niveaux de tension TTL. Le paramètre Note indique la fréquence du ton acoustique produit, Durée combien de temps cette émission doit se poursuivre (le paramètre Durée peut prendre des valeurs comprises entre 0 et 255, le temps de production est environ égal à Durée.12 millisecondes). Bien qu’à l’intérieur des “listings” cela ne soit pas nécessaire, nous vous précisons qu’il est possible de produire plusieurs notes en utilisant une seule instruction : par exemple, l’instruction Sound Speaker [Note1, Durée1, Note2, Durée2, …, NoteN, DuréeN] produit N signaux sonores de fréquence et durée spécifiées. Grâce à une seule instruction, il est donc possible de produire des signaux sonores multitons.
La subroutine Son se termine par l’instruction Low Speaker qui ne fait que mettre au niveau logique bas la broche du port spécifiée par le “speaker”.

Figure 4 : Listing “Mouvement avec contrôle des antennes”.
‘************************************************************************************
‘* Nom : Spider_Antennes                                                            *
‘* Notes : Mouvement avec contrôle des antennes                                     *
‘************************************************************************************

‘-----[ Définitions ]----------------------------------------------------------------
DEFINE LOADER_USED 1               ‘Utilisé pour boot-loader
DEFINE OSC 20                      ‘Paramètre Clock à 20 MHz
ADCON1 = 000111                 ‘Port A = Numérique

‘-----[ Vers Port ]------------------------------------------------------------------
TRISA = 110000                  ‘Paramètre pin Port A in Input et/ou Output
TRISB = 000000                  ‘Paramètre pin Port B in Input et/ou Output
TRISC = 100100                  ‘Paramètre pin Port C in Input et/ou Output

‘-----[ Définitions I/O ]------------------------------------------------------------
Servo1      VAR      PORTB.2       ‘Port Servo 1 (Droite)
Servo2      VAR      PORTB.1       ‘Port Servo 2 (Gauche)
Servo3      VAR      PORTB.0       ‘Port Servo 3 (Centre)

Antenne_1   VAR      PORTA.4       ‘Port Antenne 1 (Gauche)
Antenne_2   VAR      PORTA.5       ‘Port Antenne 2 (Droite)

Speaker     VAR      PORTA.1       ‘Port Speaker

Led_1       VAR      PORTC.3       ‘Port LED 1 (Gauche)
Led_2       VAR      PORTC.4       ‘Port LED 2 (Droite)

‘-----[ Définitions Variables ]------------------------------------------------------
Pos_Servo1  VAR      WORD          ‘position servo1 Droite
Pos_Servo2  VAR      WORD          ‘position servo2 Gauche
Pos_Servo3  VAR      WORD          ‘position servo3 Centre

mcount      VAR      BYTE          ‘loop pour subrout. marche
ncount      VAR      BYTE          ‘loop pour les autres
Note        VAR      BYTE          ‘note pour sound

‘-----[ Définitions Constantes ]-----------------------------------------------------
pos_max_3   CON      900           ‘Position Maximale Centre
pos_mid_3   CON      750           ‘Position Centrale Centre
pos_min_3   CON      600           ‘Position Minimale Centre
pos_max_1   CON      900           ‘Position Maximale Droite
pos_mid_1   CON      750           ‘Position Centrale Droite
pos_min_1   CON      600           ‘Position Minimale Droite
pos_max_2   CON      900           ‘Position Maximale Gauche
pos_mid_2   CON      750           ‘Position Centrale Gauche
pos_min_2   CON      600           ‘Position Minimale Gauche

Retard      CON      20            ‘Pause pour Pulsout en μs
Pas         CON      5             ‘Pas pour cycle Remise à zéro
Pas_1       CON      7             ‘Pas pour cycle Marche
Durée       CON      50            ‘Durée note pour Sound

‘-----[ Initialisation ]-------------------------------------------------------------
PORTA =0
PORTB =0
PORTC =0

‘-----[ Début programme ]------------------------------------------------------------
      ncount = 0
      mcount = 0
      Note = 0

      GoSub Yeux                   ‘clignotement yeux

      Note = 50
      GoSub Son ‘Emets son
      Pos_Servo1 = pos_mid_1       ‘position initiale...
      Pos_Servo2 = pos_mid_2       ‘...des trois servomoteurs...
      Pos_Servo3 = pos_mid_3       ‘...au centre
      GoSub Remise à zéro

Début :
      Pos_Servo1 = pos_min_1       ‘en arrière pattes Droites
      Pos_Servo2 = pos_min_2       ‘en avant pattes Gauches
      Pos_Servo3 = pos_max_3       ‘en bas centrale Gauches
      GoSub Marche                 ‘-mouvement en avant

      GoSub Antennes               ‘test contact sur antennes

      Pos_Servo1 = pos_max_1       ‘en avant pattes Droites
      Pos_Servo2 = pos_max_2       ‘en arrière pattes Gauches
      Pos_Servo3 = pos_min_3       ‘en bas centrale Droite
      GoSub Marche                 ‘mouvement en avant

      GoSub Antennes               ‘test contact sur antennes

      GoTo Début                   ‘répète cycle

‘-----[ Subroutine ]-----------------------------------------------------------------
Marche :

    ‘Positionne les pattes centrales
      For mcount=1 to 100 step Pas_1
        PulsOut Servo3,Pos_Servo3
        Pause Retard
      Next

    ‘Bouge les pattes Droites et Gauches
      For mcount=1 to 100 step Pas_1
        PulsOut Servo1,Pos_Servo1                   ‘Droite
        PulsOut Servo2,Pos_Servo2                   ‘Gauche
        PulsOut Servo3,Pos_Servo3                   ‘Centre
        Pause Retard
      Next

Return

Antennes :
    ‘Teste présence d’obstacles sur antennes
      IF Antenne_1 = 0 Then Gauche                  ‘contact sur antenne 1
      IF Antenne_2 = 0 Then Droite                  ‘contact sur antenne 2
      IF Antenne_1 AND Antenne_2 = 0 Then Inverse   ‘contact sur les deux antennes
      Return

Yeux :
      LED_1 = 0                                     ‘Eteins les yeux
      LED_2 = 0

      For ncount=1 to 5                             ‘5 Eclairs des yeux
        Toggle LED_1
        Toggle LED_2
        Pause 100
      Next
      Return

Son :
      Sound Speaker, [Note, Durée]                  ‘Emets son
      Low Speaker                                   ‘Eteins speaker
      Return

Mise à zéro :
‘Positionne les trois servomoteurs en position centrale
      For ncount = 1 to 100 step Pas
        PulsOut Servo1,Pos_Servo1
        PulsOut Servo2,Pos_Servo2
        PulsOut Servo3,Pos_Servo3
        Pause Retard
      Next
      Return

Gauche :
    ‘Il faut revenir en arrière de trois pas et tourner à droite...
    ‘...pour éviter l’obstacle détecté par antenne_1

      Note = 10                                     ‘Emets son
      GoSub Son

      Led_1 = 0                                     ‘Eteins LED de Gauche
      GoSub Arrière                                 ‘Reviens en arrière de trois pas

      For ncount=1 to 5                             ‘Tourne à droite
        Pos_Servo1 = pos_max_1                      ‘av. pattes dx
        Pos_Servo2 = pos_min_2                      ‘av. pattes sx
        Pos_Servo3 = pos_max_3                      ‘en bas cent. sx
        GoSub Marche

        Pos_Servo1 = pos_min_1                      ‘arr. pattes dx
        Pos_Servo2 = pos_max_2                      ‘arr. pattes sx
        Pos_Servo3 = pos_min_3                      ‘en bas cent. dx
        GoSub Marche
      Next

      Led_1 = 1                                     ‘Rallume LED Gauche
      Return

Droite :
    ‘Il faut revenir en arrière de trois pas et tourner à Gauche...
    ‘...pr éviter l’obstacle rencontré par antenne_2

      Note = 100                                    ‘Emets son
      GoSub Son

      LED_2 = 0                                     ‘Eteins LED Droite
      GoSub Arrière                                 ‘Reviens en arrière de trois pas
      For ncount=1 to 5                             ‘Tourne à Gauche
        Pos_Servo1 = pos_min_1                      ‘arr. pattes dx
        Pos_Servo2 = pos_max_2                      ‘arr. pattes sx
        Pos_Servo3 = pos_max_3                      ‘en bas cent. sx
        GoSub Marche

        Pos_Servo1 = pos_max_1                      ‘av. pattes dx
        Pos_Servo2 = pos_min_2                      ‘av. pattes sx
        Pos_Servo3 = pos_min_3                      ‘en bas cent. dx
        GoSub Marche

      Next

      LED_2 = 1                                     ‘Rallume LED Droite
      Return

Inverse :
    ‘Il faut revenir en arrière de trois pas et tourner de 180°...
    ‘...pour éviter l’obstacle rencontré par les deux antennes

      Nota = 50                                     ‘Emets son
      GoSub Son

      Led_1 = 0                                     ‘Eteins les deux LED
      Led_2 = 0
      GoSub Arrière                                 ‘Reviens en arrière de trois pas

      For ncount=1 to 7                             ‘Tourne à Gauche de180°
        Pos_Servo1 = pos_min_1                      ‘arr. pattes dx
        Pos_Servo2 = pos_max_2                      ‘arr. pattes sx
        Pos_Servo3 = pos_max_3                      ‘en bas cent. sx
        GoSub Marche
        Pos_Servo1 = pos_max_1                      ‘av. pattes dx
        Pos_Servo2 = pos_min_2                      ‘av. pattes sx
        Pos_Servo3 = pos_min_3                      ‘en bas cent. dx
        GoSub Marche

      Next

      Led_1 = 1                                     ‘Rallume les deux LED
      Led_2 = 1
      Return

Arrière :
      For ncount=1 to 4                             ‘Reviens en arrière de trois pas
        Pos_Servo1 = pos_max_1                      ‘av. pattes dx
        Pos_Servo2 = pos_max_2                      ‘arr. pattes sx
        Pos_Servo3 = pos_max_3                      ‘en bas cent. sx
        GoSub Marche
        Pos_Servo1 = pos_min_1                      ‘arr. pattes dx
        Pos_Servo2 = pos_min_2                      ‘av. pattes sx
        Pos_Servo3 = pos_min_3                      ‘en bas cent. dx
        GoSub Marche

      Next
      Return

End

Figure 5 : Le “bootloader”.
Pour faire fonctionner toute la série de nos robots, il est nécessaire d’écrire un programme qui fasse faire au robot ce que nous voulons, dans la limite des ressources disponibles. Ce programme peut être écrit en n’importe quel langage, du Basic au C en passant par l’Assembleur, etc. Il doit être ensuite compilé de manière à obtenir le fichier .HEX adapté à la mémorisation par le microcontrôleur. Nous expliquons ici comment ce fichier peut être chargé dans le microcontrôleur.
Normalement, cette opération s’effectue en utilisant un programmateur matériel adapté dans lequel le microcontrôleur est physiquement inséré. Toutefois, pour rendre plus facile cette opération, notre carte-mère prévoit un système de programmation “in-circuit” permettant de ne pas déposer le microcontrôleur de sa platine. En fait, la programmation se fait directement à partir du PC par l’intermédiaire du port sériel connecté à la prise DB9 de la carte-mère du robot.
Pour ce faire, il est nécessaire d’utiliser un système spécial de programmation appelé “bootloader”.
Ce système prévoit l’utilisation d’un logiciel spécifique (PICdownloader.exe) permettant de charger dans le microcontrôleur les programmes que nous avons développés (au format .HEX) par l’intermédiaire du port sériel. Cela est possible uniquement si on a préalablement chargé dans le microcontrôleur un bref programme de support (bootldr20Mhz-19200bps.hex) logé dans les premières cellules de mémoire : ce logiciel, bien sûr, doit être chargé avec un programmateur normal. Cependant, le microcontrôleur contenant déjà ce mini programme (“firmware”) est disponible.
Voyons donc comment utiliser le “bootloader” : avant tout, il est nécessaire de charger le programme PICdownloader.exe sur le site de la revue, ensuite ce programme doit être installé sur votre PC. Alors, par l’intermédiaire d’un compilateur adéquat, vous devez produire un fichier au format .HEX de votre programme et, grâce au PICdownloader, le charger dans l’EEPROM du PIC présent sur la carte-mère.
Pour de plus amples informations sur les opérations à exécuter, nous vous renvoyons aux précédents articles sur les robots, rubrique “ Comment charger les programmes” : vous y trouverez des détails sur les étapes nécessaires à l’installation du programme sur PC et le chargement des fichiers .HEX à l’intérieur du microcontrôleur.

Figure 6 : Utilisation pratique.
On l’a vu dans l’article, les trois servomoteurs sont commandés par le paramètre “Period” de la fonction “PulsOut”. Nous avons déjà expliqué que pour des valeurs de “Period” de 900 ou 600 l’axe se place complètement dans un sens ou complètement dans l’autre, alors que pour une “Period” de 750, l’axe se place au centre. Ces valeurs ont été calculées théoriquement en partant de la formule T = 2.10-6.Period : si l’on remplace T par les durées désirées, on obtient les valeurs correspondantes de “Period”. En réalité, dans l’utilisation pratique, les tolérances interviennent. Par exemple, au cours de nos tests, il nous est arrivé que pour une “Period” de 750 les trois servomoteurs ne fussent pas en position centrale, mais celui des pattes de gauche était décalé d’un angle minimum. Nous avons donc dû centrer les deux servomoteurs (au moyen du “listing” de la figure 7), en trouvant que le moteur des pattes de droite était centré pour une “Period” de 750 et celui des pattes de gauche de 749. On le voit, ces variations sont minimes, elles relèvent des tolérances habituelles en électronique et, dans ce cas, elles ont pu être résolues par un procédé logiciel.

Figure 7 : Listing “Centrage des servomoteurs”.
‘************************************************************************************
‘* Nom    : Centre Servomoteurs                                                     *
‘* Proces.: PIC16F876                                                               *
‘* Notes  : Permet de centrer les trois servomoteurs                                *
‘************************************************************************************
‘------[ Définitions ]---------------------------------------------------------------
DEFINE LOADER_USED 1                    ‘Utilisé pour boot-loader
DEFINE OSC 20                           ‘Paramètre Clock à 20MHz
ADCON1 = 000111                         ‘Port A = Numérique
‘------[ Vers Port ]-----------------------------------------------------------------
TRISB = 000000
‘-----[ Définitions I/O ]------------------------------------------------------------
Servo1     VAR      PORTB.2             ‘Port Servo 1
Servo2     VAR      PORTB.1             ‘Port Servo 2
Servo2     VAR      PORTB.0             ‘Port Servo 3

‘------[ Initialisation ]------------------------------------------------------------
PORTB = 0

‘------[ Début programme ]-----------------------------------------------------------
Début :
      PulsOut Servo1, 750               ‘Centre le Servo 1 avec 1500 μs
      PulsOut Servo2, 749               ‘Centre le Servo 2 avec 1498 μs
      PulsOut Servo3, 750               ‘Centre le Servo 2 avec 1500 μs
      Pause 20                          ‘Attends 20 ms
      GoTo Début
End

Second logiciel : mouvement avec contrôle des obstacles par infrarouges
C’est celui de la figure 8. Ce programme permet aussi à Spider de se déplacer à l’intérieur d’un espace, d’avancer, de reculer ou de tourner.
La différence avec le logiciel précédent est qu’ici la détection des obstacles se fait par les deux émetteurs et le récepteur à infrarouges (comme pour Filippo, voir l'article : "Deuxième robot "Filippo" (Première partie)").
Analysons donc pas à pas (c’est bien le cas de le dire !) le “listing” : comme d’habitude le programme débute par la déclaration de certains paramètres de caractère général, du sens des ports (“input” ou “output”), des liaisons entre broches des ports et dispositifs externes (servomoteurs, “speaker”, émetteurs et récepteurs à infrarouges, etc.). Ensuite sont définies et initialisées certaines variables et constantes utilisées dans le programme.
On entre alors dans le cycle principal : tous les servomoteurs se centrent (subroutine Mise à zéro), puis les tests du récepteur à infrarouges ont lieu.
Le fonctionnement est le même que pour le logiciel de Filippo : on active l’émetteur de gauche et on mémorise au sein de la variable Gau_IR_det l’état du récepteur à infrarouges. L’émetteur droit s’active ensuite et on mémorise dans Drt_IR_det l’état du récepteur (rappelons que la présence des obstacles d’un seul côté est indiquée avec Gau_IR_det ou Drt_IR_det égale 0).
Alors, en fonction de l’état des deux variables, on détermine quelle subroutine exécuter (la sélection est écrite dans la variable Action). Si aucun obstacle n’est présent Action est égale à 0, si au contraire il y a un obstacle à gauche, elle est égale à 1, si l’obstacle est à droite, elle est égale à 2 et enfin si l’obstacle est frontal, elle est égale à 3.
Les deux bits les moins significatifs d’Action sont alors écrits dans la variable VarAnd (utilisant une opération de And, représentée par le symbole &).
Nous avions déjà rencontré dans le logiciel de Filippo l’instruction déterminant le passage à la subroutine correcte et à la Branch VarAnd, [En avant, Droite, Gauche, Inverse]. Pour résumer un peu, nous pouvons dire que si VarAnd=0 on saute à En avant, si VarAnd=1 on exécute la subroutine Droite et ainsi de suite. A noter que les sauts sont équivalents à des instructions GoTo (et non Gosub) : c’est pourquoi les quatre subroutines En avant, Droite, Gauche et Inverse reviennent au cycle principal (étiqueté avec le “label” Début) au moyen de l’instruction GoTo Début et non avec une Return.
En ce qui concerne ces quatre subroutines, disons que ce sont pratiquement les mêmes que pour le premier logiciel de la figure 4 : En avant gère la marche en avant pour un pas (réclamant la Marche), c’est-à-dire des pattes droites et gauches. La subroutine Gauche est réclamée quand un obstacle est présent à droite. Au moyen de Arrière on recule de trois pas et au moyen du cycle “for” on tourne à droite. La subroutine Droite est symétrique de la Gauche : après avoir reculé on tourne à gauche. Enfin, Inverse réclame Arrière pour reculer de trois pas et inverse le sens de la marche en tournant de 180° à gauche.

Figure 8 : Listing “Mouvement avec contrôle des obstacles à infrarouges”.
‘************************************************************************************
‘* Nom : Spider_IR                                                                  *
‘* Notes : Mouvements avec contrôle des détecteurs à IR                             *
‘************************************************************************************

‘-----[ Définitions ]----------------------------------------------------------------
DEFINE LOADER_USED 1                      ‘Utilisé pour boot-loader
DEFINE OSC 20                             ‘Paramètre Clock à 20MHz
ADCON1 = 000111                           ‘Port A = Numérique

‘-----[ Vers Port ]------------------------------------------------------------------
TRISA = 110000                            ‘Paramètre pin Port A en Input et/ou Output
TRISB = 000000                            ‘Paramètre pin Port B en Input et/ou Output
TRISC = 000011                            ‘Paramètre pin Port C en Input et/ou Output

‘-----[ Définitions I/O ]------------------------------------------------------------
Servo1       VAR       PORTB.2            ‘Port Servo 1 (Droite)
Servo2       VAR       PORTB.1            ‘Port Servo 2 (Gauche)
Servo3       VAR       PORTB.0            ‘Port Servo 3 (Centre)

Speaker      VAR       PORTA.1            ‘Port Speaker

IR_1         VAR       PORTC.1            ‘Port Récepteur à infrarouges

IFR_1        VAR       PORTC.5            ‘Port Trx. infrarouges Droit
IFR_2        VAR       PORTC.2            ‘Port Trx. infrarouges Gauche

‘-----[ Définitions Variables ]------------------------------------------------------
Pos_Servo1       VAR       WORD           ‘position servo1 Droite
Pos_Servo2       VAR       WORD           ‘position servo2 Gauche
Pos_Servo3       VAR       WORD           ‘position servo3 Centre

mcount           VAR       BYTE           ‘loop pour subrout. marche
ncount           VAR       BYTE           ‘loop pour les autres
Note             VAR       BYTE           ‘note pour sound

action           VAR       BYTE
VarAnd           VAR       BYTE           ‘variable pour and logique
Sinist_IR_det    VAR       BIT            ‘variables pour sauvegarder...
Destr_IR_det     VAR       BIT            ‘...l’état du récepteur IR

‘-----[ Définitions Constantes ]-----------------------------------------------------
pos_max_3       CON       900             ‘Position Maximale Centre
pos_mid_3       CON       750             ‘Position Centrale Centre
pos_min_3       CON       600             ‘Position Minimale Centre
pos_max_1       CON       900             ‘Position Maximale Droite
pos_mid_1       CON       750             ‘Position Centrale Droite
pos_min_1       CON       600             ‘Position Minimale Droite
pos_max_2       CON       900             ‘Position Maximale Gauche
pos_mid_2       CON       750             ‘Position Centrale Gauche
pos_min_2       CON       600             ‘Position Minimale Gauche

Retard          CON       20              ‘Pause pour Pulsout en μs
Pas             CON       5               ‘Pas pour cycle Mise à zéro
Pas_1           CON       7               ‘Pas pour cycle Marche
Durée           CON       50              ‘Durée note pour Sound

‘-----[ Initialisation ]-------------------------------------------------------------
PORTA =0
PORTB =0
PORTC =0
      Gau_IR_det = 0
      Drt_IR_det = 0
      ncount = 0
      mcount = 0
      Note = 0
      VarAnd = 0

‘-----[ Début programme ]------------------------------------------------------------
      Note = 50
      GoSub Son                           ‘émets son

      Pos_Servo1 = pos_mid_1              ‘position initiale...
      Pos_Servo2 = pos_mid_2              ‘...des trois servomoteurs...
      Pos_Servo3 = pos_mid_3              ‘...au centre
      GoSub Mise à zéro

Début :
                                          ‘Vérification présence obstacle à Gauche
      High IFR_2                          ‘Active Trx. IR Gauche
      Pause 1
      Sinist_IR_det = IR_1                ‘Lis état Rx. IR
      Low IFR_2                           ‘Désactive Trx. IR
      Pause 1

      IF Gau_IR_det = 0 Then              ‘Si obstacle présent...
        Note = 10                           ‘...émets son
        GoSub Son
      EndIF
                                          ‘Vérifie présence obstacle à Droite.
      High IFR_1                          ‘Active Trx. IR Droite
      Pause 1
      Destr_IR_det = IR_1                 ‘Lis état Rx. IR
      Low IFR_1                           ‘Désactive Trx. IR
      Pause 1
      IF Destr_IR_det = 0 Then            ‘Si obstacle présent...
        Nota = 100                          ‘...émets son
        GoSub Son
      EndIF
                                          ‘Détermine quelle action exécuter
      action = 0
                                          ‘si 1 (obstacle non présent) ne rien faire
      IF Sinist_IR_det = 1 Then cont1
      action = action +1
cont1:
                                          ‘si 1 (obstacle non présent) ne rien faire
      IF Destr_IR_det = 1 Then cont2
      action = action +2
cont2:
                                          ‘Action = 0, aucun obstacle
                                          ‘Action = 1, obstacle à Gauche
                                          ‘Action = 2, obstacle à Droite
                                          ‘Action = 3, obstacle frontal
                                          ‘Exécute l’action indiquée par Action
VarAnd = action & 000011
Branch VarAnd, [Avance, Droite, Gauche, Inverse]

‘-----[ Subroutine ]-----------------------------------------------------------------
En avant :
      Pos_Servo1 = pos_min_1              ‘en arrière pattes Droite
      Pos_Servo2 = pos_min_2              ‘en avant pattes Gauche
      Pos_Servo3 = pos_max_3              ‘en bas centrale Gauche
      GoSub Marche

      Pos_Servo1 = pos_max_1              ‘en avant pattes Droite
      Pos_Servo2 = pos_max_2              ‘en arrière pattes Gauche
      Pos_Servo3 = pos_min_3              ‘en bas centrale Droite
      GoSub Marche

      GoTo Inizio                         ‘Retourne au cycle main

Marche :
                                          ‘Positionne les pattes centrales
      For mcount=1 to 100 step Pas_1
        PulsOut Servo3,Pos_Servo3
        Pause Retard
      Next
                                          ‘Bouge les pattes Droites et Gauches
      For mcount=1 to 100 step Pas_1
        PulsOut Servo1,Pos_Servo1         ‘Droite
        PulsOut Servo2,Pos_Servo2         ‘Gauche
        PulsOut Servo3,Pos_Servo3         ‘Centre
        Pause Retard
      Next
      Return

Son :
      Sound Speaker, [Note,Durée]         ‘Emets son
      Low Speaker                         ‘Eteins speaker
      Return

Mise à zéro :
                                          ‘Positionne les trois servomoteurs...
                                          ‘...en position centrale
      For ncount = 1 to 100 step Pas
        PulsOut Servo1,Pos_Servo1
        PulsOut Servo2,Pos_Servo2
        PulsOut Servo3,Pos_Servo3
        Pause Retard
      Next
      Return

Gauche :
                                          ‘Il faut revenir en arrière...
                                          ‘...de trois pas et tourner à Droite...
                                          ‘...pour éviter l’obstacle rencontré...
                                          ‘...par antenne_1
      Note = 10 ‘Emets son
      GoSub Son

GoSub Arrière                             ‘Reviens en arrière de trois pas

      For ncount=1 to 5 ‘Tourne à Droite
        Pos_Servo1 = pos_max_1 ‘av. pattes dx
        Pos_Servo2 = pos_min_2 ‘av. pattes sx
        Pos_Servo3 = pos_max_3 ‘en bas cent. sx
        GoSub Marche

        Pos_Servo1 = pos_min_1 ‘arr. pattes dx
        Pos_Servo2 = pos_max_2 ‘arr. pattes sx
        Pos_Servo3 = pos_min_3 ‘en bas cent. dx
        GoSub Marche
      Next
      Goto Début

Droite :
                                          ‘Il faut revenir en arrière...
                                          ‘...de trois pas et tourner à Gauche...
                                          ‘...pour éviter l’obstacle rencontré...
                                          ‘...par antenne_2

      Note = 100                          ‘Emets son
      GoSub Son

      GoSub Arrière                       ‘Reviens en arrière de trois pas
      For ncount=1 to 5 ‘Tourne à Gauche
        Pos_Servo1 = pos_min_1 ‘arr. pattes dx
        Pos_Servo2 = pos_max_2 ‘arr. pattes sx
        Pos_Servo3 = pos_max_3 ‘en bas cent. sx
        GoSub Marche

        Pos_Servo1 = pos_max_1 ‘av. pattes dx
        Pos_Servo2 = pos_min_2 ‘av. pattes sx
        Pos_Servo3 = pos_min_3 ‘en bas cent. dx
        GoSub Marche
      Next
      GoTo Début

Inverse :
                                          ‘Il faut revenir en arrière...
                                          ‘...de trois pas et tourner de 180°...
                                          ‘...pour éviter l’obstacle rencontré...
                                          ‘...par les deux antennes

      Note = 50                           ‘Emets son
      GoSub Son

      GoSub Arrière                       ‘Reviens en arrière de trois pas

      For ncount=1 to 7                   ‘Tourne à Gauche de 180°
        Pos_Servo1 = pos_min_1            ‘arr. pattes dx
        Pos_Servo2 = pos_max_2            ‘arr. pattes sx
        Pos_Servo3 = pos_max_3            ‘en bas cent. sx
        GoSub Marche

        Pos_Servo1 = pos_max_1            ‘av. pattes dx
        Pos_Servo2 = pos_min_2            ‘av. pattes sx
        Pos_Servo3 = pos_min_3            ‘en bas cent. dx
        GoSub Marche
      Next
      GoTo Début

En arrière :
      For ncount=1 to 4                   ‘Reviens en arrière de trois pas
        Pos_Servo1 = pos_max_1            ‘av. pattes dx
        Pos_Servo2 = pos_max_2            ‘arr. pattes sx
        Pos_Servo3 = pos_max_3            ‘en bas cent. sx
        GoSub Marche

        Pos_Servo1 = pos_min_1            ‘arr. pattes dx
        Pos_Servo2 = pos_min_2            ‘av. pattes sx
        Pos_Servo3 = pos_min_3            ‘en bas cent. dx
        GoSub Marche
      Next
      Return
End

Figure 9 : Le compilateur Basic pour PIC.
Pour pouvoir faire fonctionner chacun des trois robots disponibles, il est nécessaire d’écrire un programme qui leur fasse faire ce que nous voulons. Le programme peut être écrit en n’importe quel langage, mais pour pouvoir être transféré au PIC16F876, il est nécessaire qu’il soit compilé au format .HEX, compréhensible par le microcontrôleur. Nous avons utilisé le Basic et avons donc dû nous munir d’un compilateur Basic pour PIC capable de convertir les “listings” écrits en Basic en instructions de code machine.
Dans l’article, nous avons déjà fait référence au “bootloader” et au transfert à partir du PC des fichiers .HEX. Notre conseil est d’utiliser le “pack” PicBasic Compiler de μEngineerig Laboratoires. Avec ce logiciel, il est possible d’écrire un programme directement en Basic : ce sera ensuite au compilateur de le transformer en un fichier écrit en code machine, pouvant être mémorisé dans le microcontrôleur par l’intermédiaire du “bootloader”. L’utilisation de ce logiciel rend la programmation beaucoup plus simple et rapide, ce qui permet de réaliser en peu de lignes de Basic ce qui en demanderait beaucoup plus en Assembleur.
Deux versions du logiciel sont disponibles : une de base permettant d’utiliser des fonctions avancées de programmation, commandes de saut, d’interaction, etc., et une pro permettant en plus la gestion des “Interrupts”, la possibilité d’utiliser “array”, une meilleure gestion des sérielles au niveau matériel comme au niveau logiciel, etc. Quant à nous, nous nous sommes servis de la version de base du compilateur, suffisante pour cette application robotique.

Figure 9a : Ecran de PicBasic Compiler : il est possible d’écrire directement dans la fenêtre le listing en Basic. Avec un clic, on obtient le code compilé au format .Hex.

Figure 9b : Fenêtre de paramétrage de PicBasic Compiler : il est possible de spécifier si l’on veut utiliser la version de base ou pro, ainsi que le registre où se trouve le compilateur.

Conclusion
Cet article, le septième, achève notre chronique dédiée à la Robotique. Si vous nous avez suivi avec attention (ce dont votre abondant courrier nous interdit de douter) une bonne partie de cette année, vous êtes maintenant certainement capables de continuer par vous-mêmes à développer les ressources (matérielles et logicielles) caractérisant nos trois robots.
Il nous semble en effet que nous vous avons donné toutes les informations nécessaires pour vous permettre de réaliser ce qui, à notre avis, constitue la partie la plus intéressante, divertissante et passionnante de la robotique de loisir : étendre à de nouvelles fonctionnalités nos trois réalisations de telle façon que chacun de vous puisse personnaliser selon son goût et ses préférences son propre robot. En quelque sorte ces sept chroniques auront constitué un Cours de robotique par la pratique !
Désormais vous devriez avoir une connaissance approfondie de tous les concepts fondamentaux concernant la mécanique, l’électronique et l’informatique sous-tendant la réalisation de chaque robot présenté et, par exemple, il ne vous sera pas difficile de modifier légèrement l’électronique de manière à ajouter de nouveaux périphériques ou dispositifs.
Une idée, entre autres, nous vient à l’esprit : vous pourriez monter un second système émetteurs et récepteurs à infrarouges à l’arrière du robot et, au lieu de l’utiliser comme détecteur d’obstacles, vous pourriez réaliser un système permettant de “voir” et contourner d’éventuels trous ou marches.
Ou alors vous pourriez relier la carte-mère des trois robots à un module récepteur, de façon à réaliser une sorte de télécommande sans fil.
Si vous avez compris le fonctionnement des “listings” Basic que nous vous avons montrés et décrits ces derniers mois, vous devriez à présent être capables de les modifier pour les adapter à ces (ou à d’autres) nouvelles fonctions, comme par exemple la commande des périphériques ajoutés.
Prochainement, une nouvelle chronique remplacera celle qui s’achève : elle sera consacrée à la programmation des microcontrôleurs ST7LITE09. Merci pour votre fidélité.

Aucun commentaire:

Enregistrer un commentaire