Encoder M12 8-pole with stepper motor nema 23 + Arduino Mega

Hello,

I am working on a project to make a displacement of a trolley with a stepper motor Nema 23, and on the part to recover the data of the encoders, I manage to recover, but in duplicate, car in the form technical, quad, the engine is a whole I have to recover 500 pulse / turn, but I recover 1000 pulse/turn...!!!

and also I want to convert the value in distance but I can not see it??????!!!!!!!!!!!!!!!!!

I do not know if you have an idea after, how to integrate this data into a program when the engine rolls, for example, give him commands to return to the zero point!!!!!!!!!!!!!!!!!!!!!!

Here is the information on the encoder: encoder M12 8-pole
pin1 = signal A = white
pin2 = signal A/ = brown
pin3 = signal B = green
pin4 = signal B/ = yellow
pin5 = signal 0V = grey
pin6 = signal N/ = pink
pin7 = signal N = blue
pin8 = signal 5V DC = red
housing = shielding = shielding

knowing that I plug the wires: White in pin2, green in pin 3, Red in 5v, grey in GND

this is my code :

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 pinInterruptNema23A = 2; //Fil white au pin 2
const int pinInterruptNema23B = 3; // Fil green au pin 3

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

void setup()
{

pinMode(pinInterruptNema23A, INPUT);

pinMode(pinInterruptNema23B, INPUT);

attachInterrupt(interruptNema23A, ISRNema23A, RISING);//déclenchement de l'interruption pour l'execution de la fonction ISRNema23 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

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

}

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

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

//Fonction d'interruption pour le codeur canal A Nema23

void ISRNema23A()
{
if(digitalRead(3)==HIGH){
encoNema23++;
}else{
encoNema23--;
}
distanceNema23 = distanceparcourue(encoNema23);
}

//Fonction d'interruption pour le codeur canal B Nema23

void ISRNema23B()
{
if(digitalRead(2)==HIGH){
encoNema23--;
}else{
encoNema23++;
}
distanceNema23 = distanceparcourue(encoNema23);
}

//Fonction convertisseur impulsions en distance(cm) [ Le moteur en 1 tour = 6400 pas = 6,7cm ,, et l'encodeur en 1 tour fait 500impulsions]

float distanceparcourue(float impulsions23)
{
float a = ((6, 7) /500) * impulsions23;
return a;
}

with a stepper motor Nema 23

What color is it?

on the part to recover the data of the encoders, I manage to recover, but in duplicate, car in the form technical, quad, the engine is a whole

I have no idea what that means.

and also I want to convert the value in distance but I can not see it?

If I spin you around in a circle for 10 minutes, how far have you traveled? Falling down after I stop spinning you doesn't count as part of the distance you move.

Something moved, causing the encoder to rotate, causing it to output pulses. YOU have to measure how far the thing that moved moved between two pulses, with a scale. Then, you can calculate distance moved based on the pulse count.

float encoNema23 = 0;

Do you REALLY expect to get 3.7 pulses? The NUMBER of pulses will ALWAYS be an integral value, so an integral type is the ONLY type that is appropriate to hold the value.

Variables used in ISRs and other functions should be volatile.

  float a = ((6, 7) /500) * impulsions23;

Utter nonsense. Regardless of what symbol is used in your language to separate the fractional portion from the whole portion of a number, C and C++ only speak English, where the separator is NOT a comma.

I thank you very much for the return …

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 …

Thanks to some comments from you, I have fixed everything but my problem is that:

  • The engine works fine, but when I insert the encoder 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 impulsions23)
{
float a = ((6, 7) / 500) * impulsions23;
return a;
}

//Fonction convertisseur distance(cm) en impulsions
float impulsionsparcourues23(float distance)
{
float a = (distance * 500 / (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();
}

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

//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();
}

NEMA 17 and NEMA 23 define mounting hole locations and sizes. They are completely meaningless in terms of defining which stepper is which. So, get rid of EVERY reference to NEMA 17 or NEMA 23 from your code, and use names that reflect the purpose of each stepper.

Then, perhaps, your code will make sense.

There is a Stepper library that actually, strangely enough, knows how to make a stepper step. Use it, instead of your current approach.

There are procedures for posting code. Read about them in the stickies at the top of the forum BEFORE you make a fool of yourself posting code incorrectly AGAIN.

here is my example encoder code I use in all my programs you will need to adapt it to the mega but it works great
its non-blocking and fast

here are the two lines that will require the most work to adapt to the mega

#define readA bitRead(PIND,2)//faster than digitalRead()  (((value) >> (bit)) & 0x01)
#define readB bitRead(PIND,3)//faster than digitalRead()  (((value) >> (bit)) & 0x01)

PIND is an internal variable comprised of bits that directly link to the digital pins 0~8
you could use digitalRead ( 2 ) ; and digitalRead ( 3) ; but its much slower

/Replace the above lines with:
#define readA digitalRead(ClockPin)
#define readB digitalRead(DataPin)
#define ClockPin 2 // Must be pin 2 on UNO
#define DataPin 3 // Must be pin 3 on UNO
#define readA bitRead(PIND,2)//faster than digitalRead()  (((value) >> (bit)) & 0x01)
#define readB bitRead(PIND,3)//faster than digitalRead()  (((value) >> (bit)) & 0x01)
volatile long count = 0;
long lastCtr;

void Encoder(bool A) {
  (readB == A)  ? count++ : count--;
}

void setup() {
  Serial.begin(115200); //115200
  pinMode(ClockPin, INPUT);
  pinMode(DataPin, INPUT);
  /* 1 Step */
  attachInterrupt(digitalPinToInterrupt(ClockPin), [] {Encoder( true);}, RISING);
  /**/

  /*  2 step count
  attachInterrupt(digitalPinToInterrupt(ClockPin), [] {Encoder( readB);}, CHANGE);
  */
  
  /* Full 4 Step Count
  attachInterrupt(digitalPinToInterrupt(ClockPin), [] {Encoder( readB);}, CHANGE);
  attachInterrupt(digitalPinToInterrupt(DataPin ), [] {Encoder( !readA);}, CHANGE);
  */
}

void loop() {
  long Counter;
  noInterrupts ();
  Counter = count;
  interrupts ();
  if ((lastCtr != Counter)) {
    Serial.println(Counter);
  }
  lastCtr = Counter;
}

The code provides a count of how many pulses occurred between samples so you don't have to keep track and process each step you can see that you made 10 pulses from last reading and adjust speed to allow for easier control.
Hope this helps
Z