Slider with Nema17 + Nema23 withincremental encoder + 3 inductive limit switch

My project is to make a slider, the trolley is controlled by a Nema23 motor including an incremental encoder, and the turntable is controlled by a Nema 17 .. I have two inductive limit switches at the ends of the line, and an inductive limit switch on the turntable ..

When I download the code of the encoder and I move the cart with my hand it works well and I get the information of the encoder in translation

I have fixed everything but my problem is that:

  • The engine works fine, but when I insert the encoder code into the program, the engine stops and does not move forward.

  • and I do not know how to do a function to tell him to move forward and return to zero point!

this is my code :

//pins direction et nbre de pas
int PULNema23 = 40;
int DIRNema23 = 39;
int PULNema17 = 38;
int DIRNema17 = 37;

// Nbre de pas (1tour=6400pas=6,7cm pour la translation)
int stepsAvance = 6400; // il faut les paramétrer après
int stepsRecule = 6400;
int stepsRot = 24000;

int pinBouton = 6;//pin en entrée pour le bouton poussoir

const int interruptNema23A = 0;//numéro de l'interruption 0, correspond au pin 2
const int interruptNema23B = 1;//numéro de l'interruption 1, correspond au pin 3
const int interruptGauche = 2;//numéro de l'interruption 2, correspond au pin 18
const int interruptDroite = 3;//numéro de l'interruption 3, correspond au pin 19
const int interruptCentre = 4;//numéro de l'interruption 4, correspond au pin 20

//variables pour les fonction interrupt ::Sur un Arduino Mega, les numéros 0 à 5 correspondent aux broches 21,20,19,18,2et3//
const int pinInterruptNema23A = 2;
const int pinInterruptNema23B = 3;
const int pinInterruptGauche = 21;
const int pinInterruptDroite = 20;
const int pinInterruptCentre = 19;

//variables pour la fonction encodeur//
float encoNema23 = 0;
float newVal = 0;
float distanceNema23 = 0;

void setup()
{
pinMode (PULNema23, OUTPUT);
pinMode (DIRNema23, OUTPUT);
pinMode (PULNema17, OUTPUT);
pinMode (DIRNema17, OUTPUT);

pinMode(pinBouton, INPUT_PULLUP);//pin 6 du bouton en mode INPUT_PULLUP

pinMode(pinInterruptNema23A, INPUT);
pinMode(pinInterruptNema23B, INPUT);
pinMode(pinInterruptGauche, INPUT);
pinMode(pinInterruptDroite, INPUT);
pinMode(pinInterruptCentre, INPUT);

//les interruptions :

attachInterrupt(interruptNema23A, ISRNema23A, RISING);//déclenchement de l'interruption pour l'execution de la fonction ISRNema17 quand la broche concernée passe de LOW à HIGH
attachInterrupt(interruptNema23B, ISRNema23B, RISING);//déclenchement de l'interruption pour l'execution de la fonction ISRNema23 quand la broche concernée passe de LOW à HIGH
attachInterrupt(interruptGauche, ISRGauche, RISING);//déclenchement de l'interruption pour l'execution de la fonction ISRGauche quand la broche concernée change d’état, c’est à dire passe de LOW à HIGH ou bien de HIGH à LOW
attachInterrupt(interruptDroite, ISRDroite, RISING);//déclenchement de l'interruption pour l'execution de la fonction ISRDroite quand la broche concernée change d’état, c’est à dire passe de LOW à HIGH ou bien de HIGH à LOW
attachInterrupt(interruptCentre, ISRCentre, RISING);//déclenchement de l'interruption pour l'execution de la fonction ISRCentre quand la broche concernée change d’état, c’est à dire passe de LOW à HIGH ou bien de HIGH à LOW

//Serial.begin(9600);
//Serial.println("Démarrage du programme");

}

void loop()
{
/* boolean etatBouton = digitalRead(pinBouton); //test de l'état du bouton avec boolean etatBouton
if (etatBouton == 0)//test si bouton appuyé et relach*/

avance();
stopNema23();
rotation();
stopNema17();
recule();

}

