NEMA motor with Rotary Encoder – Final

NEMA motor with Rotary Encoder – Final



NEMA motor with Rotary Encoder – Final


OVERVIEW


Welcome to the final part of this tutorial on how to use a Rotary Encoder to control a stepper motor. To conclude this tutorial, we will add some switches to set IN and OUT points and then we will be able to make the motor move to those positions. In the code we will see how to detect long press and short press of the switches to enable us to use the switches to do two things. We will also add a buzzer to confirm the settings of the IN and OUT points.



SCHEMATIC


The IN switch is connected to A0
OUT switch is connected to A1
The 2 switches are both connected to GND

The Buzzer is connected to A2 and GND

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 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.

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.

Pin 2(CLK), 3(DT) and 4(SW) are receiving information from the rotary encoder.
The encoder is also connected to 3.3V and Ground of the UNO.

DIN of the WS2812 RGB stick is connected to Pin 5 and Voltage and Ground is connected to the 5V and GND of the UNO.

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


SOURCE CODE


#include "FastLED.h"  // FastLED library
 
// EasyDriver connections
#define dir_pin 8   // Pin 8 connected to Direction pin
#define step_pin 9  // Pin 9 connected to Steps pin on EasyDriver
#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
 
// WS2812 RGB Stick connection
#define led_pin 5  // Pin 5 connected to DIN of RGB Stick
 
// IN and OUT switches connections
#define SWITCH_PIN_IN A0 // Pin A0 connected to IN point switch
#define SWITCH_PIN_OUT A1 // Pin A1 connected to OUT point switch
 
// Rotary Encoder Module connections
const int PinCLK=2;   // Generating interrupts using CLK signal
const int PinSW=4;    // Reading Push Button switch
const int PinDT=6;    // Reading DT signal
 
#define NUM_LEDS 8  // # of WS2812 LEDs on stick
CRGB leds[NUM_LEDS];  // FastLED Library Init
 
// Buzzer connections
#define BUZZ_PIN A2  // Pin A2 connected to + of Buzzer
                    
volatile boolean TurnDetected;  // to detect rotation of Rotary Encoder
volatile boolean rotationdirection;  // CW or CCW rotation
volatile boolean rswitch=0;  // Variable to store rotary encoder switch state
volatile boolean led_speed_change; // to detect change of speed
volatile int StepsToTake=2;      // Controls the speed of the Stepper per Rotary click
 
int direction;   // Variable to set Rotation (CW-CCW) of stepper
int StepperPosition=0;    // To store Stepper Motor Position
int IN_Position=0;  // To store IN point Position
int OUT_Position=0;  // To store OUT point Position
 
int time;  //  to detect long switch press duration
 
// Interrupt routine runs if CLK goes from HIGH to LOW
void rotarydetect ()  {
  delay(10);  // delay for Debouncing Rotary Encoder
 
  if (rswitch == 1) {
    if (digitalRead(PinCLK)) {
      if (digitalRead(PinDT)) {
        if (StepsToTake > 2){
          StepsToTake=StepsToTake-1; }}
      if (!digitalRead(PinDT)) {
        if (StepsToTake < 9){
          StepsToTake=StepsToTake+1; }}
    led_speed_change = true;
    }
  }
 
  else {
    if (digitalRead(PinCLK))
      rotationdirection= digitalRead(PinDT);
    else
      rotationdirection= !digitalRead(PinDT);
      TurnDetected = true;
  }
}
  
void setup ()  {
  
  pinMode(BUZZ_PIN, OUTPUT);
  digitalWrite(BUZZ_PIN,LOW);
  pinMode(SWITCH_PIN_IN, INPUT);
  pinMode(SWITCH_PIN_OUT, INPUT);
  digitalWrite(SWITCH_PIN_IN,HIGH);
  digitalWrite(SWITCH_PIN_OUT,HIGH);
  
   FastLED.addLeds(leds, NUM_LEDS);  // Setup FastLED Library
   FastLED.clear();
   
   // Light up starting LED's
    for(int x = 0; x != (StepsToTake - 1); x++) {
    if (x < 2) leds[x] = CRGB::Red;     if (x > 1 & x < 5) leds[x] = CRGB::Orange;     if (x > 4) leds[x] = CRGB::Green; }
    
   FastLED.setBrightness(50);
   FastLED.show();
   
   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 Pins to Input
   pinMode(PinDT,INPUT);  
   pinMode(PinSW,INPUT);
   digitalWrite(PinSW,INPUT_PULLUP);  // use internal resistor of UNO for Rotary Encoder switch
   attachInterrupt (0,rotarydetect,FALLING); // interrupt 0 always connected to pin 2 on Arduino UNO
}
 
 
void loop ()  {
  
  if (digitalRead(SWITCH_PIN_IN) == LOW)  // Do if IN switch is pressed
 {
   time = millis();
   delay(500); //debounce
 
   // check if the switch is pressed for longer than 1 second.
    if(digitalRead(SWITCH_PIN_IN) == LOW && time - millis() >5000) 
 
     {
        digitalWrite(BUZZ_PIN,HIGH);
        delay(100);
        digitalWrite(BUZZ_PIN,LOW);
        IN_Position=StepperPosition;
 
    // if it is a short press  IN_Position) {  // Stepper was moved CW
            while (StepperPosition > IN_Position){  //  Do until Motor position is back to IN point
            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;
            delay(100-(StepsToTake*11));
        }
      }
      else {
        while (StepperPosition < IN_Position){ 
          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;           delay(100-(StepsToTake*11));          }        }      }     }     if (digitalRead(SWITCH_PIN_OUT) == LOW)  // Do if OUT switch is pressed  {        time = millis();       delay(500); //debounce      // check if the switch is pressed for longer than 1 second.       if(digitalRead(SWITCH_PIN_OUT) == LOW && time - millis() >5000) 
 
     {
        digitalWrite(BUZZ_PIN,HIGH);
        delay(100);
        digitalWrite(BUZZ_PIN,LOW);
        OUT_Position=StepperPosition;
        
    // if it is a short press  OUT_Position) {  // Stepper was moved CW
                  while (StepperPosition > OUT_Position){  //  Do until Motor position is back to OUT point
                  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;
                 delay(100-(StepsToTake*11));
               }
       }
      else {
        while (StepperPosition < OUT_Position){ 
          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;
           delay(100-(StepsToTake*11));
        }
      }
    }
      
    }
  
  
   if (!(digitalRead(PinSW))) {  // Do if Rotary Encoder switch is pressed
    delay(250); // debounce switch
    if (rswitch == 0) {
      rswitch = 1; }
    else {
      rswitch = 0; }
  }
 
// Runs if Rotary Encoder switch is pressed
  if (led_speed_change) {
    led_speed_change = false;  // do Not repeat IF loop until new rotation detected
    
    // Which LED's to light up
    FastLED.clear();
    for(int x = 0; x != (StepsToTake - 1); x++) {
      if (x < 2) leds[x] = CRGB::Red;       if (x > 1 & x < 5) leds[x] = CRGB::Orange;       if (x > 4) leds[x] = CRGB::Green; }
    FastLED.setBrightness(50);
    FastLED.show();
  }
    
// 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;
        }
  }
}

Comments

JamGorek
Kennlage
Diapneuck
Diapneuck
opbemruqirub
ayamoqispelo
gomibici
axasesenxa

Post Your Comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Enter Security Code: