Control panel for stepper motors using the Accelstepper library

In this video I show you how to make a comprehensive control panel for stepper motors. I used a Nokia 5110 LCD to implement a menu system and show the values of the different variables. The buttons are used for multiple purposes as well as the rotary encoder. The whole setup allows the user to use a stepper motors for careful positioning (e.g. for a milling table or camera slider) or pre-programmed movements. The circuit also contains a limit switch which stops the movement of the motor.

Useful links:



Schematics

The Nokia 5110 LCD uses the SPI protocol and it is very important to use it with a +3.3 V system. Otherwise, it can be damaged because these units are usually not +5 V tolerant. You can use it with +5 V if you use a so-called logic level shifter/con…

The Nokia 5110 LCD uses the SPI protocol and it is very important to use it with a +3.3 V system. Otherwise, it can be damaged because these units are usually not +5 V tolerant. You can use it with +5 V if you use a so-called logic level shifter/converter. One side of the up and down buttons are directly connected to the +3.3 V, then the other side of the button goes to the microcontroller and also to the GND through a 10k resistor. The buttons are open by default. The rotary encoder’s DT and CLK pins are connected to the +3.3 V via a 10k resistor. The DT and CLK pins are also connected to the microcontroller. Furthermore a 100 nF capacitor is connected between the GND and the DT and CLK pins. Notice that the middle pin on the encoder (GND) is connected to the ground via the black cable. The connections for the stepper motor are A9 (step) and A8 (A8). I did not add any specific stepper motor control circuit, because you can use any of the popular ones with this code and arrangement.



STM32/Arduino source code

//The LCD-related code was based on the following library:
//https://github.com/cbm80amiga/N5110_GUI_encoder_demo_STM32

//Defining the pins for the Nokia 5110 LCD
#define N5110_RST       PA0
#define N5110_CS        PA4
#define N5110_DC        PA1
#define N5110_BACKLIGHT PA2

#include "N5110_SPI.h"
#if USESPI==1
#include <SPI.h>
#endif
N5110_SPI lcd(N5110_RST, N5110_CS, N5110_DC); // RST,CS,DC
#include "c64enh_font.h" //smaller font
#include "term9x14_font.h" //larger font
//make sure that the font files are in the same folder as the project file!

//AccelStepper
#include <AccelStepper.h>
AccelStepper stepper(1, PA9, PA8);// pulses/steps 9; Direction 8 

//Defining pins
const int RotaryCLK = PB9; //CLK pin on the rotary encoder
const int RotaryDT = PB8; //DT pin on the rotary encoder
const int RotarySW = PB7; //SW pin on the rotary encoder (Button function)
const int UpButton = PB12; //Up button which is also a start button
const int DownButton = PB13; //Down button which is also a stop button
const int LimitSwitch_1 = PB11; //Input for the limit switch

//Statuses of the DT and CLK pins on the encoder
int CLKNow;
int CLKPrevious;
int DTNow;
int DTPrevious;

//Timing related variables, act mainly as debouncing
float RotaryTime1; //Rotary encoder timing
float RotaryTime2;
unsigned long previousInterrupt; //Button timing

//Menu-related variables
//Values
int RotaryButtonValue; //Pressed or not pressed rotary switch
int menuCounter = 0; //this is for counting the main menu (menu item number)
int stepperMaxSpeed = 400; //for setMaxSpeed
int stepperSpeed = 400; //for setSpeed
int stepperAcceleration = 800; //for setAcceleration
int stepperAbsoluteSteps; //moveTo()
int stepperRelativeSteps; //move()
int stepperRotarySteps; // This keeps track of the steps done with the rotary encoder
int stepperButtonSteps; // This keeps track of the steps done with the buttons
int stepperStepsize = 1; //Step size for changing the variable. One click on the encoder will in/decrease with this amount
int stepperPosition = 0; //position of the stepper motor, measured in steps
int previousStepperPosition = 0; //This helps us to update the display

