Watering Timer for solenoid valve

Some time now, I am trying to make a watering timer, without success, similar to the
Claber programmer: “Aquauno Select 8432” (see attachement one, its self explanatory)
That will give command to a solenoid valve (3/4’’ / 12 or 24volt / 1-12bar water presure) driven by an external relay, in order to water my plants.

For the programmer, I need to have the below selections:
a. one for the Watering Time (OFF, 1min, 2min, 3min, 4min, 5min, 10min) and
b. one for the Frequency (6hr, 12hr, 24hr, 48hr, 72hr)

To do this, I am thinking of using "PCB mountable DIP switches"

Depending on the number of switches turned on a number of minutes will be defined.
No1= 1 min
No2= 2 min
No3= 3 min
Np4= 4 min
No5= 5 min
No6= 10 min

Lets say I turn on No1 & No6, the result shoul be 1min+10min = 11min of watering.
If all are turned on watering time would be: 1+2+3+4+5+10=25min

The same philosophy will be followed for watering frequency.

I am not sure if this is easy to do, or if something simpler would be preferable in terms of programming.

I would appreciate some guidance on the above, since summer is closing up here in Greece and my plants will miss me in me in my days off period…

Thanks a lot guys

Aquauno select.jpg

DIP Switch.jpg

How about this instead of DIP switches? Only 2x analogue inputs needed then instead of 11 for DIP's

Riva: How about this instead of DIP switches? Only 2x analogue inputs needed then instead of 11 for DIP's

I was going to suggest the same, unless those dip switch already have analog output.

If it is not to complicated for the user, I would make the input settings binary, and you will get better range from the same number of switches. The way I have seen it done on a digital timer I have is that 1 is always added to the value, so with six bits, you will get from 1 minute to 64 minutes depending on how the switches are set. If you really only need the 25 minutes, you can use 5 bits for 32 minutes.

If you don't have the digital inputs needed, you can use a parallel in/serial out shift register. There is a nice Arduino tutorial here http://www.arduino.cc/en/Tutorial/ShiftIn

Otherwise, you can use the analog resistor ladder approach as suggested. If you do a google search on r/2r resistor ladder network you will find lots of information.

Thanks for the answers. Please keep in mind that I am a beginner, so I would like to keep it as simple as possible.

The Dip switches, that I already have, are simple switches (on/off) that are found in the same small plastic body.

Since I am using an Arduino tiny board, I do not mind using more or less inputs, as long as I get there...

What function should I use to sum up the values from all switches?

Regarding the frequency, is it possible to set the delay, up to two days lets say, with precision? or do I need an other function?

Thanks again

Trimitsos:
Depending on the number of switches turned on a number of minutes will be defined.
No1= 1 min
No2= 2 min
No3= 3 min
Np4= 4 min
No5= 5 min
No6= 10 min

Lets say I turn on No1 & No6, the result shoul be 1min+10min = 11min of watering.
If all are turned on watering time would be: 1+2+3+4+5+10=25min

You can do it that way, but you would have a much wider range if the switches would represent power of two:
No1= 1 min
No2= 2 min
No3= 4 min
Np4= 8 min
No5= 16 min
No6= 32 min

So 11 minutes of watering would be No1 + No2 + No4 (1+2+8 minutes)
Max. watering time would be 63 minutes then.
But it’s your decision, you also could have a much less max. watering time.

Trimitsos:
I would appreciate some guidance on the above, since summer is closing up here in Greece and my plants will miss me in me in my days off period…

As your 12/24V solenoid valve is an “inductive load”, you will need a “flyback diode” at the relay output, mounted in back direction, to avoid strong electromagnetic pulses that could damage your circuit or create malfunction on your Arduino board at the moment the valve is switched from ON to OFF.

Trimitsos:
I am not sure if this is easy to do, or if something simpler would be preferable in terms of programming.

Programming should be easy.
Please let me know if you need a base frame sketch.

This "power of two" repesentation looks much much better and I think, this way, I can achieve detail per minute and at the same time bigger range. Thanks for that.

