Aller au contenu


Photo
* * * * * 1 note(s)

Guide linéaire motorisé


  • Veuillez vous connecter pour répondre
145 réponses à ce sujet

#141 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 691 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 31 mai 2020 - 05:48

Bonjour , il n'y a aucune différence à utilisé runToPosition ou runToNewPosition(5000) , mis a part que avec que avec run to position il faut utiliser en plus moveTo ( 5000 ) pour avoir le nombre de pas que l'on cherche .

 

Ci dessous l'explication de AccelStepper 

runToNewPosition

Déplace le moteur (avec accélération / décélération) vers la nouvelle position cible et bloque jusqu'à ce qu'il soit en position. Ne l'utilisez pas dans les boucles d'événements, car il se bloque.

runToPosition

Déplace le moteur (avec accélération / décélération) vers la  position cible et bloque jusqu'à ce qu'il soit en position. Ne l'utilisez pas dans les boucles d'événements, car il se bloque.

 

D'aprés mes essais c'est vrai .

N'est ce pas bizarre de créer deux fonctions qui font la même chose ?

 

 

 

En fait c'est pour des questions d'usage, Je suppose qu'à l'origine il y avait le fonction " moveTo " et la fonction " runToPosition " . 
Puis ils ont du se dire que ça serait pratique de faire une fonction qui encapsule les deux. 

Il est possible que la fonction ressemble simplement à un truc comme ça :
 

runToNewPosition ( uint32_t position ) {

 static uint32_t currentTargetPosition = 0; 
 if( position != currentTargetPosition) {
  moveTo(position); 
  currentTargetPosition = position;

 }
 runToPosition();

}

Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 

 

Les réalisations de Mike118  

 

 

 


#142 Sandro

Sandro

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 623 messages
  • Gender:Male

Posté 31 mai 2020 - 09:03

Faire deux fonctions avec un nom différent qui seraient identiques serait en effet étrange et pourrait prêter à confusion. Mais même ça, ça existe (typiquement quand tu as une grosse librairie qui décide de changer de nom pour certaines fonctions : pendant quelques versions, ils gardent la fonction avec l'ancien nom en plus du nouveau nom, de manière à ce que les vieux programmes continuent à fonctionner (souvent ils ajoutent un avertissement que l'ancienne fonction n'existera plus dans les nouvelles fonctions)).

 

Une seconde possibilité, est que deux fonctions donnent le même résultat, mais en y aboutissant de manière différente, avec une méthode plus efficace que l'autre selon les cas (par exemple, il existe des dizaines d'algorithmes différents de tri, avec chacun leurs avantages et inconvéniants : l'un sera très rapide en moyenne mais lent dans quelques cas particuliers, un autre sera un peu plus lent en moyenne, mais plus rapide si on compare les pires des cas, un troisième utilisera moins de mémoire, un quatrième sera très efficace si les données sont déjà presque triées, un cinquième sera efficace si on connait à l'avance les valeurs possibles et qu'il y en a peu, ...)

 

Le dernier cas que je vois, qui est le tien, c'est que plusieurs fonctions différentes permettent d'aboutir à un même résultat, mais qu'il est possible d'utiliser l'une (ou les deux) fonctions également d'une manière différente.

runToNewPosition est en soit "inutile", vu qu'on peut la remplacer par moveTo suivit de runToPosition. Sauf que c'est plus rapide/clair/concis d'utiliser une seule fonction plutôt que les deux succéssivement : on a donc créé une fonction en guise de "raccourci".

Avoir les fonctions moveTo et runToPosition séparés, peut être utile dans certains cas :

- on peut utiliser moveTo suivit de runSpeedToPosition au lieu de runToPosition

- on peut utiliser moveTo, puis faire autre chose, puis exécuter runToPosition plus tard (par exemple tu pourrais fixer la destination depuis une fonction, puis lancer le déplacement quand tu appuis sur un bouton)

- on peut utiliser moveTo suivit de run (dans une boucle). On peut aussi imaginer une combinaison : on utilise moveTo, puis run dans une boucle avec une certaine condition, puis on finit le déplacement avec runToPosition. Par exemple si ton servomoteur sert à faire tourner le treuil qui catapulte un planeur d'aéromodélisme : au début, dans ta boucle, tu vérifie qu'on n'appuie pas sur un bouton "stop", puis quand le planeur à commencer à découler, tu vas jusqu'au bout peu importe le bouton (si le planeur vient de décoller mais n'est pas encore assez haut, il est impossible de lui faire faire un demi-tour pour ré-atérir, du coup il est sur de s'écraser)

- tu peux utiliser moveTo, puis la fonction distanceToGo pour savoir la distance à parcourir, et seulement ensuite décider si tu veux bouger ou pas

- ...

 

Bref, il y a plein de cas où avoir les deux fonctions séparées peut être utile, même si dans ton cas (et dans celui d'un bon nombre de personnes), avoir une fonction qui fait les deux en même temps est plus pratique.



#143 cook

cook

    Membre occasionnel

  • Membres
  • Pip
  • 86 messages

Posté 31 mai 2020 - 10:47

 
Voila tout fonctionne . J'en reviens pas . Je vais réessayé !
 

#include <AccelStepper.h>
AccelStepper stepper (1, 9, 8);
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int PinBoutonInit = A0; //Bouton qui déplacera le chariot vers la buté à 30 cm
const int PinContactBute = A1;// Contact qui stope le chariot à 30 cm
const int PinBoutonReglageDistanceCm = A2;//Bouton de reglage distance en Cm
const int PinBoutonReglageDistanceMm = A3;//Bouton de reglage distance en Mm
const int PinBoutonReglageDistancePlus5Mm = A4;//Bouton de reglage distance + 5 Mm
const int PinBoutonReglageDistanceMoins5Mm = A5;//Bouton de reglage distance - 5 Mm
const int PinBoutonConfigurationPlateau = 6;//Bouton configuration Plateau à la distance écrite sur écran LCD
const int LED = 10;


float  ReglageAffichageDistance   (float NouvelleDistance)  {

  while (digitalRead(PinBoutonReglageDistancePlus5Mm) == 0) {// Bouton + 5 mm
    NouvelleDistance = NouvelleDistance + 0.5 ;
    if (NouvelleDistance > 290) {
      NouvelleDistance = 30;
    }
    attendreMs(300);
    Serial.println(NouvelleDistance);
    AfficherLaDistance(NouvelleDistance);
    AfficherLaDistancePouce(NouvelleDistance);
  }

  while (digitalRead(PinBoutonReglageDistanceMoins5Mm) == 0)  { // Bouton - 5 mm
    NouvelleDistance = NouvelleDistance - 0.5 ;
    if (NouvelleDistance < 30) {
      NouvelleDistance = 290;
    }
    attendreMs(300);
    Serial.println(NouvelleDistance);
    AfficherLaDistance(NouvelleDistance);
    AfficherLaDistancePouce(NouvelleDistance);
  }


  while (digitalRead(PinBoutonReglageDistanceMm) == 0) { // Bouton réglage des millimetres
    NouvelleDistance = NouvelleDistance + 0.01 ;
    if (NouvelleDistance > 290) {
      NouvelleDistance = 30;
    }
    attendreMs(100);
    Serial.println(NouvelleDistance);
    AfficherLaDistance(NouvelleDistance);
    AfficherLaDistancePouce(NouvelleDistance);
  }

  while (digitalRead(PinBoutonReglageDistanceCm ) == 0) { // Bouton réglage des cm

    NouvelleDistance = NouvelleDistance + 1 ;   // Le compteur s'incrémente de 1 cm
    if (NouvelleDistance > 290) {
      NouvelleDistance = 30;
    }
    attendreMs(200);                            // on attend 500 ms sans utiliser la fonction delay()
    Serial.println(NouvelleDistance);
    AfficherLaDistance(NouvelleDistance);
    AfficherLaDistancePouce(NouvelleDistance);
  }
  return NouvelleDistance;       // quand on a fini d'incrémenter on retourne la valeur au reste du programme
}

void  ConfigurationPlateau (float Distance) {

  if (digitalRead(PinBoutonConfigurationPlateau) == 0)  {

    stepper. moveTo (- Distance * 3905.4 ) ;// 1tour = 11cm = 42960 pas soit 390.54 pas pour 1 mm .
    stepper. runToPosition () ;
    Serial.println(Distance * 3905.4); 
    delay(100);

  }
  else {
     stepper.stop();
  }
}


void attendreMs (unsigned int attente) {
  unsigned long InstantouJappuis = millis();           // Variable qui enregistre le déroulement du temps qui passe depuis l'appuis
  while (millis() - InstantouJappuis <  attente ) { // décompte de 500ms en cours
  }
}



void  AfficherLaDistance  (float Distance) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (  " BUTEE " );
  lcd.setCursor(7, 0);
  lcd.print (  Distance  );
  lcd.setCursor(13, 0);
  lcd.print (  " cm "   );
}

void  AfficherLaDistancePouce  (float Distance) {

  lcd.setCursor(1, 1);
  lcd.print (  Distance / 2.54  );
  lcd.setCursor(11, 1);
  lcd.print (  " inch "   );
}



void  AfficherInitTermine () {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (" Initialisation  "  );
  lcd.setCursor(0, 1 );
  lcd.print (" terminée "  );
  Serial.println ("Initialisation terminée " );
}

void  AfficherInitEnCours () {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print (" Initialisation  "  );
  lcd.setCursor(0, 1 );
  lcd.print (" en cours "  );
  Serial.println (" Initialisation en cours "  );

}
float initMoteur (float InitDistance ) {


  if (digitalRead(PinBoutonInit) == 0) {
    AfficherInitEnCours ();
    stepper.setSpeed(3900);

    while (digitalRead(PinContactBute) == 1) {
      stepper.runSpeed();
       digitalWrite(10, LOW); // initialisation non réalisé
      // on attends la buté
    }
    stepper.stop(); // On remet à 0 les consignes de vitesse ...
   digitalWrite(10, HIGH);  // initialisation  réalisé

    InitDistance  = 30.0;
    stepper. setCurrentPosition ( -117162 ) ;// Permet de mettre le moteur à sa position cible de 30 cm à la butée

    Serial.println (InitDistance);

    AfficherInitTermine ();
    delay(1000);
    AfficherLaDistance(InitDistance) ;
  }
  return InitDistance;   // quand on a fini d'initialisé on retourne la valeur au reste du programme
}

void setup() {

  Serial.begin(9600);
  pinMode(A0, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode(A1, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode(A2, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode(A3, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode(A4, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode(A5, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode( 6, INPUT_PULLUP); //  pour le mettre en INPUT_PULLUP
  pinMode(10, OUTPUT);
  stepper.setMaxSpeed(4000);
  stepper. setAcceleration ( 500 ) ;
  lcd.begin(16, 2);
  lcd.print("START PRESS INIT");
}

void loop() {

  static float maDistance = 29; // Variable qui va stocker la distance de consigne
  maDistance = initMoteur (maDistance);  // Permet d'initialisé ma distance sur 30 cm
  maDistance = ReglageAffichageDistance (maDistance); // réglage de la distance de 30 à 290 cm
  Serial.println (maDistance );
  ConfigurationPlateau (maDistance) ;

}


#144 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 691 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 01 juin 2020 - 05:59

ça marche et en plus le code est pas mal , propre, avec des fonctions, sans variable globales autre que les const des pins =). 

Juste quelques remarques afin d'améliorer encore si tu le souhaites : 
Au delà de la précédente proposition qui est pour le moment reportée,

perso je ferais une fonction qui map la distance en mm en step plutôt que de taper la formule à chaque fois à chaque endroit où tu auras envie de l'utiliser. ( D'ailleur j'utiliserais cette formule avec 30.0 en paramètre au lieu de mettre la valeur magique -117162 )

 

 

Tu peux aussi retirer les " valeurs magiques " dans ton code et les mettre comme constante en dessous de tes const pour les pins utilisés :) 
En effet tu vas certainement avoir besoin de changer ces constantes à plusieurs endroits ... Et si tu as besoin de les modifier, le faire juste à un endroit en haut de ton code ça sera plus facile ;) exemple const float distanceMin = 30.0 ;   et remplacer partout 30.0 par distanceMin =)

 

Pour des besoins de propreté du code tu peux éventuellement choisir d'inverser deux fils de tes moteurs pas à pas pour inverser le sens de rotation. ( En gros aller en vitesse négative pour s'initialiser et utiliser une consigne " positive " pour se positionner sur le rail au lieu de mettre un - dans ta formule =) )

 

tu as une jolie fonction attendrems mais tu utilise encore la fonction delay...

 

Je te recommande toujours de "clean au maximum ton code " qui marche avant de passer à la suite =) . 
Car plus ça va aller plus tu vas entasser du code et plus il sera dur de le nettoyer ... 

