Vitesse moteur et Accelstepper

Bonjour à tous,

J'ai une petite question concernant le vitesse max de génération de pas avec la librairie Accelstepper.

Voilà ma config, une carte mega 2560 et deux moteurs pas à pas, des drivers leadschine et la librairie accelstepper.

A un moment donné, lorsque j'essaie d'augmenter le vitesse de la variable SetMaxSpeed, l'arduino plafonne .

Si j'augmente la vitesse du premier moteur, j'ai le second qui en perd !

J'ai contourné le problème en mettant une carte 2560 par moteur et dans ce cas, j'ai mes bonnes vitesse.

Voilà pour indication une vitesse correcte avec un moteur et une carte :

Sortie.SetMaxSpeed(1800.0);

Comment calculer cette vitesse ?
Je suppose que c'est possible de calculer la vitesse maximum qu'une carte peut générer ?

Bon dimanche,

Pierre

Salut,

1800 pas/s ça commence à faire élevé ... accelstepper utilisant des digitalWrite(), pas étonnant qu'avec deux moteurs et cette vitesse tu plafonnes :s

Tu es en quel stepping ?

Bonjour Batto,

Attention, 1800, ca tient avec une carte par moteur.
Pour le microstepping, je suis au minimum du drivers soit 400 pas. Dans ce cas, pas de besoin de grande précision

1800 pas c'est élevé pour le moteur en lui même, la plupart des moteurs pas à pas ont le couple qui décroche à partir de 1000 pas/seconde donc normalement on va rarement à ces vitesses.

1800 plein pas puisque tu es en 1/2 pas ça fait 3600 crénaux par seconde, deux moteurs ça fait 7200 créneaux par seconde, en 1/2 pas dans la ib ça fait 2 digitalwrite() par demi pas soit 14 400 digitalWrite() par seconde. A 15 µS l'instruction ça fait 216 ms soit ~20% d'occupation du CPU. Il doit y avoir autre chose qui te pompe des ressources

Bonjour B@tto,

Alors dans mon Loop, j'ai trois digitalRead qui surveillent l'état de boutons ?

tu as largement de quoi faire en terme de temps cpu.
la plupart des moteur p/p que j'ai utiliser tiennent a 1500 tr/min.
Mais tes rampes et tes puls en continus doivent etre regulier.

tu dois avoir des trou dans la generation de puls.
genre gestion d'un LCD, com, ...

dans un des bouts de code que je t'avais mis, il y avais une routine avec accel/decel.
cette routine etait bloquante au deroulement du loop, mais m'as permis de passer les 1000tr/min sans probleme.

je ne connais pas la librairie AccelStepper... lien d'ou tu l'as prise?

Bonjour à tous,

Voilà mon code avec deux moteurs :

//Inclusion des librairies 
//------------------------

#include <AccelStepper.h>
#include <LiquidCrystal.h>

// Broches E/S numériques
//-----------------------


int PneumatiqueRouleau = 48; // sortie penumatique
int RelaisFil = 47;
int EnableBobine = 45;


const int BoutonOrigine = 52; // bouton pour lancer prise origine
const int BoutonArret = 50; // bouton pour arreter la machine
const int BoutonMarche = 51; // bouton pour arreter la machine
const int BoutonOuvertureRouleau = 49; // bouton commande pneumatique rouleau en manuel


// Moteur rouleau couteau
//---------

const int Pul1 = 29; // pas couteau
const int Dir1 = 27; // dir couteau --> changer ici pour inverser le sens
unsigned long PasCouteau=0;

AccelStepper Couteau(AccelStepper::DRIVER, Pul1, Dir1);

// Moteur sortie papier
//---------

const int Pul3 = 23; // pas rouleau 
const int Dir4 = 25; // dir rouleau --> changer ici pour inverser le sens
unsigned long PasSortie=0;
AccelStepper Sortie(AccelStepper::DRIVER, Pul3, Dir4);

