Page 1 of 1

Cannot adapt lnevo's custom feed mode to delay Port6 start.

Posted: Sun Jan 27, 2013 8:31 pm
by mudcat1
I am attempting to use lnevo's custom feeding mode code to delay the start of my skimmer and reactor (both are plugged into relay port 6) for 2 minutes after the 1 minute feed mode timer expires. Some of the code is working correctly but the delayed start of the skimmer and reactor is not working. The skimmer and reactor starts as soon as the feeding timer expires. I have not been able to adapt lnevo's code to work for me. Any suggestions?

See the **** CUSTOM FEEDING MODE **** section of my current code.

Code: Select all

#include <ReefAngel_Features.h>
#include <Globals.h>
#include <RA_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <InternalEEPROM.h>
#include <RA_NokiaLCD.h>
#include <RA_ATO.h>
#include <RA_Joystick.h>
#include <LED.h>
#include <RA_TempSensor.h>
#include <Relay.h>
#include <RA_PWM.h>
#include <Timer.h>
#include <Memory.h>
#include <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <ReefAngel.h>

// ************ PLACE GLOBAL VARIABLE CODE BELOW HERE *******************

// define what each relay port is used for.
#define ATO_pump       Port1 // Auto Top Off
#define Dose_Alk       Port2 // Dosing Pump Alk
#define Dose_Ca        Port3 // Dosing Pump Ca
#define Dose_Mg        Port4 // Dosing Pump Mg
#define Powerhead      Port5 // Tunze 6105 Powerhead
#define Filtration     Port6 // Reef Octopus skimmer and Reactor
#define Heater         Port7 // Heater
#define Refugium_Light Port8 // Refugium LED Light

// define Internal Memory variables for the 3 dosing pumps
#define Dose_Alk_Seconds 100 // Number of seconds to dose Alk (byte value=90)
#define Dose_Ca_Seconds  101 // Number of seconds to dose Ca (byte value=90)
#define Dose_Mg_Seconds  102 // Number of seconds to dose Mg (byte value=60)

// define Internal Memory variables for Tunze 6105 Powerhead
#define DTime_MinSpeed   103 // Tunze Powerhead Day time Minimum Speed (byte value=34)
#define DTime_MaxSpeed   104 // Tunze Powerhead Day time Maximum Speed (byte value=75  )
#define DTime_Duration   105 // Tunze Powerhead Day time Duration (byte value=3)
#define NTime_MinSpeed   106 // Tunze Powerhead Night time Minimum Speed (byte value=34)
#define NTime_MaxSpeed   107 // Tunze Powerhead Night time Maximum Speed (byte value=50)
#define NTime_Duration   108 // Tunze Powerhead Night time Duration (byte value=3)
#define NTime_StartTime  109 // Tunze Powerhead Night Start time 10:00 pm (byte value=22) 
#define NTime_EndTime    110 // Tunze Powerhead Night End time 8:00 am (byte value=8)
#define Tunze_ShortPulse 111 // TunzeShortPulse=1 or TunzeLongPulse=0 (byte value=1)
#define Feedtime         112 // Set length of time for Feeding menu option (byte value=1)


// added buzzer 1-19-13
// Initialize Buzzer variables
byte buzzer=0;
byte overheatflag=0;
byte atoflag=0;
/* added 1-19-13 - Uncomment when I purchase the IO expansion module.
byte iochannel0flag=0;
byte iochannel1flag=0;
byte iochannel2flag=0;
byte iochannel3flag=0;
byte iochannel4flag=0;
byte iochannel5flag=0;
*/

// Added 1-22-13 to delay the start of the skimmer after feeding the corals.
boolean isFeeding=false;
boolean feedDelay=false;
boolean vtOverride=false;
boolean floatHigh=true;

// Define the custom menu descriptions.
#include <avr/pgmspace.h>
prog_char menu0_label[] PROGMEM = "Feeding";
prog_char menu1_label[] PROGMEM = "Water Change";
prog_char menu2_label[] PROGMEM = "ATO Clear";
prog_char menu3_label[] PROGMEM = "Overheat Clear";
prog_char menu4_label[] PROGMEM = "PH Calibration";
prog_char menu5_label[] PROGMEM = "Sump Light On/Off";
prog_char menu6_label[] PROGMEM = "Powerhead On/Off";
prog_char menu7_label[] PROGMEM = "Version";
PROGMEM const char *menu_items[] = {
menu0_label, menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label, menu7_label  };

