So I have dabbled in coding and have done a lot of research to find a few projects that I could borrow pieces of code and wiring to help complete my project but I am still running into issues.
I have an Arduino Uno and I am using a DS1307 for time. My objective is to essentially trigger a relay at a specific time, this will open the door, and stop the relay when the limit switch is pressed. I followed a tutorial on programming the time of the DS1307 and then I followed the steps on a tutorial on triggering the relay. Both of these worked perfectly. I can get the relay to trigger at the specific time and It runs for only a minute. When the time switches to the next minute it stops. I however cannot get the Arduino to recognize that the limit switch is pressed and stop the relay.
I would like to duplicate this to add a close relay and limit switch before the final instal. I figure that it would just be duplicating code so I haven't got to messing with or wiring that either.
I would like to add a LCD which I have, to display the status and allow me to change the up and down time. I have not done much research into this because I cannot get the basic code to run right. If someone is feeling frisky and wants to spitball some code I will not complain. I have a LCD sheild with buttons, and a bare LCD thats a 16x2 plus a bunch of buttons....
but listen beggars cannot be choosers and I would love the original code to work lol!
#include <Time.h>
#include <DS1307RTC.h>
int RelayUp = 2; // Digital pin D2
int limitSwitchup = 3; // limit switch set for up set to pin 3
int lmup;
const int UpHour = 18; //figure out sunrise
const int UpMin = 04;
void setup() {
Serial.begin(9600);
while (!Serial) ; // wait for serial
delay(200);
Serial.println("DS1307RTC Read Test");
Serial.println("-------------------");
pinMode(RelayUp, OUTPUT); // declare Relay as output
digitalWrite(RelayUp, LOW); // set the pin to start low no voltage
pinMode(limitSwitchup, INPUT);
}
void loop() {
tmElements_t tm;
lmup = digitalRead(limitSwitchup);
if (RTC.read(tm)) {
Serial.print("Ok, Time = ");
print2digits(tm.Hour);
Serial.write(':');
print2digits(tm.Minute);
Serial.write(':');
print2digits(tm.Second);
Serial.print(", Date (D/M/Y) = ");
Serial.print(tm.Day);
Serial.write('/');
Serial.print(tm.Month);
Serial.write('/');
Serial.print(tmYearToCalendar(tm.Year));
Serial.println();
} else {
if (RTC.chipPresent()) {
Serial.println("The DS1307 is stopped. Please run the SetTime");
Serial.println("example to initialize the time and begin running.");
Serial.println();
} else {
Serial.println("DS1307 read error! Please check the circuitry.");
Serial.println();
}
delay(9000);
}
delay(1000);
if(tm.Hour == UpHour && tm.Minute == UpMin && lmup == LOW)
{
digitalWrite(RelayUp,HIGH);
Serial.println("door opening");
}
if(lmup == HIGH)
{
digitalWrite(RelayUp,LOW);
Serial.println("Door fully Opened");
}
}
void print2digits(int number) {
if (number >= 0 && number < 10) {
Serial.write('0');
}
Serial.print(number);
}
So as my code says I have the DS1307 wired and programmed, the serial monitor displays the time for every second and will display door opening during the minute of the set uptime. The limit switch I am using is a simple break contact spring loaded type so it is wired to the pin and then to ground... So ground when the door is opened and then no ground when it is closed. I tried setting it for LOW and for HIGH .... both times the serial monitor just laughed at me as it ignores me pressing the switch. Other times I would get door fully opened printing on the monitor every second, yet the switch was not depressed.
The motor is controlled by a car window control module so I don't need to worry about controlling the DC motor, I just need the ground signal that the relay will pass when the NPN triggers it.
PaulRB you nailed it. The change to INPUT_PULLUP was enough to get the job done. I did have to change the limitswitch readings from LOW to HIGH or visversa and now it works great. The system will trigger the relay for the full minute unless the limit switch is triggered. If during the minute the limit switch gets depressed then it will trigger the relay again.
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
int RelayUp = 2; // Digital pin D2
int limitSwitchup = 3; // limit switch set for up set to pin 3
int lmup;
const int UpHour = 11; //figure out sunrise
const int UpMin = 17;
void setup() {
Serial.begin(9600);
while (!Serial) ; // wait for serial
delay(200);
Serial.println("DS1307RTC Read Test");
Serial.println("-------------------");
pinMode(RelayUp, OUTPUT); // declare Relay as output
digitalWrite(RelayUp, LOW); // set the pin to start low no voltage
pinMode(limitSwitchup, INPUT_PULLUP);
}
void loop() {
tmElements_t tm;
lmup = digitalRead(limitSwitchup);
if (RTC.read(tm)) {
Serial.print("Ok, Time = ");
print2digits(tm.Hour);
Serial.write(':');
print2digits(tm.Minute);
Serial.write(':');
print2digits(tm.Second);
Serial.print(", Date (D/M/Y) = ");
Serial.print(tm.Day);
Serial.write('/');
Serial.print(tm.Month);
Serial.write('/');
Serial.print(tmYearToCalendar(tm.Year));
Serial.println();
} else {
if (RTC.chipPresent()) {
Serial.println("The DS1307 is stopped. Please run the SetTime");
Serial.println("example to initialize the time and begin running.");
Serial.println();
} else {
Serial.println("DS1307 read error! Please check the circuitry.");
Serial.println();
}
delay(9000);
}
delay(1000);
if(tm.Hour == UpHour && tm.Minute == UpMin && lmup == HIGH)
{
digitalWrite(RelayUp,HIGH);
Serial.println("door opening");
}
if(lmup == LOW)
{
digitalWrite(RelayUp,LOW);
Serial.println("Door fully Opened");
}
}
void print2digits(int number) {
if (number >= 0 && number < 10) {
Serial.write('0');
}
Serial.print(number);
}
There is the updated working code.
One follow up question however, can I simply add a downhour and downmin, another limit switch and then copy the code to reverse the operation? I assume yes and will try and update.
also, if someone could help me, this isn't a concern to this project because the door does not take a full minute to open. How would I change the code to accomidate a longer trigger period, as in longer than a minute?
also, I am going to want to add a LCD and buttons to allow me to be able to change the up and down times. Does anyone know of a good resource to learn about buttons and menus?
You may want to have a look at the TimeAlarms library for scheduling events:
And I recommenced this button library to make handling the buttons easy:
Both should be available in the IDE library manager so it can to the install right from the GUI with no messing with downloading of zip files.
I don't have any experience with them but there are some libraries out there for doing Menus on LCDs.
Libraries for both GLCDs and text based LCDs like the hd44780.
Often in chicken coop threads, the author uses a sunset/sunrise library to figure out an appropriate time to open and close. Probably easier and more convenient than setting it via LCD menus.
Yes, this was my solution. In my case, there are no automatic doors, only automatic lights inside the houses which encourage the chooks to roost. Shortly after, myself or my wife will go count the chooks to check all are safe before securing the doors.
I would suggest calculating times to be compared as "minutes past midnight" (hours * 60 + minutes). Then, one time can be subtracted from another and compared to any time period you like.