Académique Documents
Professionnel Documents
Culture Documents
Arduino Forum
Using Arduino => Programming Questions => Topic started by:
34DOL on Dec 07, 2012, 04:43 am
Both the DS1307 RTC and the DHT11 are communicating with the Arduino
and displaying on the LCD.
The relays are currently wired with the Com to 12V and the NC to the
various device (i.e. fans or lights). The relays seem to cycle. I can hear
them clicking, but my code doesn't control them as I intend. Please assist...
I have yet to connect or code for the stepper motor, but essentially it will
open and close a door with a screw drive based on the time of day.
Code: [Select]
#include <LiquidCrystal.h>
#include <DFR_Key.h>
#include <Wire.h>
#include "RTClib.h"
#include "DHT.h"
DFR_Key keypad;
int localKey = 0;
String keyString = "";
RTC_DS1307 RTC;
int StartHrRelay_4 = 7;
int StartMinRelay_4 = 44;
DateTime future;
DateTime DelayFuture;
DateTime Start;
int DurDay1 = 0;
int DurHour1 = 10;
int DurMinute1 = 0;
int DurSecond1 = 0;
int DurDay2 = 0;
int DurHour2 = 8;
int DurMinute2 = 0;
int DurSecond2 = 0;
int DurDay3 = 0;
int DurHour3 = 1;
int DurMinute3 = 0;
int DurSecond3 = 0;
int DurDay4 = 0;
int DurHour4 = 1;
int DurMinute4 = 30;
int DurSecond4 = 0;
#define RELAY_ON 0
#define RELAY_OFF 1
int Relay_1 = 3;
int Relay_2 = 4;
int Relay_3 = 5;
int Relay_4 = 6;
long readVcc() {
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
}
#define DHTPIN 2
void setup() {
Serial.begin(57600);
lcd.begin (16,2);
lcd.print(" Chicken Coop ");
Wire.begin();
RTC.begin();
RTC.adjust(DateTime(__DATE__, __TIME__));
if (! RTC.isrunning()) {
lcd.setCursor (0,0);
lcd.print(" *-- RTC's --*");
lcd.setCursor (0,1);
lcd.print(" NOT running!");
Serial.println(" *-- RTC's NOT running! --*");
delay (5000) ;
lcd.clear();
RTC.adjust(DateTime(__DATE__, __TIME__));
}
Start = SetStart;
digitalWrite(Relay_1, RELAY_OFF);
pinMode(Relay_1, OUTPUT);
digitalWrite(Relay_2, RELAY_OFF);
pinMode(Relay_2, OUTPUT);
digitalWrite(Relay_3, RELAY_OFF);
pinMode(Relay_3, OUTPUT);
digitalWrite(Relay_4, RELAY_OFF);
pinMode(Relay_4, OUTPUT);
delay(4000);
dht.begin();
void loop()
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(t) || isnan(h)) {
lcd.setCursor (0,0);
lcd.print("*-- Failed to");
lcd.setCursor (0,1);
lcd.print(" read T&H --*");
Serial.println("*-- Failed to read T&H --*");
delay (5000) ;
lcd.clear();
}
else {
lcd.setCursor (0,0);
lcd.print("Temp (F): ");
lcd.print(t*9/5 + 32);
lcd.print(" *F");
lcd.setCursor (0,1);
lcd.print("Humidity: ");
lcd.print(h);
lcd.print("% ");
delay (5000) ;
lcd.clear();
lcd.setCursor (0,0);
lcd.print("Temp (C): ");
lcd.print(t);
lcd.print(" *C");
lcd.setCursor (0,1);
lcd.print("Dew Point: ");
lcd.print(dewPoint(t, h));
lcd.print(" *C");
delay (5000) ;
lcd.clear();
lcd.setCursor (0,0);
lcd.print("Volts (mV): ");
lcd.print( readVcc(), DEC );
delay(5000);
lcd.clear();
lcd.setCursor (0,0);
lcd.print(" ");
lcd.print(now.year(), DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.day(), DEC);
lcd.setCursor (0,1);
lcd.print(" ");
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.println(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
delay(5000);
lcd.clear();
if (LightOn == false) {
DelayFuture = CalcFuture(Start,0L,0L,Sleep,0L);
future = CalcFuture(now,DurDay3,DurHour3,DurMinute3,DurSecond3);
LightOn = true;
digitalWrite(Relay_3, RELAY_ON);
Serial.println("\r\nLight On\r\n");
}
}
else {
LightOn = false;
digitalWrite(Relay_3, RELAY_OFF);
Serial.print("\r\nLight Off\r\n");
}
}
delay((Sleep*MultiMinute));
if (LightOn == false) {
DelayFuture = CalcFuture(Start,0L,0L,Sleep,0L);
future = CalcFuture(now,DurDay4,DurHour4,DurMinute4,DurSecond4);
LightOn = true;
digitalWrite(Relay_4, RELAY_ON);
Serial.println("\r\nLight On\r\n");
}
}
else {
LightOn = false;
digitalWrite(Relay_4, RELAY_OFF);
Serial.print("\r\nLight Off\r\n");
}
}
delay((Sleep*MultiMinute));
}
DateTime CalcFuture (DateTime now, int Days, int Hours, int Minutes, int
Seconds){
DateTime future;
long DaySeconds = 86400L;
long HourSeconds = 3600L;
long MinuteSeconds = 60L;
//
Now, perhaps if you told us how you intended that code to work, and how it
actually works, we could help you.
I intend the code to work such that the relays are turned on or off based on
information supplied by the RTC and DHT. Relays 1 & 2 are intended to
control the fans. Relays 3 & 4 are intended to control the lights.
The arduino is receiving data from the RTC and DHT and displays as the data
intended on the LCD. What doesn't work, or doesn't work as intended, is my
code to use that data to control the relays. What does that part of the code
do? Well, from what I can tell, pretty much nothing. I've search all over for
code that I could use to turn relays on or off based off data values from the
RTC and DHT compared to pre-assigned arguments and haven't been able to
put together anything that works. What I have here is the closest I've been
able to come.
Maybe my relays are connected incorrectly, but I don't think so. Since I
wired them as normally closed I am able to tell that they are at least getting
the 12V power. The lights and fans come on when plugged in.
Digital pin 3 is connected to line 1 on the relay board, pin 4 to line 2, pin 5
to line 3 and pin 6 to line 4. The 5V feed from the Arduino is connected to
the VCC on the relay board as is the ground. On the relay side, the Coms
are daisy chained together and supplied with 12V DC from a separate power
source. The normally closeds are then connected to the positive terminal on
a 4 separate RCA jacks. The jacks are used to connect the fans and lights.
The negative to the jacks comes straight from the power source.
9500 characters is more than enough to verify that the temperature sensor
can be read and the value printed to the serial monitor.
9500 characters is more than enough to verify that you can write to the
LCD.
Writing one huge program that does everything, and is full of delay()s, is not
the way to approach programming.
Develop a series of little sketches that demonstrate that the individual pieces
all work. When you know that that happens, start combining them, two at a
time. If, or when, stuff doesn't work together, it is so much simpler to detect
why.
To trigger event at certain time of RTC, I would look into how to do that in
my alarm clock code that I wrote for my phi-2 shield.
http://liudr.wordpress.com/shields/phi-2-shield/
There is a link to the alarm clock source code download. To be honest, this
shield, which I designed, is much better than what you're using. There is an
on board RTC and well-written menu and interaction libraries for user
interface.
I wrote code for the LCD with just the LCD attached. Tested it and it
worked, so I moved on.
I then wrote code for the DHT. Tested it and it worked, so I moved on.
I then wrote code for the RTC. Tested it and it worked, so I moved on.
As the RTC and DHT were successfully communicating with the Arduino
which was successfully displaying their data on the LCD, and both the RTC
and DHT are needed in the code I am writing for the relays, it was time for
me to write code for the last step, using the RTC and DHT data to control the
relay board. Before I did that, I took one step sideways and I tested that
the Arduino communicates successfully with the relay board using a simple
loop on/off code and that worked.
PaulS your suggesting that I should "develop a series of little sketches that
demonstrate that the individual pieces all work" and then, "when (I) know
that that happens, start combining them, two at a time" is, as you can now
see, exactly what I did. But good advice none-the-less and maybe it will
help someone else reading this post on one of their projects.
I apologize if this was not clear in my initial post but like I said, we are
limited to 9500 characters. And to PaulS suggestion that that does not
include attached code, yes PaulS the 9500 character limit does include
attached code. Deleting the comment lines out of my code is what got me
under 9500 characters.
Code above is an alarm clock. You can modify the alarm function to check
whether it is time to do certain thing according to RTC.
The 9500 character limit refers to posted code. That is code in this box. And
text. But, see down there? Below this window? The Additional Options link.
Well, OK, so it does not look a lot like a link. But, it is. Select that. You can
attach much larger than 9500 character files.
I am happy to hear that you are developing the code in pieces. That wasn't
clear from your post.
I still think that those delays have got to go. The millis() function and a state
machine (what do I need to do on this pass through loop, if is is time to do
anything) is much better than sitting on your hands for relatively long
periods of time.
Anyways... Which delays do you suggest I delete? All of them? Are you
suggesting the delays are causing the issue? If I don't have any delays,
won't that cause a display issue on the LCD (i.e. the data won't be displayed
long enough for anyone to read it)?
Quote
Are you suggesting the delays are causing the issue?
I don't understand what the issue is. I don't see any serial out put that says
"Time to turn the relay on" and "Time to turn the relay off", annotated to
note whether that happened, or not. Calls to delay() do not belong in a
sketch that is doing more than blinking an LED.
Quote
If I don't have any delays, won't that cause a display issue on the LCD (i.e. the data won't
be displayed long enough for anyone to read it)?
Not if you don't immediately overwrite the data. See the comments above.
Quote
What is the millis() function?
Is it necessary to point out that up there at the top of the page there is a
link that says Main Site, and that on that page there is one that says
Reference, and that on that page all the Arduino-specific functions are
documented?
DelayFuture = CalcFuture(Start,0L,0L,Sleep,0L);
future = CalcFuture(now,DurDay3,DurHour3,DurMinute3,DurSecond3);
//Turn on light
LightOn = true;
digitalWrite(Relay_3, RELAY_ON);
Serial.println("\r\nLight On\r\n");
}
}
else {
//Check current time - turn off light when conditions are met
Serial.print("\r\nLight Off\r\n");
}
}
delay((Sleep*MultiMinute));
if (LightOn == false) {
DelayFuture = CalcFuture(Start,0L,0L,Sleep,0L);
future = CalcFuture(now,DurDay4,DurHour4,DurMinute4,DurSecond4);
//Turn on light
LightOn = true;
digitalWrite(Relay_4, RELAY_ON);
Serial.println("\r\nLight On\r\n");
}
}
else {
//Check current time - turn off light when conditions are met
}
}
delay((Sleep*MultiMinute));
Code: [Select]
//Chimney fan (Relay_1) on-off temperature
if (dht.readTemperature() >= 20) {
digitalWrite(Relay_1, RELAY_OFF);
}
else if (dht.readTemperature() < 18) {
digitalWrite(Relay_1, RELAY_ON);
}
Nested ifs are far easier to understand and debug, in my opinion, than
compound ifs.
Please, do yourself, and us, a favor. Put each { on a new line, use the return
key more often, and use Tools + Auto Format.
You have Serial.print() statements in your code. You are not sharing what
you see, bogart.
No idea, I didn't write that code. I borrowed it from someone else's project.
If it doesn't need to be there, or if it should be changed to something
different, what do you suggest?
I've now used Tools + Auto Format. Didn't even know that feature existed.
Other than making my code look pretty, I don't think it will solve my issue.
But then again, neither will removing the delays.
Quote
But then again, neither will removing the delays.
Maybe not. But you aren't being clear on what the problem is, or where in
the code/when the problem occurs.
Quote
If it doesn't need to be there, or if it should be changed to something different, what do you
suggest?
I suggest that you look at the documentation for the class that now is an
instance of, and determine what type the hour(), minute(), and second()
functions return, and determine whether it is necessary to cast that value to
a different type.
Attached is my code. The delays are still in but I have Auto Formatted it.
Seems to me that if I delete the delays the loop will cycle through too fast
for the information to be displayed on the LCD.
I think its time for you to move on PaulS. This issue seem to be above your
level of competency. Thanks for your help.
Code: [Select]
float h = dht.readHumidity();
float t = dht.readTemperature();
Where are the serial print statements to show whether the relay is to be
turned on or off? What actually happens?
I know that it is frustrating when code doesn't work as you want, but, you
need to remember that we can't see what you are seeing. If you don't show
serial output, we can't see it. If you don't say what the relays are actually
doing, we don't know.
I don't know what the relays are doing with that code. As I said, they don't
seem to be doing anything.
Bob
I have however removed my delays and inserted millis()s. I've never used
this function before and am not sure if I did it correct. Attached is my code.
void setup()
{
pinMode(ledPin, OUTPUT); // set the digital pin as output:
}
void loop()
{
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval)
{
// save the last time you blinked the LED
previousMillis = currentMillis;
if (ledState == LOW) // if the LED is off turn it on and vice-versa:
ledState = HIGH;
else
ledState = LOW; // set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
Bob
Arduino Forum
Using Arduino => Programming Questions => Topic started by:
34DOL on Dec 07, 2012, 04:43 am
Both the DS1307 RTC and the DHT11 are communicating with the Arduino
and displaying on the LCD.
The relays are currently wired with the Com to 12V and the NC to the
various device (i.e. fans or lights). The relays seem to cycle. I can hear
them clicking, but my code doesn't control them as I intend. Please assist...
I have yet to connect or code for the stepper motor, but essentially it will
open and close a door with a screw drive based on the time of day.
Code: [Select]
#include <LiquidCrystal.h>
#include <DFR_Key.h>
#include <Wire.h>
#include "RTClib.h"
#include "DHT.h"
DFR_Key keypad;
int localKey = 0;
String keyString = "";
RTC_DS1307 RTC;
int StartHrRelay_3 = 7;
int StartMinRelay_3 = 44;
int StartHrRelay_4 = 7;
int StartMinRelay_4 = 44;
DateTime future;
DateTime DelayFuture;
DateTime Start;
int DurDay1 = 0;
int DurHour1 = 10;
int DurMinute1 = 0;
int DurSecond1 = 0;
int DurDay2 = 0;
int DurHour2 = 8;
int DurMinute2 = 0;
int DurSecond2 = 0;
int DurDay3 = 0;
int DurHour3 = 1;
int DurMinute3 = 0;
int DurSecond3 = 0;
int DurDay4 = 0;
int DurHour4 = 1;
int DurMinute4 = 30;
int DurSecond4 = 0;
#define RELAY_ON 0
#define RELAY_OFF 1
int Relay_1 = 3;
int Relay_2 = 4;
int Relay_3 = 5;
int Relay_4 = 6;
long readVcc() {
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
}
#define DHTPIN 2
void setup() {
Serial.begin(57600);
lcd.begin (16,2);
lcd.print(" Chicken Coop ");
Wire.begin();
RTC.begin();
RTC.adjust(DateTime(__DATE__, __TIME__));
if (! RTC.isrunning()) {
lcd.setCursor (0,0);
lcd.print(" *-- RTC's --*");
lcd.setCursor (0,1);
lcd.print(" NOT running!");
Serial.println(" *-- RTC's NOT running! --*");
delay (5000) ;
lcd.clear();
RTC.adjust(DateTime(__DATE__, __TIME__));
}
Start = SetStart;
digitalWrite(Relay_1, RELAY_OFF);
pinMode(Relay_1, OUTPUT);
digitalWrite(Relay_2, RELAY_OFF);
pinMode(Relay_2, OUTPUT);
digitalWrite(Relay_3, RELAY_OFF);
pinMode(Relay_3, OUTPUT);
digitalWrite(Relay_4, RELAY_OFF);
pinMode(Relay_4, OUTPUT);
delay(4000);
dht.begin();
void loop()
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(t) || isnan(h)) {
lcd.setCursor (0,0);
lcd.print("*-- Failed to");
lcd.setCursor (0,1);
lcd.print(" read T&H --*");
Serial.println("*-- Failed to read T&H --*");
delay (5000) ;
lcd.clear();
}
else {
lcd.setCursor (0,0);
lcd.print("Temp (F): ");
lcd.print(t*9/5 + 32);
lcd.print(" *F");
lcd.setCursor (0,1);
lcd.print("Humidity: ");
lcd.print(h);
lcd.print("% ");
delay (5000) ;
lcd.clear();
lcd.setCursor (0,0);
lcd.print("Temp (C): ");
lcd.print(t);
lcd.print(" *C");
lcd.setCursor (0,1);
lcd.print("Dew Point: ");
lcd.print(dewPoint(t, h));
lcd.print(" *C");
delay (5000) ;
lcd.clear();
delay(5000);
lcd.clear();
lcd.setCursor (0,0);
lcd.print(" ");
lcd.print(now.year(), DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.day(), DEC);
lcd.setCursor (0,1);
lcd.print(" ");
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.println(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
delay(5000);
lcd.clear();
if (LightOn == false) {
DelayFuture = CalcFuture(Start,0L,0L,Sleep,0L);
future = CalcFuture(now,DurDay3,DurHour3,DurMinute3,DurSecond3);
LightOn = true;
digitalWrite(Relay_3, RELAY_ON);
Serial.println("\r\nLight On\r\n");
}
}
else {
LightOn = false;
digitalWrite(Relay_3, RELAY_OFF);
Serial.print("\r\nLight Off\r\n");
}
}
delay((Sleep*MultiMinute));
if (LightOn == false) {
DelayFuture = CalcFuture(Start,0L,0L,Sleep,0L);
future = CalcFuture(now,DurDay4,DurHour4,DurMinute4,DurSecond4);
LightOn = true;
digitalWrite(Relay_4, RELAY_ON);
Serial.println("\r\nLight On\r\n");
}
}
else {
LightOn = false;
digitalWrite(Relay_4, RELAY_OFF);
Serial.print("\r\nLight Off\r\n");
}
}
delay((Sleep*MultiMinute));
}
DateTime CalcFuture (DateTime now, int Days, int Hours, int Minutes, int
Seconds){
DateTime future;
long DaySeconds = 86400L;
long HourSeconds = 3600L;
long MinuteSeconds = 60L;
//
Now, perhaps if you told us how you intended that code to work, and how it
actually works, we could help you.
I intend the code to work such that the relays are turned on or off based on
information supplied by the RTC and DHT. Relays 1 & 2 are intended to
control the fans. Relays 3 & 4 are intended to control the lights.
The arduino is receiving data from the RTC and DHT and displays as the data
intended on the LCD. What doesn't work, or doesn't work as intended, is my
code to use that data to control the relays. What does that part of the code
do? Well, from what I can tell, pretty much nothing. I've search all over for
code that I could use to turn relays on or off based off data values from the
RTC and DHT compared to pre-assigned arguments and haven't been able to
put together anything that works. What I have here is the closest I've been
able to come.
Maybe my relays are connected incorrectly, but I don't think so. Since I
wired them as normally closed I am able to tell that they are at least getting
the 12V power. The lights and fans come on when plugged in.
Digital pin 3 is connected to line 1 on the relay board, pin 4 to line 2, pin 5
to line 3 and pin 6 to line 4. The 5V feed from the Arduino is connected to
the VCC on the relay board as is the ground. On the relay side, the Coms
are daisy chained together and supplied with 12V DC from a separate power
source. The normally closeds are then connected to the positive terminal on
a 4 separate RCA jacks. The jacks are used to connect the fans and lights.
The negative to the jacks comes straight from the power source.
9500 characters is more than enough to verify that the temperature sensor
can be read and the value printed to the serial monitor.
9500 characters is more than enough to verify that you can write to the
LCD.
Writing one huge program that does everything, and is full of delay()s, is not
the way to approach programming.
Develop a series of little sketches that demonstrate that the individual pieces
all work. When you know that that happens, start combining them, two at a
time. If, or when, stuff doesn't work together, it is so much simpler to detect
why.
To trigger event at certain time of RTC, I would look into how to do that in
my alarm clock code that I wrote for my phi-2 shield.
http://liudr.wordpress.com/shields/phi-2-shield/
There is a link to the alarm clock source code download. To be honest, this
shield, which I designed, is much better than what you're using. There is an
on board RTC and well-written menu and interaction libraries for user
interface.
I wrote code for the LCD with just the LCD attached. Tested it and it
worked, so I moved on.
I then wrote code for the DHT. Tested it and it worked, so I moved on.
I then wrote code for the RTC. Tested it and it worked, so I moved on.
As the RTC and DHT were successfully communicating with the Arduino
which was successfully displaying their data on the LCD, and both the RTC
and DHT are needed in the code I am writing for the relays, it was time for
me to write code for the last step, using the RTC and DHT data to control the
relay board. Before I did that, I took one step sideways and I tested that
the Arduino communicates successfully with the relay board using a simple
loop on/off code and that worked.
PaulS your suggesting that I should "develop a series of little sketches that
demonstrate that the individual pieces all work" and then, "when (I) know
that that happens, start combining them, two at a time" is, as you can now
see, exactly what I did. But good advice none-the-less and maybe it will
help someone else reading this post on one of their projects.
I apologize if this was not clear in my initial post but like I said, we are
limited to 9500 characters. And to PaulS suggestion that that does not
include attached code, yes PaulS the 9500 character limit does include
attached code. Deleting the comment lines out of my code is what got me
under 9500 characters.
Code above is an alarm clock. You can modify the alarm function to check
whether it is time to do certain thing according to RTC.
The 9500 character limit refers to posted code. That is code in this box. And
text. But, see down there? Below this window? The Additional Options link.
Well, OK, so it does not look a lot like a link. But, it is. Select that. You can
attach much larger than 9500 character files.
I am happy to hear that you are developing the code in pieces. That wasn't
clear from your post.
I still think that those delays have got to go. The millis() function and a state
machine (what do I need to do on this pass through loop, if is is time to do
anything) is much better than sitting on your hands for relatively long
periods of time.
Anyways... Which delays do you suggest I delete? All of them? Are you
suggesting the delays are causing the issue? If I don't have any delays,
won't that cause a display issue on the LCD (i.e. the data won't be displayed
long enough for anyone to read it)?
Quote
Are you suggesting the delays are causing the issue?
I don't understand what the issue is. I don't see any serial out put that says
"Time to turn the relay on" and "Time to turn the relay off", annotated to
note whether that happened, or not. Calls to delay() do not belong in a
sketch that is doing more than blinking an LED.
Quote
If I don't have any delays, won't that cause a display issue on the LCD (i.e. the data won't
be displayed long enough for anyone to read it)?
Not if you don't immediately overwrite the data. See the comments above.
Quote
What is the millis() function?
Is it necessary to point out that up there at the top of the page there is a
link that says Main Site, and that on that page there is one that says
Reference, and that on that page all the Arduino-specific functions are
documented?
DelayFuture = CalcFuture(Start,0L,0L,Sleep,0L);
future = CalcFuture(now,DurDay3,DurHour3,DurMinute3,DurSecond3);
//Turn on light
LightOn = true;
digitalWrite(Relay_3, RELAY_ON);
Serial.println("\r\nLight On\r\n");
}
}
else {
//Check current time - turn off light when conditions are met
Serial.print("\r\nLight Off\r\n");
}
}
delay((Sleep*MultiMinute));
//Check status of light
if (LightOn == false) {
DelayFuture = CalcFuture(Start,0L,0L,Sleep,0L);
future = CalcFuture(now,DurDay4,DurHour4,DurMinute4,DurSecond4);
//Turn on light
LightOn = true;
digitalWrite(Relay_4, RELAY_ON);
Serial.println("\r\nLight On\r\n");
}
}
else {
//Check current time - turn off light when conditions are met
Serial.print("\r\nLight Off\r\n");
}
}
delay((Sleep*MultiMinute));
Code: [Select]
//Chimney fan (Relay_1) on-off temperature
if (dht.readTemperature() >= 20) {
digitalWrite(Relay_1, RELAY_OFF);
}
else if (dht.readTemperature() < 18) {
digitalWrite(Relay_1, RELAY_ON);
}
Nested ifs are far easier to understand and debug, in my opinion, than
compound ifs.
Please, do yourself, and us, a favor. Put each { on a new line, use the return
key more often, and use Tools + Auto Format.
You have Serial.print() statements in your code. You are not sharing what
you see, bogart.
No idea, I didn't write that code. I borrowed it from someone else's project.
If it doesn't need to be there, or if it should be changed to something
different, what do you suggest?
I've now used Tools + Auto Format. Didn't even know that feature existed.
Other than making my code look pretty, I don't think it will solve my issue.
But then again, neither will removing the delays.
Quote
But then again, neither will removing the delays.
Maybe not. But you aren't being clear on what the problem is, or where in
the code/when the problem occurs.
Quote
If it doesn't need to be there, or if it should be changed to something different, what do you
suggest?
I suggest that you look at the documentation for the class that now is an
instance of, and determine what type the hour(), minute(), and second()
functions return, and determine whether it is necessary to cast that value to
a different type.
Attached is my code. The delays are still in but I have Auto Formatted it.
Seems to me that if I delete the delays the loop will cycle through too fast
for the information to be displayed on the LCD.
Perhaps because you have not stated the problem clearly enough.
I think its time for you to move on PaulS. This issue seem to be above your
level of competency. Thanks for your help.
Code: [Select]
float h = dht.readHumidity();
float t = dht.readTemperature();
Where are the serial print statements to show whether the relay is to be
turned on or off? What actually happens?
I know that it is frustrating when code doesn't work as you want, but, you
need to remember that we can't see what you are seeing. If you don't show
serial output, we can't see it. If you don't say what the relays are actually
doing, we don't know.
I don't know what the relays are doing with that code. As I said, they don't
seem to be doing anything.
Bob
I have however removed my delays and inserted millis()s. I've never used
this function before and am not sure if I did it correct. Attached is my code.
void setup()
{
pinMode(ledPin, OUTPUT); // set the digital pin as output:
}
void loop()
{
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval)
{
// save the last time you blinked the LED
previousMillis = currentMillis;
if (ledState == LOW) // if the LED is off turn it on and vice-versa:
ledState = HIGH;
else
ledState = LOW; // set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
Bob
Pawan Kumar
Alarm Clock, Timer and Stopwatch are common time-keeping features. These functions are so frequently used
that it is difficult to imagine modern life without a time-keeping application nowadays. Whether it is a
scheduled wake up alarm, a stopwatch to track the time one has jogged or a timer and alarm to schedule
office tasks, time-keeping is part and parcel of day-to-day life. This is an Arduino project demonstrating a
complete time-keeping application. The project is a real-time clock and allows setting alarms, timers and
running stopwatch.
It also displays real-time weather conditions with temperature and humidity indications as add-ons
The project has utilized RTC DS1307 for time-keeping and DHT11 sensor for fetching weather information. It is
built on Arduino UNO and RTC used is internally powered through a button cell, so the project keeps track of
real time and perform user-defined functions irrespective of the continuity of power supply to the circuit. The
time and date, temperature and humidity values are displayed on a 16X2 LCD which also provides human
interface to set alarm, timer and stopwatch. The users can feed inputs through a 4-switch keypad with
switches for the following functions - Mode Selection, ENTER, Increment and SAVE buttons. A buzzer is
connected to the Arduino board for realizing alarm and timer alerts.
1) Default Mode: By default, the project is set to display time, date, temperature and humidity information on the
16X2 LCD screen.
2) Alarm Mode: Here, user can set an alarm. The user enters this mode by pressing Mode selection button once and
pressing the ENTER Button thereafter. He can first increase "Hours" value by pressing Increment button and skip to
increase "Minutes" value by pressing the ENTER button again. After setting "Hours" and "Minutes" value the user can
invoke alarm by pressing the SAVE button. To exit the alarm mode, Increment and mode selection buttons have to
be pressed together.
3) Timer Mode: A timer setting mode can be entered by pressing the Mode selection button twice and pressing the
ENTER button thereafter. The process for setting and saving time for timer is same as in alarm mode except that
"Seconds" value can also be set in this mode. The user can exit the timer mode after setting time by just pressing
the mode selection button once again.
4) Stopwatch Mode: To enter stopwatch mode, pressing mode selection button thrice and pressing the ENTER button
thereafter works. Here pressing the SAVE button starts the stopwatch, pressing increment button pauses the
stopwatch and pressing ENTER button again resets the stop watch. To exit the stopwatch mode, ENTER and Mode
Selection buttons have to be pressed together.
Components Required
Arduino UNO
RTC module-DC1307
16x2 LCD
5v Buzzer
BC 547 transistor
Push to ON switch-4pcs
DHT11 sensor
Circuit Connection
4) LCD Display
5) 4-switch keypad
6) Buzzer
7) Arduino Board
The Arduino UNO programmatically controls all the time-keeping functions of the application. All the components are
interfaced to the Arduino board for the circuit to run. The circuit is connected in the following manner -:
1) Power Supply - The entire circuit runs on a 5V DC supply. A 12V battery is used to source power to the circuit. The
12V supply is stepped down to 5V by a 7805 voltage regulator. The pin 1 of 7805 receives 12V supply from anode
and pin 2 is grounded. The output 5V is generated at pin 3 of the regulator. An LED is also connected in parallel to
the output as a visual indicator of power supply.
2) RTC DS1307 Interfacing - The RTC DS1307 has a built in button cell that allows keeping track of real-time
irrespective of the power supply. For interfacing with the Arduino board, SDA and SCL pins of the RTC are connected
to the SDA and SCL pins of the Arduino UNO.
Learn more about interfacing and programming RTC with Arduino here
3) DHT11 Temperature and Humidity Sensor - This is a digital sensor with inbuilt capacitive humidity sensor and
Thermistor. It relays a real-time temperature and humidity reading every 2 seconds as a digital output. The pin 1 and
4 of DHT11 are VCC and Ground respectively. The output is received from pin 2 of the sensor which is feed to A0 pin
of the Arduino board through a 10K ohm pull up resistor.
4) LCD Display - The 16X2 LCD display is connected to the Arduino board by connecting its data pins to pins 2 to 5 of
the Arduino board. The RS and E pin of LCD is connected to pins 12 and 11 of the Arduino UNO respectively. The RW
pin of the LCD is grounded.
RS 12
RW GRND
E 11
The standard code library for interfacing Arduino UNO and Arduino Pro Mini are used in the project to program
LCD with the board. The code library works as expected. Learn more about LCD interfacing with the
Arduino UNO.
5) 4-switch Keypad - The keypad here is a set of four push-to-on switches which are connected to 10, 9, 8 and 7
pins of the Arduino UNO through 1K ohm pull-up resistors. The switches connected at 10, 9, 8 and 7 pins works as
SAVE, Increment, Enter and Mode selection buttons respectively. In the circuit diagram, SAVE, Increment, Enter and
Mode selection buttons are designated by FIRST, SECOND, THIRD and MODE labels.
6) Buzzer - The buzzer is connected to pin 6 of the Arduino board. A common emitter NPN BC547 transistor circuit is
used to relay signal from Arduino pin to the buzzer.
How the Circuit Works
As the circuit is powered up, Arduino runs initial code thereof preparing LCD screen for display output and fetches
signals from RTC and temperature sensor. The project enters default mode. Some initial messages are flashed on the
display screen. The readings from RTC and temperature sensor are digitally read at pins SDA-SCL and A0
respectively. The readings are saved to internal EEPROM and time, date, temperature and humidity values are
displayed on the 16X2 LCD.
The user inputs are read through the 4-switch keypad. On pressing any switch, a LOW signal is detected at the
respective pin connected through the switch. A detection of LOW signal from the switches prompts the code to run
respective functions to enter other modes and setting or resetting time values.
The project enters alarm mode on detecting a single LOW signal at mode selection button followed by a LOW signal
at ENTER button. The setting and resetting of time values is done by detecting LOW signals at increment and SAVE
buttons in a pre-defined sequence. The time entered by the user is saved to internal EEPROM and compared to the
real-time fetched from the RTC in a loop. When the user entered time matches the current time, a LOW signal is
output at pin 6 of the Arduino board. This prompts to light up the LED connected in parallel to the buzzer circuit as
visual indicator of alarm alert. In the buzzer circuit, on receiving a LOW signal at pin 6, the common emitter
configured BC547 transistor gets short circuited allowing a flow of current from collector to emitter. The buzzer gets
a ground at the collector end of the transistor and starts buzzing the alert. The alarm mode is terminated after the
buzzer alert and LED signal. The program code allows to exit from the alarm mode on detection of LOW signals from
increment and mode selection buttons simultaneously.
The timer mode is activated on detection of two continuous LOW signals at mode selection button and followed by a
LOW signal at ENTER button. The setting and resetting of time values is again done by detecting LOW signals at
increment and SAVE buttons in a pre-defined sequence. In timer mode, user is allowed to set the "Seconds" value as
well. The user entered time is counted down by keeping a track of current time from the RTC. The countdown time is
displayed on the LCD screen with the help of loop logic. When the countdown reaches zero value, again a LOW
signal is activated on pin 6 of Arduino thereby running the buzzer and lighting up LED as explained above.
Thereafter, the mode is terminated and resumes to the default mode.
The stopwatch mode is invoked on detection of three back to back LOW signals at mode selection switch followed by
a LOW signal at ENTER button. The display at the LCD is reset to show zero time values. On detection of a LOW
signal at SAVE button, stopwatch starts. The time user starts stopwatch is fetched from RTC and saved to the
internal memory. In a loop the current time is fetched from the RTC and saved to internal memory. The current time
is compared to start time and a time update is displayed accordingly on the LCD screen. If a LOW signal is detected
at the increment button, the loop is stopped for until a start signal is received thereof stopping any time updates.
Once the stopwatch has started, on detection of a LOW signal at ENTER button resets the time to zero and prompts
to wait for a start signal. The mode is terminated on receiving LOW signals at ENTER and Mode selection buttons
simultaneously. The termination of the mode resumes the default mode.
The time and date updates in any mode remain unaltered even if the power supply is interrupted because RTC
DS1307 has an in-built button cell to keep RTC in sync. The temperature and humidity readings are updated every 2
seconds as DHT11 relays the digital readings out in that interval.
Programming Guide
The code uses standard open-source libraries of Arduino UNO. When the circuit is powered on, the Arduino loads
standard libraries of LCD, EEPROM and RTC and import the functions used from the libraries.
The Arduino board is initialized through a setup() function to start fetching real-time from RTC module, prepare LCD
for display and activating input/output mode and HIGH/LOW signals at the pins interfaced with the keypad and
buzzer circuit. Some initial messages are flashed through the LCD screen using print function of the LCD class. The
RTC is checked and configured to relay current time and date.
The RTC and DHT11 readings are saved to the internal EEPROM.
The readings are displayed on the LCD screen. With this project enters the default mode.
The other modes are activated on detection of LOW signals from keypad switches in a pre-defined pattern. A
checkTime() function is used to keep track of current time and updating it to the internal EEPROM. The same
function is utilized to return time and date values to local variables in different mode specific functions where values
are compared in specific loops and accordingly either alarm time is updated to be matched with current time or timer
value is counted down from the start time onwards or stopwatch date and time value is counted up from the start
time onwards.
In alarm mode user entered time is compared to match the current time and a LOW signal is output at pin 6 for
activating the buzzer. In timer mode, current time is compared to start time for counting down and as the counter
variable matches zero value, a LOW signal is passed to buzzer circuit. In stopwatch mode current time is compared
to start time and a counter variable is updated in ascending order and accordingly real-time values are displayed to
the LCD screen.
The detection of LOW signals from keypad switches in a pre-defined pattern controls activation, setting and resetting
of user entered time and date values, pausing or resuming and terminating the current mode. The alarm, timer and
stopwatch modes on termination resumes to the default mode.
This Code is only visible to Registered users. Please Login/Register
Add New Comment
//Program to
#include <dht.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include<EEPROM.h>
#include <RTClib.h>
LiquidCrystal lcd(13, 12, 6, 5, 4, 3);
RTC_DS1307 RTC;
int temp,inc,hours1,minut,add=11,temp1=3,mode=0;
int tSeconds=0, tMinutes=0, hours=0; //this line, along with another line in void
timerFunction(), is where you can adjust the amount of time that is counted down in
//the timer function
int centiseconds=0, sSeconds=0, sMinutes=0;
int next=A0;
int INC=A1;
int set_mad=A2;
int shw_dat=A3;
int buzzer=11;
int HOUR,MINUT,SECOND=0;
dht DHT;
#define DHT11_PIN 10
void setup(){
Wire.begin();
RTC.begin();
lcd.begin(16,2);
pinMode(INC, INPUT);
pinMode(next, INPUT);
pinMode(set_mad, INPUT);
pinMode(shw_dat, INPUT);
pinMode(buzzer, OUTPUT);
digitalWrite(next, HIGH);
digitalWrite(set_mad, HIGH);
digitalWrite(INC, HIGH);
digitalWrite(shw_dat, HIGH);
lcd.setCursor(0,0);
lcd.print("Real Time Clock");
lcd.setCursor(0,1);
lcd.print("Engineers Garage");
delay(3000);
if(!RTC.isrunning())
{
RTC.adjust(DateTime(__DATE__,__TIME__));
}
}
void loop()
{
int temp=0,val=1,temp4;
DateTime now = RTC.now();
int chk = DHT.read11(DHT11_PIN);
if(digitalRead(shw_dat) == 0)
{mode++;}
while(1)
{
if(digitalRead(set_mad) == 0)
{
stopwatchFunction();
}
if(digitalRead(INC) == 0)
break;
}
}
if(mode>=5)
{mode=0;}
lcd.clear();
lcd.setCursor(0,0);
lcd.print(HOUR=now.hour(),DEC);
lcd.print(":");
lcd.print(MINUT=now.minute(),DEC);
lcd.print(":");
lcd.print(SECOND=now.second(),DEC);
lcd.setCursor(0,1);
lcd.print(now.day(),DEC);
lcd.print("/");
lcd.print(now.month(),DEC);
lcd.print("/");
lcd.print(now.year(),DEC);
lcd.setCursor(9,0);
lcd.print("H:");
lcd.print(DHT.humidity);
lcd.setCursor(15,0);
lcd.print("%");
lcd.setCursor(11,1);
lcd.print("T:");
lcd.print(DHT.temperature);
lcd.print((char)223);
lcd.setCursor(15,1);
lcd.print("C");
delay(1000);
}
/*Function to set alarm time and feed time into Internal eeprom*/
void time()
{
int temp=1,minuts=0,hours=0,seconds=0;
while(temp==1)
{
if(digitalRead(INC)==0)
{
HOUR++;
if(HOUR==24)
{
HOUR=0;
}
while(digitalRead(INC)==0);
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Set Alarm Time ");
//lcd.print(x);
lcd.setCursor(0,1);
lcd.print(HOUR);
lcd.print(":");
lcd.print(MINUT);
lcd.print(":");
lcd.print(SECOND);
delay(100);
if(digitalRead(next)==0)
{
hours1=HOUR;
EEPROM.write(add++,hours1);
temp=2;
while(digitalRead(next)==0);
}
}
while(temp==2)
{
if(digitalRead(INC)==0)
{
MINUT++;
if(MINUT==60)
{MINUT=0;}
while(digitalRead(INC)==0);
}
// lcd.clear();
lcd.setCursor(0,1);
lcd.print(HOUR);
lcd.print(":");
lcd.print(MINUT);
lcd.print(":");
lcd.print(SECOND);
delay(100);
if(digitalRead(next)==0)
{
minut=MINUT;
EEPROM.write(add++, minut);
temp=0;
while(digitalRead(next)==0);
}
}
delay(1000);
}
/* Function to chack medication time */
void CheckTime()
{
int tem[17];
while(1)
{
DateTime now = RTC.now();
lcd.setCursor(0,1);
lcd.print(HOUR=now.hour(),DEC);
lcd.print(":");
lcd.print(MINUT=now.minute(),DEC);
lcd.print(":");
lcd.print(SECOND=now.second(),DEC);
for(int i=11;i<17;i++)
{
tem[i]=EEPROM.read(i);
}
if(HOUR == tem[11] && MINUT == tem[12])
{
for(int j=0;j<5;j++)
{
digitalWrite(buzzer, HIGH);
delay(500);
digitalWrite(buzzer, LOW);
delay(500);
}
hours1=0;
minut=0;
add=11;
return;
}
}
}
void timerFunction() //the timer function was made with the help of this post:
http://pastebin.com/f57045830
{
int set=0;
lcd.setCursor(4,1);
//lcd.setCursor(0, 1);
lcd.print("00:00:00");
while(1)
{
while(digitalRead(shw_dat)==1)
{
set=1;
if(digitalRead(set_mad)==0) //if "Start/Stop" is pressed, the
timer counts down
{
tSeconds++;
lcdOutput();
delay(300);
if(tSeconds==60)
{
tMinutes++;
tSeconds=0;
}
}
if(digitalRead(INC)==0) //if "Start/Stop" is pressed, the timer
counts down
{
tMinutes++;
lcdOutput();
delay(300);
if(tMinutes==60)
{
hours++;
tMinutes=0;
}
}
if(digitalRead(next)==0 ) //if "Start/Stop" is pressed, the timer
counts down
{
hours++;
lcdOutput();
delay(300);
if(hours==24)
{
hours=0;
}
} }
if(digitalRead(shw_dat)==0 && set==1)
{
lcd.clear();
lcd.setCursor(0,0);
//lcd.setCursor(0, 1);
lcd.print(" TIMER SET FOR ");
lcd.setCursor(4,1);
//lcd.setCursor(0, 1);
lcd.print("00:00:00");
while(digitalRead(INC)==1)
{
static unsigned long lastTick = 0;
if (tSeconds > 0)
{
if (millis() - lastTick >= 1000)
{
lastTick = millis();
tSeconds--;
lcdOutput();
}
}
if (tMinutes > 0)
{
if (tSeconds <= 0)
{
tMinutes--;
tSeconds = 60;
}
}
if (hours > 0)
{
if (tMinutes <= 0)
{
hours--;
tMinutes = 60;
}
}
void lcdOutput() //this is just used to display the timer on the LCD
{
lcd.setCursor(4, 1);
printDigits(hours);
lcd.setCursor(7, 1);
printDigits(tMinutes);
lcd.setCursor(10, 1);
printDigits(tSeconds);
delay(100);
}
void printDigits(int digits) //this void function is really useful; it adds a "0"
to the beginning of the number, so that 5 minutes is displayed as "00:05:00", rather
than "00:5 :00"
{
if(digits < 10)
{
lcd.print("0");
lcd.print(digits);
}
else
{
lcd.print(digits);
}
}
void stopwatchFunction()
{
int count=1,sMin,sSec,sCen;
lcd.setCursor(4,1);
//lcd.setCursor(0, 1);
lcd.print("00:00:00");
while(1)
{
if(digitalRead(shw_dat) == LOW )
{
count=0;
loop();
}
if(digitalRead(next) == LOW) //if the "Start/Stop" button is pressed, the time
begins running
{
while(1)
{
int count=1;
delay(6);
lcd.setCursor(4, 1);
printDigits(sMinutes);
lcd.setCursor(7, 1);
printDigits(sSeconds);
lcd.setCursor(10, 1);
printDigits(centiseconds);
centiseconds++;
sCen=centiseconds;
if(centiseconds==100)
{
sSeconds++;
sSec=sSeconds;
centiseconds=0;
if(sSeconds==60)
{
sMinutes++;
sMin=sMinutes;
sSeconds=0;
}
}
if(digitalRead(set_mad) == 0)
{
centiseconds = 0;
sSeconds = 0;
sMinutes = 0;
break;
}
if(digitalRead(INC) == LOW && count ==1)
{
while(1)
{
lcd.setCursor(4, 1);
printDigits(sMinutes);
lcd.setCursor(7, 1);
printDigits(sSeconds);
lcd.setCursor(10, 1);
printDigits(centiseconds);
if(digitalRead(set_mad) == 0)
{
count=2;
centiseconds = 0;
sSeconds = 0;
sMinutes = 0;
break;
}
}
}
}
}