1) I would like some help with the programming though, since I am still learning and understand basic examples.

2) Also thanks for the tip on the inductive load of the solenoid, I was not aware of that!!! How should I connect my diode exactly? Any kind of diode would be ok?

Thanks for helping me out with this.

p.s. What is a "base frame sketch"? ;-)

I was thinking to define seperate variables for each switch (12 of them).

In the beggining of the program it should read all swithces and thes sum up depending on their high or low value: - switches 1-6 will determin Frequency and - switches 7-12 will determin watering time

Each summed value will be placed in a new variable in order to use for the look that will repeat ono and on until I reset the board or change one of the above values.

Does this sound ok?

p.s. I have read in the forum that precission of arduino boards is about +-2sec per month, is that correct?

Trimitsos: This "power of two" repesentation looks much much better and I think, this way, I can achieve detail per minute and at the same time bigger range. Thanks for that.

That makes programming very easy.

Trimitsos: 2) Also thanks for the tip on the inductive load of the solenoid, I was not aware of that!!! How should I connect my diode exactly? Any kind of diode would be ok?

Depends on the DC current that the valve draws from the relay. High currents will require bigger flyback diodes. Is there a datasheet or product description for the valve?

Trimitsos: What is a "base frame sketch"? ;-)

Example sketch.

Trimitsos: I was thinking to define seperate variables for each switch (12 of them).

I was thinking to define one array of 6 pins and one seperate time variable for each switch.

Trimitsos: p.s. I have read in the forum that precission of arduino boards is about +-2sec per month, is that correct?

No, not at all.

If you do the timing just based on the 16 MHz timing of the Arduino board, then you will get perhaps: 50 ppm ==> Arduino boards which contain a crystal oscillator 4000 ppm ==> Arduino boards which contain a ceramic resonator

While old Arduino boards contained crystal oscillators which were very precise, most new Arduino boards use ceramic resonators only. So your accuracy can be as low as 4000 ppm (parts per million) which means: Within one million seconds your time can be 4000 seconds off. 1000000/4000= 250.

So your Arduino clocking may be wrong by one second every 250 seconds. 86400/250 = 346 seconds. So per day your clock may be 346 seconds off while using a board with ceramic resonator.

If the board has a crystal oscillator, it is 4000/50= 80 times better accuracy. So with a crystal oscillator your clock might be wrong 346/80= 4 to 5 seconds per day. Depends on the actual crystal and the temperature.

If you need high accuray you would have to use an additional realtime clock (RTC) connected to your Arduino board which keeps the time, even with battery backup. RTC modules using the DS3231 chip are relatively cheap and very accurate. Real time accurate up to 60 seconds per year, that's less than 0.2 seconds inaccuracy per day. Some DS3231 modules are really cheap when ordered from China (2 Euros or so).

So it's your decision how precise you want the timing: Arduino board, ceramic resonator ==> 346 seconds inaccuracy per day Arduino board, crystal oscillator ==> 4 to 5 seconds inaccuracy per day Arduino board + additional DS3231 RTC ==> 0.2 seconds inaccuracy per day

I bilieve 5 seconds per day (=half an hour per year, is not a big deal for watering plants) Moreover, I will surely do some seasonal modifications in the watering pattern and so additive (summed up) error should be reset/eliminated.

But how can I tell if my arduino uno/mini has ceramic resonator or crystal oscillator???

I think its crystal oscilator, if that is a silver roundi thing on my boards... and not an orange one@?!

Nevertheless, I have also ordered an DS3231 RTC, just to play around with or even try a V.2 watering programmer later on for a friend of mine.

Thanks for taking the time to explain in such detail Is there any code available, for this type of programmer, so that I can start doing some trials and tests?

Trimitsos: But how can I tell if my arduino uno/mini has ceramic resonator or crystal oscillator???

You'd have to look up the board.

Typically most old board designs use crystal oscillators. Like the first UNO, the UNO R2, or the DUEMILANOVE board. Most of the old boards are no longer available on the market.