void MenuEntry1()
{
//ReefAngel.DisplayMenuEntry("Feeding");
ReefAngel.Timer[FEEDING_TIMER].SetInterval(InternalMemory.read(Feedtime)); // Change feed time interval to ease testing of new code.
ReefAngel.FeedingModeStart();
}

void MenuEntry2()
{
//ReefAngel.DisplayMenuEntry("Water Change");
ReefAngel.WaterChangeModeStart();
}

void MenuEntry3()
{
ReefAngel.ATOClear();
ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
}

void MenuEntry4()
{
ReefAngel.OverheatClear();
ReefAngel.DisplayMenuEntry("Clear Overheat");
}

void MenuEntry5()
{
//ReefAngel.DisplayMenuEntry("PH Calibration");
ReefAngel.SetupCalibratePH();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}

void MenuEntry6()
{
// Clear the screen
ReefAngel.ClearScreen(DefaultBGColor);
// Display some text on the screen.
ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, 5, 10, "Sump Light On/Off");
// Determine whether the Sump Light is already on.
if (bitRead(ReefAngel.Relay.RelayData, Refugium_Light-1)) { // The relay controlling the sump light is on.
  // Toggle MaskOff for the light
  bitWrite(ReefAngel.Relay.RelayMaskOff, Refugium_Light-1, 1-bitRead(ReefAngel.Relay.RelayMaskOff, Refugium_Light-1));
} else { 
  // Toggle the MaskOn for the light.
  bitWrite(ReefAngel.Relay.RelayMaskOn, Refugium_Light-1, 1-bitRead(ReefAngel.Relay.RelayMaskOn, Refugium_Light-1));
}
ReefAngel.Relay.Write();
// Tell the controller to cleanup and return to the main screen.
ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
// To return to the menu instead, comment out the above line and use this line instead.
//ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}

void MenuEntry7()
{
// Clear the screen
ReefAngel.ClearScreen(DefaultBGColor);
// Display some text on the screen
ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, 5, 10, "Powerhead On/Off");
// Determine whether the Powerhead is already on.
if (bitRead(ReefAngel.Relay.RelayData, Powerhead-1)) { // If relay is on.
  // Toggle MaskOff for the powerhead
  bitWrite(ReefAngel.Relay.RelayMaskOff, Powerhead-1, 1-bitRead(ReefAngel.Relay.RelayMaskOff, Powerhead-1));
} else { 
  // Toggle the MaskOn for the powerhead.
  bitWrite(ReefAngel.Relay.RelayMaskOn, Powerhead-1, 1-bitRead(ReefAngel.Relay.RelayMaskOn, Powerhead-1));
}
ReefAngel.Relay.Write();
// Tell the controller to cleanup and return to the main screen.
ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
// To return to the menu instead, comment out the above line and use this line instead.
//ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}

void MenuEntry8()
{
//ReefAngel.DisplayMenuEntry("Display Version");
ReefAngel.DisplayVersion();
}

// ************ PLACE GLOBAL VARIABLE CODE ABOVE HERE *******************

void setup()
{
    // This must be the first line
    ReefAngel.Init();  //Initialize controller
    // Initialize the menu - Added 1-7-13
    ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));
    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = Port5Bit | Port6Bit;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = Port1Bit | Port2Bit | Port3Bit | Port4Bit | Port5Bit | Port6Bit;
    // Ports toggled when Lights On / Off menu entry selected
//    ReefAngel.LightsOnPorts = Port8Bit;  // Removed 1-21-13 to stop the buzzer alarm when sump light was turned on (i.e. 20% Actinic)
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = Port7Bit;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;
    // Set the Overheat temperature setting
    InternalMemory.OverheatTemp_write( 820 );
 
    // Ports that are always on
    ReefAngel.Relay.On( Powerhead ); // Tunze 6105 powerhead 
    ReefAngel.Relay.On( Filtration ); // Reef Octopus skimmer and reactor 
}

