Control 4 relays to turn on for a few seconds a day and then turn off

Hey guys! I found this project on youtube (How to make Time base Automatic Home Appliances Control using RTC | Real Time Clock Project Part:1 - YouTube), it switches 4 relays on and off at the scheduled hour and minute. All this is done by physical buttons and menus displayed on an LCD screen.

Here is the code provided in the video:
(Real_Time_Clock_based_4Load_Control/Real_Time_Clock_based_4Load_Control.ino at main · embeddedlab786/Real_Time_Clock_based_4Load_Control · GitHub)

I would like to use this project to build an automatic dosing pump for my aquarium. But if the pumps are on for a minute they will dump a lot of fertilizer into the aquarium, so I would like to know if it is possible to make the pumps turn on for just a few seconds. Something like that:
Load 1 On: 10:30:40
Load 1 Off: 10:30:45

If anyone knows how to do it, I would be very grateful, I know there is a way, but I still don't have enough knowledge for it :frowning:

Hello Socomofeijao

Welcome to the worldbest forum.

We need some additional information.

Post your sketch, well formated, with well-tempered comments and in so called code tags "< code >" and schematic to see how we can help.

Have a nice day and enjoy coding in C++.

1 Like

Hi, @Socomofeijao
Welcome to the forum.

Is this your first Arduino project?

Can you please tell us your electronics, programming, arduino, hardware experience?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

1 Like

This is the sketch on Proteus:

And thats is the actual code:

#include <DS3231.h>//Memanggil RTC3231 Library
#include <Wire.h>  // i2C Conection Library
#include <LiquidCrystal.h> //Libraries
#include <EEPROM.h>

LiquidCrystal lcd(2, 3, 4, 5, 6, 7); //Arduino pins to lcd

#define bt_clock  A0
#define bt_up     A1
#define bt_down   A2
#define bt_timer  A3

#define relay1 8
#define relay2 9
#define relay3 10
#define relay4 11

#define buzzer 13

// Init DS3231
DS3231  rtc(SDA, SCL);

// Init a Time-data structure
Time  t; //pencacah string time()

int hh = 0, mm = 0, ss = 0, dd = 0, bb = 0, set_day;
int yy = 0;
String Day = "  ";

int StartHH  = 0, StartMM  = 0, FinishHH  = 0, FinishMM  = 0, StartSS = 0, FinishSS = 0 setMode = 0, setAlarm = 0, alarmMode=1;
int Start1HH, Start1MM, Finish1HH, Finish1MM;
int Start2HH, Start2MM, Finish2HH, Finish2MM;
int Start3HH, Start3MM, Finish3HH, Finish3MM;
int Start4HH, Start4MM, Finish4HH, Finish4MM;
int Start1SS, Finish1SS, Start2SS, Finish2SS, Start3SS, Finish3SS, Start4SS, Finish4SS;

int timer1, timer2, timer3, timer4;

int stop =0, mode=0, flag=0;

void setup(){
rtc.begin(); // memulai koneksi i2c dengan RTC

pinMode(bt_clock, INPUT_PULLUP);
pinMode(bt_up,    INPUT_PULLUP);
pinMode(bt_down,  INPUT_PULLUP);
pinMode(bt_timer, INPUT_PULLUP);

pinMode(relay1, OUTPUT);digitalWrite(relay1, HIGH);
pinMode(relay2, OUTPUT);digitalWrite(relay2, HIGH);
pinMode(relay3, OUTPUT);digitalWrite(relay3, HIGH);
pinMode(relay4, OUTPUT);digitalWrite(relay4, HIGH);

pinMode(buzzer, OUTPUT);
  
  lcd.begin(16, 2); // Configura lcd numero columnas y filas
  lcd.setCursor(0,0);  //Show "TIME" on the LCD

  lcd.setCursor (0,0);
  lcd.print(" Real Time Clock ");
  lcd.setCursor (0,1);
  lcd.print(" 4 Load  Control ");
  delay (2000);
  lcd.clear();

stop=EEPROM.read(50);  
if(stop==0){  
}else{
mode=1;WriteEeprom ();delay (20);
mode=2;WriteEeprom ();delay (20);
mode=3;WriteEeprom ();delay (20);
mode=4;WriteEeprom ();delay (20);
mode=0;
}
EEPROM.write(50,0); 

ReadEeprom();
//Set RTC Untuk Pertama kali
//rtc.setDOW(2);     // Set Day-of-Week to SUNDAY
//rtc.setTime (00, 9, 50); 
//rtc.setDate(12, 11, 2017);  
}

void loop(){  
t = rtc.getTime();
Day = rtc.getDOWStr(1);

if (setMode == 0){
hh = t.hour,DEC;
mm = t.min,DEC;
ss = t.sec,DEC;
dd = t.date,DEC;
bb = t.mon,DEC;
yy = t.year,DEC;
//if(t.hour>12){hh=t.hour-12;}// for removing 24 houre
//else{hh=t.hour;}
}  

  if(setAlarm==0){
  lcd.setCursor(0,0); 
  lcd.print((hh/10)%10);
  lcd.print(hh % 10); 
  lcd.print(":");
  lcd.print((mm/10)%10);
  lcd.print(mm % 10);
  lcd.print(":");
  lcd.print((ss/10)%10);
  lcd.print(ss % 10); 
  lcd.print("  T:"); 
  lcd.print(rtc.getTemp(),0);
  lcd.write(223); 
  lcd.print("C");
  lcd.print("  "); 

  lcd.setCursor(1,1);
  lcd.print(Day);
  lcd.print(" ");
  lcd.print((dd/10)%10);
  lcd.print(dd % 10); 
  lcd.print("/");
  lcd.print((bb/10)%10);
  lcd.print(bb % 10);
  lcd.print("/"); 
  lcd.print((yy/1000)%10);
  lcd.print((yy/100)%10);
  lcd.print((yy/10)%10);
  lcd.print(yy % 10);
  }


setupClock();
setTimer();
delay (100);
blinking();

//Timer1 ON
if (timer1==1 && alarmMode==1 && hh==Start1HH && mm==Start1MM && ss==Start1SS)  {digitalWrite(relay1, LOW);}
//Timer1 OFF
if (timer1==1 && alarmMode==1 && hh==Finish1HH && mm==Finish1MM && ss==Finish1SS){digitalWrite(relay1, HIGH);}

//Timer2 ON
if (timer2==1 && alarmMode==1 && hh==Start2HH && mm==Start2MM && ss==Start2SS)  {digitalWrite(relay2, LOW);}
//Timer2 OFF
if (timer2==1 && alarmMode==1 && hh==Finish2HH && mm==Finish2MM && ss==Finish2SS){digitalWrite(relay2, HIGH);}

//Timer3 ON
if (timer3==1 && alarmMode==1 && hh==Start3HH && mm==Start3MM && ss==Start3SS)  {digitalWrite(relay3, LOW);}
//Timer3 OFF
if (timer3==1 && alarmMode==1 && hh==Finish3HH && mm==Finish3MM && ss==Finish3SS) {digitalWrite(relay3, HIGH);}

//Timer4 ON
if (timer4==1 && alarmMode==1 && hh==Start4HH && mm==Start4MM && ss==Start4SS)  {digitalWrite(relay4, LOW);}
//Timer4 OFF
if (timer4==1 && alarmMode==1 && hh==Finish4HH && mm==Finish4MM && ss==Finish4SS) {digitalWrite(relay4, HIGH);}

delay (100);
digitalWrite(buzzer, LOW);
}

