Go Down

Topic: Servo as a door lock, How can I ignore a button until later in the program? (Read 1 time) previous topic - next topic

GeorgeWS

Hi everyone!

I am working on a keepsake box that uses a mini servo to lock the door
(minimum security obviously but this is more like a prop for a proposal)

The sketch I have created works in a general sense, but I need a little
guidance.  

Button 2 (which is closed when the door is closed and returns the servo to
the locked position) is depressed when the circuit is powered up (because
the door is closed at the beginning of the cycle) and as a result, keeps
the ARDUINO from responding from button 1 (which will be a high signal
from a source external to the ARDUINO) which opens the lock. I also want
to cycle the LOCKED / UNLOCKED leds using PWM but not sure where to
park the additional code.  I will include my sketch, any help in at least finding
the answer would be awesome.

Thanks!
 George

Quote

// DAC box servo program REV4
// By: George Suprenant
// With help from the ARDUINO community
// 2012


#include <Servo.h>

Servo myservo;                 // create servo object to control a servo  
int pos = 20;                  // variable to store the 1st servo position LOCKED
int pos1 = 120;                // Variable to store the 2nd servo position UNLOCKED
int buttonState1 = 0;          // The initial state of the DAC button is OFF
int buttonState2 = 0;          // The initial state of the DOOR button is OFF
const int btn1 = 2;            // The nubmer of the DAC pin
const int led1 = 3;            // The number of the locked led pin ~
const int btn2 = 4;            // The number of the Door switch pin
const int led2 = 5;            // The number of the unlocked led pin ~
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by

void setup()
{
 pinMode(btn1, INPUT);        // Set btn1 as an INPUT
 pinMode(led1, OUTPUT);       // Set led1 as an OUTPUT
 pinMode(btn2, INPUT);        // Set btn2 as an INPUT
 pinMode(led2, OUTPUT);       // Set led2 as an OUTPUT
 myservo.attach(9);           // Attaches the servo on pin 9 to the servo object
 myservo.write(pos);          // Physicaly sets the servo to the LOCKED position (had problems with servo twitching 30+ deg on startup)
 digitalWrite(led1, HIGH);    // Turns on the LOCKED led
}


void loop()
{        
   buttonState1 = digitalRead(btn1);    // Look at the DAC pin
   buttonState2 = digitalRead(btn2);    // Look at the door switch

   
   if (buttonState1 == HIGH) {          // If DAC pin is HIGH then,                                      
     myservo.write(pos1);               // Move servo to the UNLOCKED position
     digitalWrite(led1, LOW);           // Turn the LOCKED led OFF
     digitalWrite(led2, HIGH);          // Turn the UNLOCKED led on
         delay (2000);                  // Wait for 2 sec to prevent door switch bounce

     
   } else if (buttonState2 == HIGH) {   // But if the DOOR CLOSED switch is HIGH      
     delay (2000);                      // Wait for 2 sec to prevent lock damage and make sure door is closed
     myservo.write(pos);                // Move servo to LOCKED position
     delay (500);                       // Wait 1/2 sec before door locked led going HIGH
         digitalWrite(led2, LOW);       // Set door unlocked led LOW
         digitalWrite(led1, HIGH);      // Set door locked led HIGH
   }
}




pylon

I don't understand what your question is. The only problem with your sketch that I see is the use of delay. This way you might loose a opening signal if your waiting for the door being locked. Try to eliminate these by storing the time of an event and checking that against millis().

I don't know why you wanna display a boolean information (locked/unlocked) using PWM (which is kind of analog output). What's your intention there?

Grumpy_Mike

Please change the quote tags to code tags.

Basically you make a note of the time in a long int variable and the millis() function. Then in the loop you look to see if the current time is greater than the time you set plus the delay, then do the stuff.
See the blink without delay example.
You can remove all the delays like that, long delays are bad in code because they block anything else from happening.

sdturner

I don't think I understand the question. Does it not unlock the door when you press Button 1?

What do you want to do with the LEDs? If you just want to fade one off and fade the other on you could do something like this instead of digitalWrite(led1, HIGH):
Code: [Select]
for (int i=0; i <= 255; i++){
      analogWrite(led1, i);
      analogWrite(led2, (255-i));
      delay(10);
}

GeorgeWS


I don't know why you wanna display a boolean information (locked/unlocked) using PWM (which is kind of analog output). What's your intention there?


The point of the lock unlock was visual indicators using LED's  Red for locked Green for unlocked, Wanted them to pulsate
during servo rotation. Does that help?

GeorgeWS

I'm sorry everyone, when I power up the circuit the door is closed which means button 2 is HIGH.
so button 1 does not respond by opening the door.  As for the LED's I am not to concerned if they
pulse or not.  But the main issue is how to temporarily ignore button 2 until after button 1 has
been pressed

sdturner

To blink them on and off replace delay(500) with something like this:
Code: [Select]

starttime = millis();
currenttime = millis();
while (currenttime < starttime + 500) {
  digitalWrite(led1, LOW);
  digitalWrite(led2, HIGH);
  delay(25);
  digitalWrite(led1, HIGH);
  digitalWrite(led2, LOW);
  currenttime = millis();
}


or if you want them to get brighter and dimmer, so the same thing, except:
Code: [Select]

...
  analogWrite(led1, 128);
  analogWrite(led1, 255);
  delay(25);
  analogWrite(led1, 255);
  analogWrite(led1, 128);
...

GeorgeWS


I don't think I understand the question. Does it not unlock the door when you press Button 1?


When I power up the project, button 2 (NO lever switch) is closed (HIGH)
so when button 1 goes HIGH the servo does not move.

sdturner

When Button1 is pressed is it high or low? Your code looks for Button1 HIGH before doing anything else. If and Only If Button1 is LOW will it evaluate Button2. That seems consistent with what you want to do.

Did you copy/paste your code or retype? could there be a difference between what is displayed and what you are actually running?


Grumpy_Mike

Quote
But the main issue is how to temporarily ignore button 2 until after button 1 has
been pressed

Get button 1 to set a flag, nothing else.
When you see button 2 being pressed, look to see if the button 1 flag is set, if so do the stuff you need and reset the flag.

GeorgeWS

sdturner,  I copied for forum using IDE

Grumpy_Mike, Thank you! Button 2 will be down at the beginning of the
cycle so if btn1 sets the flag, arduino opens the lock.  Then when btn2 opens
and closes it sets the servo back to locked position?  so should they both set
flags?  I am going to go look for an example.

GeorgeWS


When Button1 is pressed is it high or low? Your code looks for Button1 HIGH before doing anything else. If and Only If Button1 is LOW will it evaluate Button2. That seems consistent with what you want to do.

Did you copy/paste your code or retype? could there be a difference between what is displayed and what you are actually running?






at the beginning of the cycle, button 1 is low, and button 2 stays HIGH.
button 1 goes HIGH for a moment and turns the servo which unlocks the
door, when you open the door button 2 goes LOW until you close the
door, then button 2 goes high again. which turns the servo to the locked
position.

Go Up