Go Down

Topic: 3-way switch for stepper motor (Read 102 times) previous topic - next topic

incorporealist

Hello, I'm a little out of my depth here with the coding, my apologies for that. I am setting up a vertical positioning stage for a project that uses a stepper motor. What I want is for a 3-position switch to control the direction of motion, with up being up, down being down, and center being stop. I am having a lot of trouble trying to find a way to use a single pole on the stepper motor to hold the position in "stop mode".

Here is my schematic (sorry it's fritzing, but it's simple enough that it seems to make sense. If that's problematic feel free to let me know and I'll find another way)


Currently, this is the sketch I am using (yes, I know it's all wrong for this setup and the desired outcome)
Code: [Select]

// Define Pins

int reverseSwitch = 2; // push button for reverse
int driverPUL = 7; // PUL pin
int driverDIR = 6; // DIR pin
int spd = A0; // 10k pot

//vars

int pd = 500;  // Pulse delay time
boolean setdir = LOW; // Set direction

// Interrupts

void revmotor() {
 
  setdir = !setdir;
 
}

void setup() {
 
  pinMode (driverPUL, OUTPUT);
  pinMode (driverDIR, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(reverseSwitch), revmotor, FALLING);
 
}

void loop() {
 
  pd = map((analogRead(spd)),0,1023,10000,500);
  digitalWrite(driverDIR,setdir);
  digitalWrite(driverPUL,HIGH);
  delayMicroseconds(pd);
  digitalWrite(driverPUL,LOW);
  delayMicroseconds(pd);

}


My question is: how do I change this code from a reverse-direction switch to one that will read the value of A1 and respond to the different R values and no value at all? Should I be using a digital interrupt for this? If so, how do I set up a standstill state for the motor?

wildbill

You can't have multiple loop and setup functions.

It shouldn't be necessary to do anything special for hold in place, even when you're not stepping, the driver will keep the coils enabled to keep the stepper still.

gilshultz

Since there are only two positions use a single pole switch, it is either closed or open (forward or reverse). Your frizzy thing just complicates things, there are to many open wires and stuff missing. Post a schematic showing all connections, power and ground.
This response is to help you get started in solving your problem, not solve it for you.
Good Luck & Have Fun!
Gil

groundFungus

#3
Apr 07, 2021, 11:53 pm Last Edit: Apr 07, 2021, 11:54 pm by groundFungus
The switch will not work wired like that.  The analog input is only going to see 5V, floating pin, 5V.  You need another resistor to ground to form a voltage divider as below.  The added 10K resistor acts as a pulldown resistor when the switch is in the off (open) condition, and as a part of a voltage divider when the switch is in one of the closed condition.  The analog input will read 2.5V in the down and 3.3V in the up switch position and around 0V when off.



incorporealist

Since there are only two positions use a single pole switch, it is either closed or open (forward or reverse). Your frizzy thing just complicates things, there are to many open wires and stuff missing. Post a schematic showing all connections, power and ground.
It is a 3-position switch with a central off position, not a 2-position switch, so I want to utilize the center position to be a "hold" position.
The only wires present in the schematic are the ones actually wired to the board. I don't know what I'm missing, or where the open wires are in the schematic. I am missing the 5v input from the USB, that is the only ground in the circuit.

incorporealist

You can't have multiple loop and setup functions.

It shouldn't be necessary to do anything special for hold in place, even when you're not stepping, the driver will keep the coils enabled to keep the stepper still.
Yes, the code is what I need help with. I'm hoping you are correct, and that all I need to do is tell it to stop moving. However, I don't know the language to tell it to stop, and I cannot find an example anywhere. Perhaps I do not know how to look, this is pretty new to me.

incorporealist

The switch will not work wired like that.  The analog input is only going to see 5V, floating pin, 5V.  You need another resistor to ground to form a voltage divider as below.  The added 10K resistor acts as a pulldown resistor when the switch is in the off (open) condition, and as a part of a voltage divider when the switch is in one of the closed condition.  The analog input will read 2.5V in the down and 3.3V in the up switch position and around 0V when off.
Thank you! That was definitely an oversight on my part and you probably saved me a troubleshooting hassle!
So, once I have three different levels of input, how do I code the responses that I want? If this isn't your fortè or you don't wanna fix some noob's bad code no worries, I appreciate your input!

wildbill

Here's your code reduced to the parts I think you need. Up & down might be the wrong way round.
Code: [Select]

int driverPUL = 7; // PUL pin
int driverDIR = 6; // DIR pin
int spd = A0; // 10k pot

const int pd = 500;  // Pulse delay time

void setup()
{
Serial.begin(115200);
pinMode (driverPUL, OUTPUT);
pinMode (driverDIR, OUTPUT);
}

void loop()
{
int SwitchSetting=analogRead(spd);
if(SwitchSetting<480)
  {
  // Do nothing   
  }
else  if(SwitchSetting<650)
  {  // Up
  digitalWrite(driverDIR, HIGH);
  digitalWrite(driverPUL, HIGH);
  delayMicroseconds(pd);
  digitalWrite(driverPUL, LOW);
  delayMicroseconds(pd);
  }
else
  {  // Down 
  digitalWrite(driverDIR, LOW);
  digitalWrite(driverPUL, HIGH);
  delayMicroseconds(pd);
  digitalWrite(driverPUL, LOW);
  delayMicroseconds(pd);
  }
}

Compiled, not tested.

incorporealist

#8
Apr 08, 2021, 04:31 am Last Edit: Apr 08, 2021, 04:33 am by incorporealist
Here's your code reduced to the parts I think you need. Up & down might be the wrong way round.
Code: [Select]

int driverPUL = 7; // PUL pin
int driverDIR = 6; // DIR pin
int spd = A0; // 10k pot

const int pd = 500;  // Pulse delay time

void setup()
{
Serial.begin(115200);
pinMode (driverPUL, OUTPUT);
pinMode (driverDIR, OUTPUT);
}

void loop()
{
int SwitchSetting=analogRead(spd);
if(SwitchSetting<480)
  {
  // Do nothing   
  }
else  if(SwitchSetting<650)
  {  // Up
  digitalWrite(driverDIR, HIGH);
  digitalWrite(driverPUL, HIGH);
  delayMicroseconds(pd);
  digitalWrite(driverPUL, LOW);
  delayMicroseconds(pd);
  }
else
  {  // Down 
  digitalWrite(driverDIR, LOW);
  digitalWrite(driverPUL, HIGH);
  delayMicroseconds(pd);
  digitalWrite(driverPUL, LOW);
  delayMicroseconds(pd);
  }
}

Compiled, not tested.
After adding the resistor to ground per groundFungus and slighly modifying the code you wrote to address the switch on a different input than the pot and still have the pot function as intended, this works perfectly. Thank you for the routine to monitor the analog input, I was unsure how to use the if-else if-else structure. The direction was switched, no big deal. Here's the finished, functional code for public use:

Code: [Select]
// Modified 3-way switch
// Credit to wildbill on the Arduino community forum

int driverPUL = 7; // PUL pin
int driverDIR = 6; // DIR pin
int spd = A0; // 10k pot
int motDIR = A4; //switch base

int pd = 500;  // Pulse delay time

void setup()
{
Serial.begin(9600);
pinMode (driverPUL, OUTPUT);
pinMode (driverDIR, OUTPUT);
}

void loop()
{
  pd = map((analogRead(spd)),0,1023,10000,200);
 
int SwitchSetting=analogRead(motDIR);
if(SwitchSetting<100)
  {
  // Do nothing   
  }
else  if(SwitchSetting<650)
  {  // Up
  digitalWrite(driverDIR, LOW);
  digitalWrite(driverPUL, HIGH);
  delayMicroseconds(pd);
  digitalWrite(driverPUL, LOW);
  delayMicroseconds(pd);
  }
else
  {  // Down
  digitalWrite(driverDIR, HIGH);
  digitalWrite(driverPUL, HIGH);
  delayMicroseconds(pd);
  digitalWrite(driverPUL, LOW);
  delayMicroseconds(pd);
  }
}

Hope this saves someone some trouble someday

Go Up