void blinking (){
//BLINKING SCREEN
//Set Clock
if (setAlarm <2 && setMode == 1){lcd.setCursor(0,0);  lcd.print("  ");}
if (setAlarm <2 && setMode == 2){lcd.setCursor(3,0);  lcd.print("  ");}
if (setAlarm <2 && setMode == 3){lcd.setCursor(6,0);  lcd.print("  ");}
if (setAlarm <2 && setMode == 4){lcd.setCursor(1,1);  lcd.print("   ");}
if (setAlarm <2 && setMode == 5){lcd.setCursor(5,1);  lcd.print("  ");}
if (setAlarm <2 && setMode == 6){lcd.setCursor(8,1);  lcd.print("  ");}
if (setAlarm <2 && setMode == 7){lcd.setCursor(11,1); lcd.print("    "); }

//Set Timer
if (setMode == 0 && setAlarm == 1 && mode==0){lcd.setCursor(2,1); lcd.print("  "); }
if (setMode == 0 && setAlarm == 2 && mode==0){lcd.setCursor(6,1); lcd.print("  "); }
if (setMode == 0 && setAlarm == 3 && mode==0){lcd.setCursor(10,1); lcd.print("  "); }
if (setMode == 0 && setAlarm == 4 && mode==0){lcd.setCursor(13,1); lcd.print("  "); }

if (setMode == 0 && setAlarm == 1 && mode>0){lcd.setCursor(11,0); lcd.print("  "); }
if (setMode == 0 && setAlarm == 2 && mode>0){lcd.setCursor(14,0); lcd.print("  "); }
if (setMode == 0 && setAlarm == 3 && mode>0){lcd.setCursor(11,1); lcd.print("  "); }
if (setMode == 0 && setAlarm == 4 && mode>0){lcd.setCursor(14,1); lcd.print("  "); }
}

