Time Alarms + Switches

Hi all,

I've got a problem in my program and im not quite sure where its gone wrong.
The aim is to create a series of alarms that open and close a door (via a servo motor) depending on the value of 2 switches.

So far, Ive been able to isolate the process of turning the servo with a dedicated alarm, but combining the code with the 2 swtiches is giving me a problem. Ive looked for similar projects online and this forum, but ive not yet come across one that addresses this.

The problems I would like to solve are:

  • How can I make the open and close alarm work only when both switches are HIGH
  • Considering that Im going to need 10+ alarm opens + closes, would there be an array function more suitable than my proposal
  • Is it possible to use the arduino as a timer once I disconnect it from the computer (i.e. without needing a serial begin)

This is the initial code that moves the servo based on the alarm time (this works)

#include <Time.h>
#include <Servo.h> 
#include <TimeAlarms.h>

 
Servo myservo;  // create servo object to control a servo 
 int pos = 0;    // variable to store the servo position 


void setup() 
{ 
    Serial.begin(9600);
  setTime(12,0,0,1,1,11); // set time to noon Jan 1 2011
    myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  Alarm.alarmRepeat(12,0,05,Open);  // unlock door
  Alarm.alarmRepeat(12,0,10,Close);  //  lock door
  myservo.write(pos); 
} 
 
void loop(){ 
  digitalClockDisplay();
  Alarm.delay(100); 
}


void Open(){
   pos = 180;
   myservo.write(pos); 
}

void Close(){
    pos = 0;
   myservo.write(pos); 
}

  void digitalClockDisplay(){  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.println();
}

void printDigits(int digits){ // utility function for clock display
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

These are 2 options I have tested to try and make the open and close commands dependant on the switch values of the coherer and door.

Test 1:

#include <Time.h>
#include <Servo.h> 
#include <TimeAlarms.h>


Servo myservo;  // create servo object to control a servo 
int pos = 0;    // variable to store the servo position 
int coherer = 0; //attached to switch a
int door = 0;  // attached to switch b

void setup() 
{ 
    Serial.begin(9600);
  setTime(12,0,0,1,1,11); // set time to noon Jan 1 2011
      myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  pinMode(8, INPUT); // door input
  pinMode(2, INPUT); // coherer input
  pinMode(3, OUTPUT); //green light
  pinMode(4, OUTPUT); //red light
 Serial.begin(9600);
   myservo.write(pos); //reset position of servo 
    digitalClockDisplay();
  Alarm.delay(100); 

} 
 
void loop(){ 
 coherer = digitalRead(2);
 door = digitalRead(8);
  digitalClockDisplay();
  delay(500);

 if(coherer == HIGH && door == HIGH){ //door shut + coherer on
  digitalWrite(3,HIGH);
 digitalWrite(4,HIGH); 
  Alarm.alarmRepeat(12,0,05,Open);  // 5:45pm every day 
  Alarm.alarmRepeat(12,0,10,Close);  // 5:45pm every day
 
  }
  
  
else if (coherer == LOW && door == HIGH) { // door open + coherer on
 digitalWrite(3,HIGH); //green light
 digitalWrite(4,LOW); //red light
  }
  
  
 else if(coherer ==LOW && door == LOW){ //door open + coherer off
    digitalWrite(3,LOW);
    digitalWrite(4,LOW);
  } 
  
}

void Open(){
   pos = 180;
   myservo.write(pos); 
}

void Close(){
    pos = 0;
   myservo.write(pos); 
}
  void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.println();
}

void printDigits(int digits){ // utility function for clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);

}

Test 2

#include <Time.h>
#include <Servo.h> 
#include <TimeAlarms.h>

Servo myservo;  // create servo object to control a servo 
int pos = 0;    // variable to store the servo position 
int coherer = 0; // attached to switch a
int door = 0; // attached to switch b

void setup() 
{ 
    Serial.begin(9600);
  setTime(12,0,0,1,1,11); // set time to noon Jan 1 2011
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  pinMode(8, INPUT); //door input
  pinMode(2, INPUT); //coherer input
  pinMode(3, OUTPUT); // green light
  pinMode(4, OUTPUT);  // red light
   myservo.write(pos);
   
    digitalClockDisplay();
  Alarm.delay(100); 
  
  Alarm.alarmRepeat(12,0,05,Open);  // door open - 1
  Alarm.alarmRepeat(12,0,10,Close);  // door close
  
  Alarm.alarmRepeat(12,0,30,Open);  // door open - 2 
  Alarm.alarmRepeat(12,0,35,Close);  // door close 
  
} 
 
void loop(){ 
 coherer = digitalRead(2);
 door = digitalRead(8);
  digitalClockDisplay();
  delay(500);

}

void Open() {
 if(coherer == HIGH && door == HIGH){ //door shut + coherer on
  digitalWrite(3,HIGH);
 digitalWrite(4,HIGH); 
   pos = 180;
   myservo.write(pos); 
}
 
 pos = 0;
   myservo.write(pos); 
  }
  
  
  void Close() {
 if(coherer == HIGH && door == HIGH){ //door shut + coherer on
  digitalWrite(3,HIGH);
 digitalWrite(4,HIGH); 
   pos = 0;
   myservo.write(pos); 
 }
 else if (coherer == HIGH && door == LOW){ //door open + coherer on
  digitalWrite(3,HIGH);
 digitalWrite(4,LOW); 
 pos = 180;
   myservo.write(pos); 
   
 }
   else if (coherer == LOW && door == HIGH){ //door shut + coherer off
    digitalWrite(3,LOW);
 digitalWrite(4,HIGH); 
   pos = 0;
   myservo.write(pos);
   
   }
 }
  
  

  void digitalClockDisplay(){ // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.println();
}