//booleans
bool stepperMaxSpeed_Selected = false; //for setMaxSpeed
bool stepperSpeed_Selected = false; //for setSpeed
bool stepperSpeedRun = false; //for "indefinite" running
bool stepperAcceleration_Selected = false; //for setAcceleration
bool stepperAbsoluteSteps_Selected = false; //moveTo()
bool stepperRelativeSteps_Selected = false; //move()
bool rotaryStepping_Selected = false; //precisely step the motor with the rotary encoder
bool buttonStepping_Selected = false; //precisely step the motor with the buttons (UpButton/DownButton)
bool stepperStepsize_Selected = false; //Step size menu
bool stepperSetZero_Selected = false; //Reset to 0 menu
bool menuChanged = false; //Switched between menus
bool valueChanged = false; //changed the value of a menu item
bool updateValueSelection = false; //if we want to change the value of a variable, it becomes true

char buf[25]; //buffer for printing on the LCD

void setup() 
{  
  //Definition of the pins, remember where you need
  pinMode(PB9, INPUT); //CLK 
  pinMode(PB8, INPUT); //DT
  pinMode(PB7, INPUT_PULLUP); //SW 
  pinMode(PB12, INPUT); //UP 
  pinMode(PB13, INPUT); //DOWN
  pinMode(PB11, INPUT); //LimitSwitch_1
  //Store states
  CLKPrevious = digitalRead(RotaryCLK);
  DTPrevious = digitalRead(RotaryDT);

  //Rotary encoder interrupts  
  attachInterrupt(digitalPinToInterrupt(RotaryCLK), RotaryEncoder, CHANGE);

  //Stepper setup
  stepper.setSpeed(stepperSpeed); //SPEED = Steps / second
  stepper.setMaxSpeed(stepperMaxSpeed); //SPEED = Steps / second
  stepper.setAcceleration(stepperAcceleration); //ACCELERATION = Steps /(second)^2
  
  lcd.init(); //initialize LCD
  lcd.clrScr(); //clear the whole display
  printLCD(); //print the welcome message 
}

void loop() 
{

  if(menuChanged == true)
  {  
  updateMenuPosition();
  } 

  if(valueChanged == true )
  {
  updateValue();  
  }
  
  if(updateValueSelection == true)
  {
  updateSelection();    
  }

  //Looping buttons
  CheckRotaryButton();
  UpButtonPressed();
  DownButtonPressed();
  LimitSwitchPressed();

  stepper.run(); //If a step is due, this function will do a step in each loop() iteration

  //The below part takes care of the position 
  stepperPosition = stepper.currentPosition();

  if (stepperPosition != previousStepperPosition)
  {
      updatePosition(); //Pos. on the bottom of the LCD
      updateValue(); //Pos or value in the middle of the screen
      previousStepperPosition = stepper.currentPosition(); 
      //^if the motor does not move in the next loop() iteration, the code skips this part of the code
  }
}