//Seting Jam ,Tanggal,Alarm/Timer
void setupClock (void) {
   
    if (setMode == 8){
    lcd.setCursor (0,0);
    lcd.print ("Set Time Finish ");
    lcd.setCursor (0,1);
    lcd.print ("Set Date Finish ");
    delay (1000);
    rtc.setTime (hh, mm, ss);
    rtc.setDate (dd, bb, yy);  
    lcd.clear();
    setMode = 0;
    }
    
 if (setAlarm >0){alarmMode=0;}
    
 if(digitalRead (bt_clock) == 0 && flag==0) {flag=1;
 if(setAlarm>0){WriteEeprom(); setAlarm=1; mode =5;}
 else{setMode = setMode+1;}
 digitalWrite(buzzer, HIGH);
 }
  
 if(digitalRead (bt_timer) == 0 && flag==0){flag=1;
 if(setMode>0){setMode=8;}
  else{
  setAlarm = setAlarm+1;
  if(setAlarm>4){setAlarm=1; 
  WriteEeprom ();
  mode=mode+1;
  ReadEeprom();
  }
  } 
  lcd.clear();
  digitalWrite(buzzer, HIGH);
  } 

    if(setAlarm == 1 && mode==5){
    lcd.setCursor (0,0);
    lcd.print ("Set Timer Finish");
    lcd.setCursor (0,1);
    lcd.print ("-EEPROM Updated-");
    delay (2000); 
    lcd.clear();
    setAlarm=0;
    mode =0;
    alarmMode=1;
    }

if(digitalRead (bt_clock) == 1 && digitalRead (bt_timer) == 1){flag=0;}
  
 if(digitalRead (bt_up) == 0){                          
            if (setAlarm<2 && setMode==1)hh=hh+1; 
            if (setAlarm<2 && setMode==2)mm=mm+1;
            if (setAlarm<2 && setMode==3)ss=ss+1;
            if (setAlarm<2 && setMode==4)set_day=set_day+1;
            if (setAlarm<2 && setMode==5)dd=dd+1;
            if (setAlarm<2 && setMode==6)bb=bb+1;
            if (setAlarm<2 && setMode==7)yy=yy+1;
            //Timer
            if (mode==0 && setMode==0 && setAlarm==1)timer1=1;
            if (mode==0 && setMode==0 && setAlarm==2)timer2=1;
            if (mode==0 && setMode==0 && setAlarm==3)timer3=1;
            if (mode==0 && setMode==0 && setAlarm==4)timer4=1;
             
            if (mode>0 && setMode==0 && setAlarm==1)StartHH=StartHH+1;
            if (mode>0 && setMode==0 && setAlarm==2)StartMM=StartMM+1;
            if (mode>0 && setMode==0 && setAlarm==3)FinishHH=FinishHH+1;
            if (mode>0 && setMode==0 && setAlarm==4)FinishMM=FinishMM+1;
            if (mode>0 && setMode==0 && setAlarm==5)StartSS=StartSS+1;
            if (mode>0 && setMode==0 && setAlarm==6)FinishSS=FinishSS+1;

if(hh>23)hh=0;
if(mm>59)mm=0;
if(ss>59)ss=0;
if(set_day>7)set_day=0;
if(dd>31)dd=0;
if(bb>12)bb=0;
if(yy>2030)yy=2000;
if(StartHH>23)StartHH=0;
if(StartMM>59)StartMM=0;
if(FinishHH>23)FinishHH=0;
if(FinishMM>59)FinishMM=0;
if(StartSS>59)StartSS=0;
if(FinishSS>59)FinishSS=0;

rtc.setDOW(set_day);
digitalWrite(buzzer, HIGH);
 }        

if(digitalRead (bt_down) == 0){                                      
            if (setAlarm<2 && setMode==1)hh=hh-1; 
            if (setAlarm<2 && setMode==2)mm=mm-1;
            if (setAlarm<2 && setMode==3)ss=ss-1;
            if (setAlarm<2 && setMode==4)set_day=set_day-1;
            if (setAlarm<2 && setMode==5)dd=dd-1;
            if (setAlarm<2 && setMode==6)bb=bb-1;
            if (setAlarm<2 && setMode==7)yy=yy-1;
            //Timer
            if (mode==0 && setMode==0 && setAlarm==1)timer1=0;
            if (mode==0 && setMode==0 && setAlarm==2)timer2=0;
            if (mode==0 && setMode==0 && setAlarm==3)timer3=0;
            if (mode==0 && setMode==0 && setAlarm==4)timer4=0;
            
            if (mode>0 && setMode==0 && setAlarm==1)StartHH=StartHH-1;
            if (mode>0 && setMode==0 && setAlarm==2)StartMM=StartMM-1;
            if (mode>0 && setMode==0 && setAlarm==3)FinishHH=FinishHH-1;
            if (mode>0 && setMode==0 && setAlarm==4)FinishMM=FinishMM-1;
            if (mode>0 && setMode==0 && setAlarm==5)StartSS=StartSS-1;
            if (mode>0 && setMode==0 && setAlarm==6)FinishSS=FinishSS-1;

if(hh<0)hh=23;
if(mm<0)mm=59;
if(ss<0)ss=59;
if(set_day<0)set_day=7;
if(dd<0)dd=31;
if(bb<0)bb=12;
if(yy<0)yy=2030;
if(StartHH<0)StartHH=23;
if(StartMM<0)StartMM=59;
if(FinishHH<0)FinishHH=23;
if(FinishMM<0)FinishMM=59;
if(StartSS<0)StartSS=59;
if(FinishSS<0)FinishSS=59;


rtc.setDOW(set_day);
digitalWrite(buzzer, HIGH); 
 }
 
}

