Newbie here - Multiple timers, Mutliple Events, different times....

Alrighty... BRAND-SPANKING new at Arduino.... I do understand the simple logic in the programming... It's been many years since, but i used to program PLCC's and work with digital electronics all the time in the military... but I'm older and RUSTY! lol

I am positive this has been answered within these forums... but after going thru thousands of lines of code examples posted here I am now need of new glasses, a few beers, and possibly a lobotomy! What I need(using the following code for examples) is to have 4 different events happening at different intervals, with different timings between each interval. I grow Hungarian Peppers indoors, I have a homemade dome to grow cuttings and seedlings in. On this dome I have a heating pad underneath, vent fans, one light atop, a water pump, and a pond mister to keep humidity high.

Using the following basic code, I need these conditions:

  1. Ability to reduce the "on time" of the mister later(on 24 hours in the beginning) to start acclimating the seedlings to lower humidity. Looped.
  2. Turn vent fans on (always two fans together, one pushing air in, the other pulling out) for 20 seconds on, 2 hours off. Looped.
  3. Water pump turns on for 10 minutes, then off for 2 hours. Looped.
  4. Light on for 16 hours, off for 8 hours. Looped.

I have a 4-relay shield atop my Arduino Uno.

Code thus far:

// Which pins are connected to which LED
const byte Light = 4;
const byte WaterPump = 5;
const byte Fans = 6;
const byte Mister = 7;

// Time periods of blinks in milliseconds (1000 to a second).
//60000 milliseconds in 1 minute, 3600000 ms in 1 hour, 57600000/16hrs
const unsigned long Lightinterval = 5000;//57600000=16 hours
const unsigned long LightOFFinterval = 10000;//57600000=16 hours
const unsigned long WaterPumpinterval = 600000;//600000=10 minutes
const unsigned long Fansinterval = 7200000;//7200000=2 hours
const unsigned long Misterinterval = 86400000;//86400000=1 day

// Variable holding the timer value so far. One for each "Timer"
unsigned long Lighttimer;
[color=red]unsigned long LightOffTimer;[/color]
unsigned long WaterPumptimer;
unsigned long Fanstimer;
unsigned long Mistertimer;

void setup () 
  {
  pinMode (Light, OUTPUT);
  pinMode (WaterPump, OUTPUT);
  pinMode (Fans, OUTPUT);
  pinMode (Mister, OUTPUT);
  Lighttimer = millis ();
  [color=red]LightOffTimer = 5000;[/color]
  WaterPumptimer = millis ();
  Fanstimer = millis ();
  Mistertimer = millis ();
  }  // end of setup

void toggleLight ()
  {
   if (digitalRead (Light) == LOW)
      digitalWrite (Light, HIGH);
   else
      digitalWrite (Light, LOW);

  // remember when we toggled it
  Lighttimer = millis ();  
  }  // end of toggleLight

void toggleWaterPump ()
  {
   if (digitalRead (WaterPump) == LOW)
      digitalWrite (WaterPump, HIGH);
   else
      digitalWrite (WaterPump, LOW);

  // remember when we toggled it
  WaterPumptimer = millis ();  
  }  // end of toggleWaterPump
  
void toggleFans ()
  {
   if (digitalRead (Fans) == LOW)
      digitalWrite (Fans, HIGH);
   else
      digitalWrite (Fans, LOW);

  // remember when we toggled it
  Fanstimer = millis ();  
  }  // end of toggleFans

void toggleMister ()
  {
   if (digitalRead (Mister) == LOW)
      digitalWrite (Mister, HIGH);
   else
      digitalWrite (Mister, LOW);

  // remember when last toggled
  Mistertimer = millis ();  
  }  // end of toggleMister
  
void loop ()
  {

  // Handling the intervals.
  if ( (millis () - Lighttimer) >= Lightinterval)
     toggleLight ();

  if ( (millis () - WaterPumptimer) >= WaterPumpinterval) 
    toggleWaterPump ();

  if ( (millis () - Fanstimer) >= Fansinterval) 
    toggleFans ();
    
  if ( (millis () - Mistertimer) >= Misterinterval) 
    toggleMister ();

}  // end of loop

As we can see "interval" works great for turning on (HIGH) an item, however, this code uses the same amount of time (interval) to time the "LOW" (off) time as well... can't have that as I do not want the identical HIGH and LOW (on and off) times.

I started to write in "LightOffTimer" variable but am not sure how to perform the logical decisions in the final interval (Void Loop) control code to accomplish the math to make my times different for each toggle event.

Any help would be appreciated! Even just pointing me to the forum posts of similar threads with solutions as I do not want to go the lobotomy route!

Thanks in advanced,
Scott

Maybe I haven't understood the explanation, but you know when you have to change the state of the thing to be switched, so why not vary the value of the interval at the same time?