// ************ PLACE ADDITIONAL INITIALIZATION CODE BELOW HERE *******************

// Setup SMS alerts
void WifiSendAlert(byte id, boolean IsAlert)
{
  static byte alert_status;
  if (IsAlert) {
    if ((alert_status & 1<<(id-1))==0) {
      alert_status|=1<<(id-1);
      Serial.print("GET /status/alert.asp?e=3141234567@vtext.com&id=");
      Serial.println(alert_status,DEC);
      Serial.println("\n\n"); 
    }
  }
  else {
    if (id==0) {
      alert_status=0;
      delay(900);
    }
    else {
      alert_status&=~(1<<(id-1)); 
    }
  }
}

// Tunze short pulse functions. Uses milliseconds for duration.
  byte TunzeShortPulse(byte PulseMinSpeed, byte PulseMaxSpeed, int PulseDuration, boolean PulseSync)
{
  byte tspeed=0;
  PulseMinSpeed=constrain(PulseMinSpeed,0,100);
  PulseMaxSpeed=constrain(PulseMaxSpeed,0,100);
  tspeed=(millis()%(PulseDuration*2)<PulseDuration?PulseMinSpeed:PulseMaxSpeed);
  if (PulseSync) 
    return tspeed;
  else 
    return (tspeed==PulseMinSpeed)?PulseMaxSpeed:PulseMinSpeed;
}

// Tunze long pulse functions. Uses seconds for duration.
byte TunzeLongPulse(byte PulseMinSpeed, byte PulseMaxSpeed, int PulseDuration, boolean PulseSync)
{
  byte tspeed=0;
  PulseMinSpeed=constrain(PulseMinSpeed,0,100);
  PulseMaxSpeed=constrain(PulseMaxSpeed,0,100);
  tspeed=(now()%(PulseDuration*2)<PulseDuration?PulseMinSpeed:PulseMaxSpeed);
  if (PulseSync)
    return tspeed;
  else
    return (tspeed==PulseMinSpeed)?PulseMaxSpeed:PulseMinSpeed;
}

// ************ PLACE ADDITIONAL INITIALIZATION CODE ABOVE HERE *******************

void loop()
{
        
//*** Heater *** added 12-27-12
   ReefAngel.StandardHeater( Heater,755,765 );

//*** Refugium Light *** added 12-27-12 - Turn light on at 8:00 pm and off at 8:00 am.
   ReefAngel.StandardLights( Refugium_Light,20,0,8,0 );

// ************ PLACE YOUR CUSTOM CODE BELOW HERE *******************
    
   ReefAngel.CustomVar[0]=InternalMemory.read(Dose_Alk_Seconds);
   ReefAngel.CustomVar[1]=InternalMemory.read(Dose_Ca_Seconds);
   ReefAngel.CustomVar[2]=InternalMemory.read(Dose_Mg_Seconds);
   ReefAngel.CustomVar[3]=isFeeding;
//   ReefAngel.CustomVar[3]=ReefAngel.LowATO.IsActive();
   ReefAngel.CustomVar[4]=feedDelay;
//   ReefAngel.CustomVar[4]=ReefAngel.HighATO.IsActive();
   ReefAngel.CustomVar[5]=InternalMemory.read(Tunze_ShortPulse);
   ReefAngel.CustomVar[6]=InternalMemory.read(DTime_MaxSpeed);   
   ReefAngel.CustomVar[7]=InternalMemory.read(NTime_MaxSpeed);

// Added buzzer 1-19-13    
// Sound buzzer if any flag is set.
// Added 1-19-13 - Uncomment when I purchase the IO expansion module.
//   buzzer = overheatflag + atoflag + iochannel0flag + iochannel1flag + iochannel2flag + iochannel3flag + iochannel4flag + iochannel5flag;
   buzzer = overheatflag + atoflag;
   if ( buzzer >= 1 ){
     buzzer = 100; // Change value of buzzer to 100 for full volume.
 } else {
     ReefAngel.PWM.SetActinic(0);
   }  
//   Do not sound the buzzer for empty ATO reservior between 7:00 am and 10:00 pm.
   if (!ReefAngel.LowATO.IsActive() && ( hour() >= 7 && hour() < 22)) {
      ReefAngel.PWM.SetActinic( buzzer );
 } else {   
      ReefAngel.PWM.SetActinic(0);
      if (!ReefAngel.HighATO.IsActive()) { 
        ReefAngel.PWM.SetActinic( buzzer );
    } else {
        ReefAngel.PWM.SetActinic(0);
      }
   }    
/* ***** TUNZE 6105 ******
Added 1-19-13 to control Tunze 6105 powerhead using internal variables.
Night mode for Tunze powerheads starts at 10:00 pm and stops at 8:00 am. ShortPulse appears to create more random length pulses.
LongPulse appears to completely stop the powerhead between pulses.
*/
   if ( (hour() >= InternalMemory.read(NTime_StartTime)) || (hour() <= InternalMemory.read(NTime_EndTime)) ){
     if ( Tunze_ShortPulse == 1 ){ // Determine which Tunze Pulse type (Short or Long) has been selected. 
       ReefAngel.PWM.SetDaylight( TunzeShortPulse(InternalMemory.read(NTime_MinSpeed),InternalMemory.read(NTime_MaxSpeed),InternalMemory.read(NTime_Duration),false) );
   } else {
       ReefAngel.PWM.SetDaylight( TunzeLongPulse(InternalMemory.read(NTime_MinSpeed),InternalMemory.read(NTime_MaxSpeed),InternalMemory.read(NTime_Duration),false) );} 
 } else {
   // Day mode for Tunze powerheads
     if ( Tunze_ShortPulse == 1 ){ // Determine which Tunze Pulse (Short or Long) type has been selected. 
       ReefAngel.PWM.SetDaylight( TunzeShortPulse(InternalMemory.read(DTime_MinSpeed),InternalMemory.read(DTime_MaxSpeed),InternalMemory.read(DTime_Duration),false) );
   } else {
       ReefAngel.PWM.SetDaylight( TunzeLongPulse(InternalMemory.read(DTime_MinSpeed),InternalMemory.read(DTime_MaxSpeed),InternalMemory.read(DTime_Duration),false) );
     } 
   }

/* **** DOSING ****
Added code to set the dosing time in secondes from a variable in the web portal or android application, so I don't have to 
upload code every time I want to make slight adjustments to the amount I dose.  BRS dosers dose 1.1 ml per minute.
*/
// Dose Alk one time per hour between 8:00 pm and 5:00 am.
// Note: Because this dosing occurs for less than 5 minutes it will not be recorded in the Relay activity view in the web portal
   if ( hour() >=20 || hour() <5) {
     ReefAngel.DosingPumpRepeat( Dose_Alk,0,60,InternalMemory.read(Dose_Alk_Seconds));  // Dose Alk for x number of seconds at the top of the hour.
 } else {
     ReefAngel.Relay.Off( Dose_Alk );
   }  

// Dose Ca and Mg one time per hour between 9:00 am and 6:00 pm.
// Note: Because this dosing occurs for less than 5 minutes it will not be recorded in the Relay activity view in the web portal.
   if ( hour() >=9 && hour() <18) {
     ReefAngel.DosingPumpRepeat( Dose_Ca,0,60,InternalMemory.read(Dose_Ca_Seconds)); // Dose Ca for x number of seconds at the top of the hour.
     ReefAngel.DosingPumpRepeat( Dose_Mg,10,60,InternalMemory.read(Dose_Mg_Seconds)); // Dose Mg for x number of seconds 10 minutes after the top of the hour.
 } else {
     ReefAngel.Relay.Off( Dose_Ca );
     ReefAngel.Relay.Off( Dose_Mg );
   }

/* **** SMS TEXT ALERTS ****
Future enhancement: Allow us to add custom text for SMS alerts.

 List of the possible alert codes.
   WifiSendAlert(0)="Nothing"
   WifiSendAlert(1)="Auto top-off timeout"
   WifiSendAlert(2)="Water temperature too high"
   WifiSendAlert(3)="Water temperature too low"
   WifiSendAlert(4)="Lights temperature too high"
   WifiSendAlert(5)="PH too high"
   WifiSendAlert(6)="PH too low Alert"

   Let's say you would like to receive a high water temperature alert.
   The line you have to add is:
   if (ReefAngel.Params.Temp1>820) WifiSendAlert(2);
*/
// Send SMS text message alert if temp1 is less than 74.5 degrees.    
   if (ReefAngel.Params.Temp[1]<745 && ReefAngel.Params.Temp[1]>0) WifiSendAlert(3,true); 
// Send SMS text message alert if temp1 is greater than 82 degrees.
   if (ReefAngel.Params.Temp[1]>820 && ReefAngel.Params.Temp[1]<1850) WifiSendAlert(2,false);

// *** ATO *** added 12-29-12
// Shutoff ATO pump if the ATO reservoir is empty or if the sump is going to overflow.        
   if (!ReefAngel.LowATO.IsActive() || !ReefAngel.HighATO.IsActive()){
     atoflag=1;  // added 1-20-13 to start buzzer alarm.
     ReefAngel.Relay.Off (ATO_pump);
 } else {
     atoflag=0; // added 1-21-13 to reset buzzer.
     ReefAngel.Relay.On (ATO_pump);
   }
/* ****** CUSTOM FEEDING MODE ******
Added 1-22-13 Delay filtration for 120 minutes.
*/
  // Enable Feeding Mode flag
  if (ReefAngel.DisplayedMenu==FEEDING_MODE) isFeeding=true;
  // Turn on Refugium light during feeding and water change mode
  if (ReefAngel.DisplayedMenu==FEEDING_MODE || ReefAngel.DisplayedMenu==WATERCHANGE_MODE) {
    ReefAngel.Relay.On(Refugium_Light);
  }
    
  // Here's what we do if we're just out of feeding mode...
  if (ReefAngel.DisplayedMenu==DEFAULT_MENU && isFeeding) {
    isFeeding=false; 
    feedDelay=true; // This will let us know we want some extra time before starting filtration
    setRFtimer(2); // Start Filtration in 120 minutes... Change from 2 to 120 minutes after testing
  } else if (vtOverride && ReefAngel.Timer[1].IsTriggered()) { // Our RF timer is over. 
    vtOverride=false; // Stop overriding the default RF mode
  
    // First let's deal with that extra 2 to 120 minutes
    if(feedDelay) {
      feedDelay=false; // Reset the feedDelay flag
//      setRFmode(Smart_NTM,vtNTMSpeed,vtNTMDuration); // Smart_NTM time!
// added 1-27-13
      setRFtimer(2); // Start Filtration in 120 minutes... Change from 2 to 120 minutes after testing
      ReefAngel.Relay.RelayMaskOff==Port6Bit; // Turn off skimmer and reactor
    } else {
      // Otherwise go to Previous settings
//      setRFmode(vtPrevMode,vtPrevSpeed,vtPrevDuration); 
      ReefAngel.Relay.RelayMaskOn==Port6Bit; // Turn on skimmer and reactor
    }
  } else   {
//    setRFmode(); // Update the mode if we change it remotely
      ReefAngel.Relay.RelayMaskOn==Port6Bit; // Turn on skimmer and reactor
  }
// I still need to determine how to turn the skimmer and reactor off.

// ************ PLACE YOUR CUSTOM CODE ABOVE HERE *******************

// This should always be the last line
   ReefAngel.Portal( "mudcat1" );
   ReefAngel.ShowInterface();
   }

