Arduino nano with relay and timealarms library

Hello everyone

as i asked in another thread for dimming a meanwell driver, i’m trying to make the lights for my acquariom automated and nice;
i made the whole idea and making much smaller problem and then implement everything in just one program with everything connected (Should be easier this way for me)
so now:
i figured how etc about time and timealarms library (Thank you PaulStoffregen!) and i tried connecting everything to a 12v fan just for checking if it works fine so i made a code to just turn on and off a couple time and it works
the problem is that i already tried to maybe find some problem and there is: if occured a power loss at the time that arduino should turn on or off the relay it just doesn’t work…

And now i’d like to not have this problem
I’d like to solve this problem by software so that i dont have to buy anything else (I like being cheap :smiley: )

So one solution could be the arduino and relay should be powered by a battery that constanly charge and last at least a day i’d say no?

or another could be like checking the time every like idk 5-10 minutes to see if the pin connected to the relay is on or off according to the time and code?
I tried searching but probably im not searching the right keyword?

sorry if something is hard to understand, english is not my first language thank you all

if maybe it is helping here the code that i used just to check if i have my mind in the right direction with relay and time alarms library

#include <TimeLib.h>
#include <Wire.h>
#include <DS1307RTC.h>
#include <TimeAlarms.h>

void setup() {
  Serial.begin(9600);
  setSyncProvider(RTC.get);   //get time from the RTC
  if(timeStatus()!= timeSet) 
     Serial.print("Cant sync w RTC");
  else
     Serial.print("RTC has set time");
     Alarm.delay(100);

  pinMode(10, OUTPUT); //Relay1 at pinD10
  pinMode(11, OUTPUT); //Relay1 at pinD11
  digitalWrite(10, HIGH); //Turn off at startup/reset
  digitalWrite(11, HIGH); //Turn off at startup/reset

  Alarm.alarmRepeat(15,35,0, TurnOnRelay);
  Alarm.alarmRepeat(15,45,0, TurnOffRelay);
  Alarm.alarmRepeat(15,55,0, TurnOnRelay);
  Alarm.alarmRepeat(16,05,0, TurnOffRelay);
  
}

void loop() {
  digitalClockDisplay();
  Alarm.delay(1000);
 //just testing
}

void TurnOnRelay() {
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  Serial.println("Relay LOW-On");
  Serial.println();
}
void TurnOffRelay() {
  digitalWrite(10, HIGH);
  digitalWrite(11, HIGH);
  Serial.println("Relay HIGH-Off");
  Serial.println();
}