All new boards in "R3" design use ceramic resonators, such like UNO R3, MEGA R3 or other.

BTW: It's not enough to look on the board if there is any 16 MHz oscillator. Many Arduino boards use a 16 MHz oscillator for the USB-Serial chip to create an accurate USB frequency, but they use a ceramic resonator for the clocking of the main controller only. So an "UNO R3" has both on-board: A 16 MHz crystal oscillator which provides correct USB frequency. And a 16 MHz ceramic resonator to create the Arduino clock frequency.

If you like to have a board with an accurate crystal oscillator, perhaps watch out for "Sainsmart DUEMILANOVE" boards.

Trimitsos: Moreover, I will surely do some seasonal modifications in the watering pattern and so additive (summed up) error should be reset/eliminated.

If you have no RTC, the timing will always be "relative" to the time when the Arduino was started or resetted. You will never have accurate time-of-the-day timing, such as "each day at 06:00 and 18:00". This would only be possible with a RTC / timer switch.

I'll prepare a bit code as an programming example for you - stay tuned.

BTW: Is your system based on 12V/24V DC only, such like photovoltaic power or a car battery? Or do you also have mains power available?

I am thinking of purchasing a 9 or 12 volt solenoid. I would like to use a transformer, for continues power supply, so as to increase reliability and avoid power loss due to bad batteries or misscalculated consumption, in terms of mAh.

Regarding the RTC module, Please do include the lines for it, since it will be better to have it for time accuracy! Either way the RTC is already on its way to my home's post office :-)

Declare values: WTT \Watering time a1 input a2 input a4 input a8 input a16 input a32 input

WFR \Watering frequency b1 input b2 input b3 input b4 input b5 input b6 input

Read analogue inputs from switch 1 if a1=high then addit to value WT if a2=high then addit to value WT if a4=high then addit to value WT if a8=high then addit to value WT if a16=high then addit to value WT if a32 =high then addit to value WT

WTT = final "watering time" value \added values of switches in high state

Read analogue inputs from switch 2

if b8=high then addit to value WTF \3 times per Day if b12=high then addit to value WTF \2 times per Day if b24=high then addit to value WTF \1 time per Day if b48=high then addit to value WTF \1 time per 2 Days if b96=high then addit to value WTF \1 time per 3 Days if b120=high then addit to value WTF \1 time per 5 Days

WTF = final watering time \added values of switches in high state

I have done some pre work of the logic I would like to follow, for anyone that would like to help out. I just haven’t included the RTC module because I am not sure how this would be included so as the delays to be precise in timings.

Start PinX output \ Output pin for solenoid
Declare values
WTT \Watering time
WFR \Watering frequency
a1 input \1-min
a2 input \2-min
a4 input \4-min
a8 input \8-min
a16 input \16-min
a32 input \32-min
b8 input \8-hrs
b12 input \12-hrs
b24 input \1-day
b48 input \2-days
b72 input \3-days
b120 input \5-days

a1 = 1
a2 = 2
a4 = 4
a8 = 8
a16 = 16
a32 = 32
b8=8 \8hrs
b12=12 \12hrs
b24=24 \1-day, 24hrs
b48=48 \2-days
b72=72 \3-days
b120=120 \5-days

Read analogue/digital inputs from switch 1
if a1=high then add its value to value WTT
if a2=high then add its value to value WTT
if a4=high then add its value to value WTT
if a8=high then add its value to value WTT
if a16=high then add its value to value WTT
if a32 =high then add its value to value WTT
WTT = final “watering time” value \added values of switches in high state at DIP switch1

Read analogue inputs from switch 2
if b8=high then put it in value WTF
Else if b12=high then put this one to value WTF
Else if b24=high then put this one to value WTF
Else if b48=high then put this one to value WTF
Else if b72=high then put this one to value WTF
Else if b120=high then put this one to value WTF
\this way when two switches are turnen on the smallest value will be set to the value,
\ is that correct??
WTF = final “watering time” value \smallest value from switches in high state at DIP switch 2

Delay 4 secs \ in order to have time to deside the the switches positions

If WTT and WTF don’t alter value then do the following loop
\ I would like to reset the cycle once any switch is altered, according to new setting
PinX = low \ otherwise don’t do anything
else recalculate all values

Loop
If WTT<>0 and WTF<>0 then \check if switches in DIP switch 1 & 2 are turned on
PinX = high \ Open relay for solenoid only if a switch is turned on
Delay time WTT \ Watering time according to first switch
PinX Low \ Close relay for solenoid
Delay WTF \ wait for as long as set by switch2

If WTT and WTF remains the same then repeat loop
Else recalculate them before restaring the loop ???
\ This way when one switch is changed the schedule should be restarted and reset, I would like this to be continuously monitored.

Hi, I’m back on the Internet again after two days of Internet failure.

Here is some code you can use to play with.
No RTC supported, works similar like the “Aquauno Select 8432” you showed.

Pin connections of your DIP switches: Connect to GND and to the input pins specified in the arrays:
byte durationPins={2,3,4,5,6,7}; // switches for duration 0-63
byte intervalPins={A0,A1,A2,A3,A4,A5}; // switches for interval 1-64

You can use pin numbers as you like, but avoid pin-0 and pin-1, which are the pins for Serial.

For debugging reasons I wrote some code for output on Serial, which shows the relay state, the cycle time and the duration while the relay is switched ON, as well as the time left for watering and for the current cycle.

For short time debuggin I have set these initialization values:

  durationON*=MILLISECONDS_PER_SECOND;
  intervalCycle=(intervalCycle+1)*MILLISECONDS_PER_MINUTE;

So the duration switch will set the watering duration in seconds (0,1,2,4,8 etc.).
And the cycle will be set in minutes (1, 2, 4, 8 etc.)

For real usage you would change that to minutes and hours using:

//  durationON*=MILLISECONDS_PER_MINUTE;
//  intervalCycle=(intervalCycle+1)*MILLISECONDS_PER_HOUR;

Comment the two other lines and remove the comments from these two lines to activate time setting in minutes/hours instead of seconds/minutes

Actual switching is currently done on pin-13, which switches the board LED on and off.

After starting or resetting the Arduino, the first cycle will be shorter by the on-duration. So the Arduino always starts with “non watering”.

If you better like the Arduino starting with a watering after each start or reset, remove or comment out this line from the setup() function:

  lastCycleStart=-durationON; // comment out this line if you want to start with watering after reset

If that line is not executed, also the first cycle will be a full interval and begin with watering after starting the program.

Here is the code for a “water timer”:

// water timer example sketch by 'jurs' for Arduino forum
// http://forum.arduino.cc/index.php?topic=320392.0
#define RELAY_PIN 13  // a pin number to switch HIGH/LOW in intervals
#define RELAY_ACTIVE HIGH

byte durationPins[]={2,3,4,5,6,7};       // switches for duration
long durationON;  // ON time in milliseconds
byte intervalPins[]={A0,A1,A2,A3,A4,A5}; // switches for interval
long intervalCycle; // cycle time in milliseconds

#define MILLISECONDS_PER_DAY 86400000L
#define MILLISECONDS_PER_HOUR 3600000L
#define MILLISECONDS_PER_MINUTE 60000L
#define MILLISECONDS_PER_SECOND 1000L

// DO NOT USE FOR INTERVAL TIMES LONGER THAN 25 DAYS!

void initSwitches()
{ // activate internal pull-up resistors for all switches
  for (int i=0;i<6;i++)
  {
     pinMode(durationPins[i], INPUT_PULLUP);
     pinMode(intervalPins[i], INPUT_PULLUP);
  }
  // set relaypin to OUTPUT
  digitalWrite(RELAY_PIN, !RELAY_ACTIVE); // not active
  pinMode(RELAY_PIN, OUTPUT);
}

