Académique Documents
Professionnel Documents
Culture Documents
Objectifs :
Prendre en main le matériel. Réaliser des essais sur le moteur électrique afin d’obtenir
ces les paramètres de son modèle de comportement (1er ordre).
Description du matériel
Sélectionner le ‘board’
Fig6. Choix de la carte
Connecter le MegaPi
Sélectionner le port
pinMode(PWM, OUTPUT);
pinMode(BI1, OUTPUT);
pinMode(BI2, OUTPUT);
pinMode(ENC_A,INPUT_PULLUP);
pinMode(ENC_B,INPUT_PULLUP);
Alimentation du moteur
Attention le moteur doit être alimenté en 9V maximum. La carte électronique peut
alimenter jusqu 12V et peut donc potentiellement endommager le matériel.
On peut se servir de ce mécanisme pour importer des données issues des capteurs sous
matlab.
L’encodeur est souvent composé d’un disque troué et de photo-capteurs (voies A,B et Z).
Lorsque le disque tourne, les voies A et B génèrent un signal carré. Un front montant ou
descendant indique déplacement d’une unité (8 fronts montants de la voie B = 1 tour) et
le déphasage entre les deux voies indique le sens du déplacement. La fréquence des
fonts montants indique la vitesse.
Afin de détecter les impulsions (et d’éviter d’en rater), on utilise le mécanisme
d’interruptions du micro-contrôleur. Lorsqu’un front est détecté sur la pin dédiée, le
processeur met en suspend les tâches en cours et exécute la fonction d’interruption.
Une fois que celle-ci est terminée, il reprend le programme là où il a été interrompu.
Remarque : Cette solution n’est pas optimale car des impulsions ‘fantômes’ peuvent être
comptées involontairement si le moteur vibre ou si les signaux de l’encodeur sont
bruité. D’autres solutions plus complexes existent pour éviter ce phénomène mais
demandent plus de ressources processeur (très limitées dans notre cas) ou un
périphérique dédié au comptage.
setup(){
...
attachInterrupt(digitalPinToInterrupt(ENC_B), OnRisingEdge,
RISING); // Activation du mécanisme d’interruption. sur un front
montant de la voie B de l’encodeur, OnRisingEdge() sera exécutée
immédiatement.
...
}
void OnRisingEdge()
{
static long lastTime;
long t = micros();
deltaT = t-lastTime;
lastTime = t;
}
Comme la donnée est modifiée de façon asynchrone, la donnée doit être protégée
lorsque l’on cherche à l’utiliser. Pour cela on indique au compilateur la nature ‘volatile’ de
cette information et on suspend tout mécanisme d’interruption lors de la copie de cette
donnée.
float getSpeed()
{
int deltaT_temp;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{ deltaT_temp = deltaT; }
if(deltaT_temp>0) // divide by 0 ?
return 1000000.0/deltaT_temp;
else
return 0;
}
Cadencer le code
Il existe deux solutions afin de cadencer le code (avoir un échantillonnage régulier des
mesures). La première consiste à créer une boucle d’attente, la deuxième d’utiliser les
périphériques ‘timers’. L’utilisation de la fonction ‘delay’ est à proscrire car le
comportement est indéfini dans certaines situations. Afin de simplifier l’implémentation,
on choisit la première solution.
#define DT 5
void loop() {
static long lastSampleTime;
while(millis()-lastSampleTime<DT)
{ }
lastSampleTime = millis();
// code à exécuter toutes les DT ms
}