Problème pour faire tourner 2 moteurs nema17 avec NRF24L01+

Bonjour lilian2230

C'est que ton moteur a encore "quelque chose à faire", ça veut dire que tu lui a donné un ordre de déplacement.
Tu peux voire ça avec la fonction stepper1.distanceToGo().

Cordialement
jpbbricole

PS:
Mets ça

		Serial.println(stepper1.distanceToGo());
		Serial.println(stepper2().distanceToGo());

dans ta loop() et tu verra en permanence "le travail à faire" de tes MPAP.
N'oublies pas dans setup(), Serial.begin(115200); :wink:

Cordialement
jpbbricole

Essayez un truc comme cela

#include <AccelStepper.h>

// X Stepper pins
const byte STEPPERX_DIR_PIN   = 2;
const byte STEPPERX_STEP_PIN  = 3;

// Y stepper pins
const byte STEPPERY_DIR_PIN   = 5;
const byte STEPPERY_STEP_PIN  = 6;

AccelStepper stepperX(AccelStepper::DRIVER, STEPPERX_STEP_PIN, STEPPERX_DIR_PIN);
AccelStepper stepperY(AccelStepper::DRIVER, STEPPERY_STEP_PIN, STEPPERY_DIR_PIN);

float vitesse = -500;
int signe = 1;
unsigned long chrono;

void setup() {
  Serial.begin(115200);
  stepperX.setMaxSpeed(1000.0);
  stepperY.setMaxSpeed(1000.0);
  stepperX.setSpeed(vitesse);
  stepperY.setSpeed(-vitesse);
  chrono = millis();
  Serial.print(F("Vitesse Initiale: ")); Serial.println(vitesse);
}

void loop() {
  stepperX.runSpeed();
  stepperY.runSpeed();

  // changement de vitesse toutes les 3s
  if (millis() - chrono >= 3000) {
    vitesse += signe * 100;
    if (abs(vitesse) > 400) signe = -signe;
    stepperX.setSpeed(vitesse);
    stepperY.setSpeed(-vitesse);
    Serial.print(F("Changement Vitesse: ")); Serial.println(vitesse);
    chrono = millis();
  }
}

qui devrait faire bouger les moteurs en sens inverse à une vitesse qui varie toutes les 3 secondes par incréments/décréments de 100 entre -500 et +500 (pas par secondes)

NB: non testé, j'ai juste repris votre code de base pour la config

J'ai le même moteur. Mais ma doc donne:


Qui me paraît plus raisonnable: pour ce type de moteur, on l'alimente en courant ce qui va faire 2,5V à l'arrêt (et vers 7V au maximum).

Mais c'est pas important. Pour un moteur à 1,5A par phase, le A4988 devrait être réglé sur √2 fois 1,5A soit 2,1A au delà de la limite du circuit et sans doute du réglage. Pour régler le couple au maxi, tourner l'ajustable à fond dans le sens des aiguilles.

Pour le régler correctement, comme on n'a pas forcément besoin du couple maximum, tourner alors l'ajustable dans le sens inverse des aiguilles jusqu'au décrochage et le remonter un peu.
Si le moteur tourne correctement, le courant est réglé trop haut, si il perd des pas, il est réglé trop bas.

Il régule le courant, mais pas si facile de mesurer le courant ou la tension surtout en mode pas car ce n'est pas du sinus.

j'ai faite cette mesure a l'arrêt

c'est fait , ça marche bien , mais mon problème survient lorsqu'il y a un "rallongement" du code , (quand les boucles" if" s'enclenchent par exemple) , les moteurs tournent bien indépendamment (lorsque l'autre n'est pas activé) , quand le" if" du moteur éteint s'active , le deuxième moteur ralenti , mais tourne toujours . puis les 2 moteurs tournent plus lentement mais tournent bien.

Je vient de mesurer le signal de sortie de l'Arduino ( à l'oscilloscope ) .Le signal "PWM" (qui change de fréquence et non de rapport cyclique) n'est pas à 50% mais plutôt aux alentours de 1-2% , c'est réglable?

