I have an Arduino, actually an Adafruit QY PY and a DS1307 RTC and I’m struggling with how to make it do what I want. I have the RTC connected to the Arduno and it works fine – I am able to run the example sketch and print the time to the serial monitor. (Using the RTClib)
What I ultimately want to do is something like this: I would like to, for example flash an LED every 30 minutes between the hours of 10am and 4pm and I can’t figure out how to do this. If I could make the time from the RTC a variable then I would know how do that, but I can’t figure out how so if anyone could point me in the right direction I would be grateful!
Upgrade to a DS3231 and use the alarm feature to generate an interrupt?
Sorry, but that is a good idea followed by a bad one.
You haven't fully explained yourself. Must the flashes be synchronized with the clock time, for example on the half hour? Or just periodically, like a plant waterer?
There is no reason to use any interrupts in either case. But what have you tried so far?
"between hours" is easy logic, like
if (hour >= 10 and hour <= 4) { ...
except that you need to use 24 hour time if you mean 10am and 4pm, so
if (hour >= 10 and hour <= 16) { ...
Again, you say "I'm struggling" so please post your struggle, the entire sketch in code tags please.
Thank you for you reply! The LED flashes every 30 min are actually just a place holder. Eventually the LED will be replaced or augmented with a transistor circuit that will fire a digital camera so the timing does need to be fairly precise. I’m building a camera controller for time-lapse photography for longer term timelapse shooting like growing plants or construction projects.
I understand the “if (hour >= 10 and hour <= 16) { ...” logic but my main struggle is how I get the “hour” from the RTC? I was hoping that I could get the time from the RTC, something like 103530 (hhmmss), store that as an integer and then I’d be able to do something with that. The only thing I currently get from the RTC is this:
DateTime now = rtc.now();
Serial.print(now.hour(), DEC);
Serial.print(now.minute(), DEC);
Serial.print(now.second(), DEC);
This gives me the time on the serial monitor but I don’t know how to “do” anything with this info.
I was hesitant to post a sketch because what I have is basically the example sketches that I tried to modify (unsuccessfully) to be able to do this. I’ll post it anyway, but its embarrassing….
#include <Wire.h>
#include <RTClib.h>
RTC_DS1307 rtc;
unsigned long currentTime;
void setup () {
Serial.begin(57600);
#ifndef ESP8266
while (!Serial); // wait for serial port to connect. Needed for native USB
#endif
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1) delay(10);
}
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
void loop() {
currentTime = rtc.now();
Serial.println("Time: ");
Serial.println(currentTime);
delay(1000);
}
Everything else I've experimented with is similar to this, doesn't work, and is not worth posting.
Are you using ESP8266 based NodeMCU or Arduino UNO?
I appreciate your learning approach -- taking an example and modify it to meet own's specific need.
I'm actually using an Adafruit QT PY module which has an ATSAMD21E18 Cortex M0+ processor. Does that make a difference?
The sketch of your post #4 has some problems; it is not compiled.
The following sketch (tested in UNO) might help you to get the answers of your queries. Note that the Hrs, Min, and Sec are available as unsigned binary in the following variables;
byte myHrs
byte myMin
byte mySec
#include "RTClib.h"
#include<Wire.h>
byte prSec = 0;
RTC_DS1307 rtc; //object is rtc created from UDT RTC_DS1307 defined in the Library
DateTime nowDT; //nowDT object is created from UDT DateTime defined in the Library
void setup ()
{
Serial.begin(115200);
rtc.begin();
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //24-Hrs time from PC
//rtc.adjust(DateTime(2021, 12, 31, 12, 59, 57));
//set date-time manualy:yr,mo,dy,hr,mn,sec
}
void loop ()
{
showTime();
timeDelay();
//1-sec time delay comes fromm DS1307 itself
}
//===================================================
void showTime()
{
nowDT = rtc.now(); //nowDT hold Date and Time
//---------------------------
byte myHrs = nowDT.hour(); //myHour holds Hour of time of daya
Serial.print(myHrs, DEC); //12:58:57 12:4:56
Serial.print(':');
//-------------------------------------------------
byte myMin = nowDT.minute(); //to show leading zero of minute
if (myMin < 10)
{
Serial.print('0');
}
Serial.print(myMin, DEC);
Serial.print(':');
//--------------------------------------------------
byte mySec = nowDT.second();
if (mySec < 10)
{
Serial.print('0');
}
Serial.println(mySec, DEC);//
}
//---------------------------------------------
void timeDelay()
{
prSec = bcdSecond(); //current second of RTC
while (bcdSecond() == prSec) //
{
;
}
prSec = bcdSecond(); //delay(1000);
}
byte bcdSecond()
{
nowDT = rtc.now();
if (nowDT.second() == 0 )
{
return 0;
}
else
{
return nowDT.second();
}
}
Thank you @GolamMostafa , that works beautifully and I appreciate your help with this .
Can you please, post some codes that you are using to get 30-min interval/delay to flash a LED?
Sure, I can do that as soon as I have that working.
The trick is there in my sketch of post #7; hope, you will be able to use that one or your own one.
So here is my current working code with a few changes (for testing purposes). The active time is only from 10:00am to 10:02am (instead of my original 10am - 4pm) and the interval is 10 seconds (instead of 30 minutes).
There are a number of things wrong with it that I can already see:
- If I want to set the interval to 10 seconds I need to enter it as 10 and not 0010. If I go with 0010 the led flashes at and interval of 8 seconds rather than the desired 10 seconds.
- After working fine for the first minute iit stops working after that because the "action_interval2" is 60 whereas the "real time' is 1m or '100' in the sketch. It can't be this way and I need to figure out a better way of doing this.
As you can probably see I'm not very good at programming. I took a single c++ course at university but that was over 20 years ago. So I'm trying to learn as I go.
#include "RTClib.h"
#include<Wire.h>
#define LED 3
byte prSec = 0;
byte myHrs;
byte myMin;
byte mySec;
unsigned int hh;
unsigned int mm;
unsigned int hhmmss;
unsigned int mmss;
unsigned int ON_time = 100000; // 10:00:00 AM - On time hh-mm-ss
unsigned int OFF_time = 100200; // 10:02:00 AM - Off time hh-mm-ss
unsigned int action_interval = 0010; // 00:00:10 - Interval at which the "action" will take place hh-mm-ss
unsigned int action_interval2;
RTC_DS1307 rtc;
DateTime nowDT;
void setup ()
{
Serial.begin(115200);
rtc.begin();
rtc.adjust(DateTime(2021, 12, 31, 9, 59, 50)); //set date-time manualy:yr,mo,dy,hr,mn,sec
pinMode(LED, OUTPUT);
action_interval2 == action_interval;
}
void loop ()
{
build_HHMMSS();
if ((hhmmss >= ON_time) && (hhmmss < OFF_time)) {
if (mmss == action_interval2) {
for (int x = 0; x <= 10; x++) {
digitalWrite(LED, HIGH); // turn the LED on
delay(110);
digitalWrite(LED, LOW); // turn the LED off
delay(110);
}
action_interval2 = action_interval2 + action_interval;
Serial.print("action_interval2: ");
Serial.println(action_interval2);
}
}
timeDelay();
}
//===================================================
//===================================================
//===================================================
//===================================================
//===================================================
void timeDelay()
{
prSec = bcdSecond(); //current second of RTC
while (bcdSecond() == prSec) //
{
;
}
prSec = bcdSecond(); //delay(1000);
}
byte bcdSecond()
{
nowDT = rtc.now();
if (nowDT.second() == 0 )
{
return 0;
}
else
{
return nowDT.second();
}
}
//===================================================
void build_HHMMSS()
{
nowDT = rtc.now();
myHrs = nowDT.hour();
myMin = nowDT.minute();
mySec = nowDT.second();
hh = myHrs * 10000;
mm = myMin * 100;
hhmmss = hh + mm + mySec;
mmss = mm + mySec;
Serial.print("hhmmss: ");
Serial.println(hhmmss);
// Serial.print("mmss: ");
// Serial.println(mmss);
}
//===================================================
I thought that an unsigned int
could only go up to 65535. I hope you're not invoking undefined behavior or anything like that.
You probably want an unsigned long
.
Leading zeros in an integer constant get you octal (base eight). That is why your "0010" is being read as the number eight rather than ten (because 0010 read as a base-eight number equals eight).
There are 3600 seconds in an hour, not 10000.
There are 60 seconds in a minute, not 100.
While you're at it, you might want to change this
unsigned int ON_time = 100000; // 10:00:00 AM
to this
unsigned long ON_time = 36000UL; // 10:00:00 AM
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.