Moteur pas à pas Home Position

Bonjour,

Je suis sur un projet qui comporte des moteurs pas à pas. J'envois des commande sur le port série via LabVIEW. Mes commandes sont les suivantes :

-Go to position (moteur X1)
-Go to position (moteur Y1)
-Home (moteur X1)
-Home (moteur Y1)

Toutes les commandes fonctionnent correctement sauf pour le home du moteur Y1. Le partie du code qui pose problème est la suivante :

//Moteur Y1 : 
//Case 1 : Go To Position
//Case 2 : Home
  switch (State_Y1)
  {
    case 1 : // Go To Position
    stepper_Y1.run();
    if (is_run_Y1==0)
    {
      State_Y1 = 0;
    }
    break;
    
case 2 : // Home
    stepper_Y1.run();
    Val_FinDeCourseY1 = digitalRead(FinDeCourseY1);
    if (Val_FinDeCourseY1==0)
    {
  stepper_Y1.stop();
  stepper_Y1.setCurrentPosition(0);
  State_Y1 = 0;  
    }
    break;
  }

En effet le moteur Y1 rentre directement dans la condition (Val_FinDeCourseY1==0), il tourne d'un step (environ), s'arrête et prend cette nouvelle position comme la position 0.

J'ai fait des tests unitaires sur les capteurs de fin de course et ils fonctionnent correctement.
Le code fonctionnait très bien sur une carte arduino mais j'ai changé pour un tensy qui a plus de puissance de calcul.

Chose a noté, lorsque je met une tempo de 1ms après la lecture du fin de course Y1, la commande fonctionne mais je suis ralenti avec les 1ms de delay ...

Je suis sur le problème depuis plusieurs heures et je ne vois pas mon erreur.

Le code dans son intégralité :

Je vous remercie

/****************************************************************************************	
**  This is example LINX firmware for use with the PJRC Teensy 4.0 with the serial 
**  interface enabled.
**
**  For more information see:           www.labviewmakerhub.com/linx
**  For support visit the forums at:    www.labviewmakerhub.com/forums/linx
**  
**  Written By Sam Kristoff
**
**  BSD2 License.
****************************************************************************************/

//Include All Peripheral Libraries Used By LINX
#include <SPI.h>
#include <Wire.h>
#include <EEPROM.h>
#include <Servo.h>
#include <stdlib.h>
#include <AccelStepper.h>

#include <LinxPjrcTeensy40.h> //Include Device Specific Header From Sketch>>Import Library (In This Case LinxChipkitMax32.h)
#include <LinxSerialListener.h> //Also Include Desired LINX Listener From Sketch>>Import Library (In This Case LinxSerialListener.h)

AccelStepper stepper_Y1 = AccelStepper( 1, 11, 12); // Déclaration de la fonction "AccelStepper" pour le moteur Y1
AccelStepper stepper_X1 = AccelStepper( 1, 8, 9); // Déclaration de la fonction "AccelStepper" pour le moteur X1
int Motor_Y1(); //Initialisation de la fonction qui permet de bouger le moteur Y1 d'une position à une autre
int Motor_X1(); //Initialisation de la fonction qui permet de bouger le moteur X1 d'une position à une autre
int Motor_Y1_Home(); //Initialisation de la fonction qui permet de faire le home du moteur Y1
int Motor_X1_Home(); //Initialisation de la fonction qui permet de faire le home du moteur X1

byte State_Y1 = 0; //Etat du moteur Y1 (0=idle, 1=GoToPosition, 2=Home)
byte State_X1 = 0; //Etat du moteur X1 (0=idle, 1=GoToPosition, 2=Home)

int FinDeCourseY1 = 7; //Assignation de la broche 79 (fin de course Y1 à la constante "FinDeCourseY1")
int FinDeCourseX1 = 3; //Assignation de la broche 78 (fin de course X1 à la constante "FinDeCourseX1")
bool Val_FinDeCourseY1; //Déclaration du booleen Val_FinDeCourseY1
bool Val_FinDeCourseX1; //Déclaration du booleen Val_FinDeCourseX1

LinxPjrcTeensy40* LinxDevice; //Create A Pointer To The LINX Device Object We Instantiate In Setup()

