Stepper w/ limit switches

Hello,
I am stumped as to how to configure this code. Does anybody know how to base a steppers stopping from a limit sensor? It will go pos or neg based off a HIGH/LOW from an external controller giving GND or 5+, but, I need to (I think) get a "feed+ or feed- instead of "step ().

I am definitely a bit lost here. If anybody would help, it is greatly appreciated. But, also if you can clarify why so I can learn as well would be great also.

I had it kind of working with the "commented out portions", but, decided to leave them just in case and to remind myself what I have tried.
I'll remove all extemporaneous items when finished.

Here is what I've got.

#include <Stepper.h>

#define motorSteps 200   
#define motorPin1 9
#define motorPin2 10
#define motorPin3 11
#define motorPin4 12

const int inputPin = 2;     // HI/LOW pushbutton pin
const int possensorPin = 3;   // pos. direction sensor limit pin
const int negsensorPin = 4;   // neg. direction sensor limit pin
const int posledPin = 5;   // pos. LED Red
const int negledPin = 6;   // neg. LED Green
//const int posdirectionPin = 7;   // pushbutton pin
//const int negdirectionPin = 8;   // pushbutton pin
int myStepperState;  // variables will change:
int inputState = 0;         // current state of the button
int possensorState = 255;    //sets at 5+/HIGH
int negsensorState = 255;    //sets at 5+/HIGH
//int posdirectionState = 0;         // current state of the button
//int negdirectionState = 0;         // current state of the button

// initialize of the Stepper library:
Stepper myStepper(motorSteps, motorPin1,motorPin2,motorPin3,motorPin4); 



void setup() 
{
  // set the motor speed at 60 RPMS:
  myStepper.setSpeed(60);
  
  // initialize the pushbutton pins as an inputs:
  Serial.begin(9600);   // Initialize the Serial port:   
  pinMode(inputPin, INPUT);
  //pinMode(posdirectionPin, INPUT); 
  //pinMode(negdirectionPin, INPUT);
  pinMode(possensorPin, INPUT);  //sets as  pos. limit switch
  pinMode(negsensorPin, INPUT);  //sets as neg. limit switch
  pinMode(posledPin, OUTPUT);   // Up sets d-pin as output to activate LED Red
  pinMode(negledPin, OUTPUT);   // Down sets d-pin as uotput to activate LED Green  

}

void loop() 
{
  
    Serial.println("P-Shuttle Test");
   // read the state of the pushbuttons values:
  inputState = digitalRead(inputPin);
  possensorState = digitalRead(possensorPin);
  negsensorState = digitalRead(negsensorPin);
 // posdirectionState = digitalRead(posdirectionPin);
 // negdirectionState = digitalRead(negdirectionPin);
  
  if (inputState == HIGH); //if input pin gets 5+vdc
  //if (posdirectionState == HIGH);
     { 
       if (possensorState == LOW);
        {
          mystepper.step(0);
        } 
       else if (possensor == HIGH);
        {  
          digitalWrite(posledPin, HIGH);  // LED Red
          myStepper.step(300);
          digitalWrite(posledPin, LOW);
        }
     } 
  if (inputState == LOW); //if input stays at resistored GND
  //(negdirectionState == HIGH); 
     { 
       if (negsensor == LOW);
        {
          mystepper.step(0);
        }
       else if (negsensor == HIGH);
        {
          digitalWrite(negledPin, HIGH);  // LED Green
          myStepper.step(-300);
          digitalWrite(negledPin, LOW);
        }
     }
  
}

Sorry I haven't got around to answering your PM, but it's better to have more ideas here anyway.

First question, what is the point of this LED control

        digitalWrite(posledPin, HIGH);  // LED Red
          myStepper.step(300);
          digitalWrite(posledPin, LOW);

You will never see them anyway unless myStepper.step(300) takes a heck of a long time.

So I gather you want the motor to turn CW or CCW based on a digital input and stop when something activates one of two limit switches.

How about something like this.

#define CCW 	HIGH

ccw_ls 	= digitalRead(limit_sw_CCW_pin);
cw_ls 	= digitalRead(limit_sw_CW_pin);
dir 	= digitalRead(dirPin);

if (dir == CCW) {
	if (ccw_ls != HIGH)		// assume switches go HIGH when activated
		myStepper.step(300);
} else {
	if (cw_ls != HIGH)
		myStepper.step(-300);

}

Rob

Unless the Stepper library has some provision for limits, you are always going to over-run your limits as the Stepper library will complete its move. You need to control the stepper directly from your own code. you would need a step function that will exit when a limit is reached. You might want to have a variable (flag) the you set if the function exits on a limit switch, and reset if it ends by finishing the move.

Programming simple steps, wave steps or half steps is not complex. A function that you pass the number of steps and the direction - (could be 1 number of steps, positive or negative for direction, or 2 numbers, the number of steps, and -1, 0 or +1 for direction) I have some code that would do this that I used for an ATtiny2313 based Stepper Driver.

