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 ?
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.
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).
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)
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
-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
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.
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.
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.
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.
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
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