void count()
{
if (encoNema23 != newVal)

{
Serial.print("Nombre d'impulsions = ");
Serial.println(encoNema23);
Serial.print("Distance parcourue en cm = ");
Serial.println(distanceNema23);
newVal = encoNema23;
}
}

// fonction pour reculer le chariot (Nema23)
void recule()
{
for (int i = 0; i < stepsRecule; i++)
{
digitalWrite(DIRNema23, LOW);
digitalWrite(PULNema23, HIGH);
delayMicroseconds(50);
digitalWrite(PULNema23, LOW);
delayMicroseconds(50);

}
}

// fonction pour avancer le chariot (Nema23)
void avance() {
for (int i = 0; i < stepsAvance; i++)
{
digitalWrite(DIRNema23, HIGH);
digitalWrite(PULNema23, HIGH);
delayMicroseconds(50);
digitalWrite(PULNema23, LOW);
delayMicroseconds(50);
}
}

// fonction pour la rotation du chariot (Nema17)
void rotation()
{
for (int i = 0; i < stepsRot; i++) //rotation de 360°
{
digitalWrite(DIRNema17, LOW);
digitalWrite(PULNema17, HIGH);
delayMicroseconds(50);
digitalWrite(PULNema17, LOW);
delayMicroseconds(50);

}
}

//fonction pour arreter le chariot
void stopNema23()
{

digitalWrite(PULNema23, LOW);

/*
arreter la translation
*/
}

//fonction pour arreter la table tournante de tourner
void stopNema17()
{

digitalWrite(PULNema17, LOW);
/*
arreter la rotation
*/
}

//fonction servant à remettre à zéro les variables des encodeurs
void remiseAZeroEncodeur()
{
distanceNema23 = 0;
encoNema23 = 0;
}

//Fonction d'interruption pour le codeur Nema23A
void ISRNema23A()
{
if (digitalRead(3) == HIGH) {
encoNema23++;
} else {
encoNema23--;
}
distanceNema23 = distanceparcourue(encoNema23);
}

//Fonction d'interruption pour le codeur Nema23
void ISRNema23B()
{
if (digitalRead(2) == HIGH) {
encoNema23--;
} else {
encoNema23++;
}
distanceNema23 = distanceparcourue(encoNema23);
}

//Fonction convertisseur impulsions en distance(cm)
float distanceparcourue(float impulsions)
{
float a = ((6.7)/1000) * impulsions;
return a;
}

/*
//Fonction convertisseur distance(cm) en impulsions
float impulsionsparcourues(float distance)
{
float a = (distance *1000 /(6.7));
return a;
}
*/

//fonction d’interruption ou la routine d’interruption après la detection du capteur inductif de fin de course gauche
void ISRGauche()
{
stopNema23();
remiseAZeroEncodeur();
//Recommencer le loop à zéro
}

//fonction d’interruption ou la routine d’interruption après la detection du capteur inductif de fin de course droite
void ISRDroite()
{
stopNema23();
//Revenir au point zéro
}

//fonction d’interruption ou la routine d’interruption après la detection du capteur inductif de fin de course au milieu dans la table tournante
void ISRCentre()
{
stopNema17();
}

Before we go to the trouble of getting the encoders to work, I have to ask why are you using encoders with stepper motors? I have 3 different CNC machines using steppers and use no encoders. Steppers move a precise amount per step and as long as you count the steps you know the position.

Please read the how to use the forum-please read stickies to see how to properly post code.

Also, a diagram of your proposed machine would help. I can't envisage what this means "My project is to make a slider, the trolley is controlled by a Nema23 motor including an incremental encoder, and the turntable is controlled by ...."

To make it easy for people to help you please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

Your code is too long for me to study quickly without copying to a text editor.

Also use the AutoFormat tool to indent your code for easier reading.

...R

thank you for the return groundfungus and robin

