NEMA Stepper motor control with Arduino and Rotary encoder

Got Questions? Click here and post them in the Brainy-Bits Forum to get help!

OVERVIEW

Welcome again to this multi part tutorial on how to control different stepper motors using a rotary encoder. 

In this second part we will use a NEMA motor with Rotary Encoder.  The stepper motor is a NEMA 17 size motor and we are again using the Rotary Encoder that we used in the first part of the tutorial.

We will be using the popular Easy Driver board to control the stepper.

Again we will write some code to have the motor move in the direction that we turn the rotary encoder, and also keep track of how much steps we have taken, so that we can have the motor move back to the starting position by pressing down on the rotary encoder switch.

To start we will not use any library to control the motor, instead we will write very fast some pins HIGH and LOW to make the steps.

 

In the next tutorial we will use a library to give us more options, like speed, acceleration and more.



SCHEMATIC

nema easy driver arduino tutorial

We are using 5 pins to connect to the Easy Driver and 3 pins for the rotary encoder module.

Pin 8 is connected to DIR
Pin 9 to STEPS
Pin 10 to MS1
Pin 11 to MS2
and Pin 12 to SLEEP

 

The 4 leads of the NEMA stepper (2 per coils), are connected directly to the Easy Driver A and B.

A quick way to identify which wires are part of the same coil is to connect two wires together and if you feel resistance when trying to turn the stepper motor shaft, that means that those 2 wires are part of the same coil.

 

The Voltage and GND of the Easy Driver are connected to a 12V 1A power supply.
The NEMA 17 motor we are using has a max amperage draw of around 0.45A.

 

Pin 2(CLK), 3(DT) and 4(SW) are receiving information from the rotary encoder.

 

We also connect the UNO Ground to the Easy Driver to serve as a reference.



THE CODE

To see how to control the Nema 17 Stepper without using any library, we will make the stepper move by putting some pins HIGH and LOW very fast. In the next tutorial we will make use of a library to give us more options. 

As with our previous tutorial, we are using some variables to store the position of the stepper, so we can make it move back to the starting position.

 

As always for more information about the tutorial and explanation of the code please watch our tutorial video.

// EasyDriver connections
#define step_pin 9  // Pin 9 connected to Steps pin on EasyDriver
#define dir_pin 8   // Pin 8 connected to Direction pin
#define MS1 10       // Pin 10 connected to MS1 pin
#define MS2 11      // Pin 11 connected to MS2 pin
#define SLEEP 12     // Pin 12 connected to SLEEP pin
                    
volatile boolean TurnDetected;  // need volatile for Interrupts
volatile boolean rotationdirection;  // CW or CCW rotation

// Rotary Encoder Module connections
const int PinCLK=2;   // Generating interrupts using CLK signal
const int PinDT=3;    // Reading DT signal
const int PinSW=4;    // Reading Push Button switch

int StepperPosition=0;    // To store Stepper Motor Position
int StepsToTake=4;      // Controls the speed of the Stepper per Rotary click

int direction;   // Variable to set Rotation (CW-CCW) of stepper


// Interrupt routine runs if CLK goes from HIGH to LOW
void rotarydetect ()  {
delay(4);  // delay for Debouncing
if (digitalRead(PinCLK))
rotationdirection= digitalRead(PinDT);
else
rotationdirection= !digitalRead(PinDT);
TurnDetected = true;
}


void setup ()  {

   pinMode(MS1, OUTPUT);
   pinMode(MS2, OUTPUT);
   pinMode(dir_pin, OUTPUT);
   pinMode(step_pin, OUTPUT);
   pinMode(SLEEP, OUTPUT);   
   digitalWrite(SLEEP, HIGH);  // Wake up EasyDriver
   delay(5);  // Wait for EasyDriver wake up
   
 /* Configure type of Steps on EasyDriver:
 // MS1 MS2
 //
 // LOW LOW = Full Step //
 // HIGH LOW = Half Step //
 // LOW HIGH = A quarter of Step //
 // HIGH HIGH = An eighth of Step //
 */ 
   digitalWrite(MS1, LOW);      // Configures to Full Steps
   digitalWrite(MS2, LOW);    // Configures to Full Steps
   
  pinMode(PinCLK,INPUT);  // Set Pin to Input
  pinMode(PinDT,INPUT);  
  pinMode(PinSW,INPUT);
  digitalWrite(PinSW, HIGH); // Pull-Up resistor for switch
  attachInterrupt (0,rotarydetect,FALLING); // interrupt 0 always connected to pin 2 on Arduino UNO
}


void loop ()  {

  if (!(digitalRead(PinSW))) {   // check if button is pressed
  if (StepperPosition == 0) {  // check if button was already pressed
  } else {
      if (StepperPosition > 0) {  // Stepper was moved CW
        while (StepperPosition != 0){  //  Do until Motor position is back to ZERO
          digitalWrite(dir_pin, HIGH);  // (HIGH = anti-clockwise / LOW = clockwise)
          for (int x = 1; x < StepsToTake; x++) {
              digitalWrite(step_pin, HIGH);
              delay(1);
              digitalWrite(step_pin, LOW);
              delay(1);            
            }
            StepperPosition=StepperPosition-StepsToTake;
        }
      }
      else {
        while (StepperPosition != 0){ 
          digitalWrite(dir_pin, LOW);  // (HIGH = anti-clockwise / LOW = clockwise)
              for (int x = 1; x < StepsToTake; x++) {
              digitalWrite(step_pin, HIGH);
              delay(1);
              digitalWrite(step_pin, LOW);
              delay(1);            
            }
           StepperPosition=StepperPosition+StepsToTake;
        }
      }
      StepperPosition=0; // Reset position to ZERO after moving motor back
    }
  }

// Runs if rotation was detected
  if (TurnDetected)  {
        TurnDetected = false;  // do NOT repeat IF loop until new rotation detected

// Which direction to move Stepper motor
        if (rotationdirection) { // Move motor CCW
            digitalWrite(dir_pin, HIGH);  // (HIGH = anti-clockwise / LOW = clockwise)
            for (int x = 1; x < StepsToTake; x++) {
              digitalWrite(step_pin, HIGH);
              delay(1);
              digitalWrite(step_pin, LOW);
              delay(1);            
            }
            StepperPosition=StepperPosition-StepsToTake;
        }

        if (!rotationdirection) { // Move motor CW
            digitalWrite(dir_pin, LOW);  // (HIGH = anti-clockwise / LOW = clockwise)
            for (int x = 1; x < StepsToTake; x++) {
              digitalWrite(step_pin, HIGH);
              delay(1);
              digitalWrite(step_pin, LOW); 
              delay(1);         
            }
            StepperPosition=StepperPosition+StepsToTake;
        }
  }
}



TUTORIAL VIDEO



DOWNLOAD

Just Copy the above Sketch code in your Arduino IDE software to program your Arduino.

 

1 Comments

Torre Owens - Feb 02, 2017

How would you write a program already using 2push buttons. Or replace them with the rotary encoder?

Got Questions? Click here and post them in the Brainy-Bits Forum to get help!

Leave a comment

Comments have to be approved before showing up