Set IN and OUT Stepper travel point using tact switches

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

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

Arduino Stepper set In and Out travel Points

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.



THE CODE

To detect a long press or short press of the switches we will use the MILLIS function to detect the amount of time we hold down the switch.

A long press will SET the IN or OUT point and a short press will make the motor move to those points.

Also since we will use an Active Buzzer, all we need to do to make a sound when we set an IN or OUT point is to apply power to the buzzer for a short period of time to make a sound.

 

We invite you to watch all the tutorials in this series to get explanation on all the code that we are using.

 

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

 

/*Start of 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<NEOPIXEL,led_pin>(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;
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;
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;
}
}
}

/* End of Code */


TUTORIAL VIDEO



DOWNLOAD

Just copy the above Sketch code you want to use above in your Arduino IDE software to program your Arduino.

 

Used libraries:

You can download the FastLED library here

 

Once downloaded, just extract the content of the zip files inside your “arduino/libraries” folder.

 

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