void RotaryEncoder()
{
  if(stepperMaxSpeed_Selected == true) 
  {
    CLKNow = digitalRead(RotaryCLK); //Read the state of the CLK pin
  // If last and current state of CLK are different, then a pulse occurred  
  if (CLKNow != CLKPrevious  && CLKNow == 1)
  {
    // If the DT state is different than the CLK state then
    // the encoder is rotating in A direction, so we increase
    if (digitalRead(RotaryDT) != CLKNow) 
    {      
      stepperMaxSpeed = stepperMaxSpeed + stepperStepsize; //1 step size increment       
    } 
    else 
    {     
        if(stepperMaxSpeed<2)            
        {
        //Don't decrease further, it should be at least 1
        }
        else
        {
            stepperMaxSpeed = stepperMaxSpeed - stepperStepsize;  //1 step size decrement 
        }  
    }    
    valueChanged = true;
  }
  CLKPrevious = CLKNow;  // Store last CLK state
  }  
  //Stepper acceleration
  else if(stepperAcceleration_Selected == true)
  {
    CLKNow = digitalRead(RotaryCLK); //Read the state of the CLK pin
  // If last and current state of CLK are different, then a pulse occurred  
  if (CLKNow != CLKPrevious  && CLKNow == 1)
  {
    // If the DT state is different than the CLK state then
    // the encoder is rotating in A direction, so we increase
    if (digitalRead(RotaryDT) != CLKNow) 
    {      
      stepperAcceleration = stepperAcceleration + stepperStepsize; //1 step size increment    
    } 
    else 
    {     
      stepperAcceleration = stepperAcceleration - stepperStepsize;     //1 step size decrement
    }
    valueChanged = true;
  }
  CLKPrevious = CLKNow;  // Store last CLK state
  }
  //Absolute rotation
  else if(stepperAbsoluteSteps_Selected == true)
  {
  CLKNow = digitalRead(RotaryCLK); //Read the state of the CLK pin
  // If last and current state of CLK are different, then a pulse occurred  
  if (CLKNow != CLKPrevious  && CLKNow == 1)
  {
    // If the DT state is different than the CLK state then
    // the encoder is rotating in A direction, so we increase
    if (digitalRead(RotaryDT) != CLKNow) 
    {
      stepperAbsoluteSteps = stepperAbsoluteSteps + stepperStepsize; //1 step size increment    
    } 
    else 
    {
      stepperAbsoluteSteps = stepperAbsoluteSteps - stepperStepsize;  //1 step size decrement
    }    
    valueChanged = true;
  }
  CLKPrevious = CLKNow;  // Store last CLK state
  }
  //Relative rotation
  else if(stepperRelativeSteps_Selected == true)
  {
  CLKNow = digitalRead(RotaryCLK); //Read the state of the CLK pin
  // If last and current state of CLK are different, then a pulse occurred  
  if (CLKNow != CLKPrevious  && CLKNow == 1)
  {
    // If the DT state is different than the CLK state then
    // the encoder is rotating in A direction, so we increase
    if (digitalRead(RotaryDT) != CLKNow) 
    {
      stepperRelativeSteps = stepperRelativeSteps + stepperStepsize; //1 step size increment    
    } 
    else 
    {
      stepperRelativeSteps = stepperRelativeSteps - stepperStepsize; //1 step size decrement    
    }    
    valueChanged = true;
  }
  CLKPrevious = CLKNow;  // Store last CLK state
  }
  //Rotary movement
  else if(rotaryStepping_Selected == true)
  {
  CLKNow = digitalRead(RotaryCLK); //Read the state of the CLK pin
  // If last and current state of CLK are different, then a pulse occurred  
  if (CLKNow != CLKPrevious  && CLKNow == 1)
  {
    // If the DT state is different than the CLK state then
    // the encoder is rotating in A direction, so we increase
    if (digitalRead(RotaryDT) != CLKNow) 
    {        
      stepperRotarySteps = stepper.currentPosition() + stepperStepsize; //1 step size increment relative to the current position  
    } 
    else 
    {
      stepperRotarySteps = stepper.currentPosition() - stepperStepsize; //1 step size decrement relative to the current position     
    }    
    valueChanged = true;
  }
  CLKPrevious = CLKNow;  // Store last CLK state  
  stepper.moveTo(stepperRotarySteps);
  }
  else if(buttonStepping_Selected == true)
  {
    //do nothing
  } 
  //Stepper step size
  else if(stepperStepsize_Selected == true)
  {
    CLKNow = digitalRead(RotaryCLK); //Read the state of the CLK pin
  // If last and current state of CLK are different, then a pulse occurred  
  if (CLKNow != CLKPrevious  && CLKNow == 1)
  {
    // If the DT state is different than the CLK state then
    // the encoder is rotating in A direction, so we increase
    if (digitalRead(RotaryDT) != CLKNow) 
    {      
      stepperStepsize++; //1 step increment of the step size
    } 
    else 
    {     
      if(stepperStepsize < 2)
      {
        //If it goes below 2 (=1), it won't be decreased anymore further
      }
      else
      {
      stepperStepsize--;    //1 step decrement of the step size
      }     
    }    
  }
  CLKPrevious = CLKNow;  // Store last CLK state
  valueChanged = true;
  }
  //Set new zeropoint
  else if( stepperSetZero_Selected == true)
  {
    //do nothing
  }  
  else //MENU COUNTER----------------------------------------------------------------------------
  {
  CLKNow = digitalRead(RotaryCLK); //Read the state of the CLK pin
  // If last and current state of CLK are different, then a pulse occurred  
  if (CLKNow != CLKPrevious  && CLKNow == 1)
  {
    // If the DT state is different than the CLK state then
    // the encoder is rotating CCW so increase
    if (digitalRead(RotaryDT) != CLKNow)
    {
      if(menuCounter < 7) //8 menu items (0, 1, 2....7)
      {
      menuCounter++;
      }
      else
      {
      menuCounter = 0; //0 comes after 7, so we move in a "ring"
      }
      menuChanged = true;
      
    } 
    else
    {
      // Encoder is rotating CW so decrease
      if(menuCounter > 0)
      {
        menuCounter--;      
      }
      else
      {
        menuCounter = 7; //7 comes after 0 when we decrease the numbers
      }
      menuChanged = true;
    }    
  }
  CLKPrevious = CLKNow;  // Store last CLK state
  }
}

void printLCD() //Prints a "welcome screen"
{
  lcd.setFont(c64enh);
  lcd.printStr(ALIGN_CENTER, 0, "Stepper"); 
  lcd.printStr(ALIGN_CENTER, 1, "Controller");  
  lcd.printStr(ALIGN_CENTER, 3, "Rotate the");   
  lcd.printStr(ALIGN_CENTER, 4, "encoder");  
  lcd.printStr(ALIGN_CENTER, 5, "to continue...");
}

void CheckRotaryButton()
{
  RotaryButtonValue = digitalRead(RotarySW); //read the button state
  
  if(RotaryButtonValue == 0) //0 and 1 can differ based on the wiring
  {    
    RotaryTime1 = millis();
    if(RotaryTime1 - RotaryTime2 > 1000)
    {       
      switch(menuCounter)
      {
         case 0:
         stepperMaxSpeed_Selected = !stepperMaxSpeed_Selected;  //we change the status of the variable to the opposite        
         if (stepperMaxSpeed_Selected == false)//exiting
         {
             stepper.stop(); //stop upon exiting the menu
         }
         updateValueSelection = true;
         break;    
         //
         case 1:
         stepperAcceleration_Selected = !stepperAcceleration_Selected;
         updateValueSelection = true;
         break;
         //
         case 2:
         stepperAbsoluteSteps_Selected = !stepperAbsoluteSteps_Selected;
         if (stepperAbsoluteSteps_Selected == false)//exiting
         {
             stepper.stop(); //stop upon exiting the menu
         }
         updateValueSelection = true;
         break;
         //
         case 3:
         stepperRelativeSteps_Selected = !stepperRelativeSteps_Selected;
         if (stepperRelativeSteps_Selected == false)//exiting
         {
             stepper.stop(); //stop upon exiting the menu
         }
         updateValueSelection = true;
         break;
         //
         case 4:         
         rotaryStepping_Selected = !rotaryStepping_Selected;
         updateValueSelection = true;
         valueChanged = true; 
         break;
         //
         case 5:
         buttonStepping_Selected = !buttonStepping_Selected;
         updateValueSelection = true;
         valueChanged = true;
         break;
         //
         case 6:
         stepperStepsize_Selected = !stepperStepsize_Selected;
         updateValueSelection = true;
         break;
         //
         case 7:
         stepperSetZero_Selected = true; //this always has to be set to true and we set it to false somewhere else
         updateValueSelection = true;
         break;
      } 
      RotaryTime2 = millis();
      menuChanged = true; //Refresh LCD after changing the value of the menu
    }
  } 
}

void updateMenuPosition()
{ 
  lcd.clrScr();//delete the entire screen

  switch(menuCounter) //this checks the value of the counter (0, 1, 2 or 3)
  {
    //MAX SPEED
    case 0:   
    lcd.setFont(c64enh); //set the font (small one)
    lcd.printStr(ALIGN_CENTER, 0, "            "); //erase previous text
    lcd.printStr(ALIGN_CENTER, 0, "Max speed"); //print new text
    lcd.setFont(Term9x14); //Set another (larger) font
    snprintf(buf, 8, "%d", stepperMaxSpeed); //the decimal value of the variable is in the buf
    lcd.printStr(10, 2, buf); //set the cursor to 2nd line 10th pixel and print the buffer
    break;    
    //-------------------------------   
    //ACCELERATION
    case 1:
    lcd.setFont(c64enh);
    lcd.printStr(ALIGN_CENTER, 0, "            ");
    lcd.printStr(ALIGN_CENTER, 0, "Acceleration");
    lcd.setFont(Term9x14);
    snprintf(buf, 8, "%d", stepperAcceleration);
    lcd.printStr(10, 2, buf);
    break;
    //-------------------------------    
    //ABSOLUTE STEPPING
    case 2:
    lcd.setFont(c64enh);
    lcd.printStr(ALIGN_CENTER, 0, "            ");
    lcd.printStr(ALIGN_CENTER, 0, "Absolute");
    lcd.setFont(Term9x14);
    snprintf(buf, 8, "%d", stepperAbsoluteSteps);
    lcd.printStr(10, 2, buf);
    break;
    //------------------------------- 
    //RELATIVE STEPS
    case 3:
    lcd.setFont(c64enh);
    lcd.printStr(ALIGN_CENTER, 0, "            ");
    lcd.printStr(ALIGN_CENTER, 0, "Relative");
    lcd.setFont(Term9x14);
    snprintf(buf, 8, "%d", stepperRelativeSteps);
    lcd.printStr(10, 2, buf);    
    break;
    //------------------------------- 
    //MOVEMENT WITH ROTARY ENCODER
    case 4:
    lcd.setFont(c64enh);
    lcd.printStr(ALIGN_CENTER, 0, "            ");
    lcd.printStr(ALIGN_CENTER, 0, "Rotary-move");
    lcd.setFont(Term9x14);
    snprintf(buf, 8, "%d", stepperRotarySteps);
    lcd.printStr(10, 2, buf);
    break;
    //------------------------------- 
    //MOVEMENT WITH BUTTONS
    case 5:
    lcd.setFont(c64enh);
    lcd.printStr(ALIGN_CENTER, 0, "            ");
    lcd.printStr(ALIGN_CENTER, 0, "Button-move");
    lcd.setFont(Term9x14);
    snprintf(buf, 8, "%d", stepperRelativeSteps);
    lcd.printStr(10, 2, buf);    
    break;
    //------------------------------- 
    //STEPSIZE
    case 6:
    lcd.setFont(c64enh);
    lcd.printStr(ALIGN_CENTER, 0, "            ");
    lcd.printStr(ALIGN_CENTER, 0, "Step size");
    lcd.setFont(Term9x14);
    snprintf(buf, 8, "%d", stepperStepsize);
    lcd.printStr(10, 2, buf);    
    break;
    //------------------------------- 
    //RESET
    case 7:
    lcd.setFont(c64enh);
    lcd.printStr(ALIGN_CENTER, 0, "            ");
    lcd.printStr(ALIGN_CENTER, 0, "Set zero");  
    break;
  }
    //"Global" value    
    lcd.setFont(c64enh);    
    snprintf(buf, 8, "%s", "Pos: ");
    lcd.printStr(0, 5, buf);    
    snprintf(buf, 8, "%d", stepperPosition);
    lcd.printStr(30, 5, buf);    
    //
    menuChanged = false; //next loop() iteration will not enter again    
}

