Controlling a stepper motor with 3 programs on 1 Arduino Uno

Hi I am new here and to Arduino too. I am just starting to program Arduino but still in beginning stage and need help.

I have a program where I control a stepper motor to slide a platform certain steps CW as long as the trigger is high and then CCW when trigger is high. Now i need to change the steps distance on the platform to move 2 steps CW and 1 step CCW with a use of an selector switch. Can this be done and how?

when you get your trigger signal read the selector switch to determine how many steps to execute?
post your code?

Welcome to the forum and please read this

before posting and follow the advices to get more help

Hi Horace thank you for the response here is my code as present. I will need to then add in the other two scenarios into this program.





// if ENA is LOW motor is locked at last position
// this can lead to overheating of motor
// program assumes common cathode connection

#define SW1 2
#define SW2 3
#define SW3 4
#define DIR 5
#define PUL 6
#define ENA 7 // HIGH disables motor power

#define CW 1
#define CCW 0






// indicates motor is on
// this is built in LED on DP13.
#define motorOn 13

// sets how many pulses for 360 degrees
#define rot360 200

// HIGH on PUL will keep motor locked in position
// note motor will get hot after some time.

int x, y;

// this sets the motor speed
int pulseDelay = 300; // in uSec.

void setup() {
  // DP13 LED
  pinMode(motorOn, OUTPUT);
  digitalWrite(motorOn, LOW);

  pinMode(SW1, INPUT_PULLUP);
  pinMode(SW2, INPUT_PULLUP);
  pinMode(SW3, INPUT_PULLUP);
  pinMode(DIR, OUTPUT);
  digitalWrite(DIR, LOW);
  pinMode(PUL, OUTPUT);
  digitalWrite(PUL, LOW);
  pinMode(ENA, OUTPUT);
  digitalWrite(ENA, HIGH); 

}

void loop() {

  
  // manual CW when pushed
    if (digitalRead(SW1) == 0) {
      motorRun(3,CW);
     
   
  } 
  
  // end while

  // manual CCW when pushed
  if (digitalRead(SW2) == 0) {
    motorRun(3,CCW);
   
   
  // end while

  }

  if (digitalRead(SW1) && digitalRead(SW2)) digitalWrite(motorOn, LOW);

  if (digitalRead(SW3) == 0) {
    lockMotor();
  }
  else {
    unlockMotor();
  }
  delay(100);

} // end loop

void motorRun(int count, byte dir_local )   {
  digitalWrite(motorOn, HIGH); // DP13 LED
  digitalWrite(ENA, LOW); // motor power ON
  digitalWrite(DIR, dir_local);
  count = count * rot360;
  for (int x = 0; x < count; x++)   {
    digitalWrite(PUL, 1);
    digitalWrite(PUL, 0);
    delayMicroseconds(pulseDelay);
  } // end for
  digitalWrite(ENA, HIGH); // motor power OFF
  digitalWrite(motorOn, LOW);
}

void lockMotor(void) {
  digitalWrite(motorOn, HIGH);
  digitalWrite(ENA, LOW);
}

void unlockMotor(void) {
  digitalWrite(ENA, HIGH);


}

think we require a detailed specification, e.g.

  1. your program has a condition when SW1 and SW2 are pressed???
  2. what is SW3 doing?

Hi SW3 at the moment not doing anything suppose to enable motor on or off. I would like to to use a rotary switch to switch the motor steps to the different modes (steps) So i have three selections to choose what steps the motor must take.

this is very vauge - need more deails of what happens when a switch is pressed, a combination of switches pressed, how effected by dial settings, etc.
I assume you would use a rotary encoder for dial settings?

Hi So SW1 will cause the motor to step CW when triggered, there is a cutting blade that is the trigger. The stepper motor moves the platform 20mm each time the blade is raised. The platform has a limiter once it reaches it end. SW2 does the same as SW1 just CCW. Now I need to vary the distance the platform moves to allow variable predetermined cutting sizes using SW1 and SW2. I will use a three pole rotary switch to select the different cutting sizes.

I hope this makes it clearer?

how will you connect the three pole rotary switch? to three digital IO pins?
Edited: this will give 3 settings which you can use to select distance
so you have something like

if SW1 pressed
     read rotary switch 
     move CW - distance as specified by rotary switch
if SW2 pressed
    etc etc

Hi So i was thinking along the lines of adding another 3 digital pins and selecting different "loops" so basically creating another two loops with different steps for the different sizes of cuts. If that is possible?

So example: I add digital pin 8 to select a different loop while pin 8 is low this loop will run.

if that makes sense?

