Not too sure if im approaching this sketch the right way. I know theres many ways to perform a task and im not pretending to be a pro at sketches.
My project is a 24v dc LED bar for my aquarium. Im wanting it to turn on slowly in 30min 5am and turn off slowly at 8am. There is also a bypass switch so i can manually turn the LED bar on. All works ok the way ive programmed it however I have an "IF" id like to resolve.
If bypass is "ON" and 5am to 8am programs arrives, it skips the 5am to 8am program. So when I turn bypass "OFF" the lights remain off, I want them to stay on because it's between 5am and 8am.
Maybe Ive approached the sketch wrong due to my skills. Any one got any ideas, would be much appreaciated. I hope I havent been to vague.
//#include <RTClib.h>
#include <uRTCLib.h>
uRTCLib rtc(0x68);
int PWMpin = 9;
int bypassPin = 4;
int bypass;
int PWMval;
String timerLEDstate;
String bypassLEDstate;
//*********************************************
int brightness = 120;
int bypass_in_out_delay = 10;
int morning_fade_in_hr = 5;
int morning_fade_in_minute = 00;
int morning_OFF_hr = 8;
int morning_OFF_minute = 00;
int night_fade_in_hr = 16;
int night_fade_in_minute = 30;
int night_OFF_hr = 20;
int night_OFF_minute = 00;
int timeSecondMin = 0;
int timeSecondMax = 1;
//**********************************************
void runLEDfadeIn()
{
analogWrite(PWMpin, 1);
for (int x = 600; x >= 0; x--)
{
delay(1000);
Serial.println(x);
}
for ( PWMval = 2; PWMval <= brightness; PWMval++)
{
analogWrite(PWMpin, PWMval);
delay((1200/brightness*1000)); //20min(1200seconds) / brightness *1000 milliseconds
Serial.println(PWMval);
}
analogWrite(PWMpin, brightness);
bypassLEDstate = "off";
timerLEDstate = "on";
}
//**********************************************
void runLEDfadeout()
{
bypassLEDstate = "off";
for ( PWMval = brightness; PWMval >= 0; PWMval--)
{
analogWrite(PWMpin, PWMval);
delay(bypass_in_out_delay);
}
digitalWrite(PWMpin, LOW);
timerLEDstate = "off";
}
//**********************************************
void Check_morning_times()
{
if ((rtc.hour() == morning_fade_in_hr) &&
(rtc.minute() == morning_fade_in_minute) &&
(rtc.second() >= timeSecondMin) &&
(rtc.second() <= timeSecondMax) &&
(bypassLEDstate == "off") && (timerLEDstate == "off"))
{
runLEDfadeIn();
}
// if ((rtc.now() >= morning_fade_in_hr))
{
}
if ((rtc.hour() == morning_OFF_hr) &&
(rtc.minute() == morning_OFF_minute) &&
(rtc.second() >= timeSecondMin) &&
(rtc.second() <= timeSecondMax) &&
(bypassLEDstate == "off"))
{
runLEDfadeout();
}
}
//**********************************************
void Check_evening_times()
{
if ((rtc.hour() == night_fade_in_hr) &&
(rtc.minute() == night_fade_in_minute) &&
(rtc.second() >= timeSecondMin) &&
(rtc.second() <= timeSecondMax) &&
(bypassLEDstate == "off") && (timerLEDstate == "off"))
{
for ( PWMval = 0; PWMval <= brightness; PWMval++)
{
analogWrite(PWMpin, PWMval);
delay(bypass_in_out_delay);
Serial.println(PWMval);
}
timerLEDstate = "on";
}
if ((rtc.hour() == night_OFF_hr) &&
(rtc.minute() == night_OFF_minute) &&
(rtc.second() >= timeSecondMin) &&
(rtc.second() <= timeSecondMax) &&
(bypassLEDstate == "off"))
{
runLEDfadeout();
}
}
//**********************************************
void Check_bypass()
{
if (timerLEDstate == "off")
{
bypass = digitalRead(bypassPin);
if ((bypass == HIGH) && (bypassLEDstate == "off"))
{
for ( PWMval = 0; PWMval <= brightness; PWMval++)
{
analogWrite(PWMpin, PWMval);
delay(bypass_in_out_delay);
Serial.println(PWMval);
}
bypassLEDstate = "on";
}
if ((bypass == LOW) && (bypassLEDstate == "on"))
{
for ( PWMval = brightness; PWMval >= 0; PWMval--)
{
analogWrite(PWMpin, PWMval);
delay(bypass_in_out_delay);
Serial.println(PWMval);
}
bypassLEDstate = "off";
}
}
else
{
// do nothing
}
}
//**********************************************
void serial_print_time()
{
Serial.println();
Serial.print(rtc.hour());
Serial.print(':');
if (rtc.minute() <10)
Serial.print("0");
Serial.print(rtc.minute());
Serial.print(':');
if (rtc.second() <10)
Serial.print("0");
Serial.print(rtc.second());
Serial.println();
Serial.print("timer LED state: ");Serial.print(timerLEDstate);
Serial.println();
Serial.print("bypass LED state: ");Serial.print(bypassLEDstate);
Serial.println();
delay(1000);
}
//**********************************************
void setup()
{
Serial.begin(9600);
URTCLIB_WIRE.begin();
pinMode(PWMpin, OUTPUT);
pinMode(bypass, INPUT);
digitalWrite(PWMpin, LOW);
timerLEDstate = "off";
bypassLEDstate = "off";
// (Seconds,Minute,Hour,Weekday,Date,Month,Year);
// rtc.set(00, 29, 19, 3, 10,9,24);
}
void loop()
{
rtc.refresh();
Check_morning_times();
Check_evening_times();
Check_bypass();
serial_print_time();
}
b707
September 12, 2024, 9:55am
3
Your whole code written in blocking mode - once the program start the fade process - it became blind to any changes of clock and pin state for 20 minutes.
You need to complete rebuild your code to get rid all delays and blocking loops, Use a state machine code instead.
Yep agreed. My code sux and is all wrong.
Ok, so Ive made some progression. There are still a few for loops but that not an issue as they dont take long. Im still trying to work out how to know if current time is between 2 given times. I need to know this becuase if I update the code or if the power goes out, the LED bar will remain off, if current time is within a program time,
new code posted below. All help is greatly appreciated.
#include <uRTCLib.h>
uRTCLib rtc(0x68);
int PWMpin = 9;
int bypassPin = 4;
int bypass;
int PWMval;
int currentBri;
int nextbri;
String T1Mode;
String T2Mode;
String T3Mode;
String T4Mode;
String T5Mode;
String T6Mode;
String T7Mode;
String T8Mode;
String T9Mode;
String bypassLEDstate;
unsigned long now_millis_snapshot;
//*********************************************
int brightness = 100; // global brightness
int fade_in_out_delay = 20;
int timeSecondMin = 0;
int timeSecondMax = 1;
//**********************************************
// MORNING PROGRAM
// sunrise
// 4:30 - 5:00 (.5hrs)
int T1hr = 4;
int T1min = 30;
int T1bri = 1;
unsigned long T1time = .5 * 3600000;
// sunsine
// 5:00 - 7:00 (2hrs)
int T2hr = 5;
int T2min = 00;
int T2bri = brightness / 2;
unsigned long T2time = 2 * 3600000;
// fade out
// 7:00 - 16:00 8Hrs
int T3hr = 7;
int T3min = 00;
int T3bri = 0;
int T3time = 0;
//********************************************** // break 8hrs
// EVENING PROGRAM
// afternoon
// 16:00 - 18:00 (2hrs)
int T4hr = 16;
int T4min = 00;
int T4bri = brightness;
unsigned long T4time = 2 * 3600000;
// sunset
// 18:00 - 19:00 (1hrs)
int T5hr = 18;
int T5min = 00;
int T5bri = brightness;
unsigned long T5time = 1 * 3600000;
// 19:00 - 20:00 (1hr)
int T6hr = 19;
int T6min = 00;
int T6bri = brightness / 2;
//**********************************************
// NIGHT TIME PROGRAM
// moonlight
// 20:00 - 20:30 (30min)
int T7hr = 20;
int T7min = 00;
int T7bri = 1;
unsigned long T7time = .5 * 3600000;
// moonlight
// 20:30 - 22:00 30min
int T8hr = 20;
int T8min = 30;
int T8bri = 0;
unsigned long T8time = .5 * 3600000; // 30min
// blackout
// 22:00 - 4:30am
int T9hr = 22;
int T9min = 00;
int T9bri = 0;
//**********************************************
void between_brightness_fade_up()
{
for ( PWMval = currentBri; PWMval <= nextbri; PWMval++)
{
analogWrite(PWMpin, PWMval);
delay(fade_in_out_delay);
}
}
//**********************************************
void between_brightness_fade_down()
{
for ( PWMval = currentBri; PWMval >= nextbri; PWMval--)
{
analogWrite(PWMpin, PWMval);
delay(fade_in_out_delay);
}
}
//**********************************************
void check_morning_program()
{
if ((rtc.hour() == T1hr) &&
(rtc.minute() == T1min) &&
(rtc.second() >= timeSecondMin) &&
(rtc.second() <= timeSecondMax) ||
(T1Mode == "on"))
{
T8Mode = "off";
T1Mode = "on";
currentBri = T1bri; // for serial identification
static unsigned long T1 = millis();
if (bypassLEDstate == "off")
{
if (millis() - T1 < T1time)
{
currentBri = T1bri; //serial print current brightness
analogWrite(PWMpin,T1bri);
}
}
}
if ((rtc.hour() == T2hr) &&
(rtc.minute() == T2min) &&
(rtc.second() >= timeSecondMin) &&
(rtc.second() <= timeSecondMax) ||
(T2Mode == "on"))
{
T1Mode = "off";
T2Mode = "on";
if (bypassLEDstate == "off")
{
nextbri = T2bri;
between_brightness_fade_up();
currentBri = T2bri;
static unsigned long T2 = millis();
if (millis() - T2 < T2time)
{
currentBri = T2bri;
analogWrite(PWMpin,T2bri);
}
}
currentBri = T2bri;
}
if ((rtc.hour() == T3hr) &&
(rtc.minute() == T3min) &&
(rtc.second() >= timeSecondMin) &&
(rtc.second() <= timeSecondMax))
{
T2Mode = "off";
T3Mode = "on";
if (bypassLEDstate == "off")
{
nextbri = T3bri;
//dim down
for ( PWMval = currentBri; PWMval >= T3bri; PWMval--)
{
analogWrite(PWMpin, PWMval);
delay(fade_in_out_delay);
}
}
currentBri = T3bri;
}
}
//**********************************************
void check_evening_program()
{
if ((rtc.hour() == T4hr) &&
(rtc.minute() == T4min) &&
(rtc.second() >= timeSecondMin) &&
(rtc.second() <= timeSecondMax) ||
(T4Mode == "on"))
{
T3Mode = "off";
T4Mode = "on";
if (bypassLEDstate == "off")
{
nextbri = T4bri;
between_brightness_fade_up();
currentBri = T4bri;
static unsigned long T4 = millis();
if (millis() - T4 < T4time)
{
currentBri = T4bri;
analogWrite(PWMpin,T4bri);
}
}
currentBri = T4bri;
}
if ((rtc.hour() == T5hr) &&
(rtc.minute() == T5min) &&
(rtc.second() >= timeSecondMin) &&
(rtc.second() <= timeSecondMax) ||
(T5Mode == "on"))
{
T4Mode = "off";
T5Mode = "on";
if (bypassLEDstate == "off")
{
nextbri = T5bri;
between_brightness_fade_down();
currentBri = T5bri;
static unsigned long T5 = millis();
if (millis() - T5 < T5time)
{
currentBri = T5bri;
analogWrite(PWMpin,T5bri);
}
}
currentBri = T5bri;
}
if ((rtc.hour() == T6hr) &&
(rtc.minute() == T6min) &&
(rtc.second() >= timeSecondMin) &&
(rtc.second() <= timeSecondMax))
{
T5Mode = "off";
T6Mode = "on";
if (bypassLEDstate == "off")
{
nextbri = T6bri;
//dim down
for ( PWMval = currentBri; PWMval >= T6bri; PWMval--)
{
analogWrite(PWMpin, PWMval);
delay(fade_in_out_delay);
}
}
currentBri = T6bri;
}
}
//**********************************************
void check_night_time_program()
{
if ((rtc.hour() == T7hr) &&
(rtc.minute() == T7min) &&
(rtc.second() >= timeSecondMin) &&
(rtc.second() <= timeSecondMax) ||
(T7Mode == "on"))
{
T6Mode = "off";
T7Mode = "on";
currentBri = T7bri; // for serial identification
static unsigned long T7 = millis();
if (bypassLEDstate == "off")
{
if (millis() - T7 < T7time)
{
currentBri = T7bri; //serial print current brightness
analogWrite(PWMpin,T7bri);
}
}
}
if ((rtc.hour() == T8hr) &&
(rtc.minute() == T8min) &&
(rtc.second() >= timeSecondMin) &&
(rtc.second() <= timeSecondMax) ||
(T8Mode == "on"))
{
T7Mode = "off";
T8Mode = "on";
if (bypassLEDstate == "off")
{
nextbri = T8bri;
between_brightness_fade_up();
currentBri = T8bri;
static unsigned long T8 = millis();
if (millis() - T8 < T8time)
{
currentBri = T8bri;
analogWrite(PWMpin,T8bri);
}
}
currentBri = T8bri;
}
if ((rtc.hour() == T9hr) &&
(rtc.minute() == T9min) &&
(rtc.second() >= timeSecondMin) &&
(rtc.second() <= timeSecondMax))
{
T8Mode = "off";
T9Mode = "on";
if (bypassLEDstate == "off")
{
nextbri = T9bri;
//dim down
for ( PWMval = currentBri; PWMval >= T9bri; PWMval--)
{
analogWrite(PWMpin, PWMval);
delay(fade_in_out_delay);
}
}
currentBri = T9bri;
}
}
//**********************************************
void check_bypass()
{
bypass = digitalRead(bypassPin);
if ((bypass == HIGH) && (bypassLEDstate == "off"))
{
for ( PWMval = currentBri; PWMval <= brightness; PWMval++)
{
analogWrite(PWMpin, PWMval);
delay(fade_in_out_delay);
}
bypassLEDstate = "on";
}
if ((bypass == LOW) && (bypassLEDstate == "on"))
{
for ( PWMval = brightness; PWMval >= currentBri; PWMval--)
{
analogWrite(PWMpin, PWMval);
delay(fade_in_out_delay);
}
bypassLEDstate = "off";
}
}
//**********************************************
void serial_print_time()
{
Serial.println();
Serial.print(rtc.hour());
Serial.print(':');
if (rtc.minute() <10)
Serial.print("0");
Serial.print(rtc.minute());
Serial.print(':');
if (rtc.second() <10)
Serial.print("0");
Serial.print(rtc.second());
Serial.println();
Serial.print("bypass LED state: ");Serial.print(bypassLEDstate);
Serial.println();
Serial.print("Current Timer Brightness: ");Serial.print(currentBri);
Serial.println();
Serial.print("T1Mode: ");Serial.print(T1Mode);Serial.print(" ");
Serial.print(T1hr);Serial.print(":");Serial.print(T1min);Serial.print(" - ");
Serial.print(T2hr);Serial.print(":");Serial.print(T2min);
Serial.println();
Serial.print("T2Mode: ");Serial.print(T2Mode);Serial.print(" ");
Serial.print(T2hr);Serial.print(":");Serial.print(T2min);Serial.print(" - ");
Serial.print(T3hr);Serial.print(":");Serial.print(T3min);
Serial.println();
Serial.print("T3Mode: ");Serial.print(T3Mode);Serial.print(" ");
Serial.print(T3hr);Serial.print(":");Serial.print(T3min);Serial.print(" - ");
Serial.print(T4hr);Serial.print(":");Serial.print(T4min);
Serial.println();
Serial.print("T4Mode: ");Serial.print(T4Mode);Serial.print(" ");
Serial.print(T4hr);Serial.print(":");Serial.print(T4min);Serial.print(" - ");
Serial.print(T5hr);Serial.print(":");Serial.print(T5min);
Serial.println();
Serial.print("T5Mode: ");Serial.print(T5Mode);Serial.print(" ");
Serial.print(T5hr);Serial.print(":");Serial.print(T5min);Serial.print(" - ");
Serial.print(T6hr);Serial.print(":");Serial.print(T6min);
Serial.println();
Serial.print("T6Mode: ");Serial.print(T6Mode);Serial.print(" ");
Serial.print(T6hr);Serial.print(":");Serial.print(T6min);Serial.print(" - ");
Serial.print(T7hr);Serial.print(":");Serial.print(T7min);
Serial.println();
Serial.print("T7Mode: ");Serial.print(T7Mode);Serial.print(" ");
Serial.print(T7hr);Serial.print(":");Serial.print(T7min);Serial.print(" - ");
Serial.print(T8hr);Serial.print(":");Serial.print(T8min);
Serial.println();
Serial.print("T8Mode: ");Serial.print(T8Mode);Serial.print(" ");
Serial.print(T8hr);Serial.print(":");Serial.print(T8min);Serial.print(" - ");
Serial.print(T9hr);Serial.print(":");Serial.print(T9min);
Serial.println();
delay(1000);
}
//**********************************************
void setup()
{
Serial.begin(9600);
URTCLIB_WIRE.begin();
pinMode(PWMpin, OUTPUT);
pinMode(bypass, INPUT);
digitalWrite(PWMpin, LOW);
bypassLEDstate = "off";
T1Mode = "off";
T2Mode = "off";
T3Mode = "off";
T4Mode = "off";
T5Mode = "off";
T6Mode = "off";
T7Mode = "off";
T8Mode = "off";
T9Mode = "off";
// (Seconds,Minute,Hour,Weekday,Date,Month,Year);
// rtc.set(00, 53, 16, 3, 27,9,24);
}
void loop()
{
rtc.refresh();;
check_morning_program();
check_evening_program();
check_night_time_program();
check_bypass();
serial_print_time();
}
alto777
September 27, 2024, 2:19pm
7
If all your times are within the day between midnight and the next midnight, an easy way to go forward is to use "minutes since midnight" as your timing method.
Then anything becomes a simple,e comparison
if time is after the start time and before the stop time
do whatever. turn on the sprinkler say
else
don't do whatever. turn off the sprinkler
So
int startTime = 9 * 60 + 45; // 9:45 AM in minutes
int endTime = 13 * 60 + 15; // 1:15 PM in minutes
and
int timeNow = rtc.hour() * 60 + rtc.Minute(); // sry, use the real rtc functions here
if (startTime <= timeNow && timeNow < endTime) {
difitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
HTH
FWIW I had a lengthy draft, I will review the thread and see if that is still relevant. But minutes since midnight is a way to think about the in between problem. A slight tweak can let it handle intervals that incrude midnight.
a7
thanks a7. I appreciate your input. you may be right too. Ill try get my head around the idea and do some small sketch tests. thank you so much again.
#include <uRTCLib.h>
uRTCLib rtc(0x68);
int PWMpin = 9;
int bypassPin = 4;
int bypass;
int PWMval;
int nextbri;
int currentBri;
int timenow;
String bypassLEDstate;
String T1Mode;
String T2Mode;
String T3Mode;
String T4Mode;
String T5Mode;
String T6Mode;
String T7Mode;
String T8Mode;
String T9Mode;
//*******************************************************************
int brightness = 100; // global brightness
int fade_in_out_delay = 20;
int timeSecondMin = 0;
int timeSecondMax = 1;
//*******************************************************************
// MORNING PROGRAM
// sunrise
// 4:30 - 5:00 (.5hrs)
int T1start = 4 * 60 + 30; // 4:30am
int T1end = 6 * 60 + 38; // 5:00am
int T1bri = 1;
unsigned long T1time = .5 * 3600000; // 30min in millis
// sunsine
// 5:00 - 7:00 (2hrs)
int T2start = 5 * 60; // 5:00am
int T2end = 7 * 60; // 7:00am
int T2bri = brightness / 2;
unsigned long T2time = 2 * 3600000; // 2hrs in millis
// fade out
// 7:00 - 16:00 (8Hrs)
int T3start = 7 * 60; // 7:00am
int T3end = 16 * 60; // 16:00pm
int T3bri = 0;
int T3time = 0;
//*******************************************************************
void between_brightness_fade_up()
{
for ( PWMval = currentBri; PWMval <= nextbri; PWMval++)
{
analogWrite(PWMpin, PWMval);
delay(fade_in_out_delay);
}
}
//*******************************************************************
void between_brightness_fade_down()
{
for ( PWMval = currentBri; PWMval >= nextbri; PWMval--)
{
analogWrite(PWMpin, PWMval);
delay(fade_in_out_delay);
}
}
//*******************************************************************
void check_morning_program()
{
timenow = rtc.hour() * 60 + rtc.minute();
if ((timenow >= T1start ) && (timenow < T1end))
{
T8Mode = "off";
T1Mode = "on";
currentBri = T1bri; // for serial identification
static unsigned long T1 = millis();
if (bypassLEDstate == "off")
{
if (millis() - T1 < T1start)
{
currentBri = T1bri; //serial print current brightness
analogWrite(PWMpin,T1bri);
}
}
}
else
{
T1Mode = "off";
}
}
//*******************************************************************
void check_bypass()
{
bypass = digitalRead(bypassPin);
if ((bypass == LOW) && (bypassLEDstate == "off"))
{
for ( PWMval = currentBri; PWMval <= brightness; PWMval++)
{
analogWrite(PWMpin, PWMval);
delay(fade_in_out_delay);
}
bypassLEDstate = "on";
}
if ((bypass == HIGH) && (bypassLEDstate == "on"))
{
for ( PWMval = brightness; PWMval >= currentBri; PWMval--)
{
analogWrite(PWMpin, PWMval);
delay(fade_in_out_delay);
}
bypassLEDstate = "off";
}
}
//*******************************************************************
void serial_print_time()
{
Serial.println();
Serial.print(rtc.hour());
Serial.print(':');
if (rtc.minute() <10)
Serial.print("0");
Serial.print(rtc.minute());
Serial.print(':');
if (rtc.second() <10)
Serial.print("0");
Serial.print(rtc.second());
Serial.println();
Serial.print("bypass LED state: ");Serial.print(bypassLEDstate);
Serial.println();
Serial.print("Current Timer Brightness: ");Serial.print(currentBri);
Serial.println();
Serial.print("T1Mode: ");Serial.print(T1Mode);
Serial.println();
Serial.print("T1Start : ");Serial.print(T1start);
Serial.println();
Serial.print("minutes since midnight: ");Serial.print(timenow);
Serial.println();
Serial.print("T1End : ");Serial.print(T1end);
Serial.println();
delay(1000);
}
//*******************************************************************
void setup()
{
Serial.begin(9600);
URTCLIB_WIRE.begin();
pinMode(PWMpin, OUTPUT);
pinMode(bypassPin, INPUT_PULLUP);
digitalWrite(PWMpin, LOW);
bypassLEDstate = "off";
T1Mode = "off";
T2Mode = "off";
T3Mode = "off";
T4Mode = "off";
T5Mode = "off";
T6Mode = "off";
T7Mode = "off";
T8Mode = "off";
T9Mode = "off";
// (Seconds,Minute,Hour,Weekday,Date,Month,Year);
// rtc.set(00, 9, 6, 3, 28,9,24);
}
//*******************************************************************
void loop()
{
rtc.refresh();
check_morning_program();
check_bypass();
serial_print_time();
}
alto777
September 27, 2024, 8:46pm
11
Nice.
Now… be sure that the RTC is in 24 hour mode so 13 will be 1 PM and stuff.
And know with confidence that 23 * 60 + 59 is only 1439, so any time in minutes since midnight will be fine in a sixteen bit int integer.
a7
alto777
September 27, 2024, 8:49pm
12
And… one more thing.
The logic from my post would be turning on the LED many many times between starting and stopping.
Turning on an LED that is already is no big deal, but sometimes you might want to not turn on something that was already, or turning something on might involve a once-per-time startup, same same cou,d obtain on the turning the thing off.
In that case, a variabke can be used as a flag that keeps track of the thing, and if it sez it's on doesn't turn it on again.
And sam for off.
It just depends on what the controlled thing is.
a7
very elegant solution A7. thank you so very much. led bar working better than my bought 1 which has a crapola iphone app. mine now soft fades. lovely.
system
Closed
March 26, 2025, 8:59pm
14
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.