/*
void setRFmode() {
  setRFmode(InternalMemory.RFMode_read(), InternalMemory.RFSpeed_read(), InternalMemory.RFDuration_read());
}
*/

void setRFtimer(int minutes) {
  ReefAngel.Timer[1].SetInterval(minutes*60);
  ReefAngel.Timer[1].Start();
  vtOverride=true;
}
void setRFtimer() {
  setRFtimer(2); // Change 5 to 120 minutes after testing
}

Cannot adapt lnevo's custom feed mode to delay Port6 start.

Posted: Mon Jan 28, 2013 5:55 am
by lnevo
The goal of my custom feed mode was to wait 30 minutes after coming out of feed mode before doing something... I didn't want to start my Smart_NTM right away... However you are in the right part of my conditional to extend your filtration off, but your code is definitely not right. You want to use the RelayMaskOff to turn it off. Look at the code where I turn the return pump off if atohigh or atolow is active.

bitClear(ReefAngel.Relay.RelayMaskOff,Return-1);

Have you considered using DelayedOn? This seems the right function for what you are trying to accomplish which would be much simpler.

Lee

Re: Cannot adapt lnevo's custom feed mode to delay Port6 sta

Posted: Mon Jan 28, 2013 7:49 pm
by mudcat1
Lee, I have attempted to replace my original code using the DelayOn function that you suggested.

