Programmation Steppers du PAMI
Type de séance : libre · Durée : 1h30
Réalisé durant la scéance :
Code des roues du PAMI
Après plusieurs tentatives ces jours précedents et m’être plongé dans la documentation des bibliothèques (notamment FastAccelStepper chargé du pilotage des roues), j’ai trouvé et corrigé plusieurs problèmes.
Enable mais pas actifs
Avoir déclaré les Pins c’est bien, les activer, c’est mieux. Comme j’avais oublié les commandes d’activation.
leftmotor->enableOutputs();
rightmotor->enableOutputs();
Vitesse et accélération nulles
Je n’avais pas non plus défini de vitesse et d’accélération pour les steppers. Bien que je ne sois pas sûr de si cela avec un impact car il devrait y avoir une valeur de confiance par défaut.
#define STEPPER_SPEED_HZ 5000 // définition de la vitesse (en Step/s)
#define STEPPER_ACCELERATION 2000 // définition de la valeur d'accélération (en Step/s²)
leftmotor->setSpeedInHz(STEPPER_SPEED_HZ); // définition de la vitesse gauche et droite
rightmotor->setSpeedInHz(STEPPER_SPEED_HZ);
leftmotor->setAcceleration(STEPPER_ACCELERATION); // définition de l'accélération gauche et droite
rightmotor->setAcceleration(STEPPER_ACCELERATION);
Une fois ces problèmes réglés, j’ai pu piloter les steppers sans grande difficulté
Fonctions de déplacement linéaire
Les steppers étant maintenant fonctionel, j’ai pu me concentrer sur la création de fonctions afin de faciliter la programation des stratégies.
DistanceToStep(float distanceMm)
J’ai crée la fonction DistanceToStep(float distanceMm) permettant de calculer un nombre de step en fonction d’une distance (en mm).
// Pour les déplacements linéaires
#define WHEEL_DIAMETER_MM 62.4f // Diamètre exterieur des roues (en mm)
#define MICROSTEPS 16 // Microstepping réglé sur le TMC2209
#define GEAR_RATIO 1.0f // 1.0 = pas de réduction
#define MOTOR_STEPS_PER_REV 200 // Pas par tour de moteur (1.8 deg/step)
const float wheelCircumferenceMm = PI * WHEEL_DIAMETER_MM; // calcul de la circonférence des roues
const float stepsPerWheelRevolution = MOTOR_STEPS_PER_REV * MICROSTEPS * GEAR_RATIO; // calcul du nombre de step par tour de stepper
long DistanceToStep(float distanceMm) { // calcul un nombre de step en fonction d'une distance (en mm)
return lroundf(distanceMm / wheelCircumferenceMm *stepsPerWheelRevolution); // lroundf pour arrondir le float
}
Cette fonction sera utilisé pour programmer en distance et non en pas ce qui sera beaucoup plus pratique pour la réalisation de la stratégie.
Les valeurs contantes utilisés par
DistanceToStepsont à modifier dépendant des dimensions du PAMI (Roues, largeurs, réduction et nb de pas/tour).
waitForMotors()
La procédure waitForMotors() permet de déterminer si les moteurs sont actuellement en train de trourner et interromps le programme en attendant que les moteurs ai terminé leur dépaclement.
void waitForMotors() {
while (leftmotor->isRunning() || rightmotor->isRunning()) {
delay(1);
}
}
go(float distanceMm)
Une fois la conversion distance -> step programmé, j’ai pu définir la procédure go(float distanceMm) qui fait pilote les deux steppers simultanément en utilisant la fonction DistanceToStep(float distanceMm). La procédure pilote les steppers afin qu’ils tournent d’un nombre de pas équivalent à la distance demandée. La procédure prend en compte l’inversion potentielle des moteurs et les synchronisent.
// Si un moteur tourne dans le sens inverse, mettre sur "true"
#define LEFT_MOTOR_INVERTED true
#define RIGHT_MOTOR_INVERTED false
void go(float distanceMm)
{
if (!LEFT_MOTOR_INVERTED && !RIGHT_MOTOR_INVERTED) // Si les deux moteurs vont dans le même sens
{
leftmotor->move(DistanceToStep(distanceMm));
rightmotor->move(DistanceToStep(distanceMm));
waitForMotors();
}
else if (!LEFT_MOTOR_INVERTED && RIGHT_MOTOR_INVERTED) // Si le moteur droit est inversé
{
leftmotor->move(DistanceToStep(distanceMm));
rightmotor->move(-DistanceToStep(distanceMm));
waitForMotors();
}
else if (LEFT_MOTOR_INVERTED && !RIGHT_MOTOR_INVERTED) // Si le moteur gauche est inversé
{
leftmotor->move(-DistanceToStep(distanceMm));
rightmotor->move(DistanceToStep(distanceMm));
waitForMotors();
}
else if (!LEFT_MOTOR_INVERTED && !RIGHT_MOTOR_INVERTED) // Si les deux moteurs sont inversé (ne devrait pas arriver)
{
leftmotor->move(-DistanceToStep(distanceMm));
rightmotor->move(-DistanceToStep(distanceMm));
waitForMotors();
}
}
Cette procédure permettra d’alléger le code en permettant de piloter les deux steppers simultanément sans avoir à se soucier de leur synchronisation en utilisant des distances au lieux des pas.
Programme simple d’aller retour
Une fois toutes les fonctions et procédures mises en place, j’ai programmé un simple code d’avancer-reculer pour vérifier le bon fonctionnement du PAMI. Et il fonctionne !
Conclusion de la scéance :
J’ai enfin réussi à régler la plupart des problèmes lié au pilotage des moteur et ai pu créer les premières fonctions de déplacement. Certains problèmes subsistent toutefois. En effet, le servomoteur semble faire complètement dérailler les steppers bien qu’il n’y ai pas de lien apparant. Je devrait me pencher sur la question les prochaines fois.
A faire lors de la prochaine scéance :
| Type de tâche | Description | Priorité |
|---|---|---|
| Prgrammation | Trouver la sources de l’interférence servo-stepper | 1 |
| Conception | Brainrainstorm à propos du Graal | 2 |
| Rangement | Conception des slots pour les outils de la servante | 3 |