The state change detection example shows you how to determine when the switch BECOMES pressed, rather than IS pressed, or BECOMES released. Based on the time when the switch becomes pressed and when it becomes released, you can determine how long it was pressed.
So far I have written this code but unfortunately I haven't had any responce from the stepper
float pressLength_milliSeconds = 0;
// Define the *minimum* length of time, in milli-seconds, that the button must be pressed for a particular option to occur
int optionOne_milliSeconds = 100;
int optionTwo_milliSeconds = 2000;
//The Pin your button is attached to
int buttonPin = 2;
//Pin your LEDs are attached to
int directionPin = 6;
int stepPin = 10;
unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 25; // milliseconds
void setup(){
Serial.begin(9600); //Start serial communication
Serial.println("Starting Stepper Demo with millis()");
// Initialize the pushbutton pin as an input pullup
(buttonPin, INPUT_PULLUP);
//set the driver pins as outputs
pinMode(directionPin, OUTPUT);
pinMode(stepPin, OUTPUT);
} // close setup
void loop() {
curMillis = millis();
actOnButtons();
//Record *roughly* the tenths of seconds the button in being held down
while (digitalRead(buttonPin) == HIGH ){
delay(100); //if you want more resolution, lower this number
pressLength_milliSeconds = pressLength_milliSeconds + 100;
//display how long button is has been held
Serial.print("ms = ");
Serial.println(pressLength_milliSeconds);
}//close while
//every time through the loop, we need to reset the pressLength_Seconds counter
pressLength_milliSeconds = 0;
} // close void loop
//Different if-else conditions are triggered based on the length of the button press
//Start with the longest time option first
void actOnButtons(){
//Option 2 - Execute the second option if the button is held for the correct amount of time
if (pressLength_milliSeconds >= optionTwo_milliSeconds){
digitalWrite(directionPin, HIGH);
singleStep();{
digitalWrite(stepPin,HIGH);
delayMicroseconds(20);
digitalWrite(stepPin,LOW);
delayMicroseconds(20);
}
}
//option 1 - Execute the first option if the button is held for the correct amount of time
if(pressLength_milliSeconds >= optionOne_milliSeconds){
digitalWrite(directionPin, LOW);
singleStep();{
digitalWrite(stepPin,HIGH);
delayMicroseconds(1000);
digitalWrite(stepPin,LOW);
delayMicroseconds(1000);
}
}
}
void singleStep() {
if (curMillis - prevStepMillis >= millisBetweenSteps) {
prevStepMillis += millisBetweenSteps;
digitalWrite(stepPin, HIGH);
digitalWrite(stepPin, LOW);
}
}
Any idea where I'm wrong?
I know that the wiring is correct because using this other code the stepper works
// testing a stepper motor with a Pololu A4988 driver board or equivalent
// this version uses millis() to manage timing rather than delay()
// and the movement is determined by a pair of momentary push switches
// press one and it turns CW, press the other and it turns CCW
byte directionPin = 6;
byte stepPin = 10;
byte buttonCWpin = 2;
//byte buttonCCWpin = 11;
boolean buttonCWpressed = true;
//boolean buttonCCWpressed = false;
byte ledPin = 13;
unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 25; // milliseconds
void setup() {
Serial.begin(9600);
Serial.println("Starting Stepper Demo with millis()");
pinMode(directionPin, OUTPUT);
pinMode(stepPin, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(buttonCWpin, INPUT_PULLUP);
//pinMode(buttonCCWpin, INPUT_PULLUP);
}
void loop() {
curMillis = millis();
readButtons();
actOnButtons();
}
void readButtons() {
buttonCWpressed = false;
buttonCWpressed = true;
if (digitalRead(buttonCWpin) == HIGH) {
buttonCWpressed = false;
}
if (digitalRead(buttonCWpin) == LOW) {
buttonCWpressed = true;
}
}
void actOnButtons() {
if (buttonCWpressed == true) {
digitalWrite(directionPin, HIGH);
singleStep();{
digitalWrite(stepPin,HIGH);
delayMicroseconds(20);
digitalWrite(stepPin,LOW);
delayMicroseconds(20);
}
}
if (buttonCWpressed == false) {
digitalWrite(directionPin, LOW);
singleStep();{
digitalWrite(stepPin,HIGH);
delayMicroseconds(1000);
digitalWrite(stepPin,LOW);
delayMicroseconds(1000);
}
}
}
void singleStep() {
if (curMillis - prevStepMillis >= millisBetweenSteps) {
prevStepMillis += millisBetweenSteps;
digitalWrite(stepPin, HIGH);
digitalWrite(stepPin, LOW);
}
}
// Initialize the pushbutton pin as an input pullup
(buttonPin, INPUT_PULLUP);
Something missing there? Seems like you would need to use a function to actually accomplish that.
Your code is trying to read the state of a pin and act on that state. If you can't move the stepper, then there is a distinct possibility that there is a problem with the code that reads the state of the switch and acts upon the information that it got. So, ditch that code. The loop() function should do nothing more than make the stepper step 10 times, then pause for 250 milliseconds.
PaulS:
Not without changing your code. When you change code, you need to re-post it.
I have decided to start over, to be honest my first sketch wasn't so clear so I have decided to make a step back, as I was saying in my previous post this code works well:
int directionPin = 6;
int stepPin = 10;
int buttonpin = 2;
boolean buttonpressed; //false or true
int ledPin = 13;
unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 25; // milliseconds
void setup() {
Serial.begin(9600);
Serial.println("Starting Stepper Demo with millis()");
pinMode(directionPin, OUTPUT);
pinMode(stepPin, OUTPUT);
pinMode(ledPin, OUTPUT);
//If a pull-down resistor is used, the input pin will be LOW when the switch is open and HIGH when the switch is closed.
//If a pull-up resistor is used, the input pin will be HIGH when the switch is open and LOW when the switch is closed.
pinMode(buttonpin, INPUT_PULLUP);
}
void loop() {
curMillis = millis();
readButtons();
actOnButtons();
}
void readButtons() {
buttonpressed = false; //false is defined as 0 (zero), THE SWITCH IS OPEN
buttonpressed = true; //Any integer which is non-zero is true, THE SWITHCH IS CLOSED
if (digitalRead(buttonpin) == LOW) { // low means 0V
buttonpressed = true;
}
if (digitalRead(buttonpin) == HIGH) { // high menas 5V
buttonpressed = false;
}
}
void actOnButtons() {
if (buttonpressed == false)
{
digitalWrite(directionPin, LOW);
singleStep();{
digitalWrite(stepPin,HIGH);
delayMicroseconds(1000);
digitalWrite(stepPin,LOW);
delayMicroseconds(1000);
}
}
if (buttonpressed == true)
{
digitalWrite(directionPin, HIGH);
singleStep();{
digitalWrite(stepPin,HIGH);
delayMicroseconds(20);
digitalWrite(stepPin,LOW);
delayMicroseconds(20);
}
}
}
void singleStep() {
if (curMillis - prevStepMillis >= millisBetweenSteps) {
prevStepMillis += millisBetweenSteps;
digitalWrite(stepPin, HIGH);
digitalWrite(stepPin, LOW);
}
}
but on my new test using accelstepper library I haven't got the same satisfaction, the stepper doesn't move at all, do you have any advice?
#include <AccelStepper.h>
#include <MultiStepper.h>
AccelStepper Stepper1(1,6,10); //use pin 6 and 10 for dir and step, 1 is the "external driver" mode (A4988)
int dir = 1; //used to switch direction
/*float pressLength_milliSeconds = 0;
int optionOne_milliSeconds = 100;
int optionTwo_milliSeconds = 2000;*/
void setup() {
Stepper1.setMaxSpeed(3000); //set max speed the motor will turn (steps/second)
Stepper1.setAcceleration(13000); //set acceleration (steps/second^2)
}
void loop() {
if(Stepper1.distanceToGo()==0){ //check if motor has already finished his last move
Stepper1.move(1600*dir); //set next movement to 1600 steps (if dir is -1 it will move -1600 -> opposite direction)
dir = dir*(-1); //negate dir to make the next movement go in opposite direction
delay(1000); //wait 1 second
}
Stepper1.run(); //run the stepper. this has to be done over and over again to continously move the stepper
}
Hi, I have done some steps forward trying to use a button.
So far the code I have written is this:
#include <AccelStepper.h>
#include <MultiStepper.h>
AccelStepper Stepper1(1,10,6); //use pin 6 and 10 for dir and step, 1 is the "external driver" mode (A4988)
int dir = 1; //used to switch direction
boolean ShortPress;
boolean State;
int ButtonPin = 2;
void setup() {
Stepper1.setMaxSpeed(3200); //set max speed the motor will turn (steps/second)
Stepper1.setAcceleration(200); //set acceleration (steps/second^2)
pinMode(ButtonPin, INPUT_PULLUP);
}
void loop() {
readButtons();
actOnButtons();
}
void readButtons() {
ShortPress = true;
ShortPress = false;
int i = 0;
while (digitalRead(ButtonPin))
{
i++; // how much the button has been held
}
if (i<100)
{ ShortPress=true;}
else{ShortPress = false;}
}
void actOnButtons() {
if (ShortPress == true && State == true){
Stepper1.distanceToGo()==0; { //check if motor has already finished his last move
Stepper1.move(9600*dir);
}
//Stepper1.moveTo(200);
Stepper1.run(); //run the stepper. this has to be done over and over again to continously move the stepper
}
else if (ShortPress == false){
Stepper1.stop();
}
}
Using this code the stepper works only if I keep the button held, while the button is unpressed the motor is quiet.
what I want to do is to use a kind of a code like this
if (ShortPress $ state) { !state-> first press}
elseif {!state ->second press}
if (!ShortPress) {Long Press, reset}
to start the motor after one single short push
to stop the motor after a second short push
to rewind the motor after that the button has been hel for a while
while (digitalRead(ButtonPin))
{
i++; // how much the button has been held
}
The input will be HIGH (ie true) most of the time so i will increase very rapidly. Is that what you want to happen ? Will ShortPress be true or false most of the time ?
What do you intend the State variable to do considering that it start off as 0 (ie false) and is never changed ?