Programmer une distance à l'aide d'un moteur circulaire

Tout d'abord bonjour à tous,

Dans le cadre d'un projet en science de l'ingénieur, moi et mes camarades avons eu l'idée de faire un système de saut en hauteur/longeaur automatisé.

Ma partie ( la plus complexe ) consiste à ce que l'utilisateur puisse choisir sa hauteur et donc lever la barre à l'aide d'une télécommande, pour l'élévation j'utilise donc une vis-écrou ( voir le schéma ) après avoir fait mon solidwork voila que ma partie sur Arduino me pose un véritable soucis car je ne sais pas vraiment me servir d'arduino en toute honnêteté...

Le pas de ma vis écrou est de 20mm (c'est beaucoup mais c'est en modèle réel qui fait 6m) et un moteur de 200 RMP. Mon professeur ma dit d'utiliser un moteur circulaire avec un code Arduino spécifique :

voici mon code :

#include <SoftwareSerial.h>
#include <Wire.h>

#define CMD                 (byte)0x10                        // Values of 0 eing sent using write have to be cast as a byte to stop them being misinterperted as NULL
                                                              // This is a but with arduino 1
#define MD25ADDRESS         0x58                              // Address of the MD25
#define SOFTWAREREG         0x0D                              // Byte to read the software version
#define SPEED1              (byte)0x00                        // Byte to send speed to first motor
#define SPEED2              0x01                              // Byte to send speed to second motor
#define ENCODERONE          0x02                              // Byte to read motor encoder 1
#define ENCODERTWO          0x06                              // Byte to read motor encoder 2
#define VOLTREAD            0x0A                              // Byte to read battery volts
#define RESETENCODERS       0x20



int x=0;               // int x stores a value to be used as speed data for the motors
int t=0; 

#include <LiquidCrystal.h> // on importe la bibliothèque
LiquidCrystal monEcran(12,11,5,4,3,2); // on crée l'objet écran







void setup() {
 
  
  
  monEcran.begin(16,2); //on initialise la communication avec 16 colonnes et deux lignes
  monEcran.clear(); // on efface l'écran
  monEcran.print("DISTANCE?"); // on écrit distance
  monEcran.setCursor(0,1); //on passe à la ligne suivante
  monEcran.print("t=?"); 


  
  Wire.begin();
  Serial.begin(9600);

  
  delay(200);                                               // Wait for everything to power up

 

              
}

void loop(){
float y = t/0.02;

 
 
 x = 200;                                                   // Put a value of 255 in x, this will dive motors forward at full speed, début à mettre avec le codee 
    encodeReset();                                                 // Start loop to drive motors forward
 
  
    Wire.beginTransmission(MD25ADDRESS);                    // Drive motor 1 at speed value stored in x
    Wire.write(SPEED2);
    Wire.write(x);
    Wire.endTransmission();
    do
    {  
    }
    while (  encoder2() < 360);   // Loop untill encoder 1 is 5000 or more
       
 
                                              // Calls function to stop motors

  
    Wire.beginTransmission(MD25ADDRESS);                    // Drive motor 1 at speed value stored in x
    Wire.write(SPEED2);
    Wire.write(128);
    Wire.endTransmission();
    
   
    Serial.print("n="); 
    Serial.println( encoder2());
    delay (1000);                               // fin 
  
 
  
  
}

long encoder2()
  {                                            // Function to read and display velue of encoder 2 as a long
  Wire.beginTransmission(MD25ADDRESS);           
  Wire.write(ENCODERTWO);
  Wire.endTransmission();
  
  Wire.requestFrom(MD25ADDRESS, 4);                         // Request 4 bytes from MD25
  while(Wire.available() < 4);                              // Wait for 4 bytes to become available
  long poss2 = Wire.read();
  poss2 <<= 8;
  poss2 += Wire.read();                
  poss2 <<= 8;
  poss2 += Wire.read();                
  poss2 <<= 8;
  poss2  +=Wire.read(); 
  Serial.println(poss2);
   return(poss2);
  }
  
void encodeReset()
{                                        // This function resets the encoder values to 0
  Wire.beginTransmission(MD25ADDRESS);
  Wire.write(CMD);
  Wire.write(0x20);                                         // Putting the value 0x20 to reset encoders
  Wire.endTransmission(); 
}

Sauf que je suis complètement perdu, j'ai trouvé une fonction qui convertit une distance en tour : f(x)= x/0,02

mais je ne sais pas comment programmer je ne sais pas si j'ai était assez clair mais auriez vous des idées ?

Merci d'avance.

