I'm pulling my hair out with this. I'm working on writing code that will set a home position on start up by running a stepper motor in reverse till it hits a switch. hitting the switch will set its position to zero and then by pushing a button the stepper will run a window blind till it reaches a certain number of steps.
I'm working with an Arduino Mega 2560, easy driver stepper board, a 23KM-K217-P2v mineaba stepper.
I can get the switch to stop the motor, but then nothing happens. I haven't added the main button to activate the blind yet as i'm working on getting the home feature to work.
here is the latest code that only stops the motor when the button is pushed. I'm still learning.
//routine to run stepper motor controled blind. will add a button to control blind after homing stepper is working #include <AccelStepper.h>
AccelStepper stepper1(1, 6, 5);
const int homeButton = A0;
const int ledPin = 13;
int buttonState = 0;
void setup(){
stepper1.setMaxSpeed(500); //nice and slow for testing
pinMode(homeButton, INPUT);
pinMode(ledPin, OUTPUT);
attachInterrupt(0, homeMotor, CHANGE);
stepperHome(); //runs routine to home motor
}
void loop(){
stepper1.moveTo(5000); // random position to end for testing
stepper1.runToPosition();
delay(1000);
stepper1.moveTo(0);
stepper1.runToPosition();
delay(1000);
}
void stepperHome(){ //this routine should run the motor
//backwards slowly till it hits the switch and stops
stepper1.moveTo(-100);
stepper1.run();
digitalWrite(ledPin, LOW); //indicates it's doing something
}
void homeMotor(){
digitalWrite(ledPin, HIGH); //indicates it's doing something
stepper1.setCurrentPosition(0); //should set motor position to zero and go back to main routine
}
I would slowly reverse the motor until the switch is closed then go forward until the switch is open, lets say forward 100, do this in a function. Call this your zero or home position.
You don't need Interrupts to do this.
I would also enable the pull-up on the switch pin if you don't have an external one.
The interupt-routine acts on a state-change. Thats wrong, because it would also run, when the Motor is leaving the home position and releases the Switch.
Using Input_pullup has already been mentioned
I changed the interrupt to just a button it has an external pullup and goes to ground when pushed. now it does nothing but run the motor at a constant rate.
#include <AccelStepper.h>
AccelStepper stepper1(1, 6, 5);
const int homeButton = 0;
const int ledPin = 13;
void setup(){
stepper1.setMaxSpeed(500); //nice and slow for testing
pinMode(homeButton, INPUT);
pinMode(ledPin, OUTPUT);
stepperHome(); //runs routine to home motor
}
void loop(){
stepper1.moveTo(5000); // random position to end for testing
stepper1.runToPosition();
delay(1000);
stepper1.moveTo(0);
stepper1.runToPosition();
delay(1000);
}
void stepperHome(){ //this routine should run the motor
if (digitalRead(homeButton == HIGH)){
//backwards slowly till it hits the switch and stops
stepper1.moveTo(-100);
stepper1.run();
digitalWrite(ledPin, LOW); //indicates it's doing something
}
else{
digitalWrite(ledPin, HIGH); //indicates it's doing something
stepper1.setCurrentPosition(0); //should set motor position to zero and go back to main routine
}
}
ok, so i just realized i have to change the HIGH to LOW in the button statement because it's going to ground. so i did that, but it still just runs the motor and doesn't recognize the button push at all.
thanks for any help!
Ok, now i'm delirious. It''s supposed to be HIGH that way it runs the motor backwards till it hits the switch and goes LOW. I still haven't gotten anywhere with this. it just runs the motor. should the "HomeMotor" sketch be in the setup or main loop?
thanks!
Generally, "we" do not use pins 0 or 1 for general I/O. Use pin 2.
Magicd:
should the "HomeMotor" sketch be in the setup or main loop?
It's OK to have the stepperHome() [right?] function call placed in setup ().
Is if (digitalRead(homeButton == HIGH)) good form?
I use a variable.
const byte homeButton = 2;
byte hBval; // new variable
//... and now...
void stepperHome()
{ //this routine should run the motor
hBval = digitalRead(homeButton); // this could be in setup()
// before calling stepperHome function
while (hBval == HIGH)
{
//backwards slowly till it hits the switch and stops
stepper1.moveTo(-100);
stepper1.run();
digitalWrite(ledPin, LOW);
hBval = digitalRead(homeButton);
}
digitalWrite(ledPin, HIGH); //
stepper1.setCurrentPosition(0); //
}
Awesome! it's working. I've not seen code like that. it's very simple and interesting. I'm going to play with it some. I thank you for your time Runaway Pancake!
The code is above. that should be enough to work it out. I have no idea what your setup is. I used the following but it might be different for you.
#include <AccelStepper.h>
AccelStepper stepper1(1, 6, 5);
const int homeButton = 2;
const int ledPin = 13;
byte hBval;
void setup(){
stepper1.setMaxSpeed(500); //nice and slow for testing
stepper1.moveTo(-3200);
stepper1.setAcceleration(500);
pinMode(homeButton, INPUT);
pinMode(ledPin, OUTPUT);
stepperHome(); //runs routine to home motor
}
void loop(){
stepper1.moveTo(5000); // random position to end for testing
stepper1.runToPosition();
delay(1000);
stepper1.moveTo(0);
stepper1.runToPosition();
delay(1000);
}
//contributed by Runaway Pancake 9/2/13
void stepperHome(){ //this routine should run the motor
hBval = digitalRead(homeButton);
while (hBval == HIGH)
{
//backwards slowly till it hits the switch and stops
stepper1.moveTo(-3200);
stepper1.run();
digitalWrite(ledPin, LOW); //indicates it's doing something
hBval = digitalRead(homeButton);
}
digitalWrite(ledPin, HIGH); //indicates it's doing something
stepper1.setCurrentPosition(0); //should set motor position to zero and go back to main routine
}
thanks Magicd i m using unipolar motors !! can adapt or add a pin here in this line " AccelStepper stepper1(1, 6, 5); " because i need 4 pins for unipolar step motors.... and then how can i do to put all this code only in one proces and then to continue with a void loop ? i mean i onlly want this routine only when the arduino start o restart only one time and then that the oders process continue commonly.
1st of all you need to google the accelstepper library info to find out what the set up is for a unipolar motor. I'm using an easy driver stepper board which uses 3 pins to control a 4 wire stepper. if you aren't using a board then it's different. as for running the home function only on start up, that is the way this code is configured. you can see that in the void setup() it has the "stepperHome" function. when the arduino starts up it runs the void setup() once. whatever is in there runs once and then the void loop() runs for the rest of the time. the parts in the void loop() are just a random test code to run the stepper a little so i know it's working. you would put your main program in the void loop() section. the speed and steps are all dependent on what your motors specs are. some motors stall at too high a speed, and might not do much more than buzz at lower speeds. you need to work that out. There's plenty of tutorials online and on youtube about stepper motors. Rather than just copy paste code it's best to look at the code and try to understand what it does.
oh and the biggest thing to remember is DON'T UNPLUG THE MOTOR FROM YOUR CIRCUIT WHEN YOU HAVE POWERED THE CIRCUIT. if you are using a controller, or running directly from your arudino you will blow up your electronics if you unplug it while it is powered up, even just one wire. so make sure it's all plugged in really well. It will be an expensive mistake.
TokDuino:
RhysM, While trying your code, i get the error message that "i" is not defined. What is "i: supposed to be?
Thanks
I understand you are worst than me at arduino. No problem :))) glad I'm not the worst.
I would suggest you to use the accelstepper library.
Use google and you will find it. Use google also to see how to install a library in arduino. It is very easy.
Basically you download a zip with the library and then import it into arduino.
It is actually designed to run any type of stepper motors.
you can read about the class here: AccelStepper: AccelStepper Class Reference
and how to use it.
Try the examples and where you don't understand a command, look it up in the link above where it describes everything.
I've subscribed to the topic so if you have questions about the homeing part reply and I will try to help you.
I'm not that good at programming but I understood the library well.
Magicd, I'm not sure if you still read this topic, but acording to the link above, you should avoid using .runToPosition as that is a blocking command. This means until that command is finished arduino will be stuck in that loop and won't read any other command. That was the reason why you couldn't home. The arduino would not care about any pin or any other command (except interrupt) until that move command would end.