//Gestion des interruptions
//-------------------------

// Autres variables
//-----------------

int EtatArret; // utilisé par le bouton arret
int EtatMarche; // utilise par le bouton marche
int EtatOuvertureRouleau; // utilise par le bouton pour commande pneumatique rouleau

boolean Marche = false;


//***********************************************************************************************


void setup()
{  
   
  Serial.begin(9600); // Initialisation du port série à 95600 bits/seconde
  
// Etat des variables
//---------------------
  
  pinMode(PneumatiqueRouleau, OUTPUT);
  digitalWrite(PneumatiqueRouleau, LOW);
   
  pinMode(RelaisFil, OUTPUT);
  digitalWrite(RelaisFil, LOW);
  
   pinMode(EnableBobine, OUTPUT);
  digitalWrite(EnableBobine, HIGH);

  pinMode(BoutonArret, INPUT); // bouton en entree
  pinMode(BoutonMarche, INPUT); // bouton en entree
  pinMode(BoutonOuvertureRouleau, INPUT);// broche en entree

  
}// Fin de la fonction Setup


// ****************************************************************************************************


void loop()

{   
 
  EtatMarche = digitalRead(BoutonMarche);//
  EtatArret = digitalRead(BoutonArret);//
  EtatOuvertureRouleau = digitalRead(BoutonOuvertureRouleau);
  
  Couteau.setMaxSpeed(330.0); // vitesse 55 piece = 440
  Couteau.setSpeed(330);
  
  Sortie.setMaxSpeed(1700.0);
  Sortie.setSpeed(1700);

 if(EtatMarche == HIGH) //test si le bouton est activé
   {
          delay (200) ; // ne pas relire tout de suite l'état, protection anti-rebond
    //             Serial.println("bouton marche"); // message  
   Marche = true;
     
   }
 
  if(EtatArret == HIGH) //test si le bouton est activé
   {
          delay (200) ; // ne pas relire tout de suite l'état, protection anti-rebond
               //  Serial.println("bouton arret"); // message  
  Marche = false;
    }  
  
 
 if (Marche == true)
{
  // Serial.println("Marche");
 Couteau.runSpeed();
  
 Sortie.runSpeed();
  
  digitalWrite(RelaisFil, HIGH);
  digitalWrite(EnableBobine, LOW);
}
  else
  {
  digitalWrite(RelaisFil, LOW);
  digitalWrite(EnableBobine, HIGH);
  }
  
   if(EtatOuvertureRouleau == HIGH) //test si le bouton est activé
   {
   delay (300) ; // ne pas relire tout de suite l'état, protection anti-rebond      
  Serial.println("Commande ouverture rouleau"); // message  

    EtatOuvertureRouleau =  LOW;   
    digitalWrite(PneumatiqueRouleau, HIGH);   
   }
  else
 {
    digitalWrite(PneumatiqueRouleau, LOW);
  }
 
 } // fin de la fonction loop()

Avec ce code la variable "Sortie.setMaxSpeed(1700.0);" doit être de 1700
Avec un seul moteur par carte 2560, elle est de 1440 pour la même vitesse.

A part la déclaration de la librairie LCD, il n'y a que des Digital read pour des boutons.

Pour Jean, la librairie Accelstepper est ici : AccelStepper: AccelStepper Class Reference

C'est pour une machine qui coupe du papier.
Pour l'instant, je dois juste commander des rouleaux à une certaine vitesse.
C'est pourquoi j'utilise Accelstepper sans accélération et c'est pourquoi je n'ai pas encore utilisé la boucle de Jean.
Dans le cas présent, pas d'importance si j'ai une perte de pas au lancement.
C'est pas des pas à pas classique mais des servomoteurs Hybride avec des drivers spécifique.

Par la suite, j'ai un plot sur le papier qui commandera le rouleau de coupe pour tourner a un nombre de pas définit.
Mais pour l'instant, la machine est en production sans cette fonction avec une carte mega 2560 par moteur.
Mon client est comptant, ça tourne !
J'essaie juste de comprendre...