The mechanical test bench at IGUS. This test bench consists of a carriage for linear movement over a distance of one meter. This cart has a turntable. Movements are controlled by motors to include encoders, a Nema23 for translation and a Nema17 for rotation. The test bench also contains three end-of-course inductive sensors. The order will be made with a Mega card

codes work well when they are sequential ..

but as soon as I add the interruptions it does not work anymore, the nema23 engine of the trolley has trouble starting.

//pins direction et nbre de pas
int PULNema23 = 40;
int DIRNema23 = 39;
int PULNema17 = 38;
int DIRNema17 = 37;


// Nbre de pas (1tour=6400pas=6,7cm pour la translation)
int stepsAvance = 6400; // il faut les paramétrer après
int stepsRecule = 6400;
int stepsRot = 24000;

int pinBouton = 6;//pin en entrée pour le bouton poussoir


const int interruptCanalA = 0;//numéro de l'interruption 0, correspond au pin 2
const int interruptCanalB = 1;//numéro de l'interruption 1, correspond au pin 3
const int interruptBegin = 2;//numéro de l'interruption 2, correspond au pin 18
const int interruptEnd = 3;//numéro de l'interruption 3, correspond au pin 19
const int interruptRotate = 4;//numéro de l'interruption 4, correspond au pin 20


//variables pour les fonction interrupt ::Sur un Arduino Mega, les numéros 0 à 5 correspondent aux broches 21,20,19,18,2et3//
const int pinInterruptCanalA = 2;
const int pinInterruptCanalB = 3;
const int pinInterruptBegin = 21;
const int pinInterruptEnd = 20;
const int pinInterruptRotate = 19;


//variables pour la fonction encodeur//
float encoNema23 = 0;
float newVal = 0;
float distanceTranslation = 0;


void setup()
{
  pinMode (PULNema23, OUTPUT);
  pinMode (DIRNema23, OUTPUT);
  pinMode (PULNema17, OUTPUT);
  pinMode (DIRNema17, OUTPUT);

  pinMode(pinBouton, INPUT_PULLUP);//pin 6 du bouton en mode INPUT_PULLUP

  pinMode(pinInterruptCanalA, INPUT);
  pinMode(pinInterruptCanalB, INPUT);
  pinMode(pinInterruptBegin, INPUT);
  pinMode(pinInterruptEnd, INPUT);
  pinMode(pinInterruptRotate, INPUT);


  //les interruptions :

  attachInterrupt(interruptCanalA, ISRCanalA, RISING);//déclenchement de l'interruption pour l'execution de la fonction ISRCanalA quand la broche concernée passe de LOW à HIGH

  attachInterrupt(interruptCanalB, ISRCanalB, RISING);//déclenchement de l'interruption pour l'execution de la fonction ISRCanalB quand la broche concernée passe de LOW à HIGH

  attachInterrupt(interruptBegin, ISRBegin, RISING);//déclenchement de l'interruption pour l'execution de la fonction ISRBegin quand la broche concernée change d’état, c’est à dire passe de LOW à HIGH ou bien de HIGH à LOW

  attachInterrupt(interruptEnd, ISREnd, RISING);//déclenchement de l'interruption pour l'execution de la fonction ISREnd quand la broche concernée change d’état, c’est à dire passe de LOW à HIGH ou bien de HIGH à LOW

  attachInterrupt(interruptRotate, ISRRotate, RISING);//déclenchement de l'interruption pour l'execution de la fonction ISRRotate quand la broche concernée change d’état, c’est à dire passe de LOW à HIGH ou bien de HIGH à LOW

  //Serial.begin(9600);
  //Serial.println("Démarrage du programme");

}

void loop()
{
   boolean etatBouton = digitalRead(pinBouton); //test de l'état du bouton avec boolean etatBouton
    if (etatBouton == 0)//test si bouton appuyé et relach


  
  forward();
  stopTranslation();
  rotate();
  stopRotate();
  backward();
  stopTranslation();
}


  void count()
  {
  if (encoNema23 != newVal)

  {
    Serial.print("Nombre d'impulsions = ");
    Serial.println(encoNema23);
    Serial.print("Distance parcourue en cm = ");
    Serial.println(distanceTranslation);
    newVal = encoNema23;
  }
  }


