Précédente Accueil Suivante

 

Accueil
Le projet IRBOT
Chassis roues
Servomoteur
Modif servos
Test servos
Le radar IR
Premiers pas robot
Détection collision
Télécommander
Test RC5
IRBOT et RC5
Mémo parcours
Mise en veille
Vers PIC16F628
Borne recharge
Compilateur CCS
Modif matérielle
Recharge du robot
Bip Bip ...
En musique
Vidéos
Téléchargements
Carte développ.
Liens Affiliation

 

Test des servomoteurs

Pour tester notre servo modifié nous allons utiliser l'Ensemble de développement pour PIC16F84 de chez Robots Loisirs.
L'ensemble se compose d'une carte d'expérimentation et d'un programmateur de pic. La carte est équipée d'une plaque d'expérimentation sans soudure. Ceci permet d'effectuer des montages de test en un temps record.
On effectue le raccordement du servo en fil volant. Le PIC pourra être reprogrammé en quelques secondes et à volonté.



Ci-dessous le schéma de raccordement du servo et la forme du signal en sortie B0.



Pour ceux qui n'ont pas la notion du microcontrôleur PIC16F84, visitez la page http://perso.wanadoo.fr/yves.heilig/ElecRob/page1.htm

Comme dit, nous allons utiliser le compilateur CCS pour écrire notre programme de test en C.
Le programme de test va faire tourner le servo dans un sens, puis va l'arrêter, puis va le faire tourner dans l'autre sens. Dans un premier temps à la vitesse maxi puis à vitesse réduite. Et ceci indéfiniment.

Voici le programme.


//*************************************
// CCS Compiler
// Commande servomoteur
//
// Auteur : HEILIG Yves
//*************************************

#include <16f84.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=20000000)

//*******************
// variables globales
//*******************

int16 COMPTEUR1;
int COMPTEUR2, SENS;
int1 SIGNAL;

//******************
// DEFINE
//******************

#define TIME 4 // TIMER=3 --> 256-3=253 pas

#define 18MS 360 // 360*50=18000µs
#define AV 40 // 40*50 =2000µs
#define AR 20 // 20*50 =1000µs
#define AVP 32 // 32*50 =1600µs
#define ARP 28 // 28*50 =1400µs
#define STOP 30 // 30*50 =1500µs

#define PORT_SIGNAL PIN_B0

//******************
//Interruptions
//******************

#int_timer0 // Interruption toutes les (4*250)/20000000 = 50µs

main_int () {
set_timer0(TIME);
if (++COMPTEUR1 == 360) {
COMPTEUR1=0;
COMPTEUR2=0;
SIGNAL=1;
output_high(PORT_SIGNAL);
}
else {
if (SIGNAL==1) {
if (COMPTEUR2++ == SENS) {
SIGNAL=0;
output_low(PORT_SIGNAL);
}
}
}
}

//**********************
// Fonctions
//**********************

void init_timer () {

set_timer0(TIME);
setup_counters(RTCC_INTERNAL,WDT_18MS);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
}

//**********************
// Programme principal
//**********************

main() {

init_timer();

while (TRUE) { // boucle sans fin

SENS=AV; // en avant pendant 3"
delay_ms(3000);
SENS=STOP; // stop 1"
delay_ms(1000);
SENS=AR; // en arrière 3"
delay_ms(3000);
SENS=STOP; // stop
delay_ms(1000);
SENS=AVP; // en avant petite vitesse 3"
delay_ms(3000);
SENS=STOP; // stop
delay_ms(1000);
SENS=ARP; // en arrière petite vitesse
delay_ms(3000);
SENS=STOP; // stop
delay_ms(1000);
}
}


Quelques explications s'imposent.

Le principe utilisé est de générer une interruption toutes les 50µs. Lors de chaque interruption l'on incrémente COMPTEUR1. Lorsque COMPTEUR1 atteint la valeur de 360, 18ms (360*50) se seront écoulées.
On met la sortie B0 à 1 et on démarre un deuxième compeur COMPTEUR2 qui lui aussi est incrémenté toutes les 50µs. COMPTEUR2 détermine la durée de l'impulsion (entre 1 et 2ms). Lorsque COMPTEUR2 aura atteint la valeur seuil (ex: 30 pour 1.5ms (30*50)) la sortie B0 repasse à 0.

En ce qui concerne la structure du programme. Tout ce qui est après les // est du commentaire.
Le programme principal démarre à "main ()".
On configure le TIMER0 (init_timer) afin qu'il génère une interruption à chaque passage par 0. Le TIMER est un compteur 8bits qui est incrémenté à chaque cycle d'instruction (1 cycle d'intruction = 4 cycles d'horloge). Il compte de 0 jusqu'à 255, puis repasse à 0 et ainsi de suite...
Dans notre cas on le fait compter de 4 jusqu'à 255, puis 0. Ceci afin d'obtenir notre interruption toutes les 50µs.
La formule est la suivante (4*250/20000000)=50µs. Vous me direz (enfin pour ceux qui suivent ) 255-4 ne donne pas 250, mais 251. Il faut faire une légère correction, car lorsque la routine d'interruption est appelée il se passe quelques ns avant que le TIMER soit assigné à 4 et recommence à s'incrémenter.

A chaque interruption du programme principal la routine "main_int()" est appelée. C'est cette routine qui génère le signal pour notre servo.


Notre servo tourne bien comme prévu. Nous allons pouvoir passer à la suite.


Précédente Accueil Suivante