Rob, yes, you are right. This is the best place.

I have been trying to implement the code how you sent it, but, am not sure how.
I have added it I think to all areas necessary, yet, nada. It's definitely a pebcak error, but, where?

Also, the LEDs are for my peace of mind via pin verification. Nothing else and can be eliminated. I was going to anyway when finished. Sorry, I suppose it is code juvenile.

I tried your code suggestion. I'm getting a " 'ccw_ls' was not declared in this scope" message.

Here's how I applied it.....

#include <Stepper.h>

#define motorSteps 200   
#define motorPin1 9
#define motorPin2 10
#define motorPin3 11
#define motorPin4 12

#define CCW 	HIGH

const int dirPin = 2;     // HI/LOW pushbutton pin
const int limit_sw_CCW_Pin = 3;   // neg. direction sensor limit pin
const int limit_sw_CW_Pin = 4;   // pos. direction sensor limit pin
int myStepperState;  // variables will change:
Stepper myStepper(motorSteps, motorPin1,motorPin2,motorPin3,motorPin4); 

void setup() 
{
  // set the motor speed at 60 RPMS:
  myStepper.setSpeed(60);
  

ccw_ls 	= digitalRead(limit_sw_CCW_pin);
cw_ls 	= digitalRead(limit_sw_CW_pin);
dir 	= digitalRead(dirPin);

if (dir == CCW) {
	if (ccw_ls != HIGH) // assume switches go HIGH when activated
		myStepper.step(300);
} else {
	if (cw_ls != HIGH)
		myStepper.step(-300);

}

kf2qd,

Yes, that is what I'm running into. The step is running its allotment no matter what. I was thinking of perhaps a "feed +/-" command in the stepper library to allow for a directed movement based on an input such as the HI/LOW I'm using now to go. then be able to simply stop the feed with the use of the limit switches.

I have a PCB mill where in the EMC2 I can do a measured step or a feed of a motor in which ever direction I designate. When I release the feed button, the motor simply stops. This is part of what I want to acheive in this project.

I have a small stage with a stepper attached that must move only 1/2" either direction when commanded by a HI/LOW from an external controller. The stage must move to the direction commanded until it hits that directions limit switch. Then it can only execute an opposite direction command.

I have been reading all kinds of physical and e-books, looking at others' code and I am just not able to grasp the concepts as they are written.

All help is appreciated.

'ccw_ls' was not declared in this scope"

You have to declare those three variables.

int ccw_ls;
int cw_ls;
int dir;

And having the code in setup() won't help because it will only run once.

BTW, I have no idea what myStepper.step(300) does, but if it moves a long way that it's not appropriate. You need to move in very small amounts per loop.


Rob

Utoto - You can write your own code to control the stepper motor -

Here is how I did it - This is simple stepping, Half stepping is similar -
pins 4, 5, 6 & 7 are connecter to 4 MOSFETs to drive the motor. Your code used 9, 10, 11, 12, minor change...

void Step()
{
 if (dir)   // dir = 1 or 0 for direction - A GLOBAL variable
 {
   ctr-- ;     // ctr is the current step in the sequence this is a 4 step sequence - 0, 1, 2 ,3 
 }
 else
 {
   ctr++ ;
 }
 ctr = ctr & 3;   // a quick way of keeping ctr in bounds - 4 in binary = 0100 so 4 & 3 = 0100 and 0011 = 0000, -1 = 1111 1111 so -1 and 3 = 0011 or 3

 switch (ctr){
 case 0:
   digitalWrite(4,HIGH);
   digitalWrite(5,LOW);
   digitalWrite(6,LOW);
   digitalWrite(7,LOW);
   break;
 case 1:
   digitalWrite(4,LOW);
   digitalWrite(5,HIGH);
   digitalWrite(6,LOW);
   digitalWrite(7,LOW);
   break;
 case 2:
   digitalWrite(4,LOW);
   digitalWrite(5,LOW);
   digitalWrite(6,HIGH);
   digitalWrite(7,LOW);
   break;
 case 3:
   digitalWrite(4,LOW);
   digitalWrite(5,LOW);
   digitalWrite(6,LOW);
   digitalWrite(7,HIGH);
   break;
 }
}

The speed of the motor is controlled by how fast you call step(), and it will move the motor 1 step. I don't know how fast the motor could be with this code, but I have another version with DIRECT PORT OUTPUT - http://arduino.cc/en/Reference/PortManipulation - that is faster. I was able to go faster than 100 RPM as long as I kept the other parts of my code to a minimum.

I was developing an Arduino based Stepper Driver, (step/direction inputs) I later moved to AVRStudio 4 and wrote the code in assembly to speed it up. here is the link to the development if you are interested - http://arduino.cc/forum/index.php/topic,84809.0.html

kf2qd - I hate to seem major newb here, but, I only kind of "get" what you sent me. I do appreciate your willing to help, but, would be OK to ask you to dumb it up a bit if possible? I have 3 books, 4 e-books, been looking over lots of posts and other stuff to try to understand the syntax and such of the language to no avail. I do not learn well from printed materials. As a result, I am not clear as to your reference and how I might be able to build on it.

As I get better, I plan to do my own web video tutorials on learning the Arduino IDE and C++. But, that's later.

It is possible to use Uno to sense the voltage of the stepper coils to detect when it meets a mechanical limit.
I have done it in my code if you're interested.

sbright33,

Thanks. I am interested in anything that might help. But, I am using a Pro Mini 5v 16MHz 328. Does this matter?

That is fine. My code is for those cheap steppers and drivers on Ebay.

Here's a modified version of my above code

#include <Stepper.h>

#define motorSteps 200   
#define motorPin1 9
#define motorPin2 10
#define motorPin3 11
#define motorPin4 12

#define dirPin 			 2     // HI/LOW pushbutton pin
#define limit_sw_CW_Pin 3   // neg. direction sensor limit pin
#define limit_sw_CCW_Pin  4   // pos. direction sensor limit pin

#define CCW 	HIGH
#define SPEED	10			// number of mS between steps

int ccw_ls;
int cw_ls;
int dir;
int myStepperState;  // variables will change:
Stepper myStepper(motorSteps, motorPin1,motorPin2,motorPin3,motorPin4); 

void setup() {
  // set the motor speed at 60 RPMS:
  myStepper.setSpeed(60);
  
  pinMode (limit_sw_CCW_Pin, INPUT);
  pinMode (limit_sw_CW_Pin, INPUT);
  pinMode (dirPin, INPUT);
}

void stepCCW () {
	// code to step the motor a small amount in the CCW direction
}

void stepCW () {
	// code to step the motor a small amount in the CW direction
}

void loop () {

	ccw_ls 	= digitalRead(limit_sw_CCW_Pin);
	cw_ls 	= digitalRead(limit_sw_CW_Pin);
	dir 	= digitalRead(dirPin);

	if (dir == CCW) {
		if (ccw_ls != HIGH) // assume switches go HIGH when activated
							// but that means external pull down resistors
			stepCW();
	} else {
		if (cw_ls != HIGH)
			stepCCW();
	}
	delay (SPEED);

}

I don't know how the stepper library works so you'll have to fill in stepCCW() and stepCW().


Rob

sbright33,

Great! My steppers are from extra extra cheap HP All-In-One cannibalizations! My driver is a ULN2803a driver IC allowing switched GND and 8 pins which carry .5AMP per pin.

Rob,

Thanks for your time and synapses. I am trying the code now. I notice that upon verification in the IDE I get no "ELSE" errors. I was getting them likecrazy and tried everything I could to releive them! I feel truly lost. I know it is my code grammar, but, how to find out?

Rob,

The code does not actuate the motor in either direction. It does with some of my old code, so I am pretty sure it should work with this. Just to simplify, I am using 2 tact switches for my limit sensors. They are tied HIGH and the press sends them LOW. The input switch is tied LOW and sends a HIGH when pressed.

They are tied HIGH and the press sends them LOW

Modify the code accordingly.

The code does not actuate the motor in either direction.

I don't understand this, do you mean the example I posted?


Rob

Modify the code accordingly.

Yes, I figured I might have to play with the settings a bit to tailor it. The switches will be pulled up as they will ultimately have a constant 5vdc sent from them and be sent to GND upon button press signaling the input pin.

I don't understand this, do you mean the example I posted?

Yes, It seems so much cleaner than mine and straight forward.

It seems complete(though I don't understand how it is doing it). Is it a partial I should have added to my own?

I need to go milk my goats now. I'll try to catch you online after work. Thanks Rob for your efforts. You must have the Bundy spirit!

Toto

Is it a partial I should have added to my own?

Did you catch the comments?

void stepCCW () {
// code to step the motor a small amount in the CCW direction
}
void stepCW () {
// code to step the motor a small amount in the CW direction
}
you'll have to fill in stepCCW() and stepCW().

You must have the Bundy spirit!

He he. Yes they make the stuff just a few k from us but I can't stand rum.


Rob

OK yes. I tried adding steps in the loop and got errors in the void stepCW. So, I tried adding the steps in the void CW and it brought error to the #define SPEED 10. So, I tried raising that one to 100. No go.

I ALSO tried putting void CCW to 100 and got an error at #define CCW HIGH.

BTW, this hardware setup requires about 140 steps to = the 1/2" travel required. So, the 100 steps is just for test purposes.

And I must say, that is a true shame. Good Rum is one of my favorite drinks. But, that's OK. I'm sure I and the rest of Australia can find it in our hearts to forgive you. :wink:

Toto