controlling multiple steppers with multiple rotary encoders

I know that this probably is an easy solution but i cant seem to find it so here is my problem, I am using an arduino mega, three encoders to control three stepper motors. The encoders have a clock data switch neg and pos pin, the motor controllers are uln2003 and the motors are 28byj-48. i want to tune a motor on the fly so i have three encoders and three steppers that will be labeled tc for top carb, mc for mid carb, and bc for bottom carb. So far i cant get two to play nice together and i feel that i am close to figuring it out but i am reaching out for some support. I dont know much code but I am trying to learn, I apologize ahead if my notes in the code are not accurate or are not clear enough. what ends up happening is that encoder 1 turns all stepper motors but not equal amounts and encoder 2 is even worse only moving in one direction and kind of randomly as well, although both switches on the encoders return their correct stepper to the starting position without controlling the other stepper motor. Thank you all for your help.

// precise stepper motor control



#include "Stepper.h"                      //incude stepper library
#define STEPS 35                          //number of steps

volatile boolean TurnDetectedTC;            //volatile veriable needed for interupt
volatile boolean rotationdirectionTC;       //volatile veriable for direction
volatile boolean TurnDetectedMC;
volatile boolean rotationdirectionMC;

const int PinCLKTC=2;                       //rotary enc clock pin used for interupt
const int PinDTTC=12;                        //rotary enc data pin used for direction
const int PinSWTC=13;
const int PinCLKMC=3;
const int PinDTMC=14;
const int PinSWMC=15;

int RotaryPositionTC=2;                     //int to store stepper position
int RotaryPositionMC=3;

int PrevPositionTC;                        //int for rot enc prev pos
int StepsToTakeTC;                         //int for num of steps to move
int PrevPositionMC;
int StepsToTakeMC;

Stepper top_carb(STEPS, 8, 10, 9, 11);  //create instance of stepper called top_carb
Stepper mid_carb(STEPS, 16, 17, 18, 19);

void isr ()   {                                 //interupt runs for clock goes low
 delay(5) ;
 if  (digitalRead(PinCLKTC))                     //read clock
   rotationdirectionTC= digitalRead(PinDTTC);      //read data and compare to clock
 else 
   (rotationdirectionTC= !digitalRead(PinDTTC)) ;     //read data and compare to clock
 TurnDetectedTC = true;                          //set flag
 if
 (digitalRead(PinCLKMC))
 rotationdirectionMC= digitalRead(PinDTMC);
 else
 rotationdirectionMC= !digitalRead(PinDTMC);
 TurnDetectedMC = true;
}

void setup () {

pinMode(PinCLKTC,INPUT) ;                         //rot enc clk set as input
pinMode(PinDTTC,INPUT) ;                         // rot enc data set as input
pinMode(PinSWTC,INPUT);                           //rot enc switch set as input
digitalWrite(PinSWTC, HIGH);                      //switch set High
attachInterrupt (0,isr,FALLING);               //rotinterupt 0 on pin 2, call isr, falling
pinMode(PinCLKMC,INPUT);
pinMode(PinDTMC,INPUT);
pinMode(PinSWMC,INPUT);
digitalWrite(PinSWMC, HIGH);
attachInterrupt (0,isr,FALLING);
}

void loop () {
   top_carb.setSpeed(600);              //set rotation speed
   if (!(digitalRead(PinSWTC))) {              //is buton pressed
     if (RotaryPositionTC == 0) {              //has buton been pressed
     } else {
       top_carb.step(-(RotaryPositionTC*50));   //if neither is true move
       RotaryPositionTC=0;                           //reset position
     }
   }

 if (TurnDetectedTC) {                         //if rot enc was moved
   PrevPositionTC = RotaryPositionTC;            //save the last position
   if (rotationdirectionTC) {                  //check direction of turn
     RotaryPositionTC=RotaryPositionTC-1;}       //counterclockwise
   else {                                
     RotaryPositionTC=RotaryPositionTC+1;}       //clockwise

   TurnDetectedTC = false;                     //do not repeat


   if ((PrevPositionTC + 1) == RotaryPositionTC) {           //move clockwise
     StepsToTakeTC=70;                           //num steps
     top_carb.step(StepsToTakeTC);          //do move
   }

   if ((RotaryPositionTC + 1) == PrevPositionTC) {           //move clockwise
     StepsToTakeTC=-70;                           //num steps
     top_carb.step(StepsToTakeTC);          //do move
   }
 }
   mid_carb.setSpeed(600);
   if (!(digitalRead(PinSWMC))) {
     if (RotaryPositionMC == 0) {
     }else{
       mid_carb.step(-(RotaryPositionMC*50));
       RotaryPositionMC=0;
     }
   }
 if (TurnDetectedMC) {
  PrevPositionMC = RotaryPositionMC;
   if (rotationdirectionMC) {
     RotaryPositionMC=RotaryPositionMC-1;}
  else {
     RotaryPositionMC=RotaryPositionMC+1;}

   TurnDetectedMC = false;

   if ((PrevPositionMC + 1) == RotaryPositionMC) {
     StepsToTakeMC=70;
     mid_carb.step(StepsToTakeMC);
   }

   if ((RotaryPositionMC + 1) == PrevPositionMC) {
     StepsToTakeMC=-70;
     mid_carb.step(StepsToTakeMC);
   }
  }
}

presise_control_1.ino (4.05 KB)

Read the forum guidelines to see how to post code. Use the IDE autoformat tool (ctrl-t or Tools, Auto Format) to make the code easier to follow.

Delay does not work in an ISR because in an ISR interrupts are disabled.

I'd start with something simpler, like make a single stepper motor move exactly the given number of steps. Then you may notice that you need a real stepper motor driver board more urgently than encoders.

spencermcc:
I am using an arduino mega, three encoders to control three stepper motors.

You have not told us how the motors should behave in response to the encoders.

The standard Stepper library blocks the Arduino while it is moving a motor. You should probably use the non-blocking functions in the AccelStepper library. Or just use the Stepper library to move one step at a time and manage the timing with your own code.

To make it easy for people to help you please modify your post and use the code button </>
codeButton.png

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 my text editor. The text editor shows line numbers, identifies matching brackets and allows me to search for things like all instances of a particular variable or function.

...R

I edited the post to reflect the requests for the code. I am going to attempt to write some simpler code to move one stepper motor as suggested above, also I am trying to request the stepper motor to move with the encoder so one rotation of the encoder is about one rotation of the stepper. Thank you all for your responses so far

spencermcc:
so one rotation of the encoder is about one rotation of the stepper.

How many pulses per revolution does your encoder generate?

The 28BYJ-48 stepper motor needs 2048 steps for one revolution of the output shaft. And there is a lot of backlash in the gearbox which will affect accuracy if you change direction unless your program allows for it.

...R

i'm not too worried about how accurate it is, as long as it close enough I will be ok with it. The main problem is that I cant get two separate encoders to turn only their stepper motor and not each others.

I wonder about your encoders. Most encoders have A and B channel, not clock and direction pins.

You assign the same ISR to the same pin twice - why that?

Using the same ISR for both encoders cannot work, because only one encoder will trigger the ISR, the other one will have no effect.