Bientôt on va pouvoir arriver à un point où je te proposerais de faire plusieurs fichiers ;) Tu me diras quand tu trouveras que ce code est trop long pour tenir dans un seul fichier =)


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 

 

Les réalisations de Mike118  

 

 

 


#145 cook

cook

    Membre occasionnel

  • Membres
  • Pip
  • 86 messages

Posté hier, 21:52

Bonjour , avant d'amélioré le code j'ai une question sur le moteur de mon guide linéaire .

(Il m'en faut un , et peut être il y a beaucoup de délai  ) 

  Le guide est un peu différent que sur la présentation (photo jointe) . L'original était trop encombrant ." 3.20 mètres"  de long !!  

J'ai du le coupé en quatre , ce qui m’emmène à une question plutôt mécanique .

On m'avait prêté un moteur nema 17 avec un réducteur d'environ 27/1 . 

Très bien d’ailleurs . Je pourrai reprendre le même , mais vu le choix partout et la curiosité , c'est le couple qui me fait réfléchir .

 

La notice du moteur me dit :

  • Ce moteur pas à pas Nema 17 avec un corps de 48mm et un courant nominal de 1.68A, a intégré un réducteur planétaire de 26.85: 1 Rapport d'engrenage. C'est une bonne solution pour les applications avec un espace limité mais nécessitant une faible vitesse et / ou un couple élevé.

    Spécification électrique
    • Numéro de pièce du fabricant: 17HS19-1684S-PG27
    • Type de moteur: bipolaire
    • Angle de pas: 0.067 deg
    • Couple de serrage sans boîte de vitesses: 52Ncm(73.6oz.in)
    • Courant/phase: 1.68A
    • Résistance/phase: 1.65ohms
    • Tension: 2.8V
    • Inductance: 2.8mH ± 20%(1KHz)
    Spécifications de la boîte de vitesses
    • Type de boîte à engrenages: Planetary
    • Rapport d'engrenage: 26.85: 1
    • Efficacité: 81%
    • Contrecoup No-load: <=1 deg
    • Couple maximal autorisé: 3Nm(425oz.in)
    • Moment admissible Couple: 5Nm(708oz.in)
    • Charge axiale maximale de l'arbre: 50N
    • Charge radiale maximale de l'arbre: 100N
  •  
  •  
    • La question est simple : il est de combien le couple en sortie ? Il y a un rapport entre le couple moteur et la boite de vitesse ? Je pourrai dire que le couple en sortie est 27 fois plus important parce que la boite de vitesse 27 fois plus lente ?

Image(s) jointe(s)

  • zmachine.JPG


#146 Forthman

Forthman

    Pilier du forum

  • Membres
  • PipPipPipPipPip
  • 1 076 messages
  • Gender:Not Telling
  • Location:Montauban (82)

Posté hier, 22:25

à première vue, je dirais que tu as raison.

donc 52Ncm, soit 0.52Nm * 26.85 *0.81 = 11.3Nm

par contre si le couple maximal autorisé de 3Nm est en sortie, ça voudrait dire que le moteur serait capable de casser le réducteur :help:

Et le moment maxi de 5Nm c'est dans le sens de rotation ou pas ? t'as pas un petit graphique avec la doc ?

(et t'aurais pas la doc quelque part sur le net ?)






0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users