TPE année 2001 - 68hc11BUG

TPE année 2001
Le projet 68hc11bug

 
Index - Partie commande à distance - Le robot - Les photos - la triangulation

 

Partie PC

Partie microcontrôleur

 

Le programme PC
Le programme côté PC est réellement simple:
c'est un petit programme en Qbasic!
Il suffit de lui indiquer l'ordre à envoyer pour qu'il l'envoie.... plus compliqué, tu meurs ;)
donc, voilà un programme de test, qui envoie successivement les valeurs de 0 à 7 sur le port parallèle.

DO On boucle pour toujours
 FOR i = 0 to 7 on incrémente i
    OUT &H378 , i on envoie sur le port // la valeur de i
      do while inkey$="" on attend que l'utilisateur appui sur une touche
      loop
 NEXT i
LOOP

Pour le PC, on en est toujours aux programmes de tests, donc, rien de nouveau!




La commande des servos

Pour la commande des servos, on a eu une très mauvaise surprise:
En effet, malgré le passage du 68hc11A1 à 8mhz au 68HC11F1 à 16Mhz, le µContrôleur n'est toujours pas assez puissant!!
Enfin, pas autant que l'on aurait aimé....... :(
Il a donc fallut faire des choix quand à la précision.
On s'est donc tenu à une précision de 45°, soit 5 positions possibles pour chaque servo. (en fait, il va falloir modifier le programme, à cause du système de fixation, le servos va forcer dans les positions maximales).
Donc, nous sommes partis d'un système de tableau, puis, croyant que le tableau serait trop long à lire, on a stoppé les recherches dans cette voie, pour essayer un autre algorithme.
Cependant, malgré le très très bon compilateur, (on aurait fait sûrement plus long si on avait écrit directement en ASM) le programme prenait plus de 16ms..... moyen moyen!
Finalement, on est revenu à l'idée de départ, à savoir un tableau.

Vous pouvez télécharger les programmes, mais nous ne verrons ici que les parties les plus interressantes.

Principe du premier programme: (DL 6 novembre)
Le µContrôleur déclenche une interruption toutes les 16,4ms, ce qui a pour effet d'activer un programme d'interruption.
Ce programme ne fait que lire colonne par colonne le tableau:
il envoie le sur le port A la valeur contenue dans le tableau, attend quelques micro secondes, passe à la colonne suivante, etc...
Vous me direz "et Pour le 8è bit du port A, là où vous avez branché la sortie du récepteur?
Et bien la configuration entrée/sortie est effectuée en début de programme, sur le DDRA
En mettant DDRA=127, soit en binaire DDRA=%01111111, on configure le port de cette façon: les bits 0 à 6 en sortie, et le 7è bit en entrée.
Maintenant, il fallait configurer le programme pour qu'il réagisse sur l'entrée 7 du port A!

Voilà le programme sous interruption:
Remarquez qu'on a fait les tempos en assembleur pour deux raisons:
1/ ça m'amusait de les faire, car j'avais commencé à faire le programme d'interruption en ASM.
2/ c'est beaucoup plus court, et on peut modifier très très précisément la tempo. (avec un oscillo;-) )

 

interrupt function rtiint at $FFF0  
PORTA=255 'tempo de 0.8ms, impulsion minimale à envoyer
pshy  ' sauvgarde du registre y, on charge dans y la valeur 270
ldy #270  
_tmp: nop  ' nop: 2 cycles machine à ne ren faire
dey  ' decrémentation du registre y
bne _tmp  ' retourne à "_tmp" si y est positif
puly  ' fin de tempo, on recharge la valeur de y
for i= 0 to 6  ' boucle de lecture du tableau
PORTA = t(i)  
pshy  ' tempo entre chaque colonne
ldy #200  
_tmp2: nop  
dey  
bne _tmp2  
puly   restauration du registre y
next i on passe à la colonne suivante
   



TFLG2.6 = 1 ' autoriser ints a nouveau
end function

 


Deuxième programme:(12 novembre)(DL servo2, puis DL servo3)
Ce programme fut simple à réaliser:
Il "suffisait" de changer certains bits de configuration, et l'adresse du vecteur d'interruption.
Simple, oui, mais prise de tête ;)

Le programme du 13 novembre: (DL servo4, puis DL servo5)
C'est là qu'on a commencé à bien s'amuser: tout d'abord, il a fallut compter (servo4) puis définir les ordres (servo5)
Il doit réagir aux différentes largeurs d'impulsions reçues sur l'entrée 7.
Nous avons eu un problème à ce moment là: on a remarqué que le programme d'interruption ne se lance qu'après le front descendant du l'interruption.
Comme on voulait compter le temps pendant lequel l'entrée restait à 1, c'est raté!
C'est comme s'il se déclenchait sur le front descendant, au lieu du front montant.
Le mystère reste toujours présent, mais on a réussi à détourner le problème, en utilisant la fonction timer du 68HC11!
Tout simplement, en configurant le 68hc11, il nous suffit de lire le compteur PACNT pour avoir une valeur du temps pendant lequel l'entrée est restée à 1.
Finalement; ça ne fonctionne pas comme on le voudrait, mais, pour une fois, et c'est important de le préciser, ça fonctionne MIEUX!!!!
Maintenant qu'on a une valeur, il faut faire des encadrements pour lui faire faire une routine modifiant la position des servos.
L'encadrement est simple, et il utilise l'instruction "goto": oui, c'est vrai, on ne doit pas utiliser l'instruction goto, mais c'est tellement plus simple et plus rapide... ;)
Donc, voilà comment se compose cet encadrement:

comp=PACNT
if comp<70 then
ordre=0
goto fin
end if
if comp<80 then
ordre=1
goto fin
end if
etc....
jusqu'à
if comp<140 then
ordre=7
goto fin
end if

fin:
[suite du programme]

Donc, en faisant ça, on a nos ordres qui sont bien enregistrés!
Les valeurs obtenues lors du comptage sont 64, 74, 84, 94, 104, 114, 124, 134, avec des différences de l'ordre d'une unité.
Question stabilité, c'est vraiment très très bien!
Maintenant, il ne nous reste plus qu'à faire le programme de chargement du tableau, en fonction de l'ordre reçu.
Mais ça, ce n'est pas encore fait pour le moment:
Il faut tout d'abord avoir des sous routines qui modifient la position des pattes, une à une.
Ensuite, on verra question optimisation! (par exemple, pour tourner, on fait bouger les pattes gauches et droites dans le sens contraire, etc...)

Le programme du 20 novembre!
servo_6.bas puis servo_7h.bas

if ordre = 0 then 
gosub pos_0
end if
if ordre = 1 then
gosub pos_1
end if
if ordre = 2 then
gosub pos_2
end if
if ordre = 3 then
gosub pos_3
end if
if ordre = 4 then
gosub pos_4
end if
if ordre = 5 then
gosub pos_5
end if
if ordre = 6 then
gosub pos_6
end if
wai

On a pu tester pour la première fois le bon fonctionnement du µC:
Le problème, c'est que, même si le chargement du tableau se faisait, on perdait des impulsions, le µC plantait......
C'était du à 2 erreurs: le tableau de configuration n'était pas assez grand: là, le µC ne plantait plus
Pour ce qui est des impulsions qui "s'envolaient", ça s'est résolu en ajoutant une instruction "wai" en fin de configuration:
Le wai permet en effet d'attendre une interruption!

 

Programme du 27 novembre: (DL)
Là, c'est vraiment parfait:
en correction de TP (le lundi 26), j'ai recopié un petit programme  tout simple de configuration du tableau:
au niveau de l'initialisation, on a configuré un tableau de masque, pour que le µC n'ait pas à effectuer des calculs avec des puissances!

tabmsk(0)= %00000000
tabmsk(1)= %00000001
tabmsk(2)= %00000010
tabmsk(3)= %00000100
tabmsk(4)= %00001000
tabmsk(5)= %00010000
tabmsk(6)= %00100000
tabmsk(7)= %01000000

tabmsk2(0)=%11111111
tabmsk2(1)=%11111110
tabmsk2(2)=%11111101
tabmsk2(3)=%11111011
tabmsk2(4)=%11110111
tabmsk2(5)=%11101111
tabmsk2(6)=%11011111
tabmsk2(7)=%10111111

Vous aurez remarqué que tabmsk2(i) est le complément de tabmsk(i)!
C'est pour avoir plus de rapidité pendant le chargement du tableau:
au lieu de faire le complément, on charge 2 variables: msk, et msk2, complément de msk.
Après un petit problème au niveau des variables (il ne faut pas mettre tab_msk, mais tabmsk) pour le compilateur, on a obtenu ceci:

function conf_servo(numero,position)
 msk=tabmsk(numero)
 msk2=tabmsk2(numero)
 for i=0 to position
 t(i)=t(i) or msk
 next i

 for i = position to 7
 t(i)=t(i) and msk2
 next i
end function

 Donc, en indiquant conf_servo(1,3) (passage de 2 variables), on configure les masques en fonction du servo choisi, et on rempli le tableau!
Si c'est pas beau ça... ;-)
Pour le remplissage du tableau, 2 simples boucles for... next suffisent:
une pour remplir une ligne avec un certain nombre de 1, et la deuxième pour remplir le reste avec 0!
Et maintenant, on a plus rien à faire!
Le programme pour avancer, reculer, ou autre, doit en principe être fait par les 1ères. (snif, et moi, je m'amuse quand!)
Mais de toutes façons, on est maintenant soumis à l'avancement de la construction du robot!!
Je vous tiendrai au courant pour la suite!

17,18 et 19 décembre:

Ouf, c'est chouette la fin des cours: on a tout le temps voulu pour continuer la programmation!!!!
Donc, super nouvelle: le ROBOT MARCHE pour la première fois!!!!!!!!!!!!!
Une esquisse de pas le 18, et il marche réellement le 19!
et télécommandé, bien sur ;-)

voilà les programmes dispos: servo_9r.bas servo_10.bas et servo_11.bas

Vous me demanderez ce qu'on a fait le 17?
et bien, on a continué le positionnement dans l'espace du robot!!!!!

VACANCES

10 février:
non, on n'a rien fait, c'est la reprise, on repart doucement!
Le prof a commencé les CI, on va pouvoir faire les tests grandeur nature du positionnement dans l'espace du robot.

@ suivre...................


Le webmaster

Capturé par MemoWeb à partir de http://krys3.multimania.com/program.html  le 25/02/02