Slight discrepancy in my code, where am i going wrong?

Hi all,

As a project for my dissertation, I’m building a proximity operated lock. It will operate by active RFID, but thats another topic for another time. The RFID will give me an input, which will trigger a sequence of rotating a stepper motor 100 steps. Then once out of range, the switch from the RFID will break, and i want the stepper motor to rotate 100 steps the opposite direction.

Before i start playing with the RFID, i am trying to replicate the tag going in and out of range with a push button.

So, originally the code i used worked perfectly, it moved 100 steps on direction, delayed for half a second, then 100 steps back the other way, but it kept doing this on a loop without a trigger. As soon as i tried to integrate a pushbutton into it, things went wrong. Now, the motor constantly rotates in one direction, and when the switch is depressed, constantly rotates in the other, despite the code quite clearly specifying to only to move 100 steps. Im guessing im missing something pretty simple as im new to all this, could someone take a loook at my code and point me in the right direction?

Thanks
Rich

#include <Stepper.h>

const int stepsPerRevolution = 100;  
                                     
const int buttonPin = 2;                                        

int buttonState = 0;         


Stepper myStepper(stepsPerRevolution, 8,9,10,11);            

void setup() {

  myStepper.setSpeed(60);
   pinMode(buttonPin, INPUT);     

  Serial.begin(9600);
}


void loop() {
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) { 
  
  
   Serial.println("clockwise");
  myStepper.step(stepsPerRevolution);
  }
  
  
  else{

  Serial.println("counterclockwise");
  myStepper.step(-stepsPerRevolution); 
}
}/code]

despite the code quite clearly specifying to only to move 100 steps

Actually your code is constantly being told to do 100 steps, regardless if the button is pressed or not.

What exactly do you want it to do?

That would make more sense. Where did i go wrong with that bit?

Basically when the button is depressed and held, i want it to advance the stepper motor 100 steps. When the button is released, i want it to reverse 100 steps.

Thanks for the help
Rich

Ok, well what you could do is if the button is pressed and held, then you can have a counter increase from 0 to 99. OR you can have the code check to see if the button is pressed for a certain amount of time, say 2 seconds. Then if the button is held down for 2 seconds then you can run the stepper 100 steps and set a flag. Once the stepper is done, the flag is set and the button is released, you can step in the other direction until that is done.

Here is a sketch to get you started.

const byte buttonPin = 2;     
const byte ledPin =  13;

boolean buttonState = 0;
boolean  lastReading = 0;
boolean Released = false;
long onTime = 0;

void setup() { 
  pinMode(ledPin, OUTPUT);      
  pinMode(buttonPin, INPUT);     
}

void loop(){ 
  buttonState = digitalRead(buttonPin);

  if (buttonState == HIGH && lastReading == LOW) // first check to see if the button is pressed ie. HIGH and it is different from lastReading 
  {
    onTime = millis(); // record time
    lastReading = HIGH; // prevents the code from entering this IF statement, until lastReading is set to LOW again.
  }

  if (buttonState == HIGH && lastReading == HIGH) // button is still held down 
  {
    if ((millis() - onTime) > 3000) // check to see if button is held down for 3 seconds
    {
       Released = false; // button is still being held down.
      // Clockwise 100 steps here
      digitalWrite(ledPin, HIGH); // if button is held down for 3 seconds, LED on
    } 
    else 
    {
      digitalWrite(ledPin, LOW); // otherwise LED remains off
    }
  }

  if(buttonState == LOW && Released == false) //check to see if the button is LOW and was released, then start over.
  {
       // counterclockwise 100 steps
       lastReading = LOW;
       Released = true;
   }
}

You will need to add another boolean variable here to lock out this part after the stepper does its 100 steps, otherwise it will keep stepping.

The normal way to trigger an event from a button is to detect a change on that pin:

boolean previous ;

void setup ()
{
  ...
  pinMode (pin, INPUT_PULLUP) ; // or whatever
  previous = digitalRead (pin) ;
  ..
}

void loop ()
{
  ..
  boolean now = digitalRead (pin) ;
  if (now == LOW && previous == HIGH)   // detect only button press
    trigger_event () ;
  previous = now ;  // set previous for next time round.

Note that this code doesn't address de-bouncing the button,
but if the button is held down it won't continually trigger.

You wrote "Basically when the button is depressed and held, i want it to advance the stepper motor 100 steps. When the button is released, i want it to reverse 100 steps"

but what I think that you meant is

Basically when the button is taken from not pressed to pressed, I want it to advance the stepper motor 100 steps. When the button is released (changed from pressed to not pressed), I want it to reverse 100 steps.

You may need debouncing as well.

You may need debouncing as well.

Probably not, since the switch should have stopped bouncing long before the stepper has stepped 100 times.

In the code in your original post you haven't allowed any time for the stepper to complete it's moves. The Arduino doesn't wait while "myStepper.step(stepsPerRevolution);" does it's stuff.

...R

The Arduino doesn’t wait while “myStepper.step(stepsPerRevolution);” does it’s stuff.

Ummm. Yes, it does. It wouldn’t if myStepper (stupid name) were an instance of AccelStepper, but Stepper::step() is a blocking function.

Thanks for the help guys. Im still very new to code, its not part of my course but i felt Arduino was the best route for the rest of the project so i went with it. Maybe bitten off a little more than i can chew with all my other workload, but im getting there slowly.

I'll have a go through the code that HazardsMind posted tonight and let you guys know how i get on.

On a side note, how does debouncing compare from a push button to a relay? I would expect it to be fairly similar?

Thanks
Rich

PaulS:

The Arduino doesn't wait while "myStepper.step(stepsPerRevolution);" does it's stuff.

Ummm. Yes, it does. It wouldn't if myStepper (stupid name) were an instance of AccelStepper, but Stepper::step() is a blocking function.

Thanks for that. Apologies for my ignorance.

...R

Navara-Rich:
On a side note, how does debouncing compare from a push button to a relay? I would expect it to be fairly similar?

A relay would be liable to the same contact bounce issues as a pushbutton switch, if that's what you're asking.