Ton code n'est pas simple, mais bon. Je suppose que tu sais ce qu'est un encodeur.
L'arduino communique avec le moteur et l'encodeur par le protocole I2S (bibli Wire dans ton code). Est-ce que par hasard, tu aurais ce module ?


Tu vois qu'il y a des broches pour connecter un capteur à effet hall et un moteur (2 fois). SDA et SCL sont les broches pour connecter le I2C.

Ce que fait ton code (dans la loop, le reste c'est des initialisations) :

D'abord il fait tourner le moteur "à pleine vitesse". Ici la variable x correspond à la vitesse. Tu vois que la communication se fait à chaque fois en plusieurs temps : pour lui indiquer une vitesse, il envoie d'abord le mot clé SPEED2 (en fait la valeur 1) puis il envoie la valeur de la vitesse.

x = 200;                                                   // Put a value of 255 in x, this will dive motors forward at full speed, début à mettre avec le code
    encodeReset();                                                 // Start loop to drive motors forward
 
  
    Wire.beginTransmission(MD25ADDRESS);                    // Drive motor 1 at speed value stored in x
    Wire.write(SPEED2);
    Wire.write(x);
    Wire.endTransmission();

Ensuite il lit la position donnée par l'encodeur et attend que celle-ci soit égale à une valeur de consigne, ici 360.

 do
    {  
    }
    while (  encoder2() < 360);   // Loop untill encoder 1 is 5000 or more
       
 
                                              // Calls function to stop motors

Enfin, il stoppe le moteur en envoyant '1' puis le code 128 qui veut dire STOP.

    Wire.beginTransmission(MD25ADDRESS);                    // Drive motor 1 at speed value stored in x
    Wire.write(SPEED2);
    Wire.write(128);
    Wire.endTransmission();

Donc ce que tu dois faire c'est étalonner ton moteur : connaitre le nombre de tours (ou la fraction de tour) nécessaire pour déplacer la barre d'une distance donnée (par exemple 10 cm). Il te suffira d'utiliser cet étalonnage pour mettre la consigne correspondant à la hauteur ou la distance voulue, par une simple règle de 3.

Merci pour votre réponse, je ne sais pas si j'ai le module au lycée ( tout le matériel est dans mon lycée est je suis encore en vacances scolaire )

J'ai assez bien compris la partie avec les codes mais je ne comprend pas très bien ce que vous voulez dire par "étalonner" le moteur.

J'ai fait un latispro de la distance en fonction du temps (ci-joint la capture) :

Si j'ai compris je dois savoir combien fait par exemple 1m en nombre de tours ?

nathan latispro.PNG - Google Drive ( l'autre lien ne fonctionne pas apparement voici le bon car je ne sais pas comment mettre des images ici )

bonjour,
c'est quoi ton moteur?
moteur dc, pas a pas?
avec un PAP, c'est simple, mais il faut en prendre un gros si ta tige fait réellement 6m.
un tour, 200 pas imaginons, font 20mm
donc pour 4m par exemple, il te faudra 200 pas*200 tours, soit 40000 pas (si je ne me trompe pas dans le calcul)

Natfrd:
J'ai fait un latispro de la distance en fonction du temps

Moi je ne connais pas latispro, mais c'est pas bien grave : ta courbe est linéaire : tu peux en tirer une équation du genre x = a * t + b (mon fils en seconde sait faire ça...)

Après, je ne sais pas ce que représentent les axes : je suppose que l'ordonnée 'x' représente la hauteur et l'abscisse 't' le temps de rotation du moteur ? A quelle vitesse ?

Si c'est ça (hypothèse à confirmer), alors tu commandes le moteur par la durée de fonctionnement, pas par la position fournie par l'encodeur : est-ce bien ce qui t'est demandé ?

Si tu utilises la proposition d'Infobarquee, tu peux t'inspirer de ceci.

A t'on besoin de précision ? Combien d'erreur acceptable ?

Car faire tourner le moteur continu un certain temps pour atteindre une hauteur proportionnelle à la durée va induire une erreur de positionnement. Ce ne sera pas très reproductible.
A chaque changement de position les erreurs vont s'accumuler (à moins de se recaler à zéro à chaque fois).

L'utilisation d'un moteur pas à pas, ou d'un encodeur à encoches est en revanche très précise, à 1 pas près on est à 0.1 mm (200 pas par tour de 20mm de translation).

Bonjour à tous,

Oui il faudrait un maximum de précision, c'était aussi prévu de se recaler à zéro à chaque fois.

lesept : J'avais cette fonction et je voulais la mettre dans mon programme de tel sorte que ont demande à l'utilisateur la distance et que le calcul ce fasse tout seul, mais c'est possible sur Arduino ?

Il me semble que le moteur donné par mon professeur est un moteur Dc.

Et si je n'arrive pas à rentrer la fonction faut t-il que je convertisse par exemple 1m en nombre de tours à chaque fois ? (mais je ne vois pas comment convertir des m en tour ce n'est pas possible ?)

si tu répondais aux questions, ca serait bien, non?

infobarquee:
bonjour,
c'est quoi ton moteur?
moteur dc, pas a pas?
avec un PAP, c'est simple, mais il faut en prendre un gros si ta tige fait réellement 6m.
un tour, 200 pas imaginons, font 20mm
donc pour 4m par exemple, il te faudra 200 pas*200 tours, soit 40000 pas (si je ne me trompe pas dans le calcul)

Natfrd:
Il me semble que le moteur donné par mon professeur est un moteur Dc.

Je ne comprends pas ton projet : ton code parle clairement d'encodeur. J'en déduis que c'est grâce à l'encodeur que tu vas piloter la position de la barre.

Mais ensuite, tu fournis une courbe (une droite en fait), sans expliquer ce qu'elle représente. Là je suis perdu : je ne sais pas s'il faut utiliser cette courbe ni comment l'utiliser.

Donc avant de savoir comment la mettre dans le programme, il faut expliquer ce qu'elle représente.

J'ai fait une courbe pour m'aider. Elle représente en ordonnées la distance en mètres en fonction du temps
donc par exemple combien de temps vas durer la montée de la barre pour 1m. Peut-être que ce que j'ai fait ne sert strictement à rien :confused:

Bonsoir

-le programme , "ton" programme, fait référence à la carte MD25

  • la documentation de cette carte indique qu'elle est conçue pour piloter des moteurs EMG30 (moteur+ réducteur+ codeur relatif).

  • Oui ou non la carte de commande du moteur est-elle une MD25 ?

  • Oui ou non le moteur utilisé est-il un EMG30 ?
    (si la réponse aux deux questions est oui , alors le code présenté à du sens , sinon il faut reprendre à zéro en tenant compte des caractéristiques de la carte et du moteur utilisés et de la transmission du mouvement)

Le code présenté compte sur la carte MD25 pour l'information 'nombre de tours effectués par le moteur', information que la carte ne peut pas élaborer sans signaux issus du codeur relatif du moteur EMG30

Bonsoir,

C'est mon professeur qui m'a dis " je vais te donné un code ça vas te servir" je pense que si il m'a donné ce code c'est que la carte du moteur est une MD25. Et pour le moteur j'en suis sur je l'ai vu c'est bien un EMG30.

Au message #13 on a enfin la révélation !!!

récapitulons :

1)le moteur est associé à un réducteur dont on connait le rapport, tu peux donc savoir combien de tours du moteur sont nécessaires pour que l'arbre de sortie du réducteur fasse un tour.

  1. tu connais le pas du système vis-écrou et peux donc calculer la longueur parcourue par l'écrou pour un tour de l'arbre de sortie du réducteur.

  2. une fois établi cette dernière donnée tu peux traduire la hauteur saisie par l'utilisateur en nombre de tours de moteur à faire effectuer par le moteur. Ton programme lancera le moteur, interrogera (bus I2C) le compteur de tours intégré à la carte MD25 et arrêtera le moteur à temps, au besoin en réduisant la vitesse en approche.

On ne fait pas ça aujourd'hui en "Sciences de l'Ingénieur" ?

Pour compléter ce que dit al1fch, si je le comprends bien, le calcul du nombre de tours que tu fais te donnera la consigne, qu'il faudra mettre à la place du '360' dans ton code initial.

Bonjour, nous n'avons jamais fait ça avec Arduino. Nous avons vu ça en cours très rapidement.

Savez vous comment " calculer la longueur parcourue par l'écrou pour un tour de l'arbre de sortie du réducteur." ?

Merci beaucoup de votre aide.

lesept:
Pour compléter ce que dit al1fch, si je le comprends bien, le calcul du nombre de tours que tu fais te donnera la consigne, qu'il faudra mettre à la place du '360' dans ton code initial.

D'accord merci pour cette information :slight_smile:
mais je comprend pas trop comment faire pour convertir ma distance en nombre de tours, avec le pas mais je ne vois pas quel calcul faire

Wikipedia :

Le pas de vis correspond à la distance relative parcourue en translation par une vis par rapport à son écrou lors d'un tour complet

Si le pas de vis vaut 'h', la hauteur augmente de 'h' à chaque tour.

  • 1 tour : +h
  • 2 tours : +2h
  • etc.
    C'est pas sorcier...

complément içi