//Initialize LINX Device And Listener
void setup()
{
  //Instantiate The LINX Device
  LinxDevice = new LinxPjrcTeensy40();
  
  //The LINXT Listener Is Pre Instantiated, Call Start And Pass A Pointer To The LINX Device And The UART Channel To Listen On
  LinxSerialConnection.Start(LinxDevice, 0);

  //LINX custom command
  LinxSerialConnection.AttachCustomCommand(0, Motor_Y1); //Custom command numero 0 (Fonction GotoPosition for Y1 motor)
  LinxSerialConnection.AttachCustomCommand(1, Motor_X1); //Custom command numero 1 (Fonction GotoPosition for X1 motor)
  LinxSerialConnection.AttachCustomCommand(2, Motor_Y1_Home); //Custom command numero 2 (Fonction Home for Y1 motor)
  LinxSerialConnection.AttachCustomCommand(3, Motor_X1_Home); //Custom command numero 3 (Fonction Home for X1 motor)
  pinMode(FinDeCourseY1, INPUT); // Assignation de FinDeCourseY1 comme étant une entrée
  pinMode(FinDeCourseX1, INPUT); // Assignation de FinDeCourseX1 comme étant une entrée

  stepper_Y1.setMinPulseWidth(15);
  stepper_X1.setMinPulseWidth(15);
  
}

void loop()
{
  //Listen For New Packets From LabVIEW
  LinxSerialConnection.CheckForCommands();
  
  bool is_run_X1 = stepper_X1.isRunning(); //Permet de savoir si le moteur X1 est en mouvement
  bool is_run_Y1 = stepper_Y1.isRunning(); //Permet de savoir si le moteur Y1 est en mouvemen   

//Moteur X1 : 
//Case 1 : Go To Position
//Case 2 : Home
   switch (State_X1)
  {
    case 1 : // Go To Position
    stepper_X1.run();
    if (is_run_X1==0)
    {
      State_X1 = 0;
    }
    break;

    case 2 : // Home
    stepper_X1.run();
    Val_FinDeCourseX1 = digitalRead(FinDeCourseX1);
    if (Val_FinDeCourseX1==0)
    {
  stepper_X1.stop();
  stepper_X1.setCurrentPosition(0);
  State_X1 = 0;  
    }
    break;
  }

//Moteur Y1 : 
//Case 1 : Go To Position
//Case 2 : Home
  switch (State_Y1)
  {
    case 1 : // Go To Position
    stepper_Y1.run();
    if (is_run_Y1==0)
    {
      State_Y1 = 0;
    }
    break;
    
case 2 : // Home
    stepper_Y1.run();
    Val_FinDeCourseY1 = digitalRead(FinDeCourseY1);
    if (Val_FinDeCourseY1==0)
    {
  stepper_Y1.stop();
  stepper_Y1.setCurrentPosition(0);
  State_Y1 = 0;  
    }
    break;
  }
}

int Motor_Y1(unsigned char numInputBytes, unsigned char* input, unsigned char* numResponseBytes, unsigned char* response) // Moteur Y1 Commande Go To Position
{
    //Convertion of the char Array input to unsigned interger (Step to move)
    unsigned int Step_To_Move_Y1 = atoi((char*)input);
    

    // Set the maximum speed and acceleration:
    stepper_Y1.setMaxSpeed(18000);
    stepper_Y1.setAcceleration(3500);

    // Set the target position:
    stepper_Y1.moveTo(-Step_To_Move_Y1);

    //Change l'etat du moteur Y1 à 1 (GoToPosition)
    State_Y1 = 1;
  
    return 0; 
}

int Motor_X1(unsigned char numInputBytes, unsigned char* input, unsigned char* numResponseBytes, unsigned char* response) // Moteur X1 Commande Go To Position
{
    //Convertion of the char Array input to unsigned interger (Step to move)
    unsigned int Step_To_Move_X1 = atoi((char*)input);
    

    // Set the maximum speed and acceleration:
    stepper_X1.setMaxSpeed(3500);
    stepper_X1.setAcceleration(1500);

    // Set the target position:
    stepper_X1.moveTo(Step_To_Move_X1);

    //Change l'etat du moteur X1 à 1 (GoToPosition)
    State_X1 = 1;
    
    return 0; 
}

int Motor_Y1_Home(unsigned char numInputBytes, unsigned char* input, unsigned char* numResponseBytes, unsigned char* response) // Moteur Y1 Commande Home
{
    
    // Set the maximum speed and acceleration:
    stepper_Y1.setMaxSpeed(1000);
    stepper_Y1.setAcceleration(500);

    // Set the target position:
    stepper_Y1.moveTo(50000);

    //Change l'etat du moteur Y1 à 2 (Home)
    State_Y1 = 2;

    return 0; 
}

int Motor_X1_Home(unsigned char numInputBytes, unsigned char* input, unsigned char* numResponseBytes, unsigned char* response) // Moteur X1 Commande Home
{
    
    // Set the maximum speed and acceleration:
    stepper_X1.setMaxSpeed(1000);
    stepper_X1.setAcceleration(500);

    // Set the target position:
    stepper_X1.moveTo(-25000);

    //Change l'etat du moteur X1 à 2 (Home)
    State_X1 = 2;

    return 0; 
}

Il n'y a pas de bloc 'default' dans tes case ? Pour le cas où très variables veulent 0.

Tu peux essayer de mettre des accolades autour de chaque bloc 'case', peu de chance que ça change mais...

J'ai essayé avec un case defaut et les accolades mais rien ne change, même constat.

C'est vraiment étrange.

Je confirme bien qu'avec un delay de 1ms à cet endroit ca "fonctionne" bien. Le déroulement du soft s'effectue correctement mais 1ms c'est embêtant et pas vraiment propre ...

case 2 : // Home
stepper_Y1.run();
Val_FinDeCourseY1 = digitalRead(FinDeCourseY1);
delay(1);
if (Val_FinDeCourseY1==0)
{
stepper_Y1.stop();
stepper_Y1.setCurrentPosition(0);
State_Y1 = 0;
}
break;
}

J'ai trouvé quelque chose d'intéressant.
Lorsque je lis la valeur du capteur qui pose problème trop rapidement (sans delay) il me retourne une valeur erroné. Et lorsque je lis la valeur plus lentement (1ms) la valeur est correcte.

Plus qu'à trouver pourquoi j'ai ce soucis.

hello
les entrées des fdc ont bien des résistances de rappel ( push down ou pullup) ?

Aucune idée,

Voir ci-joint mon fichier de câblage (il n'est pas à jour, les capteurs dont j'ai parlés ne sont plus branchés sur la carte arduino mais sur la tensy 4.0. Néanmoins le câblage reste le même).

J'ai trouvé une solution qui me "convient".

Au lieu de lire une valeur digital, je lis la valeur analogique. Depuis cette valeur numérique je fais mois même la distinction entre le niveau bas et haut du capteur TOR.

/****************************************************************************************	
**  This is example LINX firmware for use with the PJRC Teensy 4.0 with the serial 
**  interface enabled.
**
**  For more information see:           www.labviewmakerhub.com/linx
**  For support visit the forums at:    www.labviewmakerhub.com/forums/linx
**  
**  Written By Sam Kristoff
**
**  BSD2 License.
****************************************************************************************/

//Include All Peripheral Libraries Used By LINX
#include <SPI.h>
#include <Wire.h>
#include <EEPROM.h>
#include <Servo.h>
#include <stdlib.h>
#include <AccelStepper.h>

#include <LinxPjrcTeensy40.h> //Include Device Specific Header From Sketch>>Import Library (In This Case LinxChipkitMax32.h)
#include <LinxSerialListener.h> //Also Include Desired LINX Listener From Sketch>>Import Library (In This Case LinxSerialListener.h)

AccelStepper stepper_Y1 = AccelStepper( 1, 11, 12); // Déclaration de la fonction "AccelStepper" pour le moteur Y1
AccelStepper stepper_X1 = AccelStepper( 1, 8, 9); // Déclaration de la fonction "AccelStepper" pour le moteur X1
int Motor_Y1(); //Initialisation de la fonction qui permet de bouger le moteur Y1 d'une position à une autre
int Motor_X1(); //Initialisation de la fonction qui permet de bouger le moteur X1 d'une position à une autre
int Motor_Y1_Home(); //Initialisation de la fonction qui permet de faire le home du moteur Y1
int Motor_X1_Home(); //Initialisation de la fonction qui permet de faire le home du moteur X1