void setTimer (){
//Timer
if (setMode == 0 && setAlarm >0 && mode>0){
  lcd.setCursor (0,0);
  lcd.print(mode);
  lcd.print(" On :");
  lcd.setCursor (6,0);
  lcd.print((StartHH/10)%10);
  lcd.print(StartHH % 10);
  lcd.print(":");
  lcd.print((StartMM/10)%10);
  lcd.print(StartMM % 10);

  lcd.print(":");
  lcd.print((StartSS/10)%10);
  lcd.print(StartSS % 10);

  lcd.setCursor (0,1);
  lcd.print(mode);
  lcd.print(" Off:");
  lcd.setCursor (6,1);
  lcd.print((FinishHH/10)%10);
  lcd.print(FinishHH % 10);
  lcd.print(":");
  lcd.print((FinishMM/10)%10);
  lcd.print(FinishMM % 10);

  lcd.print(":");
  lcd.print((FinishSS/10)%10);
  lcd.print(FinishSS % 10);
 }

if (setMode == 0 && setAlarm >0 && mode==0){
  lcd.setCursor (0,0);
  lcd.print(" L1  L2  L3  L4 ");
  lcd.setCursor (0,1);
    if(timer1==1){lcd.print("  A");}
  else{lcd.print("  D");}
   
    if(timer2==1){lcd.print("   A");}
  else{lcd.print("   D");}
  
    if(timer3==1){lcd.print("   A");}
  else{lcd.print("   D");}
  
    if(timer4==1){lcd.print("   A");}
  else{lcd.print("   D");}
}
}

void ReadEeprom() {
Start1HH=EEPROM.read(11);Start1MM=EEPROM.read(12);Finish1HH=EEPROM.read(13);Finish1MM=EEPROM.read(14);
Start2HH=EEPROM.read(21);Start2MM=EEPROM.read(22);Finish2HH=EEPROM.read(23);Finish2MM=EEPROM.read(24);
Start3HH=EEPROM.read(31);Start3MM=EEPROM.read(32);Finish3HH=EEPROM.read(33);Finish3MM=EEPROM.read(34);
Start4HH=EEPROM.read(41);Start4MM=EEPROM.read(42);Finish4HH=EEPROM.read(43);Finish4MM=EEPROM.read(44);

Start1SS=EEPROM.read(51);Finish1SS=EEPROM.read(52);
Start2SS=EEPROM.read(61);Finish2SS=EEPROM.read(62);
Start3SS=EEPROM.read(71);Finish3SS=EEPROM.read(72);
Start4SS=EEPROM.read(81);Finish4SS=EEPROM.read(82);


if(mode==1){StartHH=Start1HH, StartMM=Start1MM, StartSS=Start1SS, FinishHH=Finish1HH,FinishMM=Finish1MM,FinishSS=Finish1SS;}
if(mode==2){StartHH=Start2HH, StartMM=Start2MM, StartSS=Start2SS, FinishHH=Finish2HH,FinishMM=Finish2MM,FinishSS=Finish2SS;}
if(mode==3){StartHH=Start3HH, StartMM=Start3MM, StartSS=Start3SS, FinishHH=Finish3HH,FinishMM=Finish3MM,FinishSS=Finish3SS;}
if(mode==4){StartHH=Start4HH, StartMM=Start4MM, StartSS=Start4SS, FinishHH=Finish4HH,FinishMM=Finish4MM,FinishSS=Finish4SS;}

timer1=EEPROM.read(1);
timer2=EEPROM.read(2);
timer3=EEPROM.read(3);
timer4=EEPROM.read(4);
}

void WriteEeprom() {
if(mode==1){EEPROM.write(11,StartHH);EEPROM.write(12,StartMM);EEPROM.write(13,FinishHH);EEPROM.write(14,FinishMM);EEPROM.write(51,StartSS);EEPROM.write(52,FinishSS);}
if(mode==2){EEPROM.write(21,StartHH);EEPROM.write(22,StartMM);EEPROM.write(23,FinishHH);EEPROM.write(24,FinishMM);EEPROM.write(61,StartSS);EEPROM.write(62,FinishSS);}
if(mode==3){EEPROM.write(31,StartHH);EEPROM.write(32,StartMM);EEPROM.write(33,FinishHH);EEPROM.write(34,FinishMM);EEPROM.write(71,StartSS);EEPROM.write(72,FinishSS);}
if(mode==4){EEPROM.write(41,StartHH);EEPROM.write(42,StartMM);EEPROM.write(43,FinishHH);EEPROM.write(44,FinishMM);EEPROM.write(81,StartSS);EEPROM.write(82,FinishSS);}

EEPROM.write(1,timer1);
EEPROM.write(2,timer2);
EEPROM.write(3,timer3);
EEPROM.write(4,timer4);
}

