2

I'm really bad with this coding part of using two rotary encoders to control two stepper motors [using 28BYJ-48 stepper motor with the ULN2003 board]. This code works fine using one rotary encoder for one stepper motor using this off brainy-bits.com:

enter image description here https://brainy-bits.com/blogs/tutorials/stepper-motor-rotary-encoder-p1

When I slightly modify the code for two encoders and two stepper motors I'm using this: However I'm not getting the results I expected. The two motors just don't respond.

#include "Stepper.h"
#define STEPS 32   // Number of steps for one revolution of Internal shaft
// 2048 steps for one revolution of External shaft

volatile boolean TurnDetected;  // need volatile for Interrupts
volatile boolean rotationdirection;  // CW or CCW rotation

const int PinCLK = 2; // Generating interrupts using CLK signal
const int PinDT = 3;  // Reading DT signal
const int PinSW = 4;  // Reading Push Button switch
const int PinCLK2 = 46;
const int PinDT2 = 47;
const int PinSW2 = 48;

int RotaryPosition = 0;  // To store Stepper Motor Position
int RotaryPosition2 = 0;

int PrevPosition;     // Previous Rotary position Value to check accuracy
int PrevPosition2;
int StepsToTake;      // How much to move Stepper
int StepsToTake2;

// Setup of proper sequencing for Motor Driver Pins
// In1, In2, In3, In4 in the sequence 1-3-2-4
Stepper small_stepper(STEPS, 8, 10, 9, 11);
Stepper small_stepper2(STEPS, 40, 41, 42, 43);


// Interrupt routine runs if CLK goes from HIGH to LOW
void isr () {
  delay(4);  // delay for Debouncing
  if (digitalRead(PinCLK))
    rotationdirection = digitalRead(PinDT);
  else
    rotationdirection = !digitalRead(PinDT);
  TurnDetected = true;
  /////I added this
  delay(4);  // delay for Debouncing
  if (digitalRead(PinCLK2))
    rotationdirection = digitalRead(PinDT2);
  else
    rotationdirection = !digitalRead(PinDT2);
  TurnDetected = true;
}
/////up to here


void setup () {
  pinMode(PinCLK, INPUT);
  pinMode(PinDT, INPUT);
  pinMode(PinSW, INPUT);
  digitalWrite(PinSW, HIGH); // Pull-Up resistor for switch
  attachInterrupt (0, isr, FALLING); // interrupt 0 always connected to pin 2 on Arduino UNO
  pinMode(PinCLK2, INPUT);
  pinMode(PinDT2, INPUT);
  pinMode(PinSW2, INPUT);
  digitalWrite(PinSW2, HIGH); // Pull-Up resistor for switch
  attachInterrupt (0, isr, FALLING); // interrupt 0 always connected to pin 2 on Arduino UNO
}

void loop () {
  small_stepper.setSpeed(600); //Max seems to be 700
  if (!(digitalRead(PinSW))) {   // check if button is pressed
    if (RotaryPosition == 0) {  // check if button was already pressed
    } else {
      small_stepper.step(-(RotaryPosition * 50));
      RotaryPosition = 0; // Reset position to ZERO
    }
  }

  // Runs if rotation was detected
  if (TurnDetected) {
    PrevPosition = RotaryPosition; // Save previous position in variable
    if (rotationdirection) {
      RotaryPosition = RotaryPosition - 1;
    } // decrase Position by 1
    else {
      RotaryPosition = RotaryPosition + 1;
    } // increase Position by 1

    TurnDetected = false;  // do NOT repeat IF loop until new rotation detected

    // Which direction to move Stepper motor
    if ((PrevPosition + 1) == RotaryPosition) { // Move motor CW
      StepsToTake = 50;
      small_stepper.step(StepsToTake);
    }

    if ((RotaryPosition + 1) == PrevPosition) { // Move motor CCW
      StepsToTake = -50;
      small_stepper.step(StepsToTake);
      small_stepper2.setSpeed(600); //Max seems to be 700
      if (!(digitalRead(PinSW2))) {   // check if button is pressed
        if (RotaryPosition2 == 0) {  // check if button was already pressed
        } else {
          small_stepper2.step(-(RotaryPosition * 50));
          RotaryPosition2 = 0; // Reset position to ZERO
        }
      }

      // Runs if rotation was detected
      if (TurnDetected)
      {
        PrevPosition2 = RotaryPosition2; // Save previous position in variable
        if (rotationdirection) {
          RotaryPosition2 = RotaryPosition2 - 1;
        } // decrase Position by 1
        else {
          RotaryPosition2 = RotaryPosition2 + 1;
        } // increase Position by 1

        TurnDetected = false;  // do NOT repeat IF loop until new rotation detected

        // Which direction to move Stepper motor
        if ((PrevPosition2 + 1) == RotaryPosition2) { // Move motor CW
          StepsToTake = 50;
          small_stepper2.step(StepsToTake);
        }

        if ((RotaryPosition2 + 1) == PrevPosition2) { // Move motor CCW
          StepsToTake = -50;
          small_stepper2.step(StepsToTake);
        }
      }
    }
  }
}
-1

simple:

1) write a set of routines that drive your servo motor via interrupts: you will need to specify the on-time for each servo channel.

2) write a set of routines that read the rotary positions.

3) write a set of routines that convert the rotary positions into the on-time parameter.

4) integrate them all.

in your loop, you will simply need to read one rotary position, convert it into the on-time for that channel, and update the on-time parameter. The servo routines will run in the background transparently to your code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.