dimanche 18 janvier 2015

Meccano + Arduino : mesurer la vitesse de rotation d'un moteur

Je possède différents modèles de moteurs Meccano, et pour savoir lesquels sont les mieux adaptés selon le montage, je voulais connaitre une de leurs caractéristiques principale : leur vitesse de rotation en tours par minute (souvent abrégé en RPM pour rotation per minute en anglais). Pour cela, il existe à ma connaissance deux méthodes : la première utilisant un phénomène physique appelé effet Hall, et basé sur la variation de tension provoqué par un courant traversant un aimant fixé sur l'arbre du moteur ; et la deuxième basée sur un faisceau infrarouge. C'est cette méthode que j'ai utilisé. Son principe est le suivant : un disque opaque pourvu de trous laissant passer la lumière est placé entre l'émetteur infrarouge et le récepteur. Lorsqu'un trou passe devant le capteur, le récepteur reçoit le signal et retourne la valeur 1, et lorsqu'une partie pleine passe, le signal est coupé et le capteur renvoie la valeur 0. De cette manière, on peut connaitre la vitesse de rotation du moteur en comptant le nombre de trous "vus" par le capteur durant un intervalle de temps donné.

Le capteur :

J'ai utilisé ce capteur trouvé sur eBay pour 1,50€ :


Une des colonnes en plastique contient l'émetteur, l'autre le récepteur. Il dispose de 3 pins : ground, +5V et out qui envoie 0 ou 1 comme dit plus haut. Il dispose en outre d'une petite LED intégrée qui s'allume si le signal passe, et qui fonctionne indépendamment du programme mis dans la carte Arduino, ce qui est pratique pour vérifier le comportement du capteur. La fourche étant petite (10mm de large sur 10mm de hauteur), il faut vraiment la positionner sur le bord de la roue perforée, et veiller à ce que celle-ci ne soit pas trop large. Dans mon cas, j'ai tout simplement utilisé une roue dentée Meccano, qui est évidemment munie de trous comme toutes les pièces Meccano (8 trous en l’occurrence).

Le moteur :

Pour ce premier test, j'ai pris un moteur 4,5V des années 70 appelé "Junior Power Drive Unit" ou plus simplement "Reversible 4,5V DC Motor". La notice d'origine indique une vitesse de 1000 tr/min, que je vais pouvoir vérifier maintenant.


Le montage :


Le montage est très simple : le moteur est alimenté par une batterie 12V à travers un abaisseur de tension pour arriver à sa tension nominale de 4,5V. Le capteur est placé devant la roue et est branché sur la carte Arduino (le shield moteur visible sur la photo n'est pas utilisé). Enfin, la carte est reliée à l'ordinateur par USB pour l'alimentation et l'envoi des données mesurées.

Le programme :
/*Code adapté de celui de CMPalmer :
 * http://www.instructables.com/id/Arduino-Based-Optical-Tachometer/step4/Programming/
 */

volatile int rpmcount;  //compte le nbre de fois où le faisceau du capteur optique est coupé
float rpm;  //la variable qui va afficher le nombre de tours, et qui sera mise à jour dans le loop()
unsigned long timeold;  //sert à enregistrer le temps écoulé depuis la dernière mise à jour du compteur
unsigned int nbTrous=8;  //le nombre de trous dans la roue fixée sur l'arbre du moteur

void rpm_counter()
{
  //A chaque rotation du moteur, cette fonction d'interruption est appelée [nbTrous] fois
  rpmcount++; //on incrémente le compteur
}

void setup()
{
  Serial.begin(9600);  //initialisation de la liaison série

  //la pin "out" du capteur doit être reliée sur une pin de l'arduino gérant les interruptions
  //sur mon Arduino Mega 2560, je l'ai branché sur la pin 21, qui correspond à Interrupt 2
  //voir http://arduino.cc/en/Reference/attachInterrupt pour plus d'infos sur les interruptions avec 
  //les pins associées suivant votre modèle de carte

  //la fonction rpm_counter sera appelée sur chaque front descendant (FALLING) de la pin 21
  attachInterrupt(2, rpm_counter, FALLING);

  //initialisation des variables
  rpmcount = 0;
  rpm = 0;  
  timeold = 0;  
}

void loop()
{
  //on met à jour le compteur toutes les 500 ms
  delay(500);

  //le traitement des interruptions est stoppé pendant les calculs
  detachInterrupt(2);

  //calcul du nombre de rotations par minute (rpm) :
  //rpm = [nbre de rotations depuis le dernier calcul]/[temps écoulé en ms]*[60000ms(=1min)]/[nbre de trous]
  rpm = (float)rpmcount/(millis() - timeold)*60000.0/nbTrous;

  timeold = millis();  //on actualise timeold pour le prochain calcul
  rpmcount = 0;  //on remet à zero le compteur avant le prochain calcul

  //on affiche la valeur sur le moniteur série
  Serial.println(rpm);

  //on rédemarre le traitement des interruptions
  attachInterrupt(2, rpm_counter, FALLING);
}

Les résultats :

J'ai fait tourner le programme pendant 50s pour avoir 100 valeurs qui m'ont permis de tracer la courbe suivante :


La moyenne est de 1656,47 tr/min, soit largement plus que les 1000 tr/min indiqués dans la notice !

4 commentaires:

  1. J'ai tester le programme et le montage sauf que les valeurs retournées par arduino sont fausses, j'ai pu vérifier avec un compte tour.

    RépondreSupprimer
  2. Bonjour! J'ai testé votre programme la mais il affiche toujours une vitesse de 0.00

    RépondreSupprimer