ce sont des fils qui peuvent (je crois) passer + ou - 2A donc pas de problème de ce coté là
et environ 1M de long , ce sont les câbles livrés avec les moteurs , mais je n'est pas de connecteur (je suis sur plaque d'essai , donc j'ai mis des fils ~5-6cm pour les raccorder
mais bon, voici mon montage (au cas ou)(désolé c'est un peux flou) :

2A dans la breadboard …. Pas top.

Si mon code fonctionne correctement c’est déjà un bon debut au niveau du montage.

Les if est petits calculs que vous rajoutez ne consomment que quelques microsecondes au pire, le souci ne vient de pas de là.

notez que j’ai pris des valeurs raisonnables pour la vitesse Et que j’utilise runSpeed() et pas run(), c’est à dire que je laisse le moteur tourner. Vous faites des pas de 1 et recalculez la vitesse à chaque pas, ça peut avoir un effet.

Je vient de réessayer avec runSpeed , cela na rien changée.

quelques microsecondes peuvent suffire à modifier la fréquence et donc la vitesse .les A4988 sont trés precis.

Je ne suis pas sûr de quelle fréquence vous parlez. Au pire l’ordre est un peu en retard mais le driver fait le job.

Les imprimantes 3D interprètent du GRBL et pilotent trois moteurs et il n’y a pas de soucis…

Il doit y avoir autre chose

Pour piloter un moteur pas à pas via un driver comme le A4988, on envoie en principe des impulsions. La partie du code qui fait ceci dans AccelStepper est:

void AccelStepper::step1(long step)
{
    (void)(step); // Unused

    // _pin[0] is step, _pin[1] is direction
    setOutputPins(_direction ? 0b10 : 0b00); // Set direction first else get rogue pulses
    setOutputPins(_direction ? 0b11 : 0b01); // step HIGH
    // Caution 200ns setup time 
    // Delay the minimum allowed pulse width
    delayMicroseconds(_minPulseWidth);
    setOutputPins(_direction ? 0b10 : 0b00); // step LOW
}

Cette fonction est appelée chaque fois que l'on a besoin de faire un pas. On y voit que step passe à HIGH, on attend et on repasse à LOW. L'attente est pour certains drivers qui on besoin d'un minimum de temps pour STEP à l'état haut (A4988 = 1µs par exemple). Cette impulsion dure le même temps quelle que soit la vitesse. Si on va à 1000pas/s, le signal STEP est à 1000Hz, avec par exemple état bas = 1ms et état haut=20µs. Si on fait maintenant 100pas/s, on a l'état bas à 10ms et l'état haut à 20µs... Ce n'est pas du PWM. Le rapport cyclique n'a aucun intérêt.
Note: avec les moteurs bipolaires, le rapport cyclique est de 50,00% à vitesse constante, le pilotage n'est pas le même.

Le réglage du rapport cyclique est ajustable avec la fonction setMinPulseWidth, mais pour un A4988 cela n'a aucun intérêt, que ce soit 1µs, 20µs ou 1ms, cela ne change strictement rien. Augmenter ce temps diminue la fréquence maximale des pas de la bibliothèque.

Elles n'utilisent pas forcément AccelStepper. J'ai fait tourner 4 moteurs en même temps à 780tr/mn en mode 16 micros-pas. Mais pas avec AccelStepper.

Qu'est ce que cela donne avec des vitesses de l'ordre de 100 pas/s?

Bonsoir lilian2230

Plus tu en ajoutera dans loop, plus la régularité de la marche de tes moteurs se dégradera.
Pour avoir deux MPAP ou plus qui fonctionnent "proprement", je consacrerai un Arduino avec GRBL et, depuis un autre Arduino, je lui enverrai du G-Code. D'autant plus que GRBL a un mode joystick

Cordialement
jpbbricole

Oui c’est vrai (grbl/stepper.c at master · grbl/grbl · GitHub)

c’était juste pour illustrer que le souci n’est pas à mon avis pour quelques microsecondes de calculs et que c’est tout à fait faisable.

c'est justement ça le problème, plus tard il y aura tout la partie wifi en plus, j'ai fait un test avec un ne555 à 50%(rapport cyclique) puis fais varier la fréquence , ça marchait nickel , mais je ne sais pas comment le contrôler via l'Arduino , ça réglerait pas mal de problème au moins .
voici le montage utilisée (il y a probablement mieux):


peux être qu'un montage comme ça marcherez ? :

Quel est le besoin? Tout doit partir de là.

je l'ai expliquée dans le poste 1 , faire tourner 2 moteurs nema17 via un joystick (présent sur un autre Arduino , (communication wifi)

pas avec des NRF24L01...

essayez ce code:

#include <AccelStepper.h>

// Axe Horizontal
const byte POTX_PIN           = A1;
const byte STEPPERX_DIR_PIN   = 2;
const byte STEPPERX_STEP_PIN  = 3;
AccelStepper stepperX(AccelStepper::DRIVER, STEPPERX_STEP_PIN, STEPPERX_DIR_PIN);
int vitesseX = 0;

// Axe Vertical
const byte POTY_PIN           = A0;
const byte STEPPERY_DIR_PIN   = 5;
const byte STEPPERY_STEP_PIN  = 6;
AccelStepper stepperY(AccelStepper::DRIVER, STEPPERY_STEP_PIN, STEPPERY_DIR_PIN);
int vitesseY = 0;

void setup() {
  Serial.begin(115200);
  stepperX.setMaxSpeed(1000.0);
  stepperY.setMaxSpeed(1000.0);
  stepperX.setSpeed(vitesseX);
  stepperY.setSpeed(vitesseY);
  Serial.print(F("Vx:")); Serial.print(vitesseX); Serial.print(F("\tVy:")); Serial.println(vitesseY);
}

void loop() {
  stepperX.runSpeed();
  stepperY.runSpeed();

  int Vx = map(analogRead(POTX_PIN), 0, 1023, -500, 500);
  int Vy = map(analogRead(POTY_PIN), 0, 1023, -500, 500);
  if (Vx != vitesseX) {
    vitesseX = Vx;
    stepperX.setSpeed(vitesseX);
    Serial.print(F("Vx:")); Serial.println(vitesseX);
  }

  if (Vy != vitesseY) {
    vitesseY = Vy;
    stepperY.setSpeed(vitesseY);
    Serial.print(F("Vy:")); Serial.println(vitesseY);
  }
}

les moteurs risquent de bouger tout le temps, il faudrait définir une zone morte au centre (par exemple entre 500 et 524). si vous voulez aller plus vite si vous vous êtes presque au bord, ça pourra se rajouter ensuite

Pour le cahier des charges, il manque par exemple:

  • la vitesse de rotation souhaitée
  • éventuellement le nombre de micro-pas
    J'ai vraiment l'impression que c'est la bibliothèque qui ne va pas assez vite.

c'est fais ça marche bien plus de problème. je l'ai un peux modifié en créant une zone mort :

#include <AccelStepper.h>

// Axe Horizontal
const byte POTX_PIN           = A1;
const byte STEPPERX_DIR_PIN   = 2;
const byte STEPPERX_STEP_PIN  = 3;
AccelStepper stepperX(AccelStepper::DRIVER, STEPPERX_STEP_PIN, STEPPERX_DIR_PIN);
int vitesseX = 0;

// Axe Vertical
const byte POTY_PIN           = A0;
const byte STEPPERY_DIR_PIN   = 5;
const byte STEPPERY_STEP_PIN  = 6;
AccelStepper stepperY(AccelStepper::DRIVER, STEPPERY_STEP_PIN, STEPPERY_DIR_PIN);
int vitesseY = 0;

int t1 = 0;
int t2 = 0;
void setup() {
  Serial.begin(115200);
  stepperX.setMaxSpeed(1000.0);
  stepperY.setMaxSpeed(1000.0);
  stepperX.setSpeed(vitesseX);
  stepperY.setSpeed(vitesseY);
  Serial.print(F("Vx:")); Serial.print(vitesseX); Serial.print(F("\tVy:")); Serial.println(vitesseY);
}

void loop() {
  if(t1 == 1){
    stepperX.runSpeed();
  }
    if(t2 == 1){
    stepperY.runSpeed();
  }
  t1 = 0;
  t2 = 0;
  int Vx = map(analogRead(POTX_PIN), 0, 1023, -1000, 1000);
  int Vy = map(analogRead(POTY_PIN), 0, 1023, -1000, 1000);
  if ((Vx < -200)||(Vx > 200)){
     vitesseX = Vx;
     stepperX.setSpeed(vitesseX);
     Serial.print(F("Vx:")); Serial.println(vitesseX);
     t1 = 1;
   }

  if ((Vy < -200)||(Vy > 200)){
     vitesseY = Vy;
     stepperY.setSpeed(vitesseY);
     Serial.print(F("Vy:")); Serial.println(vitesseY);
     t2 = 1;
  }
}

mais maintenant j'ai un autre problème , la vitesse des moteurs n'augment pas de manière linéaire mais plutôt par palier :

voyez vous une solution , je pense que le problème est dans la bibliothèque

le problème c'est que je ne sais pas ce qui sera nécessaire , je créé une tourelle motorisé contrôlée à distance , et je n'ai toujours pas décidé du moyen de transmission moteurs - tourelle :

  • courroie ?
  • engrenage ?

Dans les deux cas cela dépend de la taille des pièces , que je n'ai pas encore déterminée, donc il faudrait pouvoir faire varier la vitesse min/max facilement (si c'est possible).