sounds as though it could work!
try writing some code

Hi This is what i have done so far but have not tested yet.




// if ENA is LOW motor is locked at last position
// this can lead to overheating of motor
// program assumes common cathode connection

#define SW1 2
#define SW2 3
#define SW3 4
#define DIR 5
#define PUL 6
#define ENA 7 // HIGH disables motor power

#define CW 1
#define CCW 0

#define SW4 8
#define SW5 9
#define SW6 10




// indicates motor is on
// this is built in LED on DP13.
#define motorOn 13

// sets how many pulses for 360 degrees
#define rot360 200

// HIGH on PUL will keep motor locked in position
// note motor will get hot after some time.

int x, y;

// this sets the motor speed
int pulseDelay = 300; // in uSec.

void setup()  {
  // DP13 LED
  pinMode(motorOn, OUTPUT);
  digitalWrite(motorOn, LOW);
  pinMode(SW1, INPUT_PULLUP);
  pinMode(SW2, INPUT_PULLUP);
  pinMode(SW3, INPUT_PULLUP);
  pinMode(SW4, INPUT_PULLUP);
  pinMode(SW5, INPUT_PULLUP);
  pinMode(SW6, INPUT_PULLUP);
  pinMode(DIR, OUTPUT);
  digitalWrite(DIR, LOW);
  pinMode(PUL, OUTPUT);
  digitalWrite(PUL, LOW);
  pinMode(ENA, OUTPUT);
  digitalWrite(ENA, HIGH); 

}

void loop () {
  if (digitalRead (SW4) == 0);
  // execute loop_0   
  if (digitalRead (SW5) == 0);
  // ececute loop_1
  if (digitalRead (SW6) == 0);
  // execute loop_2

} // end loop

void loop_0() {

    
  // manual CW when pushed
    if (digitalRead(SW1) == 0) {
      motorRun(3,CW);
     
   
  } 
  
  // end while

  // manual CCW when pushed
  if (digitalRead(SW2) == 0) {
    motorRun(3,CCW);
   
   
  // end while

  }

  if (digitalRead(SW1) && digitalRead(SW2)) digitalWrite(motorOn, LOW);

  if (digitalRead(SW3) == 0) {
    lockMotor();
  }
  else {
    unlockMotor();
  }
  delay(100);

} // end loop

void loop_1() {
    
  // manual CW when pushed
    if (digitalRead(SW1) == 0) {
      motorRun(3,CW);
     
   
  } 
  
  // end while

  // manual CCW when pushed
  if (digitalRead(SW2) == 0) {
    motorRun(6,CCW);
   
   
  // end while

  }

  if (digitalRead(SW1) && digitalRead(SW2)) digitalWrite(motorOn, LOW);

  if (digitalRead(SW3) == 0) {
    lockMotor();
  }
  else {
    unlockMotor();
  }
  delay(100);

} // end loop

void loop_2() {

    
  // manual CW when pushed
    if (digitalRead(SW1) == 0) {
      motorRun(1.5,CW);
     
   
  } 
  
  // end while

  // manual CCW when pushed
  if (digitalRead(SW2) == 0) {
    motorRun(1.5,CCW);
   
   
  // end while

  }

  if (digitalRead(SW1) && digitalRead(SW2)) digitalWrite(motorOn, LOW);

  if (digitalRead(SW3) == 0) {
    lockMotor();
  }
  else {
    unlockMotor();
  }
  delay(100);

} // end loop

void motorRun(int count, byte dir_local )   {
  digitalWrite(motorOn, HIGH); // DP13 LED
  digitalWrite(ENA, LOW); // motor power ON
  digitalWrite(DIR, dir_local);
  count = count * rot360;
  for (int x = 0; x < count; x++)   {
    digitalWrite(PUL, 1);
    digitalWrite(PUL, 0);
    delayMicroseconds(pulseDelay);
  } // end for
  digitalWrite(ENA, HIGH); // motor power OFF
  digitalWrite(motorOn, LOW);
}

void lockMotor(void) {
  digitalWrite(motorOn, HIGH);
  digitalWrite(ENA, LOW);
}

void unlockMotor(void) {
  digitalWrite(ENA, HIGH);


}

Sorry, wrong terminology. :grin:

There is only ever one "loop()". In that loop, you may - and indeed should - choose between alternate tasks. This is called a "state machine".

Actually your code as shown (is wrong and ...) does not choose alternate tasks, but - quite appropriately in general - successively implements each of several tasks based on whether the corresponding "state variable" or "switch" is active.

To do that it should be

