I am trying to make an automatic lock which stays open during different times and on different days. I want the door open Monday through Friday 8am to 5pm. On Saturdays and Sundays I want the door locked. I will be using an electric lock strike the + wire to pin 9 and - to ground on arduino. I am using an LED for development purposes for now because I don't have the lock yet. The code I have now works (stays open) for 8am to 5pm through the whole week but i want the door locked for Saturdays and Sundays. This is my code so far:
#include <Time.h>
#define doorPin 9
void setup() {
// put your setup code here, to run once:
pinMode(doorPin, OUTPUT); // Connected to relay to activate the door lock
setTime(10,1,1,6,7,2014);
}
void loop() {
if (hour()>=8 && hour()<=17){
digitalWrite(doorPin, HIGH);
}
else if (weekday()==1 || weekday()==7){
digitalWrite(doorPin, LOW);
}
2 Answers 2
This is what's happening: it's still between 8 AM and 5 PM on the weekend, so it unlocks it. Since you use an else if
, it terminates the if
statement and never checks the day between 8 and 5. I'm almost positive that if you checked it another time in the day, it'd be "locked."
Fixed code:
#include <Time.h>
#define doorPin 9
void setup() {
// put your setup code here, to run once:
pinMode(doorPin, OUTPUT); // Connected to relay to activate the door lock
setTime(10,1,1,6,7,2014);
}
void loop() {
if ((hour()>=8 && hour()<=17) && !(weekday()==1 || weekday()==7)){
digitalWrite(doorPin, HIGH);
}
else {
digitalWrite(doorPin, LOW);
}
Note: !
means "not." Thus, the door is locked only if it's not a weekend and it's between 8 and 5.
(削除) Additionally, you might want to get a lock that is the other way around: unlocked only with power applied so someone can't unplug the Arduino to get access. (削除ここまで) EDIT: miscommunication, ignore this part paragraph...
-
I'm sorry I meant open from Mon - Fri 8-5, locked on Sat - Sun. (The lock is unlocked with electricity)Kyriazis– Kyriazis2014年07月06日 20:14:30 +00:00Commented Jul 6, 2014 at 20:14
-
@user the code should stay the same, just with a [slightly] different explanation.Anonymous Penguin– Anonymous Penguin2014年07月06日 20:20:30 +00:00Commented Jul 6, 2014 at 20:20
Adding to Annonomus Penguin's answer, it might be cleaner and easier to understand if you extract the variable:
bool doorOpen = ( (hour()>=8 && hour()<=17) && !(weekday()==1 || weekday()==7) );
Or in my eyes even nicer if you unnegate the last part, ymmv:
bool doorOpen = ( (hour()>=8 && hour()<=17) && (weekday()!=1 && weekday()!=7) );
And then use them directly in the code without the if statement:
digitalWrite( doorPin, doorOpen ? HIGH : LOW );
This way you make sure that the doorPin always gets set and you din't forget a path like in your if-elseif-nothing version.
Another benefit is you can test independently if the doorOpen variable is correct and if the functionality that is triggered by it is correct.
-
2In that last Boolean expression, all of the parentheses other than the function calls are redundant and distracting.
bool doorOpen = hour() >= 8 && hour() <= 17 && weekday() != 1 && weekday() != 7;
is much clearer.Pete Becker– Pete Becker2014年07月06日 23:26:13 +00:00Commented Jul 6, 2014 at 23:26 -
[As for the boolean statement change]: It's pretty much a personal preference, I personally think it flows better the way in my answer, but I'm pretty quirky! :-) However, a boolean directly is a good idea, +1 for that.Anonymous Penguin– Anonymous Penguin2014年07月07日 21:21:21 +00:00Commented Jul 7, 2014 at 21:21