void digitalClockDisplay() {
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println();
}
void printDigits(int digits) {
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

So one solution could be the arduino and relay should be powered by a battery that constanly charge and last at least a day i'd say no?

With the right size battery, you'd be wrong.

What does the code actually do? How does that differ from what you want.

english is not my first language

Then you should NOT be trying to stick text-speak crap in your post. Spell out all words. idk has no place in your post.

johnnykol: or another could be like checking the time every like idk 5-10 minutes to see if the pin connected to the relay is on or off according to the time and code?

It does not hurt to turn a pin ON if it is already ON or OFF if it is already OFF. Rather than using alarms tu turn relays ON once or OFF once, each time through loop() just set the pins the way they should be for the current time. When power comes back the relays will be set as appropriate very quickly. I have a sketch that will do sunrise/sunset dimming of multiple sets of lights, if that might provide a useful example.

PaulS: With the right size battery, you'd be wrong.

What does the code actually do? How does that differ from what you want. Then you should NOT be trying to stick text-speak crap in your post. Spell out all words. idk has no place in your post.

I dont think i understand about the battery, if both were connected to some kind of "ups" or like 2x 18650 there should be enough power for both for quite some time i think

sorry for the abbreviation, my bad i mean that if arduino have to set pin HIGH or LOW but in that precise time, it is not powered, the change doesnt occur when the arduino has power again but only when there will be the next alarm. i want the pins follow my instructions as soon there is power again not only at the next alarm thank you

johnwasser: It does not hurt to turn a pin ON if it is already ON or OFF if it is already OFF. Rather than using alarms tu turn relays ON once or OFF once, each time through loop() just set the pins the way they should be for the current time. When power comes back the relays will be set as appropriate very quickly. I have a sketch that will do sunrise/sunset dimming of multiple sets of lights, if that might provide a useful example.

Hello so you dont think i need to use the time alarms library but just a simple code to check time every loop, like 1 second from a delay(1000) and nothing more? if you can post your code please do, for sure it's gonna be useful for me, thank you!

Most of the magic is in the ‘brightness()’ function. It takes as arguments the current time (seconds since midnight), the time at which the LED starts its fade in, and the time the LED starts its fade out. All fades take two hours and go between off and 3/4 full. This could be changed to take a list of fade start and end times and brightnesses for each to allow any pattern you might like. For On/Off channels (like relays) a separate function could take a list of on times and off times.

#include "Wire.h"
#define DS1307_ADDRESS 0x68  // This is the I2C address


const int Blue1Pin = 3;
const int Blue2Pin = 5;
const int White3Pin = 6;
const int White4Pin = 9;


const unsigned long HOUR = 60 * 60;
const unsigned long MINUTE = 60;


const int TARGET_BRIGHTNESS = (255 * 3) / 4;  // Target brightness is 3/4 of full


void setup() {
  Wire.begin();
}


byte bcdToDec(byte val)  {
  // Convert binary coded decimal to normal decimal numbers
  return ( (val / 16 * 10) + (val % 16) );
}


void loop() {
  /////  Get time from RTC into RTCHour, RTCMinute, RTCSecond


  // Set the register pointer to 0 (Second)
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write((byte)0);
  Wire.endTransmission();


  //  Read Second, Minute, and Hour
  Wire.requestFrom(DS1307_ADDRESS, 3);


  int RTCSecond = bcdToDec(Wire.read());
  int RTCMinute = bcdToDec(Wire.read());
  int RTCHour = bcdToDec(Wire.read() & 0b111111); //24 hour time


  unsigned long time = RTCHour * HOUR + RTCMinute * MINUTE + RTCSecond;  // Time in seconds


  analogWrite(Blue1Pin,   brightness(time, 7 * HOUR,                 17 * HOUR));
  analogWrite(Blue2Pin,   brightness(time, 7 * HOUR + 30 * MINUTE,   16 * HOUR + 30 * MINUTE));
  analogWrite(White3Pin,  brightness(time, 8 * HOUR,                 15 * HOUR));
  analogWrite(White4Pin,  brightness(time, 9 * HOUR,                 14 * HOUR));


  delay(1000);
}


// Calculate brightness based on a 2 hour fade-up period starting at
// a specified time in the morning and a 2 hour fade-down period
// starting at a specified time in the evening.
byte brightness(unsigned long time, unsigned long fadeUpStart,
                unsigned long fadeDownStart) {
  //  Mid day, light is at maximum brightness
  if (time >= fadeUpStart + 2 * HOUR  && time <= fadeDownStart)
    return TARGET_BRIGHTNESS;


  // Dawn:  fade up the light
  if (time >= fadeUpStart && time <= fadeUpStart + 2 * HOUR) // Fading up
  {
    unsigned long seconds = time - fadeUpStart;  // Number of seconds into the fade time
    return TARGET_BRIGHTNESS * seconds / (HOUR * 2); // Fade up based on portion of interval completed.
  }


  // Evening: Fade down the light
  if (time >= fadeDownStart && time <= fadeDownStart + 2 * HOUR) // Fading down
  {
    unsigned long seconds = (fadeDownStart + (HOUR * 2)) - time; // Number of seconds remaining in the fade time
    return TARGET_BRIGHTNESS * seconds / (HOUR * 2); // Fade down based on portion of interval left.
  }


  // The remaining times are night and the lights is off
  return 0;
}

Thank you johnwasser

that code helped me seeing what i want to do more or less, at the end my code should be a really simpler code like this

#include <TimeLib.h>
#include <Wire.h>
#include <DS1307RTC.h>


unsigned long OnTime = 7;
unsigned long OffTime = 19;



void setup() {
  Serial.begin(9600);
  setSyncProvider(RTC.get);   //get time from the RTC
  if(timeStatus()!= timeSet) 
     Serial.print("Cant sync w RTC");
  else
     Serial.print("RTC has set time");
     delay(100);

  pinMode(6, OUTPUT);//PWM arduino nano for dimming driver
  pinMode(9, OUTPUT);//PWM arduino nano for dimming driver
  pinMode(10, OUTPUT); //Relay1 at pinD10
  pinMode(11, OUTPUT); //Relay2 at pinD11
  digitalWrite(10, HIGH); //Turn off at startup/reset
  digitalWrite(11, HIGH); //Turn off at startup/reset
}
void loop() {

  CheckTime();
  delay(50);
  SetRelay();
  delay(950);
}
void CheckTime() {
  setSyncProvider(RTC.get);   //get time from the RTC
  if(timeStatus()!= timeSet) 
     Serial.print("Cant sync w RTC");
  else
     Serial.print("RTC has set time");
     /*Alarm.*/delay(100);
}

void SetRelay(){
  if ( hour() >= OnTime && hour() <= OffTime) {
    digitalWrite(10, HIGH);
  }
    else {
      digitalWrite(10, LOW);
    }
  }

so if in next phase i’d like to dim those driver could i do this?

void SetDimOn() {
  if ( hour() == OnTime && minute() >= 0 && minute() <= 30) {
    analogWrite(6, 200);
    analogWrite(9, 200);
    }
   }
   
void SetDimOff() {
  if ( hour() == OffTime - 1 && minute() >= 30 && minute() <= 59) {
    analogWrite(6, 200);
    analogWrite(9, 200);
    }
   }

This example should dim for 30 minutes when it start and 30 minutes before ending, right?

I just want know if i interpreted this correctly;
The relay stays always on also during dimming.
so that in the loop i call

SetDimOn();
SetDimOff();
and add a short delay(50);
and then SetRelay();

right?

Thank you

void SetDimOn() {
  if ( hour() == OnTime && minute() >= 0 && minute() <= 30) {
    analogWrite(6, 200);
    analogWrite(9, 200);
    }
   }

That won’t do any dimming because you only set the brightness to 200. To do dimming you have to calculate the current brightness based on the position between the start and end of the fade cycle. If you don’t include seconds in that calculation it will only adjust the brightness once per minute. To get a smoother transition I recommend you convert the hour(), minute(), and second() time into “seconds since midnight” and use that to calculate the desired brightness.

johnwasser:

void SetDimOn() {

if ( hour() == OnTime && minute() >= 0 && minute() <= 30) {
    analogWrite(6, 200);
    analogWrite(9, 200);
    }
  }



That won't do any dimming because you only set the brightness to 200. To do dimming you have to calculate the current brightness based on the position between the start and end of the fade cycle. If you don't include seconds in that calculation it will only adjust the brightness once per minute. To get a smoother transition I recommend you convert the hour(), minute(), and second() time into "seconds since midnight" and use that to calculate the desired brightness.

i think i’m a bit lost in here
the driver i’m using has 2 pins for the leds and 2 other pins for the dimming function, and when there is nothing in the 2 pins for dimming it goes 100% power
so i need to have some kind of output from arduino that goes into dimming pins of the driver only for example 30 minutes at starting and ending of the day for the acquarium. (Alsoo 200 is just an example i’ll have to try a bit for the correct 0-255 value)

I didnt use your time variables from the code because for me it’s kind of hard to use and explain to myself what is that…
what i thought about my code is that second are not presents because is should not be considered by arduino to set on or off relay or dim driver

if now is 7:12:45 or 7:12:59 or anything else is always true that current time is 7:12 so if this time is in between a SetDimOn or SetDimOff is just true and this result to have a certain analogWrite to that pin that set the driver
or is it just wrong?
Sorry for my long message but i can’t just understand what is wrong
thank you very much again