J'ai encore beaucoup de fonctions, de boutons, de capteurs, de LCD à ajouter.
Dans ce cas, pourquoi pas continuer à utiliser un arduino par moteur commandé par une interruption.
Une carte principale qui gère les boutons, capteurs, LCD qui communique avec les arduinos esclaves via les interruptions et si je veux changer les vitesses utiliser le protocole I2c par exemple ?

J'ai fait des tests avec un code tout simple :

// MultiStepper.pde


#include <AccelStepper.h>

// Define some steppers and the pins the will use

AccelStepper stepper1(AccelStepper::DRIVER, 22, 26);
AccelStepper stepper2(AccelStepper::DRIVER, 29, 27);

void setup()
{ 
    stepper1.setMaxSpeed(350.0);
    stepper1.setAcceleration(1000.0);
    stepper1.moveTo(3000000);
   
    stepper2.setMaxSpeed(1440.0);
    stepper2.setAcceleration(1000.0);
    stepper2.moveTo(-3000000); 
    
}

void loop()
{

stepper1.run();
stepper2.run();

}

Avec ce code basique, je suis à la bonne vitesse.

les delay sont boquants.

if(EtatMarche == HIGH) //test si le bouton est activé
   {
          delay (200) ; // ne pas relire tout de suite l'état, protection anti-rebond
    //             Serial.println("bouton marche"); // message  
   Marche = true;
     
   }
 
  if(EtatArret == HIGH) //test si le bouton est activé
   {
          delay (200) ; // ne pas relire tout de suite l'état, protection anti-rebond
               //  Serial.println("bouton arret"); // message  
  Marche = false;
    }

example:
je suppose que tu est dans un etat ou dans l'autre.
tu as donc deja 200mS de retard dans ta generation de puls.

utilise millis().

Bonjour

Mon client est comptant, ça tourne !
J'essaie juste de comprendre...

Superbe lapsus orthographique. Tu veux parler de la satisfaction du client et ton cerveau pense
"Money, Money" :wink:
Tu n'as rien compris a la fonction anti-rebond :
tu vas lire l'etat du bouton, tu attends puis tu continues comme si tout etait bon.
Il faut :

  • recevoir une info, par pooling ou par interrupt
  • attendre un delai raisonnable, de l'ordre de 10 a 20mS
  • verifier l'info
  • agir.
    Comme l'a dit Jean, il ne faut pas utiliser la fonction delay au milieu d'une boucle, surtout si tu envisages de completer ton programme avec de nouvelles fonctions.
    Il faut utiliser la fonction "millis".
    C'est tres simple a utiliser. Je suis debutant en programmation Arduino et mon premier programme qui utilise millis a 3 fonctions simultanees:
    Une led qui flashe pour indiquer que tout fonctionne cerrectement, un decompteur de secondes et le multiplexage de l'affichage de 2 x 7 segments. Il suffit juste de lire, essayer, comprendre, utiliser.

Pour le bouton Stop : DANGER. Tu es un pro et tu travailles pour l'industrie. Deja dit dans un autre message, ce n'est pas ainsi que l'on travaille.
Supposons un ascenseur, quand le moteur se met en marche pour la descente de la cabine, c'est qu'une quantite de conditions sont toutes remplies. Fin de courses, cablage, mesure du poids maximum, cables sur la poulie etc. Tout est OK
Tu dois faire la meme chose.
Le bouton arret doit etre un NC ou "normalement ferme" qui place la pin d'entree STOP au GND.
Dans chaque boucle, tu viens verifier si la pin est toujours au GND. Dans ce cas tu ne touches pas au status de la commande moteur.
Si le bouton est enfonce ou si le cable est coupe ou si la vis qui n'etait pas serree a laisse s'echapper le fil .... alors tu arretes ton moteur.
Cela s'appelle de la securite active.
Bonne continuation.
Jacques