Hi,
You may find the 10K base resistors could be a little high in value to make the BJTs saturate.

How do you know how much to dose your aquarium in the first place?

Do you understand the code you already have?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

Is the timing that critical to demand a RTC?

My brother has a large pond with Tilapia in it. I built a feeder based on a Trinket and a 1 second counter that runs for 6 seconds twice a day. It loses about 45 seconds a month. No RTC needed. Just power it on at the morning feeding time. He can reset it about once a year or when he has to do battery maintenance.

I also have a timer that charges my RV battery 1 hour every 5 days. No RTC required.

I'm just suggesting a simpler alternative.

The Proteus simulation does not match his breadboard set-up and he does not provide a schematic for the breadboard set-up.

I would look for another example.

I agree, the relay module is nothing like what is used.
My confidence in that project is now ZERO, what else has the maker got wrong.

Can you please tell us your electronics, programming, arduino, hardware experience?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

It seems you are not yet able, or didn't know you are able, to read code with an eye to modifying it.

These two lines turn on and off relay1:

Until it is obvious how those lines might be changed to do something for 15 seconds at a certain time, I recommend you do whatever it takes to come to a complete understanding of how those two lines of code do that.

Having said that, it is very not the best way to exploit an RTC and a relay to do something for a small period.

Slog your way through this thread:

tl;dr: when working with variables and time, comparisons for exact matches are fraught. Use earlier and later rather than exactly.

tl;dr: working with hh, mm, and ss is harder than using a single number like seconds since midnight or, oddly, seconds since 1 January 1970.

HTH

a7

Yes, it is. Dosing must be done accurately, or the entire aquarium ecosystem could be compromised.

Yes, I modified it myself, the Proteus schema is just a prototype yet, nothing definitive.

As for the dosage, this is done by each aquarist, he must know his ecosystem and know what to feed him, I am sure about that.

Yes, its just for tests, and works really fine. I've fixed the code and now we can setup the seconds too.

I'm new in arduino, but in programming I already have a certain experience in JS, node.JS and some basics of python.

I've fixed the code, and now I just need fix my proteus simulation, working on it right now. Already did a few tests in simulation and works fine, but its slow, think I should improve the proteus schematic before doing a final build in real life.

Hello! I really hadn't stopped to pay attention to all the details of the code. I also didn't have the knowledge of EEPROM and how to store data in it. I did some research and testing and finally the project works as it should, with a friendly and easy to use interface, like changing the times needed. Now the relays can be programmed to turn on for a few seconds, just add something like potentiometers to control the forced and speed of the pumps, it should work fine.

Thank you for the help and attetion!

If you have certain RTC module, you shoukd modify it according to this advice:


I never argue with success.

With the tests written as they are, you are absolutely depending on the tests being done more than once per second.

Which, for all I know, the code will manage.

You are also hoping that there is not a brief and well-timed power outrage… or should I say badly-timed.

You might open the valve and miss closing it.

As I type this I consider that there are all kindsa ways this can go bad for the fishies. I recommend you think out any failure modes and build in some kind of answer for each and every one.

I understand thy perfection is impossible, and getting closer will cost more and more, but there is some low-hanging fruit that could make it somewhat more reliable.

a7

Sure! I'm working on it right now, its just the version 1 of this porject. I'm already thinking in how to prevent overdose, power failure and etc. I will test it when its finished for maybe 1 month before put in in aquarium. Ty

1 Like

You need to now get into the real world and build a prototype.
Do you have all the hardware?

If you don't have your relays, use LEDs on the controller outputs to show the output states.

How do you know on a day to day basis how much to dose your aquarium.

Tom.. :smiley: :+1: :coffee: :australia:

It sounds interesting.. fertilizer to feed what the fish eat? Even corals eat?

Just supposing that on-time you have one or more sensors that detect fertilizer level, pH, temperature, even color of the water?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.