la fonction map travaille en entier, mais ça m'étonnerait que ce soit cela. Combien de paliers voyez vous ? comment les identifiez vous ?

sinon vos t1 et t2 ne servent à rien il vaut mieux mettre la vitesse à 0 plutôt que de ne pas appeler runSpeed()

essayez comme cela:

#include <AccelStepper.h>

// Axe Horizontal
const byte POTX_PIN           = A1;
const byte STEPPERX_DIR_PIN   = 2;
const byte STEPPERX_STEP_PIN  = 3;
AccelStepper stepperX(AccelStepper::DRIVER, STEPPERX_STEP_PIN, STEPPERX_DIR_PIN);
int vitesseX = 0;

// Axe Vertical
const byte POTY_PIN           = A0;
const byte STEPPERY_DIR_PIN   = 5;
const byte STEPPERY_STEP_PIN  = 6;
AccelStepper stepperY(AccelStepper::DRIVER, STEPPERY_STEP_PIN, STEPPERY_DIR_PIN);
int vitesseY = 0;

void setup() {
  Serial.begin(115200);
  stepperX.setMaxSpeed(1000.0);
  stepperY.setMaxSpeed(1000.0);
  stepperX.setSpeed(vitesseX);
  stepperY.setSpeed(vitesseY);
  Serial.print(F("Vx:")); Serial.print(vitesseX); Serial.print(F("\tVy:")); Serial.println(vitesseY);
}

void loop() {
  stepperX.runSpeed();
  stepperY.runSpeed();

  int Vx = map(analogRead(POTX_PIN), 0, 1023, -500, 500);
  if ((Vx >= -200) && (Vx <= 200)) Vx = 0;

  int Vy = map(analogRead(POTY_PIN), 0, 1023, -500, 500);
  if ((Vy >= -200) && (Vy <= 200)) Vy = 0;

  if (Vx != vitesseX) {
    vitesseX = Vx;
    stepperX.setSpeed(vitesseX);
    Serial.print(F("Vx:")); Serial.println(vitesseX);
  }

  if (Vy != vitesseY) {
    vitesseY = Vy;
    stepperY.setSpeed(vitesseY);
    Serial.print(F("Vy:")); Serial.println(vitesseY);
  }
}

ça fait une grosse plage sans mouvement cela dit... peut-être envisager ±50 ou ±100 au lieu de ±200