Cours:MiniQ
Sommaire
documentations
Schéma de la carte électronique du miniQ
programmation avec arduino
|
Description et utilisation des commandes moteursUtilisation du timer 0 pour la MLIUn chapitre entier a été consacré [[../Le_Timer_0| au timer 0]] dans ce livre. Vous avez intérêt à le relire avant d'aller plus loin. Certains se demandent probablement s'il ne serait pas mieux d'utiliser le timer 1 pour la réalisation de la MLI (Modulation de Largeur d'Impulsion). C'est probablement vrai, mais c'est impossible à réaliser sans interruption. Nous allons essayer d'expliquer pourquoi maintenant. Commande des deux moteursLe timer 0 comme les autres timers permet une commande simultanée de deux moteurs. Puisqu'il s'agit du timer 0, les deux bits associés sont OC0A en PD6 (bit 6 du PORTD) et OC0B en PD5. Si le concepteur du robot a cablé ces deux bits comme commande des moteurs il est naturel d'utiliser le timer 0. C'est le cas comme on peut le voir sur le schéma de principe. Vous voyez bien PD5 connecté à EN1... mais par contre PD6 connecté à IN2. C'est forcément une erreur : PD6 doit être connecté à EN2. Côté puissance, la commande nécessite deux signaux :
avec i=1 ou i=2 pour chacun des moteurs. Le code d'initialisation de la PWM (ou MLI) est examiné maintenant. Code pour initialiser la MLIRappelons avant de commencer comment est câblé le module de commande des moteurs avec le processeur à l'aide d'une figure ci-contre) Voici le code fourni avec la platine est le suivant : void pwm_init(void)
{
TCCR0A = 0XA3;
TCCR0B = 0X03;//clk/64
TCNT0 = 0X00; //initialisation timer 0
TIMSK0 = 0X00;//Aucune interruption timer
}
Ce que fait la ligne TCCR0B=0X03 est décrit dans le commentaire. On rappelle que la division de l'horloge est choisie par les trois bits de poids faibles de TCCR0B
T0 est un bit qui n'est pas placé au même endroit suivant la famille. Ce que fait la ligne TCCR0A = 0XA3 est un peu plus complexe et nécessite la lecture de deux tableaux (qui sont rappelés). Voici le premier pour le poids fort de TCCR0A.
qui est identique pour COM0B1 et COM0B0. Les deux bits de poids fort du 0xA3 choisissent donc le troisième mode, et idem pour B. On utilise donc pour les deux moteurs la mise à zéro de OC0A (et aussi OC0B) qui sont les deux sorties reliées à EN1 et EN2. L'autre tableau à lire est :
Même si WGM02 est dans un autre registre, il n'y a aucune difficulté de remarquer que c'est la ligne 3 (PWM rapide) qui est choisie. Ceci est facilement trouvé avec la figure qui est rappelée : Code pour utiliser les moteursIl est possible de trouver des exemples de programmation du robot. A partir de ces exemples nous présentons un code source légèrement modifié pour être conforme au schéma de principe. Nous avons aussi renommé les paramètres pour savoir qui est moteur gauche et droit et diminué aussi leur taille. void Motor_Control(char MG_DIR,char MG_EN,char MD_DIR,char MD_EN)
{
//////////MGauche////////////////////////
if(MG_DIR==FORW)//si vers l'avant
PORTD |=(1<<7);//IN2 passé à 1
else
PORTD &=~(1<<7);//IN2 passé à 0
OCR0A = MG_EN;//Rapport cyclique
///////////MDroit//////////////////////
if(MD_DIR==FORW)//si vers l'avant
PORTD |=(1<<4);//IN1 passé à 1
else
PORTD &=~(1<<4);//IN1 passé à 0
OCR0B = MD_EN;//Rapport cyclique
}
Nous avons inversé les les numéros des moteurs pour être conforme au schéma de principe. Nous aurions préféré une appellation moteur droit et moteur gauche plutôt que des chiffres. Ce code doit donc être vérifié. Travail à faire : Exercice 1 (arduino)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. 1°) Voici un code complet d'initialisation et d'utilisation des moteurs : #define FORW 1
void setup() {
DDRD = 0XF2;//PORTD
DDRB = 0XFE;//PORTB en sortie sauf b0
pwm_init();
}
void pwm_init(void) {
TCCR0A = 0XA3;
TCCR0B = 0X03;//clk/64
TCNT0 = 0X00; //initialisation timer 0
TIMSK0 = 0X00;//Aucune interruption timer
}
void Motor_Control(char MG_DIR,char MG_EN,char MD_DIR,char MD_EN) {
//////////MGauche////////////////////////
if(MG_DIR==FORW)//si vers l'avant
PORTD |=(1<<7);//IN2 passé à 1
else
PORTD &=~(1<<7);//IN2 passé à 0
OCR0A = MG_EN;//Rapport cyclique
///////////MDroit//////////////////////
if(MD_DIR==FORW)//si vers l'avant
PORTD |=(1<<4);//IN1 passé à 1
else
PORTD &=~(1<<4);//IN1 passé à 0
OCR0B = MD_EN;//Rapport cyclique
}
void loop(){
Motor_Control(1,100,1,100);
delay(5000);
Motor_Control(0,0,0,0);
delay(1000);
Motor_Control(0,100,0,100);
delay(5000);
Motor_Control(0,0,0,0);
while(1);
}
Modifier ce code pour réaliser un simple cercle. Seule la partie loop est à modifier ! Modèle:Attention 2°) Étude du rayon du cercle. Nous avons vu en cours que Échec d'analyse (L’exécutable <code>texvc</code> est introuvable. Lisez math/README pour le configurer.): R(t) = \frac{L}{2} \frac{v_g(t)+v_d(t)}{v_g(t)-v_d(t)} Essayez d'étudier si le rayon peut s'écrire Échec d'analyse (L’exécutable <code>texvc</code> est introuvable. Lisez math/README pour le configurer.): R = K \frac{\alpha_g+\alpha_d}{\alpha_g-\alpha_d} où Échec d'analyse (L’exécutable <code>texvc</code> est introuvable. Lisez math/README pour le configurer.): \alpha_g et Échec d'analyse (L’exécutable <code>texvc</code> est introuvable. Lisez math/README pour le configurer.): \alpha_d désignent le rapport cyclique des moteurs gauche et droit (qui varient entre 0 et 255) et K est une constante à déterminer.
|