Door Opening + Counting Presses

Hi! I'm fairly new to Arduino and still trying to learn the ropes. I have a project where I am trying to mimic a hotel door, in that it will only allow 4 people in at a time. I want to be able to press a button, have the sweep function occur on a servo motor after the button press, and I want the program to count up (baseline of 0, maximum of 5). Once it reaches the 5th button press, I want the servo to NOT work. I'd also need ANOTHER button to "leave the room", aka subtract from the number that is being counted (as if someone had left the room).

I'm not sure exactly what codes would be best to use. I've been looking through examples but am having a hard time parsing what sorts of codes to use to create this system.

I'd really appreciate any help and if you have any questions, please let me know.

Do you know how to read the switches? The State Change Detection example does. You only want to count up or down when the appropriate switch BECOMES pressed, not when the switch IS pressed.

Do you know how to sweep the servo? There are examples provided with the IDE to move the servo in different ways.

This is my Frankenstein’s monster of code so far.
It’s not complete yet but I think I’m on the right path:

#include <Servo.h>
// constants won’t change. They’re used here to
// set pin numbers:
Servo myservo;
const int buttonPin = 2; // the number of the pushbutton pin

// variables will change:
int buttonPushCounter = 0;
int buttonState = 0; // variable for reading the pushbutton status
int lastButtonState = 0;
int pos = 0; // variable to store the servo position

void setup() {
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
}

void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);

// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// if the state has changed, increment the counter
if (buttonState == HIGH) {
// if the current state is HIGH then the button
// wend from off to on:
buttonPushCounter++;
Serial.println(“on”);
Serial.print("number of button pushes: ");
Serial.println(buttonPushCounter);
}
else {
// if the current state is LOW then the button
// went from on to off:
Serial.println(“off”);
}
// Delay a little bit to avoid bouncing
delay(50);
}
// save the current state as the last state,
//for next time through the loop
lastButtonState = buttonState;

// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
for(pos = 0; pos <= 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=0; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
buttonPushCounter++;
}
}

Look at your code. What will happen if the user holds the switch down?

When the switch becomes pressed, the current state will not be the same as the previous state, so, since the switch is pressed, you will increment the counter.

Then, you look again to see if the switch IS pressed. If so, you wave the servo around AND you increment the counter again.

Next time through loop, the switch has not changed state, so you skip incrementing the counter.

But the switch is still pressed, so you wave the servo around AND increment the counter again.

When, exactly, should you wave the servo around? I would wave the servo around only in the if block that tests that the switch is pressed inside the if block that determines that the switch changed state, and only if the counter was less than some value.

Thanks for your help, PaulS. That's what I'm struggling with. I'm having a difficult time trying to figure out where to put these events in a cohesive order.

I want button1 to be the button you press as you enter a hotel room. That will "open the door" (wave the servo from 0 --> 90 --> 0) and increase the button press counter. Once the button press counter reaches 5, I don't want the servo to wave.

I want button 2 to be the button you press as you leave a hotel room. This won't affect the servo, but will decrease the button press counter. I also don't want the button press counter to go below 0.

Is there any way I could change my code to reflect that, in the correct order?

I appreciate your advice a lot, and thanks for your time so far!

Is there any way I could change my code to reflect that, in the correct order?

Of course.

// compare the buttonState to its previous state
  if (buttonState != lastButtonState)
  {
    // if the state has changed, increment the counter 
    // AND wave the servo if the count is low enough
    if (buttonState == HIGH)
    {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);

      if(buttonPushCounter < 5)
        openTheDoor();
    }
  }

Now, you’ll need to create the openTheDoor() function. I’m sure that you can tell what is supposed to happen to openTheDoor.

Thanks so much PaulS! How should I go about addressing my button2, which will decrease the buttonPushCounter?

How should I go about addressing my button2, which will decrease the buttonPushCounter?

The same way as button1. Of course, upButtonPin and downButtonPin would be MUCH more sensible names.

As would currUpState, prevUpState, currDownState, and prevDownState.

And, you really aren't counting button pushes, are you. You are counting people in the room.