Code: Select all

/* ****** CUSTOM FEEDING MODE ******
Added 1-22-13 Delay filtration on Port6 for 1 minute.
*/
  if (ReefAngel.DisplayedMenu==FEEDING_MODE) { 
    ReefAngel.Relay.DelayedOn(Port6,1);
  }
  // Turn on Refugium light during feeding and water change mode
  if (ReefAngel.DisplayedMenu==FEEDING_MODE || ReefAngel.DisplayedMenu==WATERCHANGE_MODE) {
    ReefAngel.Relay.On(Refugium_Light);
  }
When I enter Feeding Mode from the menu the timer starts the 60 second countdown and Ports 5 and 6 turn off as they should. After the Feed timer expires Port 5 comes back on. After another minute Port 6 should come on but it does not. Is there something else that is required to get the DelayedOn function to turn on Port6?

Thanks for your help,
John

Cannot adapt lnevo's custom feed mode to delay Port6 start.

Posted: Mon Jan 28, 2013 8:30 pm
by lnevo
Just use delayedon instead of on for the devices instead of all the conditionals and stuff.. That will automatically add the delay after feeding mode.

Re: Cannot adapt lnevo's custom feed mode to delay Port6 sta

Posted: Mon Jan 28, 2013 8:34 pm
by mudcat1
Lee, I don't understand your comment. I did remove most of the conditionals. All I have left is...

if (ReefAngel.DisplayedMenu==FEEDING_MODE) {
ReefAngel.Relay.DelayedOn(Port6,1);
}

But it does not turn on Port 6 after the minute delay expires.

Cannot adapt lnevo's custom feed mode to delay Port6 start.

Posted: Mon Jan 28, 2013 9:07 pm
by lnevo
Thats not going to do anything after feeding mode ends..it will revert to whatever function is assigned to that port when not in feeding mode. When i say no conditionals i meant none at all. Just put at the top of your loop DelayedOn for that port instead of any other On or such function.

When you enter water change if that port is set to go off it will stay off during feeding mode and when feeding mode is done it will stay off for whatever time you've set in your delay.

Cannot adapt lnevo's custom feed mode to delay Port6 start.

Posted: Mon Jan 28, 2013 9:11 pm
by lnevo
Like I said, my custom code was not to address keeping the skimmer turned off for x minutes after feeding mode...thats a default built into the standard functions. The design of those conditionals was to start something 30 minutes after feeding mode ended. It could still be adapted for doing what you want, but DelayedOn doesn't require it at all.

The only downside for you that i can see in just using DelayedOn is that it will also delay on at Startup and WaterChange mode...but neither of those should be happening to often...

Re: Cannot adapt lnevo's custom feed mode to delay Port6 sta

Posted: Mon Jan 28, 2013 10:15 pm
by mudcat1
lnevo wrote:Like I said, my custom code was not to address keeping the skimmer turned off for x minutes after feeding mode...thats a default built into the standard functions. The design of those conditionals was to start something 30 minutes after feeding mode ended. It could still be adapted for doing what you want, but DelayedOn doesn't require it at all.

The only downside for you that i can see in just using DelayedOn is that it will also delay on at Startup and WaterChange mode...but neither of those should be happening to often...
Thanks for the clarification Lee. You explanation makes perfect sense now. I will remove all of the conditional statements and use only the DelayedOn. Thanks for all of your help.