byte State_Y1 = 0; //Etat du moteur Y1 (0=idle, 1=GoToPosition, 2=Home)
byte State_X1 = 0; //Etat du moteur X1 (0=idle, 1=GoToPosition, 2=Home)

int FinDeCourseY1 = 14; //Assignation de la broche 14 (fin de course Y1 à la constante "FinDeCourseY1")
int FinDeCourseX1 = 7; //Assignation de la broche 7 (fin de course X1 à la constante "FinDeCourseX1")
int Val_FinDeCourseY1; //Déclaration du booleen Val_FinDeCourseY1
bool Val_FinDeCourseX1; //Déclaration du booleen Val_FinDeCourseX1

LinxPjrcTeensy40* LinxDevice; //Create A Pointer To The LINX Device Object We Instantiate In Setup()

//Initialize LINX Device And Listener
void setup()
{
  //Instantiate The LINX Device
  LinxDevice = new LinxPjrcTeensy40();
  
  //The LINXT Listener Is Pre Instantiated, Call Start And Pass A Pointer To The LINX Device And The UART Channel To Listen On
  LinxSerialConnection.Start(LinxDevice, 0);

  //LINX custom command
  LinxSerialConnection.AttachCustomCommand(0, Motor_Y1); //Custom command numero 0 (Fonction GotoPosition for Y1 motor)
  LinxSerialConnection.AttachCustomCommand(1, Motor_X1); //Custom command numero 1 (Fonction GotoPosition for X1 motor)
  LinxSerialConnection.AttachCustomCommand(2, Motor_Y1_Home); //Custom command numero 2 (Fonction Home for Y1 motor)
  LinxSerialConnection.AttachCustomCommand(3, Motor_X1_Home); //Custom command numero 3 (Fonction Home for X1 motor)
  pinMode(FinDeCourseY1, INPUT); // Assignation de FinDeCourseY1 comme étant une entrée
  pinMode(FinDeCourseX1, INPUT); // Assignation de FinDeCourseX1 comme étant une entrée

  stepper_Y1.setMinPulseWidth(15);
  stepper_X1.setMinPulseWidth(15);
  
}

void loop()
{
  //Listen For New Packets From LabVIEW
  LinxSerialConnection.CheckForCommands();
  
  bool is_run_X1 = stepper_X1.isRunning(); //Permet de savoir si le moteur X1 est en mouvement
  bool is_run_Y1 = stepper_Y1.isRunning(); //Permet de savoir si le moteur Y1 est en mouvemen   

//Moteur X1 : 
//Case 1 : Go To Position
//Case 2 : Home
   switch (State_X1)   
  {
   {case 0 :
   break;}
    
    {case 1 : // Go To Position
    stepper_X1.run();
    if (is_run_X1==0)
    {
      State_X1 = 0;
    }
    break;}

    {case 2 : // Home
    stepper_X1.run();
    Val_FinDeCourseX1 = digitalRead(FinDeCourseX1);
    if (Val_FinDeCourseX1==LOW)
    {
      stepper_X1.stop();
      stepper_X1.setCurrentPosition(0);
      State_X1 = 0;  
    }
    break;}
  }

//Moteur Y1 : 
//Case 1 : Go To Position
//Case 2 : Home
  switch (State_Y1)
  {
    {case 0 :
     break;}
    
    {case 1 : // Go To Position
    stepper_Y1.run();
    if (is_run_Y1==0)
    {
      State_Y1 = 0;
    }
    break;}
    
{case 2 : // Home
    stepper_Y1.run();
    Val_FinDeCourseY1 = analogRead(FinDeCourseY1);
    if (Val_FinDeCourseY1<200)
    {
      stepper_Y1.stop();
      stepper_Y1.setCurrentPosition(0);
      State_Y1 = 0;  
    }
    break;}
  }
}

int Motor_Y1(unsigned char numInputBytes, unsigned char* input, unsigned char* numResponseBytes, unsigned char* response) // Moteur Y1 Commande Go To Position
{
    //Convertion of the char Array input to unsigned interger (Step to move)
    unsigned int Step_To_Move_Y1 = atoi((char*)input);
    

    // Set the maximum speed and acceleration:
    stepper_Y1.setMaxSpeed(18000);
    stepper_Y1.setAcceleration(3500);

    // Set the target position:
    stepper_Y1.moveTo(-Step_To_Move_Y1);

    //Change l'etat du moteur Y1 à 1 (GoToPosition)
    State_Y1 = 1;
  
    return 0; 
}

int Motor_X1(unsigned char numInputBytes, unsigned char* input, unsigned char* numResponseBytes, unsigned char* response) // Moteur X1 Commande Go To Position
{
    //Convertion of the char Array input to unsigned interger (Step to move)
    unsigned int Step_To_Move_X1 = atoi((char*)input);
    

    // Set the maximum speed and acceleration:
    stepper_X1.setMaxSpeed(3500);
    stepper_X1.setAcceleration(1500);

    // Set the target position:
    stepper_X1.moveTo(Step_To_Move_X1);

    //Change l'etat du moteur X1 à 1 (GoToPosition)
    State_X1 = 1;
    
    return 0; 
}

int Motor_Y1_Home(unsigned char numInputBytes, unsigned char* input, unsigned char* numResponseBytes, unsigned char* response) // Moteur Y1 Commande Home
{
    
    // Set the maximum speed and acceleration:
    stepper_Y1.setMaxSpeed(2000);
    stepper_Y1.setAcceleration(500);

    // Set the target position:
    stepper_Y1.moveTo(50000);

    //Change l'etat du moteur Y1 à 2 (Home)
    State_Y1 = 2;

    return 0; 
}

int Motor_X1_Home(unsigned char numInputBytes, unsigned char* input, unsigned char* numResponseBytes, unsigned char* response) // Moteur X1 Commande Home
{
    
    // Set the maximum speed and acceleration:
    stepper_X1.setMaxSpeed(1000);
    stepper_X1.setAcceleration(500);

    // Set the target position:
    stepper_X1.moveTo(-25000);

    //Change l'etat du moteur X1 à 2 (Home)
    State_X1 = 2;

    return 0; 
}

C'est quoi ces capteurs?

Ce sont des capteurs inductif 3 fils

ces capteurs sont soit NPN soit PNP
tu es sur qu'ils sont tous du meme type?
une ref serait la bienvenue, ou un lien

ils travaillent bien en 5V/
d'après ton code ils doivent etre de type NPN puisque sur un retour à GND tu stoppes le moteur.

tu peux croiser deux capteurs ( dont celui qui déconne) pour voir si le problème reste sur place ou s'il suit le capteur

Les capteurs sont de type NPN effectivement, avec une tension d'alimentation de 5-35V.

Le problème se déplace donc viens bien d'un des capteurs en question. Le capteur qui pause problème a une longueur de câble supérieur (1m). Ils sont alimenté en 5V afin d'éviter d'abaisser leurs tension pour mes différentes cartes. Le problème peut venir de la, longueur de câble un peut élever et tension d'alimentation un peut faible.

Le code fonctionnait très bien sur ma carte arduino mais sur la tensy j'ai ce problème de capteur. Comme dit plus haut en baissant la vitesse d'acquisition du capteur tout fonctionne correctement (delay de 1ms ok en dessou sa ne fonctionne plus).

Donc des collecteurs ouverts.
Maintenant, la question pour laquelle on a encore pas eu de réponse:
As-tu câblé des résistance de pullups?

Non je n'ai pas câblé de résistance de pullups.
Qu'elle est son utilité ?

Je viens de me renseigner, je ne connaissais pas.

Je peux donc tester avec une resistance interne pull up ?

pinMode(PIN_D7, INPUT_PULLUP);

Quand le transistor est bloqué s'il n'y a pas de résistance qui tire la ligne au +5V alors celle-ci est en l'air.
Effectivement le INPUT_PULLUP devrait faire l'affaire.
Maintenant, si la ligne est longue ou l'environnement bruité il serait préférable d'avoir une résistance externe de l'ordre de quelques kOhms.

Très bien. Ce qui est étonnant c'est que lorsque je fait un petit programme pour lire la valeur des deux capteur je n'ai pas de soucis avec un delay de (1ms) en dessous un des deux capteurs renvois une valeur erronée.

si c'est ton capteur qui est defectueux ou au bord des tolérences de fabrication, as tu un capteur en RAB?