void readSwitchTimes()
{
  durationON=0;
  intervalCycle=0;
  for (int i=0;i<6;i++)
  {
    if (digitalRead(durationPins[i])==LOW) bitSet(durationON,i);
    if (digitalRead(intervalPins[i])==LOW) bitSet(intervalCycle,i);
  }
  durationON*=MILLISECONDS_PER_SECOND;
  intervalCycle=(intervalCycle+1)*MILLISECONDS_PER_MINUTE;
//  durationON*=MILLISECONDS_PER_MINUTE;
//  intervalCycle=(intervalCycle+1)*MILLISECONDS_PER_HOUR;
}

unsigned long lastCycleStart=0;

void SerialFormatted(long time)
{
  time/=MILLISECONDS_PER_SECOND; // get time in seconds
  int hours=time/3600; // hours
  time-=hours*3600L;
  int minutes=time/60;
  int seconds=time%60;
  if (hours<10) Serial.print('0');
  Serial.print(hours);
  Serial.print(':');
  if (minutes<10) Serial.print('0');
  Serial.print(minutes);
  Serial.print(':');
  if (seconds<10) Serial.print('0');
  Serial.print(seconds);
}

void showSomeStatistics(long restCycleTime, long restOnTime, byte relayState)
{
  if (relayState) Serial.print("ON\t");
  else Serial.print("OFF\t");
  if (restOnTime<0) restOnTime=0;
  Serial.print("Cycle: ");
  SerialFormatted(intervalCycle);
  Serial.print("\tOn time: ");
  SerialFormatted(durationON);
  Serial.print("\tON time to go: ");
  SerialFormatted(restOnTime);
  Serial.print("\tCycle time to go: ");
  SerialFormatted(restCycleTime);
  Serial.println();
}

void setup() {
  Serial.begin(9600);
  initSwitches();
  readSwitchTimes();
  lastCycleStart=-durationON; // comment out this line if you want to start with watering after reset
}

void loop() {
  long now=millis();
  if (now-lastCycleStart>=intervalCycle) // interval ended
    lastCycleStart+=intervalCycle; // start a new interval
  byte relayState= now-lastCycleStart<durationON; // while in hightime
  if (relayState) digitalWrite(RELAY_PIN, RELAY_ACTIVE); // ON
  else digitalWrite(RELAY_PIN, !RELAY_ACTIVE);  // OFF
  static unsigned long lastStatistics;
  if (now-lastStatistics>=1000) // call statistics function every second
  {
    lastStatistics+=1000;
    showSomeStatistics(intervalCycle-(now-lastCycleStart), durationON-(now-lastCycleStart), relayState);
  }  
}

This is so much more that i believed it would take... Thank you so much. I will start trials this weekend hopefully I will send you a PM in case I stack somewhere, since some of the things you write i see for the first time!

Thanks again

p.s. how long did it take to write down all this code? I am imperssed!

Trimitsos: I will send you a PM in case I stack somewhere, since some of the things you write i see for the first time!

If you want to discuss the code or if you need further explanation, please stay within this thread with your additional questions!

Watering timer switches are fairly standard applications, and if any code I posted in this thread needs further discussion or explanation, I'd prefer to discuss or explain it in this thread. So that possibly other users may find all the useful information about the watering timer code in this thread.

Trimitsos: p.s. how long did it take to write down all this code? I am imperssed!

Reading the state of a pin array is pretty standard. Switching things on and off in time cycles is pretty standard. So the only thing I had to think a bit about was the "showSomeStatistics()" functions to make it visible on the serial monitor what's actually going on within the program.

Writing and copying together the program was simple, half an hour or so. But fine-tuning and debugging then was an extra hour or so, to make the program switch exactly up to the second at the begin/end of the interval and at the end of the on-time. So the writing took roughly (I didn't really count the time): 0.5 hours ==> creating 95% of the code 1.0 hours ==> creating last 5% of the code, including fine-tuning and debugging Total one and a half hour, perhaps.

Thanks so much for your time. I will post back any questions once I have some time to play around and try it out.

Instead of sending PM you could share your questions here that way we all learn.

I am a little bit confused on how to connect the dip switches according to your code.

could you make a schematic?