void updateValue()
{
  switch(menuCounter) //this checks the value of the counter (0, 1, 2 or 3)
  {
    //Max speed menu
    case 0:   
    stepper.setMaxSpeed(stepperMaxSpeed);
    lcd.setFont(Term9x14);
    lcd.printStr(10, 2, "        ");
    snprintf(buf, 8, "%d", stepperMaxSpeed);
    lcd.printStr(10, 2, buf);
    break;    
    //-------------------------------      
    //Acceleration menu
    case 1:    
    stepper.setAcceleration(stepperAcceleration);
    lcd.setFont(Term9x14);
    lcd.printStr(10, 2, "        ");
    snprintf(buf, 8, "%d", stepperAcceleration);
    lcd.printStr(10, 2, buf);
    break;
    //-------------------------------    
    //Absolute movement - moveTo()
    case 2:
    lcd.setFont(Term9x14);
    lcd.printStr(10, 2, "        ");
    snprintf(buf, 8, "%d", stepperAbsoluteSteps);
    lcd.printStr(10, 2, buf);
    break;
    //------------------------------- 
    //Relative movement - move()
    case 3:
    lcd.setFont(Term9x14);
    //Command values
    lcd.printStr(10, 2, "        "); //block 8 in line 2
    snprintf(buf, 8, "%d", stepperRelativeSteps);
    lcd.printStr(10, 2, buf);  
    break;
    //------------------------------- 
    //Rotary encode movement - step by step
    case 4:
    lcd.setFont(Term9x14);
    lcd.printStr(10, 2, "        ");
    snprintf(buf, 8, "%d", stepperPosition); //location
    lcd.printStr(10, 2, buf);
    break;
    //------------------------------- 
    //Button movement - step by step
    case 5:
    lcd.setFont(Term9x14);
    lcd.printStr(10, 2, "        ");
    snprintf(buf, 8, "%d", stepperPosition); //location
    lcd.printStr(10, 2, buf);
    break;
    //------------------------------- 
    //Step size menu - increment-decrement
    case 6:
    lcd.setFont(Term9x14);
    lcd.printStr(10, 2, "        ");
    snprintf(buf, 8, "%d", stepperStepsize); 
    lcd.printStr(10, 2, buf);
    break;
  }
   //"Global" values    
    //this is always shown on the bottom of the display
    lcd.setFont(c64enh);
    lcd.printStr(30, 5, "        ");
    snprintf(buf, 8, "%d", stepperPosition);
    lcd.printStr(30, 5, buf);
    //
    valueChanged = false; //next loop() iteration will not enter again
}

void updatePosition()
{
    lcd.setFont(c64enh);
    lcd.printStr(30, 5, "        ");
    snprintf(buf, 8, "%d", stepperPosition);
    lcd.printStr(30, 5, buf);    
}

void updateSelection()
{
  
  lcd.setFont(Term9x14); //Large font size for the cursor (same as of the values)
  
  if(stepperMaxSpeed_Selected == true)
  {
    snprintf(buf, 8, "%s", ">"); //print the ">" as the cursor, the ">" indicates the selection/activation
    lcd.printStr(0, 2, buf); //put it on the display: 2nd line 0 pixel    
  }    
  else if(stepperAcceleration_Selected == true)
  {
    snprintf(buf, 8, "%s", ">");
    lcd.printStr(0, 2, buf);
  }  
  else if(stepperAbsoluteSteps_Selected == true)
  {
    snprintf(buf, 8, "%s", ">");
    lcd.printStr(0, 2, buf);
  }  
  else if(stepperRelativeSteps_Selected == true)
  {
    snprintf(buf, 8, "%s", ">");
    lcd.printStr(0, 2, buf);
  }  
  else if(rotaryStepping_Selected == true)
  {
    snprintf(buf, 8, "%s", ">");
    lcd.printStr(0, 2, buf);
  } 
  else if(buttonStepping_Selected == true)
  {
    snprintf(buf, 8, "%s", ">");
    lcd.printStr(0, 2, buf);
  }  
  else if(stepperStepsize_Selected == true)
  {
    snprintf(buf, 8, "%s", ">");
    lcd.printStr(0, 2, buf);
  } 
  else if(stepperSetZero_Selected == true)
  { 
    snprintf(buf, 8, "%s", "Reset!"); //we indicate that the position was reset to 0 by printing a message
    lcd.printStr(0, 2, buf);
    stepper.setCurrentPosition(0); //set the current position to zero    
    stepperSetZero_Selected = false; //we reset this here
  } 
  else
  {    
    snprintf(buf, 8, "%s", " ");
    lcd.printStr(0, 2, buf);
  }  
  updateValueSelection = false; //next loop() iteration will not enter      
}