I'm starting to think that the term "interval" is not the proper method here as the interval is being used for the "on" time as well as the "off" time, thus (for example) on for 5, off for 5, on for 5, off for 5, (looped endlessly....) Here's a better description of what I'm looking for:

  1. Arduino powered on.
  2. All 4 events triggered... all external devices powered up with timers initiated.
    a. Light turns on
    b. Water Pump turns on
    c. Heat pad & Mister turns on (both connected to same event and powered by same activated relay... 1 output powers both devices via SSR)
    d. Fans turn on.
  3. At the instant the Arduino is powered on: Light stays on for 16 hours, Water Pump stays on for 10 minutes. Fans stay on for 10 seconds. Heating Pad/Mister stays on 24/7(at first, able to change timing later via variables)
  4. 10 seconds after Arduino is powered on: Fans turn off for 2 hours. This loops continuously.
  5. 10 minutes after Arduino is powered on: Water Pump turns off for 1 hour. This loops continuously.
  6. 16 hours after Arduino is powered on: Light turns off for 8 hours. This loops continuously.
  7. Heating Pad/Mister still on via the relay's contacts NC connections. Later the relay can be actuated via a timed loop like the other devices' loops.
  8. Every 24 hours the Arduino resets the code (or itself) to restart the entire process over again.

There cannot be any "delay" commands as this halts the entire program until the delay is finished. I've tried using the "Led timer without Delay" sample code, but cannot for the life of me figure out how to do the above functions simultaneously and loop the commands effectively.

Hopefully that helps describe my intentions more thoroughly.

Thanks!
Scott

you need to keep a bit more state

unsigned long LightONinterval = 5000; 
unsigned long LightOFFinterval = 10000; 
unsigned long lastLight = 0;
int lightState = HIGH;

void setup () 
{
  pinMode (Light, OUTPUT);
}  

void loop()
{
  if (lightState == HIGH && millis() - lastLight > LightONinterval )
  {
    lightState = LOW;
    digitalWrite(LED, lightState);
  }
  if (lightState == LOW && millis() - lastLight > LightOFFinterval )
  {
    lightState = HIGH;
    digitalWrite(LED, lightState);
  }
}

you can include the checking code into the toggleLight function which makes the main loop simpler.

Ok, found just what I was looking for! Instead of counting milliseconds, this counts "ticks" so-to-speak, and "ticks" are incremented by counters using milliseconds. This way you can define as many different "ticks" as you need, using the same timer. Here's the code I found - The only changes I made were the pins used, I changed the output pins to match that of the 4-relay shield I bought at Radio Shack:

/*
 *
 * Description:
 * EventFuse example demonstrating control of 
 * multiple independent switched outputs. Each
 * output can be configured with independent
 * on and off durations with a minimum of 1 second
 * and a maximum of about 1100 hours (2^32 mS).
 *
 */
 
#include <EventFuse.h>
#include <MsTimer2.h>

#define OutputCount 4
// These would be better handled as enums, 
// but that requires a seperate .h file.
#define OffTime 0
#define OnTime 1
#define OutputPin 2

// The outputs array defines how long each output will
// be turned off, on, and what pin to use for that output.
// The off and on values are in units of 'ticks'. The length
// of a tick is controlled by the setup of MsTimer2. 
                             // off   on  pin
byte outputs[OutputCount][3] ={{  5,  10,  7},   // Output A
                               { 15,  20,  6},   // Output B
                               {  2,  12,  5},   // Output C
                               { 10,   2,  4},}; // Output D
                    
void OutputHandler(FuseID fuseID, int outputID){
  // look up the pin associated with this output
  byte pin = outputs[outputID][OutputPin];

  // get and invert the current pin state and write
  // it back to the port to invert the current pin state.
  int state = 1&~digitalRead(pin);
  digitalWrite( pin, state );
  
  // Reset the fuse length with a new interval. The current state
  // of the pin is used to determine which interval should be used.
  eventFuse[fuseID].fuseLen = outputs[outputID][state];
}

void timerTick(){
  eventFuse.burn(1);
}

void setup() {
  // Set up and init all outputs to off
  for(byte i = 0; i<OutputCount; i++){
    pinMode( outputs[i][OutputPin], OUTPUT);
    digitalWrite( outputs[i][OutputPin], LOW );

    // Set up an event fuse for this output.
    eventFuse.newFuse( i, outputs[i][OffTime], INF_REPEAT, OutputHandler );
  }
  
  // Set MsTimer2 for one second per tick.
  MsTimer2::set(1000, timerTick );
  MsTimer2::start();
}

void loop(){
}

And here is the link to a good description of such a beast and the links to the libraries: Multiple Timer help [using DateTimeAlarm.h] - #12 by system - Syntax & Programs - Arduino Forum

I hope my noob-ish plundering thru tons of forums and Google searches help someone else out as well... Especially anyone who grows plants indoors with a custom built humidi-dome and/or grow room for veggies and what-not. I plan on using this code to control a Light, ventilation fans, heating pad, pond fogger(mister), and a water pump to recirculate the water condensate back into my fogger reservoir. Eventually I'd like to have feedback loops as well such as humidity and temperature control.

Thanks for replying Rob! It was your post that got me thinking of what to search for after I studied your code....

S2H

http://hacking.majenko.co.uk/finite-state-machine

see if this helps