// fonction pour reculer le chariot (Nema23)
void backward()
{
  for (int i = 0; i < stepsRecule; i++)
  {
    digitalWrite(DIRNema23, LOW);
    digitalWrite(PULNema23, HIGH);
    delayMicroseconds(50);
    digitalWrite(PULNema23, LOW);
    delayMicroseconds(50);

  }
}


// fonction pour avancer le chariot (Nema23)
void forward() {
  for (int i = 0; i < stepsAvance; i++)
  {
    digitalWrite(DIRNema23, HIGH);
    digitalWrite(PULNema23, HIGH);
    delayMicroseconds(50);
    digitalWrite(PULNema23, LOW);
    delayMicroseconds(50);
  }
}


// fonction pour la rotation du chariot (Nema17)
void rotate()
{
  for (int i = 0; i < stepsRot; i++) //rotation de 360°
  {
    digitalWrite(DIRNema17, LOW);
    digitalWrite(PULNema17, HIGH);
    delayMicroseconds(50);
    digitalWrite(PULNema17, LOW);
    delayMicroseconds(50);

  }
}


//fonction pour arreter le chariot
void stopTranslation()
{

  digitalWrite(PULNema23, LOW);

  /*
     arreter la translation
  */
}



//fonction pour arreter la table tournante de tourner
void stopRotate()
{

  digitalWrite(PULNema17, LOW);
  /*
     arreter la rotation
  */
}


  //fonction servant à remettre à zéro les variables des encodeurs
  void remiseAZeroEncodeur()
  {
  distanceTranslation = 0;
  encoNema23 = 0;
  }




  //Fonction d'interruption pour le codeur Nema23A
  void ISRCanalA()
  {
  if (digitalRead(3) == HIGH) {
    encoNema23++;
  } else {
    encoNema23--;
  }
  distanceTranslation = distanceparcourue(encoNema23);
  }

  //Fonction d'interruption pour le codeur Nema23
  void ISRCanalB()
  {
  if (digitalRead(2) == HIGH) {
    encoNema23--;
  } else {
    encoNema23++;
  }
  distanceTranslation = distanceparcourue(encoNema23);
  }


  //Fonction convertisseur impulsions en distance(cm)
  float distanceparcourue(float impulsions)
  {
  float a = ((6.7)/1000) * impulsions;
  return a;
  }

/*
  //Fonction convertisseur distance(cm) en impulsions
  float impulsionsparcourues(float distance)
  {
  float a = (distance *1000 /(6.7));
  return a;
  }
*/

//fonction d’interruption ou la routine d’interruption après la detection du capteur inductif de fin de course gauche
void ISRBegin()
{
  stopTranslation();
  remiseAZeroEncodeur();
  //Recommencer le loop à zéro!!!!
}



//fonction d’interruption ou la routine d’interruption après la detection du capteur inductif de fin de course droite
void ISREnd()
{
  stopTranslation();
  //Revenir au point zéro!!!!!
}


//fonction d’interruption ou la routine d’interruption après la detection du capteur inductif de fin de course au milieu dans la table tournante
void ISRRotate()
{
  stopRotate();
}

you will find attached the photos of the test bench
Thank you very very much :slight_smile:

Images from Reply #4 so we don't have to download them. See this Simple Image Guide

...R

fifik93:
but as soon as I add the interruptions it does not work anymore, the nema23 engine of the trolley has trouble starting.

What is the purpose of all the interrupts?

You probably should not be using delayMicroseconds() to control the motor pulses. have a look at how millis() and micros() are used in this Simple Stepper Code

I don't understand the need for a function to stop a stepper motor. Why not just stop sending it step pulses?

...R

ISRBegin() calls the stopTranslation() function which doesn't actually stop the movement. When the ISR finishes, it goes back to where it was in the main code and keeps stepping past the limit. Limit switches are usually checked in the main code and not in an interrupt.