void loop () {
  if (digitalRead (SW4) == 0) {
  // execute task_0
    }
  if (digitalRead (SW5) == 0) {
  // execute task_1
    }
  if (digitalRead (SW6) == 0) {
  // execute task_2
    }
  } // end loop

Note that

if (something == whatever) ;

With the semicolon immediately after, means if that comparison is true, do nothing but just continue to the next statement.

Hi Paul_B thank you for your input I will correct my code and try it. I am not to clued up with the syntax but I am getting there .. thank you!

Hi Paul_B sorry to ask but in the code that I have submitted I have this section that I need to change when I use the rotary selector switch. So its just the amount of turns the motor needs to change.

  // manual CW when pushed
    if (digitalRead(SW1) == 0) {
      motorRun(3,CW);
     
   
  } 
  
  // end while

  // manual CCW when pushed
  if (digitalRead(SW2) == 0) {
    motorRun(3,CCW);
   
   
  // end while

Should be no "end while" in the code as there should be no "while()". :grin:

Thanks I am still struggling with creating tasks where I can change the steps of the motor and to select these tasks. I have tried various ways to do this and I am not winning

Hi guys here is the code I have written but not working I am not sure if FreeRTOS is the way to go but here is my attempt but no luck please let me know what I am doing wrong ??

// Include Arduino FreeRTOS library
#include <Arduino_FreeRTOS.h>

// if ENA is LOW motor is locked at last position
// this can lead to overheating of motor
// program assumes common cathode connection

#define SW1 2
#define SW2 3
#define SW3 4
#define DIR 5
#define PUL 6
#define ENA 7 // HIGH disables motor power

#define CW 1
#define CCW 0

#define SW4 8
#define SW5 9
#define SW6 10

// indicates motor is on
// this is built in LED on DP13.
#define motorOn 13

// sets how many pulses for 360 degrees
#define rot360 200

// HIGH on PUL will keep motor locked in position
// note motor will get hot after some time.

int x, y;

// this sets the motor speed
int pulseDelay = 300; // in uSec.

void TaskCut20x20( void *pvParameters ); 
void TaskCut20x40( void *pvParameters ); 
void TaskCut10x10( void *pvParameters );

void motorRun(int count, byte dir_local )   {
  digitalWrite(motorOn, HIGH); // DP13 LED
  digitalWrite(ENA, LOW); // motor power ON
  digitalWrite(DIR, dir_local);
  count = count * rot360;
  for (int x = 0; x < count; x++)   {
    digitalWrite(PUL, 1);
    digitalWrite(PUL, 0);
    delayMicroseconds(pulseDelay);
  } // end for
  digitalWrite(ENA, HIGH); // motor power OFF
  digitalWrite(motorOn, LOW);
}

void lockMotor(void) {
  digitalWrite(motorOn, HIGH);
  digitalWrite(ENA, LOW);
}

void unlockMotor(void) {
  digitalWrite(ENA, HIGH);


}


void setup() {
  xTaskCreate(TaskCut20x20,"TaskCut20x20",128,NULL,0,NULL);
  xTaskCreate(TaskCut20x40,"TaskCut20x40",128,NULL,0,NULL);
  xTaskCreate(TaskCut10x10,"TaskCut10x10",128,NULL,0,NULL);

}

void loop() {
  if (digitalRead (SW4) == 0);
  // execute Task1   
  if (digitalRead (SW5) == 0);
  // execute Task2
  if (digitalRead (SW6) == 0);
  // execute Task3
  
 }
void TaskCut20x20(void *pvParameters)
{
  // manual CW when pushed
    if (digitalRead(SW1) == 0) {
      motorRun(3,CW);

     
  // end while   
   
  } 
  
  
  // manual CCW when pushed
  if (digitalRead(SW2) == 0) {
    motorRun(3,CCW);
   
   
  // end while

  }

  if (digitalRead(SW1) && digitalRead(SW2)) digitalWrite(motorOn, LOW);

  if (digitalRead(SW3) == 0) {
    lockMotor();
  }
  else {
    unlockMotor();
  }
  delay(100);

} // end loop 


void TaskCut20x40(void *pvParameters){
   // manual CW when pushed
    if (digitalRead(SW1) == 0) {
      motorRun(3,CW);
      
      
  // end while   
   
  } 
  
  

  // manual CCW when pushed
  if (digitalRead(SW2) == 0) {
    motorRun(6,CCW);
   
   
  // end while

  }

  if (digitalRead(SW1) && digitalRead(SW2)) digitalWrite(motorOn, LOW);

  if (digitalRead(SW3) == 0) {
    lockMotor();
  }
  else {
    unlockMotor();
  }
  delay(100);

} // end loop

void TaskCut10x10(void *pvParameters){
   // manual CW when pushed
    if (digitalRead(SW1) == 0) {
      motorRun(1.5,CW);
      
      
  // end while   
   
  } 
  
 
  // manual CCW when pushed
  if (digitalRead(SW2) == 0) {
    motorRun(1.5,CCW);
   
   
  // end while

  }

  if (digitalRead(SW1) && digitalRead(SW2)) digitalWrite(motorOn, LOW);

  if (digitalRead(SW3) == 0) {
    lockMotor();
  }
  else {
    unlockMotor();
  }
  delay(100);

} // end loop

Hi Guys thank you for your assistance I have sorted out the combining of 3 sketches and manually select the sketch i need. here is how I achieved it. Thank you again for your help.


// if ENA is LOW motor is locked at last position
// this can lead to overheating of motor
// program assumes common cathode connection

#define SW1 2
#define SW2 3
#define SW3 4
#define DIR 5
#define PUL 6
#define ENA 7 // HIGH disables motor power

#define CW 1
#define CCW 0

#define SW4 8
#define SW5 9
#define SW6 10

// indicates motor is on
// this is built in LED on DP13.
#define motorOn 13

// sets how many pulses for 360 degrees
#define rot360 200

// HIGH on PUL will keep motor locked in position
// note motor will get hot after some time.

int x, y;

// this sets the motor speed
int pulseDelay = 300; // in uSec.


void motorRun(int count, byte dir_local )   {
  digitalWrite(motorOn, HIGH); // DP13 LED
  digitalWrite(ENA, LOW); // motor power ON
  digitalWrite(DIR, dir_local);
  count = count * rot360;
  for (int x = 0; x < count; x++)   {
    digitalWrite(PUL, 1);
    digitalWrite(PUL, 0);
    delayMicroseconds(pulseDelay);
  } // end for
  digitalWrite(ENA, HIGH); // motor power OFF
  digitalWrite(motorOn, LOW);
}

void lockMotor(void) {
  digitalWrite(motorOn, HIGH);
  digitalWrite(ENA, LOW);
}

void unlockMotor(void) {
  digitalWrite(ENA, HIGH);


}

void setup() {
  // DP13 LED
  pinMode(motorOn, OUTPUT);
  digitalWrite(motorOn, LOW);

  pinMode(SW1, INPUT_PULLUP);
  pinMode(SW2, INPUT_PULLUP);
  pinMode(SW3, INPUT_PULLUP);
  pinMode(DIR, OUTPUT);
  digitalWrite(DIR, LOW);
  pinMode(PUL, OUTPUT);
  digitalWrite(PUL, LOW);
  pinMode(ENA, OUTPUT);
  digitalWrite(ENA, HIGH); 

}


void loop() {
  if (digitalRead (SW4) == 0){
     // manual CW when pushed
    if (digitalRead(SW1) == 0) {
      motorRun(3,CW);

      
  // end while   
   
  } 
  
  
  // manual CCW when pushed
  if (digitalRead(SW2) == 0) {
    motorRun(3,CCW);
   
   
  // end while

  }

  if (digitalRead(SW1) && digitalRead(SW2)) digitalWrite(motorOn, LOW);

  if (digitalRead(SW3) == 0) {
    lockMotor();
  }
  else {
    unlockMotor();
  }
  delay(100);

} // end loop    
 
  if (digitalRead (SW5) == 0){ 
     // manual CW when pushed
    if (digitalRead(SW1) == 0) {
      motorRun(3,CW);

      
  // end while   
   
  } 
  
  
  // manual CCW when pushed
  if (digitalRead(SW2) == 0) {
    motorRun(6,CCW);
   
   
  // end while



  if (digitalRead(SW1) && digitalRead(SW2)) digitalWrite(motorOn, LOW);

  if (digitalRead(SW3) == 0) {
    lockMotor();
  }
  else {
    unlockMotor();
  }
  delay(100);

} // end loop 

  }

  if (digitalRead (SW6) == 0){
     // manual CW when pushed
    if (digitalRead(SW1) == 0) {
      motorRun(1.5,CW);

      
  // end while   
   
  } 
  
  
  // manual CCW when pushed
  if (digitalRead(SW2) == 0) {
    motorRun(1.5,CCW);
   
   
  // end while

  }

  if (digitalRead(SW1) && digitalRead(SW2)) digitalWrite(motorOn, LOW);

  if (digitalRead(SW3) == 0) {
    lockMotor();
  }
  else {
    unlockMotor();
  }
  delay(100);

} // end loop  

  }