void UpButtonPressed()
{
  if(digitalRead(UpButton) == 1) //1 or 0, depends on your wiring also! 
  {   
   if(millis() - previousInterrupt > 300) //debounce, sort of. If another click comes within 300 ms, we don't care about it
   {    
      if(stepperMaxSpeed_Selected == true) //runSpeed()
      {   
        //Runs the motor "indefinitely", until it stopped by the user
        stepper.move(999999999); //some really large value, for demonstration        
      }
    
      else if(stepperRelativeSteps_Selected == true) //move()
      {
        stepper.move(stepperRelativeSteps);   //start relative stepping         
      }
    
      else if(stepperAbsoluteSteps_Selected == true) //moveTo()
      {        
        stepper.moveTo(stepperAbsoluteSteps); //start absolute stepping
      }
      previousInterrupt = millis(); //update the value so the counting from 300 ms is started over from 0      
    }    
    else if(buttonStepping_Selected == true)
    {  
       //buttonstepping does not care about the 300 ms time limit
       //a little more explanation in the DownButtonPressed() function
       stepperButtonSteps = stepper.currentPosition() + stepperStepsize; //increase the target position by 1 stepsize
       stepper.moveTo(stepperButtonSteps);
    }   
   valueChanged = true; //display has to be updated  
  } 
}

void DownButtonPressed()
{   
  if(digitalRead(DownButton) == 1) //1 or 0, depends on your wiring also! 
  {
    if(millis() - previousInterrupt > 300)
    {
      if(stepperMaxSpeed_Selected == true) //runSpeed()
      {            
        stepper.stop(); //stop and note down the position (next line)
        stepperPosition = stepper.currentPosition();        
      }
    
      else if(stepperRelativeSteps_Selected == true) //move()
      {        
        stepper.stop();
        stepperPosition = stepper.currentPosition();
      }
    
      else if(stepperAbsoluteSteps_Selected == true) //moveTo()
      {       
        stepper.stop();
        stepperPosition = stepper.currentPosition();
      }
      
      previousInterrupt = millis(); //update the value so the counting from 300 ms is started over from 0
      
    }    
    else if(buttonStepping_Selected == true)
    {  
        //Optionally, this part should also be in a timing part, but then the time between two steps is limited.
        //On the other hand, that can be good if you just want one step per buttonclick
        //Otherwise, pressing the button continuously will still move the motor slowly, but even 1 click will cause several steps

        //We always want to move 1 stepsize away from the current position
        stepperButtonSteps = stepper.currentPosition() - stepperStepsize; //decrease the target position by 1 stepsize
        stepper.moveTo(stepperButtonSteps);
    }    
    valueChanged = true; //display has to be updated  
   }
}

void LimitSwitchPressed()
{
    if (digitalRead(LimitSwitch_1) == 0) //0 or 1, depends on the wiring!
    {
        if (millis() - previousInterrupt > 300)
        {            
            stepper.stop(); //"soft" stop - decelerates to 0.
            previousInterrupt = millis();
            //Alternatively we can make it to go to a specific place:
            //stepper.moveTo(0); //This goes back to absolute 0, which is technically the homing            
        }
    }
}

Previous
Previous

Building a coil winder [Part 1] - Introduction

Next
Next

MCP4725 12 bit DAC and SZBK07 DC-DC converter