void printDigits(int digits){ // utility function for clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);

}

My logic would ideally proceed like this:

IF - switch a is HIGH
YES
IF - switch b is HIGH
YES
IF - TIME ALARM IS OPEN
YES

THEN - Servo pos - 180

OTHERWISE Servo pos - 0

Please accept my humble attempts to make the circuit. This is my first dive into the arduino world!
If this is not in the right thread, anything is unclear, or this something I should pay the community to help me with please let me know.
Im quite excited about trying this out, and look forward to putting the final results up here! :slight_smile:

  Alarm.delay(100); 

} 
 
void loop(){ 
 coherer = digitalRead(2);
 door = digitalRead(8);
  digitalClockDisplay();
  delay(500);

The first and last statements in this snippet are incompatible.

When the alarm goes off is the time to read the state of the switches.

In Test 2, in your Open() function, you are going to always end up with the servo at position 0, regardless of the state of the switches, and the servo is NOT going to move far. If you decide that it does need to move, you tell it to start moving, and then immediately tell it to move back. So, it isn't going to travel very far.

Hi Paul, Thank you for your response.

Removed the "alarm.delay command"

Is it possible you could elaborate on the open() function? I presented a code with it working above the 2 tests. it shows the same setup of voids and void loops. It moves the servo 180 for the 5 second gap, in accordance with the alarm open and alarm close gap.

My problem seems the be assigning the 'if' statements into that workflow, and this is the bit I don't understand how to get working.

Removed the "alarm.delay command"

It's a method, and that was the wrong one. You need to use Alarm.delay() everywhere in your code, not delay().

it shows the same setup of voids and void loops.

There are no voids in your code. There are functions.

Crappy indenting alert!

void Open() {
 if(coherer == HIGH && door == HIGH){ //door shut + coherer on
  digitalWrite(3,HIGH);
 digitalWrite(4,HIGH); 
   pos = 180;
   myservo.write(pos); 
}
 
 pos = 0;
   myservo.write(pos); 
  }

If the switches are in the correct state, move the servo to 180. Before it even has a chance to get started moving, send it back to 0. I fail to see how that is useful.

Tools + Auto Format, on the other hand, IS useful.

Ah I see what point you are getting at, tying myself in knots here!
This section of code has improved however to create the unlocking scenario and subsequent closure:

  Alarm.alarmRepeat(12,0,01,Open);  // unlock door
  Alarm.alarmRepeat(12,0,10,Close);  //  lock door
  myservo.write(pos); 
  coherer = digitalRead(2);
   door = digitalRead(8);
   digitalWrite(3,LOW);
   digitalWrite(4, LOW);

} 
 
void loop(){ 
  digitalClockDisplay();
  Alarm.delay(100); 
  }


void Open(){
  if(coherer == HIGH & door == HIGH){
   pos = 180;
   myservo.write(pos); 
}
}

void Close(){
  digitalWrite(3,LOW);
  pos = 0;
   myservo.write(pos); 
}

Its been more successful, however, if the 2 switches aren't down at the start of the serial.output, then nothing happens with the servo regardless if I push the switches down before the alarm time goes off... 2 steps forward 1 back.

Perhaps the fine folks at http://snippets-r-us.com can help you with your snippets.

I'll try and stay punctual then:

#include <Time.h>
#include <Servo.h> 
#include <TimeAlarms.h>
 // This code only works before the serial begins timing, after that it doesnt go over and check the different codes. 
 // Its possible that they all need to be written into the void loop.
 
Servo myservo;  // create servo object to control a servo 
 int pos = 0;    // variable to store the servo position 
int coherer = 0; // attached to switch a
int door = 0;

void setup() 
{ 
    Serial.begin(9600);
  setTime(12,0,0,1,1,11); // set time to noon Jan 1 2011
    pinMode(8, INPUT); //door input
  pinMode(2, INPUT); //coherer input
  pinMode(3, OUTPUT); // green light
  pinMode(4, OUTPUT);  // red light
    myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
  Alarm.alarmRepeat(12,0,05,Open);  // unlock door
  Alarm.alarmRepeat(12,0,10,Close);  //  lock door
  myservo.write(pos); 
  coherer = digitalRead(2);
   door = digitalRead(8);
   digitalWrite(3,LOW);
   digitalWrite(4, LOW);

} 
 
void loop(){ 
  digitalClockDisplay();
  Alarm.delay(100); 
  }


void Open(){ //open lock if door is shut and coherer is on
  if(coherer == HIGH & door == HIGH){
    digitalWrite(3,HIGH);
   pos = 180;
   myservo.write(pos); 
}
}

void Close(){ // close lock
  digitalWrite(3,LOW);
  pos = 0;
   myservo.write(pos); 
}

  void digitalClockDisplay(){  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.println();
}

void printDigits(int digits){ // utility function for clock display
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

This achieves the goal to turn servo 180 for 5 seconds at the set alarm interval before moving back to 0 "if coherer and door are HIGH"

Problem:
The switches are not ...live? ...i.e. they have to be down before the program starts or the serial resets otherwise they do not command the servo. This may be fine for just 1 alarm command, but I'll need several including the possibility to prompt other if statements, releasing the switches.

Thoughts on that? :slight_smile:

Thoughts on that?

Yes, and I mentioned that problem back in reply #1:

When the alarm goes off is the time to read the state of the switches.

You only read the state of the switches in setup().

Thankyou Paul. I moved the digitalreads to the loop function and it now works perfectly.

I know that was a bit long winded, but sometimes us newbies need a little bit of hand holding :slight_smile: