I am stuck on one part of my sketch, handle button stepper(50) issue?



I originally had this sketch working with a servo, but i over stressed it and it failed. So i changed it to a stepper.
Everything is working correctly, keypad will operate the stepper and helper lights ect except the handle button does not operate the stepper. Button press shows in the serial monitor and i put a serial.write very close to the end that says -  last line -  and it shows in the serial monitor . But for some reason the sketch seams to skip over the if statement for the handle button operation.  What did i not do correctly? 










#include <Password.h>
#include <Keypad.h>
#include <Stepper.h>
//Stepper myStepper;
Password password = Password( "4444" ); //password to unlock door, can be changed

const byte ROWS = 4; // Four rows
const byte COLS = 3; // columns
const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// Define the Keymap
char keys[ROWS][COLS] = {
{'1','2','3',},
{'4','5','6',},
{'7','8','9',},
{'*','0','#',},
};

byte rowPins[ROWS] = { 5, 4, 3, 2 };// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte colPins[COLS] = { 8, 7, 6,};// Connect keypad COL0, COL1 and COL2 to these Arduino pins.


// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

unsigned long offtime;
boolean  helper_light_is_on = false; // helper light off
#define BUTTON_PIN        A0  // Button
#define DELAY            100  // Delay per loop in ms

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


boolean handle_button()
{
  int button_pressed = !digitalRead(BUTTON_PIN); // pin low -> pressed
  return button_pressed;
}

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

  pinMode(BUTTON_PIN, INPUT);
  digitalWrite(BUTTON_PIN, HIGH); // pull-up
  Serial.begin(9600);
  Serial.write(254);
  Serial.write(0x01);
  delay(200);
  pinMode(15, OUTPUT);  //Helper light
  pinMode(16, OUTPUT);  //green light
  pinMode(17, OUTPUT);  //red light
 
   keypad.addEventListener(keypadEvent); //add an event listener for this keypad
}
void loop()
{
   //handle button
  boolean button_pressed = handle_button();

  // do other things
  Serial.println(button_pressed ? " button press" : ".");

 
  static int counter = 0;
  if ((++counter & 0x3f) == 0)
   Serial.println();

  delay(DELAY);


  keypad.getKey();
  myStepper.step(0);
  process_helper_light();
}

//take care of some special events
void keypadEvent(KeypadEvent eKey)
{
  switch (keypad.getState())
  {
    case PRESSED:
      // a key is pressed so light the helper light
      helper_light_is_on = true;
      digitalWrite(15,HIGH);
      offtime = millis() + 5000;  // set the offtime for 30 seconds in the future
     
      Serial.print(" enter: ");
      Serial.println(eKey);
      delay(10);
      Serial.write(254);
      switch (eKey)
      {
        case '*':
          checkPassword();
          delay(1);
          break;
        case '#':
          password.reset();
          delay(1);
          break;
        default:
          password.append(eKey);
          delay(1);
    
      }
  }
}

void checkPassword()
{
  if (password.evaluate())  //if password is right unlock door
  { 
    Serial.println(" Accepted");
    Serial.write(254);
    delay(10);
    myStepper.step(50);
    Serial.print(" open ");
    digitalWrite(16, HIGH);//turn on green led
    delay(2000); //wait 5 seconds
    digitalWrite(16, LOW);// turn offgreen led
    myStepper.step(-50);

  }  //Closes if password.evalute
  else
  {
    Serial.println(" Denied"); //if passwords wrong keep door locked
    Serial.write(254);
    delay(10);
    myStepper.step(0);
    Serial.println(" locked ");    
    digitalWrite(17, HIGH); //turn on red led
    delay(2000); //wait 5 seconds
    digitalWrite(17, LOW);//turn off red led
   
  }  //Closes first else
  if (handle_button == LOW)
  {         
    Serial.write (" pressed ");   
     myStepper.step(50);
     Serial.write(" clockwise ");
     
    digitalWrite(15, HIGH);//turn on helper light
    delay(2000); //wait 5 seconds
    myStepper.step(-50);
    digitalWrite(15, LOW);// turn off helper light


  //}   //Closes if handle button low
  //else
// {
   
   //myStepper.step(0);
    //digitalWrite(15, LOW); //turn on
    //delay(2000); //wait 5 seconds
    //digitalWrite(15, LOW);//turn off 
    Serial.println(" last line");      
    delay(50); //wait 5 seconds
    
  }  // Closes second else
}  //Closes Check password

// this routine turns off the light when the timer expires
void process_helper_light(void)
{
  if (helper_light_is_on)
  {
    if (millis() >= offtime)
    {
      digitalWrite(15,LOW);  //turn off the helper light
      helper_light_is_on = false;
    }
  }
}

sort by: active | newest | oldest
WWC (author) 4 years ago
I followed and compared this with my keyless servo sketch as far as the {} go and i am not see where they are missing. Where exactly were you talking about. BTW how do you turn on the line numbers?
The handle button routine does the servo in the second example. The check password routine does it in the first program. There is you problem I think!
WWC (author)  steveastrouk4 years ago
Best answer.
You were basically correct I needed to get the button_pin out of the check password.

Thanks for your help
No worries. Glad it helped.

Steve
WWC (author)  steveastrouk4 years ago
OK here is my button_pin servo sketch that is working. Next i will try and plug that into the key pad sketch

#include

Stepper myStepper = Stepper(200,9,10,11,12);

int ledpin = 13;
int pirpin = 4;
int button_pin = A0;
int button_pinstate = 0; // variable to store current pir state
//int lastpirstate = 0; // variable to store last pir state
int lastbutton_pinstate = 0;
int pos = 60;
int pos2 = -60;

void setup() {

myStepper.setSpeed(60); // sets speed of stepper

pinMode(ledpin, OUTPUT);
pinMode( button_pin, INPUT);

}

void loop() {

button_pinstate = digitalRead(button_pin);

if(button_pinstate != lastbutton_pinstate) {
if(button_pinstate == LOW) {
digitalWrite(ledpin, HIGH);
myStepper.step(pos);
} else {

digitalWrite(ledpin, LOW);
myStepper.step(pos2);
delay(1000);
}
}
lastbutton_pinstate = button_pinstate;
}
WWC (author)  steveastrouk4 years ago
I am working on that angle now
frollard4 years ago
Without knowing your circuit it's hard to say immediately if something works or not.

If you strip down your code into another sketch that JUST moves the stepper - does the stepper move?

I would recommend making separate functions for
void unLockDoor(){//stepper move code here}
void LockDoor(){//stepper move code here}

Then you know by the Serial.print door is "Accepted" unlocked that proper door opening code is being run.

For steppers don't you feed them a number of steps to move? If I recall it doesn't work like servos where you just set an angle and the library handles it.
http://arduino.cc/en/Reference/StepperConstructor
WWC (author)  frollard4 years ago
I appreciated you input. You always have very good information.
I don't mean to toot my own horn but as you can see me coding skill are considerable better than the first time you helped me with the people counter i was working on.

Thanks
reading it again;
http://arduino.cc/en/Reference/StepperStep

Steppers have no idea where they are, so calling myStepper.step(0) says 'move zero steps' - not move to zero.

You need end-stops with steppers that tell the code when to quit moving. it's as easy as moving a step and checking the endstop switch to see if its activated, if not, move again. Do this in setup so you know where 'zero' is, then its easy to say
unlock door is step forward 50 steps
lock door is step backward 50 steps

dont lock a locked door or it will poo the bed.
WWC (author)  frollard4 years ago
I am somewhat confused as i am calling the steppers a positive number for one direction and a negative number for opposite direction. I didn't actually call the myStepper.step(0); to go to 0. I believe it is a reference point needed in the code. Yes it doesn't know where it is only returns to the placed it is called. I was referring to 0 as the place it started from in my previous reply.
I think it will work without the end stops, after the stepper has rotated to unlock the door it rotates back. If i can use - release - for the stepper the spring in the lock will always return the stepper to the correct position.
The code works correctly with the keypad so i assume it will wok correctly with the push button, i just do not have the correct if maybe so the push button will work.

Does this make scene or am i off track?
frollard WWC4 years ago
That makes sense - I thought it was a deadbolt style door where you would need definite hard stops.
(to your other root level reply)
Saying myStepper.step(0) should not goto zero, it moves that number of steps. whatever number of steps you go forward you will need to go backward to get back to zero :)
WWC (author)  frollard4 years ago
Yes i do that now, but the problem i am getting is why will the button pin not move the stepper when the keypad will?
frollard WWC4 years ago
Not sure why my reply didn't work...

It would seem your 'if' statement doesn't have curly brackets after it, so the only line of code executed is
if ((++counter & 0x3f) == 0)
Serial.println();

if you intend any of the next lines to be executed, they all have to be in { } brackets.

And I have to reiterate -- that stepper.step is not a goto, it's a go x steps, so positive and negative numbers are both valid.
WWC (author) 4 years ago

Final. Everything working.
I made the int (pos); and int(pos2); global so the key pad and button press will move the stepper the same amount.
Got rid of the global delay as it was only used one time.
The button_pin is directly after void loop and keypad and everything else comes after that so button_pin is no longer in check password.


#include
#include
#include
Password password = Password( "4444" ); //password to unlock door, can be changed

const byte ROWS = 4; // Four rows
const byte COLS = 3; // columns
const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution
// Define the Keymap
char keys[ROWS][COLS] = {
{'1','2','3',},
{'4','5','6',},
{'7','8','9',},
{'*','0','#',},
};

byte rowPins[ROWS] = { 5, 4, 3, 2 };// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte colPins[COLS] = { 8, 7, 6,};// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
Stepper myStepper(stepsPerRevolution, 9,10,11,12);

int button_pin = A0;
int button_pinstate = 0; // variable to store current pir state
//int lastpirstate = 0; // variable to store last pir state
int lastbutton_pinstate = 0;
int pos = 60;
int pos2 = -60;

// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

unsigned long offtime;
boolean helper_light_is_on = false; // helper light off

void setup(){

myStepper.setSpeed(60); // set the speed at 60 rpm:
pinMode( button_pin, INPUT);

digitalWrite(button_pin, HIGH); // pull-up
Serial.begin(9600);
Serial.write(254);
Serial.write(0x01);
delay(200);
pinMode(15, OUTPUT); //Helper light
pinMode(16, OUTPUT); //green light
pinMode(17, OUTPUT); //red light

keypad.addEventListener(keypadEvent); //add an event listener for this keypad
}
void loop()
{
button_pinstate = digitalRead(button_pin);
if(button_pinstate != lastbutton_pinstate) {
if(button_pinstate == LOW) {
myStepper.step(pos);
} else{
myStepper.step(pos);
delay(1000);
myStepper.step(pos2);
delay(1000);
}
}
static int counter = 0;
if ((++counter & 0x3f) == 0)
Serial.println();
delay(100);
keypad.getKey();
myStepper.step(0);
process_helper_light();
}
void keypadEvent(KeypadEvent eKey)
{
switch (keypad.getState())
{
case PRESSED:
// a key is pressed so light the helper light
helper_light_is_on = true;
digitalWrite(15,HIGH);
offtime = millis() + 5000; // set the offtime for 30 seconds in the future

Serial.print(" enter: ");
Serial.println(eKey);
delay(10);
Serial.write(254);
switch (eKey)
{
case '*':
checkPassword();
delay(1);
break;
case '#':
password.reset();
delay(1);
break;
default:
password.append(eKey);
delay(1);
}
}
}

void checkPassword()
{
if (password.evaluate()) //if password is right unlock door
{
Serial.println(" Accepted");
Serial.write(254);
delay(10);
myStepper.step(pos);
Serial.print(" open ");
digitalWrite(16, HIGH);//turn on green led
delay(2000); //wait 5 seconds
digitalWrite(16, LOW);// turn offgreen led
myStepper.step(pos2);
}
else
{
Serial.println(" Denied"); //if passwords wrong keep door locked
Serial.write(254);
delay(10);
myStepper.step(0);
Serial.println(" locked ");
digitalWrite(17, HIGH); //turn on red led
delay(2000); //wait 5 seconds
digitalWrite(17, LOW);//turn off red led

} //Closes first else
if (button_pin == LOW)
{
Serial.write (" pressed ");
myStepper.step(50);
Serial.write(" clockwise ");

digitalWrite(15, HIGH);//turn on helper light
delay(2000); //wait 5 seconds
myStepper.step(-50);
digitalWrite(15, LOW);// turn off helper light
} // Closes second else
} //Closes Check password
// this routine turns off the light when the timer expires
void process_helper_light(void)
{
if (helper_light_is_on)
{
if (millis() >= offtime)
{
digitalWrite(15,LOW); //turn off the helper light
helper_light_is_on = false;
}
}
}
...because the only place the button is tested is inside check password, and that's only called on a keypress ?
WWC (author)  steveastrouk4 years ago
Funny thing about that Steve is that is how the sketch is in my keyless entry ible is set up and it works. Unless something is different and i just can't see it.
Post that code then so we can take a quick look at it. have I seen that one ?
WWC (author)  steveastrouk4 years ago

#include
#include
#include //tells to use servo library
int pos = 5; // variable to store the servo position
int button = A0; // The button will be on Pin 7
Servo myservo; //declares servo
#define DELAY 20 // Delay per loop in ms

Password password = Password( "4444" ); //password to unlock door, can be changed

const byte ROWS = 4; // Four rows
const byte COLS = 3; // columns
// Define the Keymap
char keys[ROWS][COLS] = {
{'1','2','3',},
{'4','5','6',},
{'7','8','9',},
{'*','0','#',},
};

byte rowPins[ROWS] = { 5, 4, 3, 2 };// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte colPins[COLS] = { 8, 7, 6,};// Connect keypad COL0, COL1 and COL2 to these Arduino pins.


// Create the Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

unsigned long offtime;
boolean helper_light_is_on = false; // helper light off
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
int lastButtonState = 0;

void handle_button()
{
// read the state of the pushbutton value:
buttonState = digitalRead(button);
// check if the pushbutton is pressed.
if (buttonState != lastButtonState) {
// Lock release
myservo.write(100);
delay(20);
digitalWrite(10, HIGH);
delay(1000); // this delay could be changed to suitable value
digitalWrite(10, LOW);
myservo.write(160);// move to lock position after 5 second
delay(20);
}
lastButtonState = buttonState;
}
void setup()
{
Serial.begin(9600);
Serial.write(254);
Serial.write(0x01);
delay(200);
pinMode(10, OUTPUT); //Helper light
pinMode(11, OUTPUT); //green light
pinMode(12, OUTPUT); //red light
pinMode(button, INPUT);
myservo.attach(9); //servo on digital pin 9 //servo
keypad.addEventListener(keypadEvent); //add an event listener for this keypad
pinMode(pos, OUTPUT);
pinMode(button, INPUT);
delay(200);
}
void loop()
{
handle_button();
keypad.getKey();
myservo.write(5);
process_helper_light();
}

//take care of some special events
void keypadEvent(KeypadEvent eKey)
{
switch (keypad.getState())
{
case PRESSED:
// a key is pressed so light the helper light
helper_light_is_on = true;
digitalWrite(10,HIGH);
offtime = millis() + 10000; // set the offtime for 30 seconds in the future

Serial.print(" enter: ");
Serial.println(eKey);
delay(10);
Serial.write(254);
switch (eKey)
{
case '*':
checkPassword();
delay(1);
break;
case '#':
password.reset();
delay(1);
break;
default:
password.append(eKey);
delay(1);
}
}
}


void checkPassword()
{
if (password.evaluate()) //if password is right unlock door
{
Serial.println(" Accepted");
Serial.write(254);
delay(10);
//Add code to run if it works
myservo.write(90); //160deg
digitalWrite(11, HIGH);//turn on Green Led
delay(3000); //wait 5 seconds
digitalWrite(11, LOW);// turn off Green Led
}
else
{
Serial.println(" Denied"); //if passwords wrong keep door locked
Serial.write(254);
delay(10);
//add code to run if it did not work
myservo.write(5);
digitalWrite(12, HIGH); //turn on RedLed
delay(3000); //wait 5 seconds
digitalWrite(12, LOW);//turn off Red Led
}
{
if (digitalRead(button) == LOW)
myservo.write(90);
//for(pos = 0; pos < 90; pos += 90) // goes from 0 degrees to 90 degrees
{ // in steps of degree
Serial.println(" Opened ");
myservo.write(pos);
myservo.write(90); //160deg
//delay(80);
myservo.write(pos); // tell servo to go to position in variable 'pos'

}
if (digitalRead(button) == HIGH)
//else
//for(pos = 90; pos>=90; pos-=90) // goes from 90 degrees to 0 degrees
myservo.write(90);
{
Serial.println(" Stay Closed ");
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(50);
myservo.write(5); //160deg
myservo.write(pos); // tell servo to go to position in variable 'pos'
}
}
}

// this routine turns off the light when the timer expires
void process_helper_light(void)
{
if (helper_light_is_on)
{
if (millis() >= offtime)
{
digitalWrite(10,LOW); //turn off the helper light
helper_light_is_on = false;
}
}
}
The code's got quite a few bits commented out. Is this the correct version again ?
WWC (author)  steveastrouk4 years ago
Correct version yes.

The commented out parts is from me adding and tweeking things. The only thing that is not working is the push button to operate the stepper. I don't think i have the   if 's correct.

This is from my keyless entry ible sketch and i used a push button to operate a stepper motor sketch that i tested and was working. I replaced the servo stuff with stepper stuff. 
WWC (author)  WWC4 years ago
It didn't make a difference of the program operations if those parts were commented out or left in. Everything still works like i said except the push button to operate the stepper. i just left them there cuz i am not positive what is correct or what isn't there.
Ah !

This bit ?

if (handle_button == LOW)
{
Serial.write (" pressed ");
myStepper.step(50);
Serial.write(" clockwise ");

digitalWrite(15, HIGH);//turn on helper light
delay(2000); //wait 5 seconds
myStepper.step(-50);
digitalWrite(15, LOW);// turn off helper light


//} //Closes if handle button low
//else
// {

//myStepper.step(0);
//digitalWrite(15, LOW); //turn on
//delay(2000); //wait 5 seconds
//digitalWrite(15, LOW);//turn off
Serial.println(" last line");
delay(50); //wait 5 seconds

} // Closes second else
WWC (author)  steveastrouk4 years ago
Yes that
WWC (author) 4 years ago

Yes the stepper moves with a push button sketch only. I moved that sketch into my lock sketch.
I used the way to turn the stepper 90 degrees was, 200 steps per revolution divided by 4 is 50. myStepper(50); It actually turns the stepper 1/4 of a turn or 90 deg. Then the myStepper(-50); returns it back to 0 deg. Don't know if that is a standard method but i got it to work like that.

Ok i am going to try your suggestion and see what i can get.

Thanks