00Warpig00's Code Works In Progress

Share you PDE file with our community

Posts: 289
Joined: Wed May 16, 2012 9:52 pm
PostPosted: Mon Jun 30, 2014 9:29 pm
Version 101

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


// Initialize Alert variables
byte AlertNonCritical=0;
byte AlertCritical=0;
byte overheatflag=0;
byte atoflag=0;
byte iochannel0flag=0;
byte iochannel1flag=0;
byte iochannel2flag=0;
byte iochannel3flag=0;
byte iochannel4flag=0;
byte iochannel5flag=0;

//*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions
int T1CurrentMinTemp=0;
int T1CurrentMaxTemp=0;
int T1MinTemp=0;
int T1MaxTemp=0;
//*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

//*****Begin WaterChange Additions

// skimmer port
byte SkimmerPort = Port4;
// return port
byte ReturnPort = Port3;
// sump drain port
byte SumpDrainPort = Port8;
// SaltWater brute pump
byte SWBrutePort = Port7;
// Timer for countdowns
TimerClass tm;

//*****End WaterChange Additions


//*****Begin ATO By Salinity Additions

byte ATOBrutePort = Port2;

//*****End ATO By Salinity Additions


////// Place global variable code above here


//*****Begin Custom Menu Additions

#include <avr/pgmspace.h>
prog_char menu1_label[] PROGMEM = "Mask LED's On";
prog_char menu2_label[] PROGMEM = "Mask LED's Off";
prog_char menu3_label[] PROGMEM = "Mask LED's Clear";
prog_char menu4_label[] PROGMEM = "Water Change";
prog_char menu5_label[] PROGMEM = "Clear ATO Timeout";
prog_char menu6_label[] PROGMEM = "Overheat Clear";
prog_char menu7_label[] PROGMEM = "PH Calibration";
prog_char menu8_label[] PROGMEM = "Date / Time";

// Group the menu entries together
PROGMEM const char *menu_items[] =
  {
    menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label, menu7_label, menu8_label,
  };

//*****End Custom Menu Additions


void setup()
{
    // This must be the first line
    ReefAngel.Init();  //Initialize controller

    //_Running_Config_Revision_101
    InternalMemory.write(100, 101);


    //*****Begin Custom Menu Additions... Initialize Custom Menu

    ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));   
    InternalMemory.write(199, 0); //sets the controller to non masked LED mode upon boot.   

    //*****End Custom Menu Additions


    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = 0;
    ReefAngel.FeedingModePortsE[0] = 0;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = 0;
    ReefAngel.LightsOnPortsE[0] = Port1Bit | Port2Bit;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = Port4Bit | Port5Bit | Port6Bit;
    ReefAngel.OverheatShutoffPortsE[0] = 0;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;
    // Set the Overheat temperature setting
    InternalMemory.OverheatTemp_write( 850 );


    // Ports that are always on
    ReefAngel.Relay.On( Port3 );
    ReefAngel.Relay.On( Box1_Port5 );
    ReefAngel.Relay.On( Box1_Port6 );
    ReefAngel.Relay.On( Box1_Port7 );


    ////// Place additional initialization code below here

    ReefAngel.CustomVar[0]=0;
    ReefAngel.CustomVar[1]=0;
    ReefAngel.CustomVar[2]=0;
    ReefAngel.CustomVar[3]=0;
    ReefAngel.CustomVar[4]=0;
    ReefAngel.CustomVar[5]=0;
    ReefAngel.CustomVar[6]=0;   
    ReefAngel.CustomVar[7]=0;   

    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions
    T1CurrentMinTemp=1;
    T1CurrentMaxTemp=1;
    T1MinTemp=0;
    T1MaxTemp=0;
    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

    ////// Place additional initialization code above here
}

void loop()
{
    ReefAngel.StandardFan( Port1,790,820 );
    ReefAngel.Relay.DelayedOn( Port4,1 );
    ReefAngel.WavemakerRandom( Port5,30,100 );
    ReefAngel.StandardHeater( Port6,750,760 );
    ReefAngel.StandardLights( Box1_Port1,13,0,23,0 );
    ReefAngel.StandardLights( Box1_Port2,13,0,23,0 );
    ReefAngel.StandardHeater( Box1_Port3,750,760 );
    ReefAngel.StandardHeater( Box1_Port4,750,760 );


//*****Begin Custom Menu Additions

  // Removes LED's from a "MASKED" State
  if ( InternalMemory.read(199) == 0 )
    {
      ReefAngel.PWM.SetChannel( 0, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch0 to Parabola math
      ReefAngel.PWM.SetChannel( 1, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch1 to Parabola math
      ReefAngel.PWM.SetChannel( 3, PWMSlope(2,0,7,30,0,50,0,0) ); //Opens/closes 5V relay on Ch3 that shorts\opens dimmer leads on Ch0 LED driver to turn Driver on/off
      ReefAngel.PWM.SetChannel( 4, PWMSlope(0,0,14,0,0,50,0,0) ); //Opens/closes 5V relay on Ch4 that shorts\opens dimmer leads on Ch1 LED driver to turn Driver on/off
    }

  // MASKS LED's Off
  if ( InternalMemory.read(199) == 1 )
    {
      ReefAngel.PWM.SetChannel( 0, 0 ); //Sets LED Drivers on Ch0 to 0%
      ReefAngel.PWM.SetChannel( 1, 0 ); //Sets LED Drivers on Ch1 to 0%
      ReefAngel.PWM.SetChannel( 3, 50 ); //closes 5V relay on Ch3 that shorts dimmer leads on Ch0 LED driver to turn Driver off
      ReefAngel.PWM.SetChannel( 4, 50 ); //closes 5V relay on Ch4 that shorts dimmer leads on Ch1 LED driver to turn Driver off
    }

  if ( InternalMemory.read(199) == 2 )
    {
      ReefAngel.PWM.SetChannel( 0, 100 ); //Sets LED Drivers on Ch0 to 100%
      ReefAngel.PWM.SetChannel( 1, 100 ); //Sets LED Drivers on Ch1 to 100%
      ReefAngel.PWM.SetChannel( 3, 0 ); //Opens 5V relay on Ch3 that removes short on dimmer leads on Ch0 LED driver to turn Driver on
      ReefAngel.PWM.SetChannel( 4, 0 ); //Opens 5V relay on Ch4 that removes short on dimmer leads on Ch1 LED driver to turn Driver on
    }

  else
    {
    }
       
//*****End Custom Menu Additions


//*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions

    T1CurrentMinTemp=ReefAngel.Params.Temp[T1_PROBE];
      if ( T1CurrentMinTemp < T1MinTemp )
        {
          T1MinTemp = T1CurrentMinTemp;
          InternalMemory.write(101, T1MinTemp);
        }
 
    T1CurrentMaxTemp=ReefAngel.Params.Temp[T1_PROBE];
      if ( T1CurrentMaxTemp > T1MaxTemp )
        {
          T1MaxTemp = T1CurrentMaxTemp;
          InternalMemory.write(102, T1MaxTemp);
        }
   
//*****End reporting of Maximum\Minimum Temperature on probe T1 Additions


    overheatflag = InternalMemory.read( Overheat_Exceed_Flag );
    atoflag = InternalMemory.read( ATO_Exceed_Flag );
    iochannel0flag = ! ReefAngel.IO.GetChannel( 0 );
    iochannel1flag = ! ReefAngel.IO.GetChannel( 1 );
    iochannel2flag = ! ReefAngel.IO.GetChannel( 2 );
    iochannel3flag = ! ReefAngel.IO.GetChannel( 3 );
    iochannel4flag = ! ReefAngel.IO.GetChannel( 4 );
    iochannel5flag = ! ReefAngel.IO.GetChannel( 5 );
    AlertNonCritical = atoflag + iochannel2flag + iochannel3flag + iochannel4flag + iochannel5flag;
    AlertCritical = overheatflag + iochannel0flag + iochannel1flag;   
    if ( AlertNonCritical >= 1 ) AlertNonCritical = 5;
    if ( AlertCritical >= 1 ) AlertCritical = 5;   
    ReefAngel.PWM.SetActinic(millis()%60000<100?AlertNonCritical:0);
    ReefAngel.PWM.SetDaylight(millis()%60000<100?AlertNonCritical:0);
    if ( AlertCritical >= 1 ) ReefAngel.PWM.SetActinic(millis()%300<100?AlertCritical:0);
    if ( AlertCritical >= 1 ) ReefAngel.PWM.SetDaylight(millis()%300<100?AlertCritical:0);   

   
    ////// Place your custom code below here

    ReefAngel.CustomVar[0]=InternalMemory.read(ATO_Exceed_Flag);
    ReefAngel.CustomVar[1]=InternalMemory.read(Overheat_Exceed_Flag);
    ReefAngel.CustomVar[2]=0;
    ReefAngel.CustomVar[3]=0;
    ReefAngel.CustomVar[4]=InternalMemory.read(199);
    ReefAngel.CustomVar[5]=AlertNonCritical;
    ReefAngel.CustomVar[6]=AlertCritical;   
    ReefAngel.CustomVar[7]=ATOBrutePort;
   
    if ( ReefAngel.CustomVar[0]== 1 )
      {
        ReefAngel.Relay.RelayMaskOff=~(Port4Bit);
      }

    //*****Begin WC Additions

    // If menu equals waterchange mode
    // then we start the automatic water change
    // Otherwise we ignore and proceed
    if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
      {
        AutoWaterChange();
      }
   
    //*****End WC Additions
   
   
    //*****Begin ATO By Salinity Additions
   
    if (ReefAngel.Params.Salinity<300)
      {
        ATOBrutePort=Port7;
      }
    else
      {
        ATOBrutePort=Port2;
      }
    ReefAngel.StandardATO(ATOBrutePort,40 );
    if (iochannel2flag == 1)
      {
        ReefAngel.Relay.RelayMaskOff=~(Port7Bit);
      }
    if (iochannel4flag == 1)
      {
        ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
      }
     
    //*****End ATO By Salinity Additions


    ////// Place your custom code above here

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


//*****Begin Custom Menu Additions

//Mask LED's On. Forces LED's On Full Blast
void MenuEntry1()
  {
    InternalMemory.write(199, 2);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights On"); waitForTime(2);
    ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
  }

//Mask LED's Off. Forces LED's Off
void MenuEntry2()
  {
    InternalMemory.write(199, 1);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Off"); waitForTime(2);
    ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
  }

//Mask LED's Clear. Remove LED Masking Returns LED's To Normal Schedule
void MenuEntry3()
  {
    InternalMemory.write(199, 0);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Clear"); waitForTime(2);
    ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
  }
 
//Start Waterchange Mode
void MenuEntry4()
  {
    ReefAngel.WaterChangeModeStart();
  }

//Clear ATO Timeout Flag
void MenuEntry5()
  {
    ReefAngel.ATOClear();
    ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
  }

//Clear Overheat Flag
void MenuEntry6()
  {
    ReefAngel.OverheatClear();
    ReefAngel.DisplayMenuEntry("Clear Overheat");
  }

//Calibrate PH Probe
void MenuEntry7()
  {
    ReefAngel.SetupCalibratePH();
    ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
  }

//Set clock Date & Time
void MenuEntry8()
  {
    ReefAngel.SetupDateTime();
    ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
  }
 
//*****End Custom Menu Additions


//*****Begin WC Additions

void AutoWaterChange()
{
    // auto water change mode
    // Display Starting Water Change"
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Water Change"); waitForTime(3);

    // Check Saltwater BRUTE for sufficient saltwater on IO Module Port2
    if ( isSWBruteEmpty() )
      {
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Not Enough Saltwater"); waitForTime(3);

        //Abort Water Change if insufficient saltwater
        // Handles the cleanup to return to the main screen
        ReefAngel.ClearScreen(DefaultBGColor);
        ReefAngel.DisplayedMenu = DEFAULT_MENU;
        DrawCustomGraph();
        return;
      }
   
    //Display Disabling ATO Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");   
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Disabling ATO Pump"); waitForTime(3);

    // turn off ATO pump port to prevent ATO from trying to fill a sump being drained intentionally
    ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
   
    //Display Stopping Skimmer
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Skimmer"); waitForTime(3);

    // turn off the skimmer port
    ReefAngel.Relay.Off(SkimmerPort);
    ReefAngel.Relay.Write();
   
    //Display Skimmer Draining
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Draining"); waitForTime(3);   

    // wait for 1 minute
    waitForTime(60);

    //Display Skimmer Done Draining
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Done Draining"); waitForTime(3);
   
    //display Stopping Return Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Return Pump"); waitForTime(3);

    //Stop Return Pump
    ReefAngel.Relay.Off(ReturnPort);
    ReefAngel.Relay.Write();
   
    //Display Draining To Sump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Draining To Sump"); waitForTime(3);

    //display Sump Filling
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Filling"); waitForTime(3);

    // wait for IO Mod Port 1 to be active
    waitForIOChannel(1);

    //display Sump Is Full
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

    //Display Sump Settling
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

    // wait for sump to settle
    waitForTime(30);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

    // display Draining Sump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Draining Sump"); waitForTime(3);

    //turn on sump drain pump
    ReefAngel.Relay.On(SumpDrainPort);
    ReefAngel.Relay.Write();

    //display Sump Draining
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Draining"); waitForTime(3);

    // wait for sump empty port active, IO Mod Port 0
    waitForIOChannel(0);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Empty"); waitForTime(3);

    //display Stopping Sump Draining
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Sump Drain"); waitForTime(3);

    // turn off sump drain
    ReefAngel.Relay.Off(SumpDrainPort);
    ReefAngel.Relay.Write();

    //Display Sump Settling
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

    // wait for sump to settle
    waitForTime(30);

    //display Sump Settled
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

    //display Starting Saltwater Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Saltwater Pump"); waitForTime(3);
 
    //turn on Saltwater Pump
    ReefAngel.Relay.On(SWBrutePort);
    ReefAngel.Relay.Write();

    //display Saltwater Pumping
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Saltwater Pumping"); waitForTime(3);

    // wait for sump full float switch active, IO Mod Port 1
    waitForIOChannel(1);

    //display Stop Saltwater Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stop Saltwater Pump"); waitForTime(3);

    // turn off sw brute pump
    ReefAngel.Relay.Off(SWBrutePort);
    ReefAngel.Relay.Write();   

    //diasplay Sump is Full
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

    //Display Sump Settling
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

    // wait for sump to settle
    waitForTime(30);

    //display Sump Settled
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);
   
    //display Starting Return Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Return Pump"); waitForTime(3);

    // turn on return pump
    ReefAngel.Relay.On(ReturnPort);
    ReefAngel.Relay.Write();

    //display Return Pump Started
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Return Pump Started"); waitForTime(3);
 
    //display Normalizing Waterlevel
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Waterlevel"); waitForTime(3);

    //waiting 2 minutes for waterlevel to normalize
    waitForTime(120);
   
    //display Starting Skimer
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Skimmer"); waitForTime(3);

    //turn on skimmer
    ReefAngel.Relay.On(SkimmerPort);
    ReefAngel.Relay.Write();

    //display Normalizing Skimmer
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Skimmer"); waitForTime(3);

    //wait for 2 minutes for skimmer to normalize
    waitForTime(120);

    //display Skimmer Normalized
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Normalized"); waitForTime(3);

    //display Enabling ATO Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Enabling ATO Pump"); waitForTime(3);

    //Enable ATO pump
    ReefAngel.Relay.RelayMaskOff = B11111111;
    ReefAngel.Relay.Write();

    //display Water Change Complete
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Water Change Complete"); waitForTime(3);

    // Handles the cleanup to return to the main screen
    ReefAngel.ClearScreen(DefaultBGColor);
    ReefAngel.DisplayedMenu = DEFAULT_MENU;
    DrawCustomGraph();
}

bool isSWBruteEmpty()
{
  // check status of IO Mod Port 2
  if ( ! ReefAngel.IO.GetChannel(2) )
      return true;
  return false;
}

void waitForTime(int seconds)
{
    bool done = false;
    tm.SetInterval(seconds);
    tm.Start();
    int t = tm.Trigger - now();
    do
    {
      // check the wifi interface
      pingSerial();
      // wait for specified seconds
      if ( (t >= 0) && ! tm.IsTriggered() )
        {
          // TODO finish countdown on screen
          // show countdown on screen
          //LCD.Clear(DefaultBGColor,60+(intlength(t)*5),100,100,108);
          //LCD.DrawText(DefaultFGColor,DefaultBGColor,60,100,t);
          wdt_reset();
          delay(200);
        }
        else
        {
          done = true;
        }
    } while ( !done );
    return;
}

void waitForIOChannel(byte channel)
{
    // TODO complete this function
    do
    {
      wdt_reset();
      // display something on screen
      // check the wifi interface
      pingSerial();
      delay(200);
      // TODO check the IO channel logic
    } while ( ReefAngel.IO.GetChannel(channel) );
}

//*****End WC Additions


void DrawCustomMain()
{
    int x,y;
    char text[10];
    // Dimming Expansion
    x = 15;
    y = 2;
    for ( int a=0;a<6;a++ )
    {
      if ( a>2 ) x = 75;
      if ( a==3 ) y = 2;
      ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x,y,"Ch :   " );
      ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+12,y,a );
      ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+24,y,ReefAngel.PWM.GetChannelValue(a) );
      y += 10;
    }
    pingSerial();

    // I/O Expansion
    byte bkcolor;
    x = 14;
    y = 34;
    for ( int a=0;a<6;a++ )
    {
      ReefAngel.LCD.DrawCircleOutline( x+(a*20),y,4,COLOR_MEDIUMORCHID );
      if ( ReefAngel.IO.GetChannel(a) ) bkcolor=COLOR_WHITE; else bkcolor=COLOR_GRAY;
      ReefAngel.LCD.FillCircle( x+(a*20),y,2,bkcolor );
    }
    pingSerial();

    // Parameters
#if defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params,
    ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params );
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
    pingSerial();

    // Salinity
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,76, "SAL:" );
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,60,76, "L" );   
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,90,76, "H" );       
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,39,76, ReefAngel.Params.Salinity );
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,69,76, T1MinTemp );
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,98,76, T1MaxTemp );   
    pingSerial();

    // Main Relay Box
    byte TempRelay = ReefAngel.Relay.RelayData;
    TempRelay &= ReefAngel.Relay.RelayMaskOff;
    TempRelay |= ReefAngel.Relay.RelayMaskOn;
    ReefAngel.LCD.DrawOutletBox( 12, 90, TempRelay );
    pingSerial();

    // Relay Expansion
    TempRelay = ReefAngel.Relay.RelayDataE[0];
    TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
    TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
    ReefAngel.LCD.DrawOutletBox( 12, 104, TempRelay );
    pingSerial();

    // Date and Time
    ReefAngel.LCD.DrawDate( 6, 122 );
    pingSerial();
}

void DrawCustomGraph()
{
}


180G FOWLR
20GH QT#1
29G QT#2

Image

Posts: 289
Joined: Wed May 16, 2012 9:52 pm
PostPosted: Mon Jun 30, 2014 9:31 pm
Version 102

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


// Initialize Alert variables
byte AlertNonCritical=0;
byte AlertCritical=0;
byte overheatflag=0;
byte atoflag=0;
byte iochannel0flag=0;
byte iochannel1flag=0;
byte iochannel2flag=0;
byte iochannel3flag=0;
byte iochannel4flag=0;
byte iochannel5flag=0;

//*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions
int T1MinTemp=9999;
int T1MaxTemp=1;
int T1Temp=1;

//*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

//*****Begin WaterChange Additions

// skimmer port
byte SkimmerPort = Port4;
// return port
byte ReturnPort = Port3;
// sump drain port
byte SumpDrainPort = Port8;
// SaltWater brute pump
byte SWBrutePort = Port7;
// Timer for countdowns
TimerClass tm;

//*****End WaterChange Additions


//*****Begin ATO By Salinity Additions

byte ATOBrutePort = Port2;

//*****End ATO By Salinity Additions


////// Place global variable code above here


//*****Begin Custom Menu Additions

#include <avr/pgmspace.h>
prog_char menu1_label[] PROGMEM = "Mask LED's On";
prog_char menu2_label[] PROGMEM = "Mask LED's Off";
prog_char menu3_label[] PROGMEM = "Mask LED's Clear";
prog_char menu4_label[] PROGMEM = "Water Change";
prog_char menu5_label[] PROGMEM = "Clear ATO Timeout";
prog_char menu6_label[] PROGMEM = "Overheat Clear";
prog_char menu7_label[] PROGMEM = "PH Calibration";
prog_char menu8_label[] PROGMEM = "Date / Time";

// Group the menu entries together
PROGMEM const char *menu_items[] =
  {
    menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label, menu7_label, menu8_label,
  };

//*****End Custom Menu Additions


void setup()
{
    // This must be the first line
    ReefAngel.Init();  //Initialize controller

    //_Running_Config_Revision_102
    InternalMemory.write(100, 102);


    //*****Begin Custom Menu Additions... Initialize Custom Menu

    ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));   
    InternalMemory.write(199, 0); //sets the controller to non masked LED mode upon boot.   

    //*****End Custom Menu Additions


    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = 0;
    ReefAngel.FeedingModePortsE[0] = 0;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = 0;
    ReefAngel.LightsOnPortsE[0] = Port1Bit | Port2Bit;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = Port4Bit | Port5Bit | Port6Bit;
    ReefAngel.OverheatShutoffPortsE[0] = 0;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;
    // Set the Overheat temperature setting
    InternalMemory.OverheatTemp_write( 850 );


    // Ports that are always on
    ReefAngel.Relay.On( Port3 );
    ReefAngel.Relay.On( Box1_Port5 );
    ReefAngel.Relay.On( Box1_Port6 );
    ReefAngel.Relay.On( Box1_Port7 );


    ////// Place additional initialization code below here

    ReefAngel.CustomVar[0]=0;
    ReefAngel.CustomVar[1]=0;
    ReefAngel.CustomVar[2]=0;
    ReefAngel.CustomVar[3]=0;
    ReefAngel.CustomVar[4]=0;
    ReefAngel.CustomVar[5]=0;
    ReefAngel.CustomVar[6]=0;   
    ReefAngel.CustomVar[7]=0;   


    ////// Place additional initialization code above here
}

void loop()
{
    ReefAngel.StandardFan( Port1,790,820 );
    ReefAngel.Relay.DelayedOn( Port4,1 );
    ReefAngel.WavemakerRandom( Port5,30,100 );
    ReefAngel.StandardHeater( Port6,750,760 );
    ReefAngel.StandardLights( Box1_Port1,13,0,23,0 );
    ReefAngel.StandardLights( Box1_Port2,13,0,23,0 );
    ReefAngel.StandardHeater( Box1_Port3,750,760 );
    ReefAngel.StandardHeater( Box1_Port4,750,760 );


//*****Begin Custom Menu Additions

  // Removes LED's from a "MASKED" State
  if ( InternalMemory.read(199) == 0 )
    {
      ReefAngel.PWM.SetChannel( 0, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch0 to Parabola math
      ReefAngel.PWM.SetChannel( 1, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch1 to Parabola math
      ReefAngel.PWM.SetChannel( 3, PWMSlope(2,0,7,30,0,50,0,0) ); //Opens/closes 5V relay on Ch3 that shorts\opens dimmer leads on Ch0 LED driver to turn Driver on/off
      ReefAngel.PWM.SetChannel( 4, PWMSlope(0,0,14,0,0,50,0,0) ); //Opens/closes 5V relay on Ch4 that shorts\opens dimmer leads on Ch1 LED driver to turn Driver on/off
    }

  // MASKS LED's Off
  if ( InternalMemory.read(199) == 1 )
    {
      ReefAngel.PWM.SetChannel( 0, 0 ); //Sets LED Drivers on Ch0 to 0%
      ReefAngel.PWM.SetChannel( 1, 0 ); //Sets LED Drivers on Ch1 to 0%
      ReefAngel.PWM.SetChannel( 3, 50 ); //closes 5V relay on Ch3 that shorts dimmer leads on Ch0 LED driver to turn Driver off
      ReefAngel.PWM.SetChannel( 4, 50 ); //closes 5V relay on Ch4 that shorts dimmer leads on Ch1 LED driver to turn Driver off
    }

  if ( InternalMemory.read(199) == 2 )
    {
      ReefAngel.PWM.SetChannel( 0, 100 ); //Sets LED Drivers on Ch0 to 100%
      ReefAngel.PWM.SetChannel( 1, 100 ); //Sets LED Drivers on Ch1 to 100%
      ReefAngel.PWM.SetChannel( 3, 0 ); //Opens 5V relay on Ch3 that removes short on dimmer leads on Ch0 LED driver to turn Driver on
      ReefAngel.PWM.SetChannel( 4, 0 ); //Opens 5V relay on Ch4 that removes short on dimmer leads on Ch1 LED driver to turn Driver on
    }

  else
    {
    }
       
//*****End Custom Menu Additions


//*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions


    T1Temp=ReefAngel.Params.Temp[T1_PROBE];

//T1MaxTemp = T1Temp;
//T1MinTemp = T1Temp;

      if ( T1Temp > T1MaxTemp ) T1MaxTemp = T1Temp;
          InternalMemory.write(102, T1MaxTemp);
       
      if ( T1Temp < T1MinTemp ) T1MinTemp = T1Temp;
          InternalMemory.write(101, T1MinTemp);
 
   
//*****End reporting of Maximum\Minimum Temperature on probe T1 Additions


    overheatflag = InternalMemory.read( Overheat_Exceed_Flag );
    atoflag = InternalMemory.read( ATO_Exceed_Flag );
    iochannel0flag = ! ReefAngel.IO.GetChannel( 0 );
    iochannel1flag = ! ReefAngel.IO.GetChannel( 1 );
    iochannel2flag = ! ReefAngel.IO.GetChannel( 2 );
    iochannel3flag = ! ReefAngel.IO.GetChannel( 3 );
    iochannel4flag = ! ReefAngel.IO.GetChannel( 4 );
    iochannel5flag = ! ReefAngel.IO.GetChannel( 5 );
    AlertNonCritical = atoflag + iochannel2flag + iochannel3flag + iochannel4flag + iochannel5flag;
    AlertCritical = overheatflag + iochannel0flag + iochannel1flag;   
    if ( AlertNonCritical >= 1 ) AlertNonCritical = 5;
    if ( AlertCritical >= 1 ) AlertCritical = 5;   
    ReefAngel.PWM.SetActinic(millis()%60000<100?AlertNonCritical:0);
    ReefAngel.PWM.SetDaylight(millis()%60000<100?AlertNonCritical:0);
    if ( AlertCritical >= 1 ) ReefAngel.PWM.SetActinic(millis()%300<100?AlertCritical:0);
    if ( AlertCritical >= 1 ) ReefAngel.PWM.SetDaylight(millis()%300<100?AlertCritical:0);   

   
    ////// Place your custom code below here

    ReefAngel.CustomVar[0]=InternalMemory.read(ATO_Exceed_Flag);
    ReefAngel.CustomVar[1]=InternalMemory.read(Overheat_Exceed_Flag);
    ReefAngel.CustomVar[2]=0;
    ReefAngel.CustomVar[3]=0;
    ReefAngel.CustomVar[4]=InternalMemory.read(199);
    ReefAngel.CustomVar[5]=AlertNonCritical;
    ReefAngel.CustomVar[6]=AlertCritical;   
    ReefAngel.CustomVar[7]=ATOBrutePort;
   
    if ( ReefAngel.CustomVar[0]== 1 )
      {
        ReefAngel.Relay.RelayMaskOff=~(Port4Bit);
      }

    //*****Begin WC Additions

    // If menu equals waterchange mode
    // then we start the automatic water change
    // Otherwise we ignore and proceed
    if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
      {
        AutoWaterChange();
      }
   
    //*****End WC Additions
   
   
    //*****Begin ATO By Salinity Additions
   
    if (ReefAngel.Params.Salinity<300)
      {
        ATOBrutePort=Port7;
      }
    else
      {
        ATOBrutePort=Port2;
      }
    ReefAngel.StandardATO(ATOBrutePort,40 );
    if (iochannel2flag == 1)
      {
        ReefAngel.Relay.RelayMaskOff=~(Port7Bit);
      }
    if (iochannel4flag == 1)
      {
        ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
      }
     
    //*****End ATO By Salinity Additions


    ////// Place your custom code above here

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


//*****Begin Custom Menu Additions

//Mask LED's On. Forces LED's On Full Blast
void MenuEntry1()
  {
    InternalMemory.write(199, 2);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights On"); waitForTime(2);
    ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
  }

//Mask LED's Off. Forces LED's Off
void MenuEntry2()
  {
    InternalMemory.write(199, 1);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Off"); waitForTime(2);
    ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
  }

//Mask LED's Clear. Remove LED Masking Returns LED's To Normal Schedule
void MenuEntry3()
  {
    InternalMemory.write(199, 0);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Clear"); waitForTime(2);
    ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
  }
 
//Start Waterchange Mode
void MenuEntry4()
  {
    ReefAngel.WaterChangeModeStart();
  }

//Clear ATO Timeout Flag
void MenuEntry5()
  {
    ReefAngel.ATOClear();
    ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
  }

//Clear Overheat Flag
void MenuEntry6()
  {
    ReefAngel.OverheatClear();
    ReefAngel.DisplayMenuEntry("Clear Overheat");
  }

//Calibrate PH Probe
void MenuEntry7()
  {
    ReefAngel.SetupCalibratePH();
    ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
  }

//Set clock Date & Time
void MenuEntry8()
  {
    ReefAngel.SetupDateTime();
    ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
  }
 
//*****End Custom Menu Additions


//*****Begin WC Additions

void AutoWaterChange()
{
    // auto water change mode
    // Display Starting Water Change"
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Water Change"); waitForTime(3);

    // Check Saltwater BRUTE for sufficient saltwater on IO Module Port2
    if ( isSWBruteEmpty() )
      {
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Not Enough Saltwater"); waitForTime(3);

        //Abort Water Change if insufficient saltwater
        // Handles the cleanup to return to the main screen
        ReefAngel.ClearScreen(DefaultBGColor);
        ReefAngel.DisplayedMenu = DEFAULT_MENU;
        DrawCustomGraph();
        return;
      }
   
    //Display Disabling ATO Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");   
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Disabling ATO Pump"); waitForTime(3);

    // turn off ATO pump port to prevent ATO from trying to fill a sump being drained intentionally
    ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
   
    //Display Stopping Skimmer
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Skimmer"); waitForTime(3);

    // turn off the skimmer port
    ReefAngel.Relay.Off(SkimmerPort);
    ReefAngel.Relay.Write();
   
    //Display Skimmer Draining
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Draining"); waitForTime(3);   

    // wait for 1 minute
    waitForTime(60);

    //Display Skimmer Done Draining
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Done Draining"); waitForTime(3);
   
    //display Stopping Return Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Return Pump"); waitForTime(3);

    //Stop Return Pump
    ReefAngel.Relay.Off(ReturnPort);
    ReefAngel.Relay.Write();
   
    //Display Draining To Sump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Draining To Sump"); waitForTime(3);

    //display Sump Filling
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Filling"); waitForTime(3);

    // wait for IO Mod Port 1 to be active
    waitForIOChannel(1);

    //display Sump Is Full
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

    //Display Sump Settling
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

    // wait for sump to settle
    waitForTime(30);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

    // display Draining Sump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Draining Sump"); waitForTime(3);

    //turn on sump drain pump
    ReefAngel.Relay.On(SumpDrainPort);
    ReefAngel.Relay.Write();

    //display Sump Draining
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Draining"); waitForTime(3);

    // wait for sump empty port active, IO Mod Port 0
    waitForIOChannel(0);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Empty"); waitForTime(3);

    //display Stopping Sump Draining
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Sump Drain"); waitForTime(3);

    // turn off sump drain
    ReefAngel.Relay.Off(SumpDrainPort);
    ReefAngel.Relay.Write();

    //Display Sump Settling
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

    // wait for sump to settle
    waitForTime(30);

    //display Sump Settled
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

    //display Starting Saltwater Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Saltwater Pump"); waitForTime(3);
 
    //turn on Saltwater Pump
    ReefAngel.Relay.On(SWBrutePort);
    ReefAngel.Relay.Write();

    //display Saltwater Pumping
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Saltwater Pumping"); waitForTime(3);

    // wait for sump full float switch active, IO Mod Port 1
    waitForIOChannel(1);

    //display Stop Saltwater Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stop Saltwater Pump"); waitForTime(3);

    // turn off sw brute pump
    ReefAngel.Relay.Off(SWBrutePort);
    ReefAngel.Relay.Write();   

    //diasplay Sump is Full
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

    //Display Sump Settling
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

    // wait for sump to settle
    waitForTime(30);

    //display Sump Settled
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);
   
    //display Starting Return Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Return Pump"); waitForTime(3);

    // turn on return pump
    ReefAngel.Relay.On(ReturnPort);
    ReefAngel.Relay.Write();

    //display Return Pump Started
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Return Pump Started"); waitForTime(3);
 
    //display Normalizing Waterlevel
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Waterlevel"); waitForTime(3);

    //waiting 2 minutes for waterlevel to normalize
    waitForTime(120);
   
    //display Starting Skimer
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Skimmer"); waitForTime(3);

    //turn on skimmer
    ReefAngel.Relay.On(SkimmerPort);
    ReefAngel.Relay.Write();

    //display Normalizing Skimmer
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Skimmer"); waitForTime(3);

    //wait for 2 minutes for skimmer to normalize
    waitForTime(120);

    //display Skimmer Normalized
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Normalized"); waitForTime(3);

    //display Enabling ATO Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Enabling ATO Pump"); waitForTime(3);

    //Enable ATO pump
    ReefAngel.Relay.RelayMaskOff = B11111111;
    ReefAngel.Relay.Write();

    //display Water Change Complete
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Water Change Complete"); waitForTime(3);

    // Handles the cleanup to return to the main screen
    ReefAngel.ClearScreen(DefaultBGColor);
    ReefAngel.DisplayedMenu = DEFAULT_MENU;
    DrawCustomGraph();
}

bool isSWBruteEmpty()
{
  // check status of IO Mod Port 2
  if ( ! ReefAngel.IO.GetChannel(2) )
      return true;
  return false;
}

void waitForTime(int seconds)
{
    bool done = false;
    tm.SetInterval(seconds);
    tm.Start();
    int t = tm.Trigger - now();
    do
    {
      // check the wifi interface
      pingSerial();
      // wait for specified seconds
      if ( (t >= 0) && ! tm.IsTriggered() )
        {
          // TODO finish countdown on screen
          // show countdown on screen
          //LCD.Clear(DefaultBGColor,60+(intlength(t)*5),100,100,108);
          //LCD.DrawText(DefaultFGColor,DefaultBGColor,60,100,t);
          wdt_reset();
          delay(200);
        }
        else
        {
          done = true;
        }
    } while ( !done );
    return;
}

void waitForIOChannel(byte channel)
{
    // TODO complete this function
    do
    {
      wdt_reset();
      // display something on screen
      // check the wifi interface
      pingSerial();
      delay(200);
      // TODO check the IO channel logic
    } while ( ReefAngel.IO.GetChannel(channel) );
}

//*****End WC Additions


void DrawCustomMain()
{
    int x,y;
    char text[10];
    // Dimming Expansion
    x = 15;
    y = 2;
    for ( int a=0;a<6;a++ )
    {
      if ( a>2 ) x = 75;
      if ( a==3 ) y = 2;
      ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x,y,"Ch :   " );
      ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+12,y,a );
      ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+24,y,ReefAngel.PWM.GetChannelValue(a) );
      y += 10;
    }
    pingSerial();

    // I/O Expansion
    byte bkcolor;
    x = 14;
    y = 34;
    for ( int a=0;a<6;a++ )
    {
      ReefAngel.LCD.DrawCircleOutline( x+(a*20),y,4,COLOR_MEDIUMORCHID );
      if ( ReefAngel.IO.GetChannel(a) ) bkcolor=COLOR_WHITE; else bkcolor=COLOR_GRAY;
      ReefAngel.LCD.FillCircle( x+(a*20),y,2,bkcolor );
    }
    pingSerial();

    // Parameters
#if defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params,
    ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params );
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
    pingSerial();

    // Salinity
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,76, "SAL:" );
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,60,76, "L" );   
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,90,76, "H" );       
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,39,76, ReefAngel.Params.Salinity );
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,69,76, T1MinTemp );
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,98,76, T1MaxTemp );   
    pingSerial();

    // Main Relay Box
    byte TempRelay = ReefAngel.Relay.RelayData;
    TempRelay &= ReefAngel.Relay.RelayMaskOff;
    TempRelay |= ReefAngel.Relay.RelayMaskOn;
    ReefAngel.LCD.DrawOutletBox( 12, 90, TempRelay );
    pingSerial();

    // Relay Expansion
    TempRelay = ReefAngel.Relay.RelayDataE[0];
    TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
    TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
    ReefAngel.LCD.DrawOutletBox( 12, 104, TempRelay );
    pingSerial();

    // Date and Time
    ReefAngel.LCD.DrawDate( 6, 122 );
    pingSerial();
}

void DrawCustomGraph()
{
}


180G FOWLR
20GH QT#1
29G QT#2

Image

Posts: 289
Joined: Wed May 16, 2012 9:52 pm
PostPosted: Mon Jun 30, 2014 9:31 pm
Version 103

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 <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


// Initialize Alert variables
byte AlertNonCritical=0;
byte AlertCritical=0;
byte overheatflag=0;
byte atoflag=0;
byte iochannel0flag=0;
byte iochannel1flag=0;
byte iochannel2flag=0;
byte iochannel3flag=0;
byte iochannel4flag=0;
byte iochannel5flag=0;

//*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions
int T1MinTemp=9999;
int T1MaxTemp=1;
int T1Temp=1;

//*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

//*****Begin WaterChange Additions

// skimmer port
byte SkimmerPort = Port4;
// return port
byte ReturnPort = Port3;
// sump drain port
byte SumpDrainPort = Port8;
// SaltWater brute pump
byte SWBrutePort = Port7;
// Timer for countdowns
TimerClass tm;

//*****End WaterChange Additions


//*****Begin ATO By Salinity Additions

byte ATOBrutePort = Port2;

//*****End ATO By Salinity Additions


//*****Begin Custom IO Expander Additions

byte CustomIOExpanderData = 255;

//*****End Custom IO Expander Additions


////// Place global variable code above here


//*****Begin Custom Menu Additions

#include <avr/pgmspace.h>
prog_char menu1_label[] PROGMEM = "Mask LED's On";
prog_char menu2_label[] PROGMEM = "Mask LED's Off";
prog_char menu3_label[] PROGMEM = "Mask LED's Clear";
prog_char menu4_label[] PROGMEM = "Water Change";
prog_char menu5_label[] PROGMEM = "Clear ATO Timeout";
prog_char menu6_label[] PROGMEM = "Overheat Clear";
prog_char menu7_label[] PROGMEM = "PH Calibration";
prog_char menu8_label[] PROGMEM = "Date / Time";

// Group the menu entries together
PROGMEM const char *menu_items[] =
  {
    menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label, menu7_label, menu8_label,
  };

//*****End Custom Menu Additions


void setup()
{
    // This must be the first line
    ReefAngel.Init();  //Initialize controller

    //_Running_Config_Revision_103
    InternalMemory.write(100, 103);


    //*****Begin Custom Menu Additions... Initialize Custom Menu

    ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));   
    InternalMemory.write(199, 0); //sets the controller to non masked LED mode upon boot.   

    //*****End Custom Menu Additions


    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = 0;
    ReefAngel.FeedingModePortsE[0] = 0;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = 0;
    ReefAngel.LightsOnPortsE[0] = Port1Bit | Port2Bit;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = Port4Bit | Port5Bit | Port6Bit;
    ReefAngel.OverheatShutoffPortsE[0] = 0;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;
    // Set the Overheat temperature setting
    InternalMemory.OverheatTemp_write( 850 );


    // Ports that are always on
    ReefAngel.Relay.On( Port3 );
    ReefAngel.Relay.On( Box1_Port5 );
    ReefAngel.Relay.On( Box1_Port6 );
    ReefAngel.Relay.On( Box1_Port7 );


    ////// Place additional initialization code below here

    ReefAngel.CustomVar[0]=0;
    ReefAngel.CustomVar[1]=0;
    ReefAngel.CustomVar[2]=0;
    ReefAngel.CustomVar[3]=0;
    ReefAngel.CustomVar[4]=0;
    ReefAngel.CustomVar[5]=0;
    ReefAngel.CustomVar[6]=0;   
    ReefAngel.CustomVar[7]=0;   


    ////// Place additional initialization code above here
}

void loop()
{
    ReefAngel.StandardFan( Port1,790,820 );
    ReefAngel.Relay.DelayedOn( Port4,1 );
    ReefAngel.WavemakerRandom( Port5,30,100 );
    ReefAngel.StandardHeater( Port6,750,760 );
    ReefAngel.StandardLights( Box1_Port1,13,0,23,0 );
    ReefAngel.StandardLights( Box1_Port2,13,0,23,0 );
    ReefAngel.StandardHeater( Box1_Port3,750,760 );
    ReefAngel.StandardHeater( Box1_Port4,750,760 );


//*****Begin Custom Menu Additions

  // Removes LED's from a "MASKED" State
  if ( InternalMemory.read(199) == 0 )
    {
      ReefAngel.PWM.SetChannel( 0, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch0 to Parabola math
      ReefAngel.PWM.SetChannel( 1, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch1 to Parabola math
      ReefAngel.PWM.SetChannel( 3, PWMSlope(2,0,7,30,0,50,0,0) ); //Opens/closes 5V relay on Ch3 that shorts\opens dimmer leads on Ch0 LED driver to turn Driver on/off
      ReefAngel.PWM.SetChannel( 4, PWMSlope(0,0,14,0,0,50,0,0) ); //Opens/closes 5V relay on Ch4 that shorts\opens dimmer leads on Ch1 LED driver to turn Driver on/off
    }

  // MASKS LED's Off
  if ( InternalMemory.read(199) == 1 )
    {
      ReefAngel.PWM.SetChannel( 0, 0 ); //Sets LED Drivers on Ch0 to 0%
      ReefAngel.PWM.SetChannel( 1, 0 ); //Sets LED Drivers on Ch1 to 0%
      ReefAngel.PWM.SetChannel( 3, 50 ); //closes 5V relay on Ch3 that shorts dimmer leads on Ch0 LED driver to turn Driver off
      ReefAngel.PWM.SetChannel( 4, 50 ); //closes 5V relay on Ch4 that shorts dimmer leads on Ch1 LED driver to turn Driver off
    }

  if ( InternalMemory.read(199) == 2 )
    {
      ReefAngel.PWM.SetChannel( 0, 100 ); //Sets LED Drivers on Ch0 to 100%
      ReefAngel.PWM.SetChannel( 1, 100 ); //Sets LED Drivers on Ch1 to 100%
      ReefAngel.PWM.SetChannel( 3, 0 ); //Opens 5V relay on Ch3 that removes short on dimmer leads on Ch0 LED driver to turn Driver on
      ReefAngel.PWM.SetChannel( 4, 0 ); //Opens 5V relay on Ch4 that removes short on dimmer leads on Ch1 LED driver to turn Driver on
    }

  else
    {
    }
       
//*****End Custom Menu Additions


//*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions


    T1Temp=ReefAngel.Params.Temp[T1_PROBE];

//T1MaxTemp = T1Temp;
//T1MinTemp = T1Temp;

      if ( T1Temp > T1MaxTemp ) T1MaxTemp = T1Temp;
          InternalMemory.write(102, T1MaxTemp);
       
      if ( T1Temp < T1MinTemp ) T1MinTemp = T1Temp;
          InternalMemory.write(101, T1MinTemp);
 
   
//*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

   
    overheatflag = InternalMemory.read( Overheat_Exceed_Flag );
    atoflag = InternalMemory.read( ATO_Exceed_Flag );
    iochannel0flag = ! ReefAngel.IO.GetChannel( 0 );
    iochannel1flag = ! ReefAngel.IO.GetChannel( 1 );
    iochannel2flag = ! ReefAngel.IO.GetChannel( 2 );
    iochannel3flag = ! ReefAngel.IO.GetChannel( 3 );
    iochannel4flag = ! ReefAngel.IO.GetChannel( 4 );
    iochannel5flag = ! ReefAngel.IO.GetChannel( 5 );
    AlertNonCritical = atoflag + iochannel2flag + iochannel3flag + iochannel4flag + iochannel5flag;
    AlertCritical = overheatflag + iochannel0flag + iochannel1flag;   
    if ( AlertNonCritical >= 1 ) AlertNonCritical = 5;
    if ( AlertCritical >= 1 ) AlertCritical = 5;   
    ReefAngel.PWM.SetActinic(millis()%60000<100?AlertNonCritical:0);
    ReefAngel.PWM.SetDaylight(millis()%60000<100?AlertNonCritical:0);
    if ( AlertCritical >= 1 ) ReefAngel.PWM.SetActinic(millis()%300<100?AlertCritical:0);
    if ( AlertCritical >= 1 ) ReefAngel.PWM.SetDaylight(millis()%300<100?AlertCritical:0);   

   
    ////// Place your custom code below here

    ReefAngel.CustomVar[0]=InternalMemory.read(ATO_Exceed_Flag);
    ReefAngel.CustomVar[1]=InternalMemory.read(Overheat_Exceed_Flag);
    ReefAngel.CustomVar[2]=CustomIOExpanderData;
    ReefAngel.CustomVar[3]=0;
    ReefAngel.CustomVar[4]=InternalMemory.read(199);
    ReefAngel.CustomVar[5]=AlertNonCritical;
    ReefAngel.CustomVar[6]=AlertCritical;   
    ReefAngel.CustomVar[7]=ATOBrutePort;
   
    if ( ReefAngel.CustomVar[0]== 1 )
      {
        ReefAngel.Relay.RelayMaskOff=~(Port4Bit);
      }

    //*****Begin WC Additions

    // If menu equals waterchange mode
    // then we start the automatic water change
    // Otherwise we ignore and proceed
    if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
      {
        AutoWaterChange();
      }
   
    //*****End WC Additions
   
   
    //*****Begin ATO By Salinity Additions
   
    if (ReefAngel.Params.Salinity<300)
      {
        ATOBrutePort=Port7;
      }
    else
      {
        ATOBrutePort=Port2;
      }
    ReefAngel.StandardATO(ATOBrutePort,40 );
    if (iochannel2flag == 1)
      {
        ReefAngel.Relay.RelayMaskOff=~(Port7Bit);
      }
    if (iochannel4flag == 1)
      {
        ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
      }
     
    //*****End ATO By Salinity Additions


    //*****Begin Custom IO Expander Additions

    Serial.println(expanderRead());

    //*****End Custom IO Expander Additions


    ////// Place your custom code above here

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


//*****Begin Custom Menu Additions

//Mask LED's On. Forces LED's On Full Blast
void MenuEntry1()
  {
    InternalMemory.write(199, 2);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights On"); waitForTime(2);
    ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
  }

//Mask LED's Off. Forces LED's Off
void MenuEntry2()
  {
    InternalMemory.write(199, 1);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Off"); waitForTime(2);
    ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
  }

//Mask LED's Clear. Remove LED Masking Returns LED's To Normal Schedule
void MenuEntry3()
  {
    InternalMemory.write(199, 0);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Clear"); waitForTime(2);
    ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
  }
 
//Start Waterchange Mode
void MenuEntry4()
  {
    ReefAngel.WaterChangeModeStart();
  }

//Clear ATO Timeout Flag
void MenuEntry5()
  {
    ReefAngel.ATOClear();
    ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
  }

//Clear Overheat Flag
void MenuEntry6()
  {
    ReefAngel.OverheatClear();
    ReefAngel.DisplayMenuEntry("Clear Overheat");
  }

//Calibrate PH Probe
void MenuEntry7()
  {
    ReefAngel.SetupCalibratePH();
    ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
  }

//Set clock Date & Time
void MenuEntry8()
  {
    ReefAngel.SetupDateTime();
    ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
  }
 
//*****End Custom Menu Additions


//*****Begin WC Additions

void AutoWaterChange()
{
    // auto water change mode
    // Display Starting Water Change"
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Water Change"); waitForTime(3);

    // Check Saltwater BRUTE for sufficient saltwater on IO Module Port2
    if ( isSWBruteEmpty() )
      {
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Not Enough Saltwater"); waitForTime(3);

        //Abort Water Change if insufficient saltwater
        // Handles the cleanup to return to the main screen
        ReefAngel.ClearScreen(DefaultBGColor);
        ReefAngel.DisplayedMenu = DEFAULT_MENU;
        DrawCustomGraph();
        return;
      }
   
    //Display Disabling ATO Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");   
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Disabling ATO Pump"); waitForTime(3);

    // turn off ATO pump port to prevent ATO from trying to fill a sump being drained intentionally
    ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
   
    //Display Stopping Skimmer
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Skimmer"); waitForTime(3);

    // turn off the skimmer port
    ReefAngel.Relay.Off(SkimmerPort);
    ReefAngel.Relay.Write();
   
    //Display Skimmer Draining
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Draining"); waitForTime(3);   

    // wait for 1 minute
    waitForTime(60);

    //Display Skimmer Done Draining
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Done Draining"); waitForTime(3);
   
    //display Stopping Return Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Return Pump"); waitForTime(3);

    //Stop Return Pump
    ReefAngel.Relay.Off(ReturnPort);
    ReefAngel.Relay.Write();
   
    //Display Draining To Sump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Draining To Sump"); waitForTime(3);

    //display Sump Filling
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Filling"); waitForTime(3);

    // wait for IO Mod Port 1 to be active
    waitForIOChannel(1);

    //display Sump Is Full
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

    //Display Sump Settling
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

    // wait for sump to settle
    waitForTime(30);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

    // display Draining Sump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Draining Sump"); waitForTime(3);

    //turn on sump drain pump
    ReefAngel.Relay.On(SumpDrainPort);
    ReefAngel.Relay.Write();

    //display Sump Draining
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Draining"); waitForTime(3);

    // wait for sump empty port active, IO Mod Port 0
    waitForIOChannel(0);
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Empty"); waitForTime(3);

    //display Stopping Sump Draining
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Sump Drain"); waitForTime(3);

    // turn off sump drain
    ReefAngel.Relay.Off(SumpDrainPort);
    ReefAngel.Relay.Write();

    //Display Sump Settling
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

    // wait for sump to settle
    waitForTime(30);

    //display Sump Settled
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

    //display Starting Saltwater Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Saltwater Pump"); waitForTime(3);
 
    //turn on Saltwater Pump
    ReefAngel.Relay.On(SWBrutePort);
    ReefAngel.Relay.Write();

    //display Saltwater Pumping
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Saltwater Pumping"); waitForTime(3);

    // wait for sump full float switch active, IO Mod Port 1
    waitForIOChannel(1);

    //display Stop Saltwater Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stop Saltwater Pump"); waitForTime(3);

    // turn off sw brute pump
    ReefAngel.Relay.Off(SWBrutePort);
    ReefAngel.Relay.Write();   

    //diasplay Sump is Full
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

    //Display Sump Settling
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

    // wait for sump to settle
    waitForTime(30);

    //display Sump Settled
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);
   
    //display Starting Return Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Return Pump"); waitForTime(3);

    // turn on return pump
    ReefAngel.Relay.On(ReturnPort);
    ReefAngel.Relay.Write();

    //display Return Pump Started
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Return Pump Started"); waitForTime(3);
 
    //display Normalizing Waterlevel
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Waterlevel"); waitForTime(3);

    //waiting 2 minutes for waterlevel to normalize
    waitForTime(120);
   
    //display Starting Skimer
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Skimmer"); waitForTime(3);

    //turn on skimmer
    ReefAngel.Relay.On(SkimmerPort);
    ReefAngel.Relay.Write();

    //display Normalizing Skimmer
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Skimmer"); waitForTime(3);

    //wait for 2 minutes for skimmer to normalize
    waitForTime(120);

    //display Skimmer Normalized
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Normalized"); waitForTime(3);

    //display Enabling ATO Pump
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Enabling ATO Pump"); waitForTime(3);

    //Enable ATO pump
    ReefAngel.Relay.RelayMaskOff = B11111111;
    ReefAngel.Relay.Write();

    //display Water Change Complete
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
    ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Water Change Complete"); waitForTime(3);

    // Handles the cleanup to return to the main screen
    ReefAngel.ClearScreen(DefaultBGColor);
    ReefAngel.DisplayedMenu = DEFAULT_MENU;
    DrawCustomGraph();
}

bool isSWBruteEmpty()
{
  // check status of IO Mod Port 2
  if ( ! ReefAngel.IO.GetChannel(2) )
      return true;
  return false;
}

void waitForTime(int seconds)
{
    bool done = false;
    tm.SetInterval(seconds);
    tm.Start();
    int t = tm.Trigger - now();
    do
    {
      // check the wifi interface
      pingSerial();
      // wait for specified seconds
      if ( (t >= 0) && ! tm.IsTriggered() )
        {
          // TODO finish countdown on screen
          // show countdown on screen
          //LCD.Clear(DefaultBGColor,60+(intlength(t)*5),100,100,108);
          //LCD.DrawText(DefaultFGColor,DefaultBGColor,60,100,t);
          wdt_reset();
          delay(200);
        }
        else
        {
          done = true;
        }
    } while ( !done );
    return;
}

void waitForIOChannel(byte channel)
{
    // TODO complete this function
    do
    {
      wdt_reset();
      // display something on screen
      // check the wifi interface
      pingSerial();
      delay(200);
      // TODO check the IO channel logic
    } while ( ReefAngel.IO.GetChannel(channel) );
}

//*****End WC Additions


//*****Begin Custom IO Expander Additions

    byte expanderRead()
    {
      byte _data=0;
      Wire.requestFrom(0x27, 1);
      if(Wire.available())
        {
        _data = Wire.read();
        CustomIOExpanderData = _data;
        }
      delay(10);
      return _data;
    }

//*****End Custom IO Expander Additions
   

void DrawCustomMain()
{
    int x,y;
    char text[10];
    // Dimming Expansion
    x = 15;
    y = 2;
    for ( int a=0;a<6;a++ )
    {
      if ( a>2 ) x = 75;
      if ( a==3 ) y = 2;
      ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x,y,"Ch :   " );
      ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+12,y,a );
      ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+24,y,ReefAngel.PWM.GetChannelValue(a) );
      y += 10;
    }
    pingSerial();

    // I/O Expansion
    byte bkcolor;
    x = 14;
    y = 34;
    for ( int a=0;a<6;a++ )
    {
      ReefAngel.LCD.DrawCircleOutline( x+(a*20),y,4,COLOR_MEDIUMORCHID );
      if ( ReefAngel.IO.GetChannel(a) ) bkcolor=COLOR_WHITE; else bkcolor=COLOR_GRAY;
      ReefAngel.LCD.FillCircle( x+(a*20),y,2,bkcolor );
    }
    pingSerial();

    // Parameters
#if defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params,
    ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params );
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
    pingSerial();

    // Salinity
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,76, "SAL:" );
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,60,76, "L" );   
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,90,76, "H" );       
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,39,76, ReefAngel.Params.Salinity );
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,69,76, T1MinTemp );
    ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,98,76, T1MaxTemp );   
    pingSerial();

    // Main Relay Box
    byte TempRelay = ReefAngel.Relay.RelayData;
    TempRelay &= ReefAngel.Relay.RelayMaskOff;
    TempRelay |= ReefAngel.Relay.RelayMaskOn;
    ReefAngel.LCD.DrawOutletBox( 12, 90, TempRelay );
    pingSerial();

    // Relay Expansion
    TempRelay = ReefAngel.Relay.RelayDataE[0];
    TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
    TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
    ReefAngel.LCD.DrawOutletBox( 12, 104, TempRelay );
    pingSerial();

    // Date and Time
    ReefAngel.LCD.DrawDate( 6, 122 );
    pingSerial();
}

void DrawCustomGraph()
{
}


180G FOWLR
20GH QT#1
29G QT#2

Image

Posts: 289
Joined: Wed May 16, 2012 9:52 pm
PostPosted: Mon Jun 30, 2014 9:32 pm
Version 104

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 <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


    // Initialize Alert variables
    byte AlertNonCritical=0;
    byte AlertCritical=0;
    byte overheatflag=0;
    byte atoflag=0;
    byte iochannel0flag=0;
    byte iochannel1flag=0;
    byte iochannel2flag=0;
    byte iochannel3flag=0;
    byte iochannel4flag=0;
    byte iochannel5flag=0;

    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions
    int T1MinTemp=9999;
    int T1MaxTemp=1;
    int T1Temp=1;

    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

    //*****Begin WaterChange Additions

    // skimmer port
    byte SkimmerPort = Port4;
    // return port
    byte ReturnPort = Port3;
    // sump drain port
    byte SumpDrainPort = Port8;
    // SaltWater brute pump
    byte SWBrutePort = Port7;
    // Timer for countdowns
    TimerClass tm;

    //*****End WaterChange Additions


    //*****Begin ATO By Salinity Additions

    byte ATOBrutePort = Port2;

    //*****End ATO By Salinity Additions


    //*****Begin Custom IO Expander Additions

    byte CustomIOExpander = 255;

    //*****End Custom IO Expander Additions


    ////// Place global variable code above here


    //*****Begin Custom Menu Additions

    #include <avr/pgmspace.h>
    prog_char menu1_label[] PROGMEM = "Mask LED's On";
    prog_char menu2_label[] PROGMEM = "Mask LED's Off";
    prog_char menu3_label[] PROGMEM = "Mask LED's Clear";
    prog_char menu4_label[] PROGMEM = "Water Change";
    prog_char menu5_label[] PROGMEM = "Clear ATO Timeout";
    prog_char menu6_label[] PROGMEM = "Overheat Clear";
    prog_char menu7_label[] PROGMEM = "PH Calibration";
    prog_char menu8_label[] PROGMEM = "Date / Time";

    // Group the menu entries together
    PROGMEM const char *menu_items[] =
      {
        menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label, menu7_label, menu8_label,
      };

    //*****End Custom Menu Additions


    void setup()
    {
        // This must be the first line
        ReefAngel.Init();  //Initialize controller

        //_Running_Config_Revision_104
        InternalMemory.write(100, 104);


        //*****Begin Custom Menu Additions... Initialize Custom Menu

        ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));   
        InternalMemory.write(199, 0); //sets the controller to non masked LED mode upon boot.   

        //*****End Custom Menu Additions


        // Ports toggled in Feeding Mode
        ReefAngel.FeedingModePorts = 0;
        ReefAngel.FeedingModePortsE[0] = 0;
        // Ports toggled when Lights On / Off menu entry selected
        ReefAngel.LightsOnPorts = 0;
        ReefAngel.LightsOnPortsE[0] = Port1Bit | Port2Bit;
        // Ports turned off when Overheat temperature exceeded
        ReefAngel.OverheatShutoffPorts = Port4Bit | Port5Bit | Port6Bit;
        ReefAngel.OverheatShutoffPortsE[0] = 0;
        // Use T1 probe as temperature and overheat functions
        ReefAngel.TempProbe = T1_PROBE;
        ReefAngel.OverheatProbe = T1_PROBE;
        // Set the Overheat temperature setting
        InternalMemory.OverheatTemp_write( 850 );


        // Ports that are always on
        ReefAngel.Relay.On( Port3 );
        ReefAngel.Relay.On( Box1_Port5 );
        ReefAngel.Relay.On( Box1_Port6 );
        ReefAngel.Relay.On( Box1_Port7 );


        ////// Place additional initialization code below here

        ReefAngel.CustomVar[0]=0;
        ReefAngel.CustomVar[1]=0;
        ReefAngel.CustomVar[2]=0;
        ReefAngel.CustomVar[3]=0;
        ReefAngel.CustomVar[4]=0;
        ReefAngel.CustomVar[5]=0;
        ReefAngel.CustomVar[6]=0;   
        ReefAngel.CustomVar[7]=0;   


        ////// Place additional initialization code above here
    }

    void loop()
    {
        ReefAngel.StandardFan( Port1,790,820 );
        ReefAngel.Relay.DelayedOn( Port4,1 );
        ReefAngel.WavemakerRandom( Port5,30,100 );
        ReefAngel.StandardHeater( Port6,750,760 );
        ReefAngel.StandardLights( Box1_Port1,13,0,23,0 );
        ReefAngel.StandardLights( Box1_Port2,13,0,23,0 );
        ReefAngel.StandardHeater( Box1_Port3,750,760 );
        ReefAngel.StandardHeater( Box1_Port4,750,760 );


    //*****Begin Custom Menu Additions

      // Removes LED's from a "MASKED" State
      if ( InternalMemory.read(199) == 0 )
        {
          ReefAngel.PWM.SetChannel( 0, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch0 to Parabola math
          ReefAngel.PWM.SetChannel( 1, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch1 to Parabola math
          ReefAngel.PWM.SetChannel( 3, PWMSlope(2,0,7,30,0,50,0,0) ); //Opens/closes 5V relay on Ch3 that shorts\opens dimmer leads on Ch0 LED driver to turn Driver on/off
          ReefAngel.PWM.SetChannel( 4, PWMSlope(0,0,14,0,0,50,0,0) ); //Opens/closes 5V relay on Ch4 that shorts\opens dimmer leads on Ch1 LED driver to turn Driver on/off
        }

      // MASKS LED's Off
      if ( InternalMemory.read(199) == 1 )
        {
          ReefAngel.PWM.SetChannel( 0, 0 ); //Sets LED Drivers on Ch0 to 0%
          ReefAngel.PWM.SetChannel( 1, 0 ); //Sets LED Drivers on Ch1 to 0%
          ReefAngel.PWM.SetChannel( 3, 50 ); //closes 5V relay on Ch3 that shorts dimmer leads on Ch0 LED driver to turn Driver off
          ReefAngel.PWM.SetChannel( 4, 50 ); //closes 5V relay on Ch4 that shorts dimmer leads on Ch1 LED driver to turn Driver off
        }

      if ( InternalMemory.read(199) == 2 )
        {
          ReefAngel.PWM.SetChannel( 0, 100 ); //Sets LED Drivers on Ch0 to 100%
          ReefAngel.PWM.SetChannel( 1, 100 ); //Sets LED Drivers on Ch1 to 100%
          ReefAngel.PWM.SetChannel( 3, 0 ); //Opens 5V relay on Ch3 that removes short on dimmer leads on Ch0 LED driver to turn Driver on
          ReefAngel.PWM.SetChannel( 4, 0 ); //Opens 5V relay on Ch4 that removes short on dimmer leads on Ch1 LED driver to turn Driver on
        }

      else
        {
        }
           
    //*****End Custom Menu Additions


    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions


        T1Temp=ReefAngel.Params.Temp[T1_PROBE];

    //T1MaxTemp = T1Temp;
    //T1MinTemp = T1Temp;

          if ( T1Temp > T1MaxTemp ) T1MaxTemp = T1Temp;
              InternalMemory.write(102, T1MaxTemp);
           
          if ( T1Temp < T1MinTemp ) T1MinTemp = T1Temp;
              InternalMemory.write(101, T1MinTemp);

       
    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

       
        overheatflag = InternalMemory.read( Overheat_Exceed_Flag );
        atoflag = InternalMemory.read( ATO_Exceed_Flag );
        iochannel0flag = ! ReefAngel.IO.GetChannel( 0 );
        iochannel1flag = ! ReefAngel.IO.GetChannel( 1 );
        iochannel2flag = ! ReefAngel.IO.GetChannel( 2 );
        iochannel3flag = ! ReefAngel.IO.GetChannel( 3 );
        iochannel4flag = ! ReefAngel.IO.GetChannel( 4 );
        iochannel5flag = ! ReefAngel.IO.GetChannel( 5 );
        AlertNonCritical = atoflag + iochannel2flag + iochannel3flag + iochannel4flag + iochannel5flag;
        AlertCritical = overheatflag + iochannel0flag + iochannel1flag;   
        if ( AlertNonCritical >= 1 ) AlertNonCritical = 5;
        if ( AlertCritical >= 1 ) AlertCritical = 5;   
        ReefAngel.PWM.SetActinic(millis()%60000<100?AlertNonCritical:0);
        ReefAngel.PWM.SetDaylight(millis()%60000<100?AlertNonCritical:0);
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetActinic(millis()%300<100?AlertCritical:0);
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetDaylight(millis()%300<100?AlertCritical:0);   

       
        ////// Place your custom code below here

        ReefAngel.CustomVar[0]=InternalMemory.read(ATO_Exceed_Flag);
        ReefAngel.CustomVar[1]=InternalMemory.read(Overheat_Exceed_Flag);
        ReefAngel.CustomVar[2]=CustomIOExpander;
        ReefAngel.CustomVar[3]=0;
        ReefAngel.CustomVar[4]=InternalMemory.read(199);
        ReefAngel.CustomVar[5]=AlertNonCritical;
        ReefAngel.CustomVar[6]=AlertCritical;   
        ReefAngel.CustomVar[7]=ATOBrutePort;
       
        if ( ReefAngel.CustomVar[0]== 1 )
          {
            ReefAngel.Relay.RelayMaskOff=~(Port4Bit);
          }

        //*****Begin WC Additions

        // If menu equals waterchange mode
        // then we start the automatic water change
        // Otherwise we ignore and proceed
        if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
          {
            AutoWaterChange();
          }
       
        //*****End WC Additions
       
       
        //*****Begin ATO By Salinity Additions
       
        if (ReefAngel.Params.Salinity<300)
          {
            ATOBrutePort=Port7;
          }
        else
          {
            ATOBrutePort=Port2;
          }
        ReefAngel.StandardATO(ATOBrutePort,40 );
        if (iochannel2flag == 1)
          {
            ReefAngel.Relay.RelayMaskOff=~(Port7Bit);
          }
        if (iochannel4flag == 1)
          {
            ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
          }
         
        //*****End ATO By Salinity Additions


        //*****Begin Custom IO Expander Additions

        //*****End Custom IO Expander Additions


        ////// Place your custom code above here

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


    //*****Begin Custom Menu Additions

    //Mask LED's On. Forces LED's On Full Blast
    void MenuEntry1()
      {
        InternalMemory.write(199, 2);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights On"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask LED's Off. Forces LED's Off
    void MenuEntry2()
      {
        InternalMemory.write(199, 1);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Off"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask LED's Clear. Remove LED Masking Returns LED's To Normal Schedule
    void MenuEntry3()
      {
        InternalMemory.write(199, 0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Clear"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }
     
    //Start Waterchange Mode
    void MenuEntry4()
      {
        ReefAngel.WaterChangeModeStart();
      }

    //Clear ATO Timeout Flag
    void MenuEntry5()
      {
        ReefAngel.ATOClear();
        ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
      }

    //Clear Overheat Flag
    void MenuEntry6()
      {
        ReefAngel.OverheatClear();
        ReefAngel.DisplayMenuEntry("Clear Overheat");
      }

    //Calibrate PH Probe
    void MenuEntry7()
      {
        ReefAngel.SetupCalibratePH();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }

    //Set clock Date & Time
    void MenuEntry8()
      {
        ReefAngel.SetupDateTime();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }
     
    //*****End Custom Menu Additions


    //*****Begin WC Additions

    void AutoWaterChange()
    {
        // auto water change mode
        // Display Starting Water Change"
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Water Change"); waitForTime(3);

        // Check Saltwater BRUTE for sufficient saltwater on IO Module Port2
        if ( isSWBruteEmpty() )
          {
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Not Enough Saltwater"); waitForTime(3);

            //Abort Water Change if insufficient saltwater
            // Handles the cleanup to return to the main screen
            ReefAngel.ClearScreen(DefaultBGColor);
            ReefAngel.DisplayedMenu = DEFAULT_MENU;
            DrawCustomGraph();
            return;
          }
       
        //Display Disabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");   
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Disabling ATO Pump"); waitForTime(3);

        // turn off ATO pump port to prevent ATO from trying to fill a sump being drained intentionally
        ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
       
        //Display Stopping Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Skimmer"); waitForTime(3);

        // turn off the skimmer port
        ReefAngel.Relay.Off(SkimmerPort);
        ReefAngel.Relay.Write();
       
        //Display Skimmer Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Draining"); waitForTime(3);   

        // wait for 1 minute
        waitForTime(60);

        //Display Skimmer Done Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Done Draining"); waitForTime(3);
       
        //display Stopping Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Return Pump"); waitForTime(3);

        //Stop Return Pump
        ReefAngel.Relay.Off(ReturnPort);
        ReefAngel.Relay.Write();
       
        //Display Draining To Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Draining To Sump"); waitForTime(3);

        //display Sump Filling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Filling"); waitForTime(3);

        // wait for IO Mod Port 1 to be active
        waitForIOChannel(1);

        //display Sump Is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        // display Draining Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Draining Sump"); waitForTime(3);

        //turn on sump drain pump
        ReefAngel.Relay.On(SumpDrainPort);
        ReefAngel.Relay.Write();

        //display Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Draining"); waitForTime(3);

        // wait for sump empty port active, IO Mod Port 0
        waitForIOChannel(0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Empty"); waitForTime(3);

        //display Stopping Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Sump Drain"); waitForTime(3);

        // turn off sump drain
        ReefAngel.Relay.Off(SumpDrainPort);
        ReefAngel.Relay.Write();

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        //display Starting Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Saltwater Pump"); waitForTime(3);

        //turn on Saltwater Pump
        ReefAngel.Relay.On(SWBrutePort);
        ReefAngel.Relay.Write();

        //display Saltwater Pumping
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Saltwater Pumping"); waitForTime(3);

        // wait for sump full float switch active, IO Mod Port 1
        waitForIOChannel(1);

        //display Stop Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stop Saltwater Pump"); waitForTime(3);

        // turn off sw brute pump
        ReefAngel.Relay.Off(SWBrutePort);
        ReefAngel.Relay.Write();   

        //diasplay Sump is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);
       
        //display Starting Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Return Pump"); waitForTime(3);

        // turn on return pump
        ReefAngel.Relay.On(ReturnPort);
        ReefAngel.Relay.Write();

        //display Return Pump Started
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Return Pump Started"); waitForTime(3);

        //display Normalizing Waterlevel
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Waterlevel"); waitForTime(3);

        //waiting 2 minutes for waterlevel to normalize
        waitForTime(120);
       
        //display Starting Skimer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Skimmer"); waitForTime(3);

        //turn on skimmer
        ReefAngel.Relay.On(SkimmerPort);
        ReefAngel.Relay.Write();

        //display Normalizing Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Skimmer"); waitForTime(3);

        //wait for 2 minutes for skimmer to normalize
        waitForTime(120);

        //display Skimmer Normalized
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Normalized"); waitForTime(3);

        //display Enabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Enabling ATO Pump"); waitForTime(3);

        //Enable ATO pump
        ReefAngel.Relay.RelayMaskOff = B11111111;
        ReefAngel.Relay.Write();

        //display Water Change Complete
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Water Change Complete"); waitForTime(3);

        // Handles the cleanup to return to the main screen
        ReefAngel.ClearScreen(DefaultBGColor);
        ReefAngel.DisplayedMenu = DEFAULT_MENU;
        DrawCustomGraph();
    }

    bool isSWBruteEmpty()
    {
      // check status of IO Mod Port 2
      if ( ! ReefAngel.IO.GetChannel(2) )
          return true;
      return false;
    }

    void waitForTime(int seconds)
    {
        bool done = false;
        tm.SetInterval(seconds);
        tm.Start();
        int t = tm.Trigger - now();
        do
        {
          // check the wifi interface
          pingSerial();
          // wait for specified seconds
          if ( (t >= 0) && ! tm.IsTriggered() )
            {
              // TODO finish countdown on screen
              // show countdown on screen
              //LCD.Clear(DefaultBGColor,60+(intlength(t)*5),100,100,108);
              //LCD.DrawText(DefaultFGColor,DefaultBGColor,60,100,t);
              wdt_reset();
              delay(200);
            }
            else
            {
              done = true;
            }
        } while ( !done );
        return;
    }

    void waitForIOChannel(byte channel)
    {
        // TODO complete this function
        do
        {
          wdt_reset();
          // display something on screen
          // check the wifi interface
          pingSerial();
          delay(200);
          // TODO check the IO channel logic
        } while ( ReefAngel.IO.GetChannel(channel) );
    }

    //*****End WC Additions


    //*****Begin Custom IO Expander Additions

        byte expanderRead()
        {
          byte _data=0;
          Wire.requestFrom(0x27, 1);
          if(Wire.available())
            {
            _data = Wire.read();
            CustomIOExpander = _data;
            }
          delay(10);
          return _data;
        }
       
        boolean expanderReadGetChannel(byte channel)
        {
          return bitRead(expanderRead(),channel);
        }

    //*****End Custom IO Expander Additions
       

    void DrawCustomMain()
    {
        int x,y;
        char text[10];
        // Dimming Expansion
        x = 15;
        y = 2;
        for ( int a=0;a<6;a++ )
        {
          if ( a>2 ) x = 75;
          if ( a==3 ) y = 2;
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x,y,"Ch :   " );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+12,y,a );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+24,y,ReefAngel.PWM.GetChannelValue(a) );
          y += 10;
        }
        pingSerial();

        // I/O Expansion
        byte bkcolor;
        x = 14;
        y = 34;
        for ( int a=0;a<6;a++ )
        {
          ReefAngel.LCD.DrawCircleOutline( x+(a*20),y,4,COLOR_MEDIUMORCHID );
          if ( ReefAngel.IO.GetChannel(a) ) bkcolor=COLOR_WHITE; else bkcolor=COLOR_GRAY;
          ReefAngel.LCD.FillCircle( x+(a*20),y,2,bkcolor );
        }
        pingSerial();

        // Parameters
    #if defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params,
        ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
    #else // defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params );
    #endif // defined DisplayLEDPWM && ! defined RemoveAllLights
        pingSerial();

        // Salinity
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,76, "SAL:" );
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,60,76, "L" );   
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,90,76, "H" );       
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,39,76, ReefAngel.Params.Salinity );
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,69,76, T1MinTemp );
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,98,76, T1MaxTemp );   
        pingSerial();

        // Main Relay Box
        byte TempRelay = ReefAngel.Relay.RelayData;
        TempRelay &= ReefAngel.Relay.RelayMaskOff;
        TempRelay |= ReefAngel.Relay.RelayMaskOn;
        ReefAngel.LCD.DrawOutletBox( 12, 90, TempRelay );
        pingSerial();

        // Relay Expansion
        TempRelay = ReefAngel.Relay.RelayDataE[0];
        TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
        TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
        ReefAngel.LCD.DrawOutletBox( 12, 104, TempRelay );
        pingSerial();

        // Date and Time
        ReefAngel.LCD.DrawDate( 6, 122 );
        pingSerial();
    }

    void DrawCustomGraph()
    {
    }


180G FOWLR
20GH QT#1
29G QT#2

Image

Posts: 289
Joined: Wed May 16, 2012 9:52 pm
PostPosted: Mon Jun 30, 2014 9:33 pm
Version 105

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 <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


    // Initialize Alert variables
    byte AlertNonCritical=0;
    byte AlertCritical=0;
    byte overheatflag=0;
    byte atoflag=0;
    byte iochannel0flag=0;
    byte iochannel1flag=0;
    byte iochannel2flag=0;
    byte iochannel3flag=0;
    byte iochannel4flag=0;
    byte iochannel5flag=0;

    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions
    int T1LowTemp=999;
    int T1HighTemp=1;
    int T1Read=1;
   

    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

    //*****Begin WaterChange Additions

    // skimmer port
    byte SkimmerPort = Port4;
    // return port
    byte ReturnPort = Port3;
    // sump drain port
    byte SumpDrainPort = Port8;
    // SaltWater brute pump
    byte SWBrutePort = Port7;
    // Timer for countdowns
    TimerClass tm;

    //*****End WaterChange Additions


    //*****Begin ATO By Salinity Additions

    byte ATOBrutePort = Port2;

    //*****End ATO By Salinity Additions


    //*****Begin Custom IO Expander Additions

    byte CustomIOExpander = 255;

    //*****End Custom IO Expander Additions


    ////// Place global variable code above here


    //*****Begin Custom Menu Additions

    #include <avr/pgmspace.h>
    prog_char menu1_label[] PROGMEM = "Mask LED's On";
    prog_char menu2_label[] PROGMEM = "Mask LED's Off";
    prog_char menu3_label[] PROGMEM = "Mask LED's Clear";
    prog_char menu4_label[] PROGMEM = "Water Change";
    prog_char menu5_label[] PROGMEM = "Clear ATO Timeout";
    prog_char menu6_label[] PROGMEM = "Overheat Clear";
    prog_char menu7_label[] PROGMEM = "PH Calibration";
    prog_char menu8_label[] PROGMEM = "Date / Time";

    // Group the menu entries together
    PROGMEM const char *menu_items[] =
      {
        menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label, menu7_label, menu8_label,
      };

    //*****End Custom Menu Additions


    void setup()
    {
        // This must be the first line
        ReefAngel.Init();  //Initialize controller

        //_Compiled_With_Libs_Version_1.1.0
        InternalMemory.write(100, 110);
   
        //_Running_Config_Revision_105
        InternalMemory.write(102, 105);

        //*****Begin Custom Menu Additions... Initialize Custom Menu

        ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));   
        InternalMemory.write(199, 0); //sets the controller to non masked LED mode upon reboot.   

        //*****End Custom Menu Additions


        // Ports toggled in Feeding Mode
        ReefAngel.FeedingModePorts = 0;
        ReefAngel.FeedingModePortsE[0] = 0;
        // Ports toggled when Lights On / Off menu entry selected
        ReefAngel.LightsOnPorts = 0;
        ReefAngel.LightsOnPortsE[0] = Port1Bit | Port2Bit;
        // Ports turned off when Overheat temperature exceeded
        ReefAngel.OverheatShutoffPorts = Port4Bit | Port5Bit | Port6Bit;
        ReefAngel.OverheatShutoffPortsE[0] = 0;
        // Use T1 probe as temperature and overheat functions
        ReefAngel.TempProbe = T1_PROBE;
        ReefAngel.OverheatProbe = T1_PROBE;
        // Set the Overheat temperature setting
        InternalMemory.OverheatTemp_write( 850 );


        // Ports that are always on
        ReefAngel.Relay.On( Port3 );
        ReefAngel.Relay.On( Box1_Port5 );
        ReefAngel.Relay.On( Box1_Port6 );
        ReefAngel.Relay.On( Box1_Port7 );


        ////// Place additional initialization code below here

        ReefAngel.CustomVar[0]=0;
        ReefAngel.CustomVar[1]=0;
        ReefAngel.CustomVar[2]=0;
        ReefAngel.CustomVar[3]=0;
        ReefAngel.CustomVar[4]=0;
        ReefAngel.CustomVar[5]=0;
        ReefAngel.CustomVar[6]=0;   
        ReefAngel.CustomVar[7]=0;   


        ////// Place additional initialization code above here
    }

    void loop()
    {
        ReefAngel.StandardFan( Port1,790,820 );
        ReefAngel.Relay.DelayedOn( Port4,1 );
        ReefAngel.WavemakerRandom( Port5,30,100 );
        ReefAngel.StandardHeater( Port6,750,760 );
        ReefAngel.StandardLights( Box1_Port1,13,0,23,0 );
        ReefAngel.StandardLights( Box1_Port2,13,0,23,0 );
        ReefAngel.StandardHeater( Box1_Port3,750,760 );
        ReefAngel.StandardHeater( Box1_Port4,750,760 );


    //*****Begin Custom Menu Additions

      // Removes LED's from a "MASKED" State
      if ( InternalMemory.read(199) == 0 )
        {
          ReefAngel.PWM.SetChannel( 0, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch0 to Parabola math
          ReefAngel.PWM.SetChannel( 1, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch1 to Parabola math
          ReefAngel.PWM.SetChannel( 3, PWMSlope(2,0,7,30,0,50,0,0) ); //Opens/closes 5V relay on Ch3 that shorts\opens dimmer leads on Ch0 LED driver to turn Driver on/off
          ReefAngel.PWM.SetChannel( 4, PWMSlope(0,0,14,0,0,50,0,0) ); //Opens/closes 5V relay on Ch4 that shorts\opens dimmer leads on Ch1 LED driver to turn Driver on/off
        }

      // MASKS LED's Off
      if ( InternalMemory.read(199) == 1 )
        {
          ReefAngel.PWM.SetChannel( 0, 0 ); //Sets LED Drivers on Ch0 to 0%
          ReefAngel.PWM.SetChannel( 1, 0 ); //Sets LED Drivers on Ch1 to 0%
          ReefAngel.PWM.SetChannel( 3, 50 ); //closes 5V relay on Ch3 that shorts dimmer leads on Ch0 LED driver to turn Driver off
          ReefAngel.PWM.SetChannel( 4, 50 ); //closes 5V relay on Ch4 that shorts dimmer leads on Ch1 LED driver to turn Driver off
        }

      // MASKS LED's On
      if ( InternalMemory.read(199) == 2 )
        {
          ReefAngel.PWM.SetChannel( 0, 100 ); //Sets LED Drivers on Ch0 to 100%
          ReefAngel.PWM.SetChannel( 1, 100 ); //Sets LED Drivers on Ch1 to 100%
          ReefAngel.PWM.SetChannel( 3, 0 ); //Opens 5V relay on Ch3 that removes short on dimmer leads on Ch0 LED driver to turn Driver on
          ReefAngel.PWM.SetChannel( 4, 0 ); //Opens 5V relay on Ch4 that removes short on dimmer leads on Ch1 LED driver to turn Driver on
        }

      else
        {
        }
           
    //*****End Custom Menu Additions


    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions

        T1Read = ReefAngel.Params.Temp[T1_PROBE];
          if (T1Read !=0)
            {
              T1LowTemp = min(T1LowTemp, T1Read);
              T1HighTemp = max(T1HighTemp, T1Read);
            }
         
       
    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

       
        overheatflag = InternalMemory.read( Overheat_Exceed_Flag );
        atoflag = InternalMemory.read( ATO_Exceed_Flag );
        iochannel0flag = ! ReefAngel.IO.GetChannel( 0 );
        iochannel1flag = ! ReefAngel.IO.GetChannel( 1 );
        iochannel2flag = ! ReefAngel.IO.GetChannel( 2 );
        iochannel3flag = ! ReefAngel.IO.GetChannel( 3 );
        iochannel4flag = ! ReefAngel.IO.GetChannel( 4 );
        iochannel5flag = ! ReefAngel.IO.GetChannel( 5 );
        AlertNonCritical = atoflag + iochannel2flag + iochannel3flag + iochannel4flag + iochannel5flag;
        AlertCritical = overheatflag + iochannel0flag + iochannel1flag;   
        if ( AlertNonCritical >= 1 ) AlertNonCritical = 5;
        if ( AlertCritical >= 1 ) AlertCritical = 5;   
        ReefAngel.PWM.SetActinic(millis()%60000<100?AlertNonCritical:0);
        ReefAngel.PWM.SetDaylight(millis()%60000<100?AlertNonCritical:0);
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetActinic(millis()%300<100?AlertCritical:0);
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetDaylight(millis()%300<100?AlertCritical:0);   

       
        ////// Place your custom code below here

        ReefAngel.CustomVar[0]=InternalMemory.read(ATO_Exceed_Flag);
        ReefAngel.CustomVar[1]=InternalMemory.read(Overheat_Exceed_Flag);
        ReefAngel.CustomVar[2]=CustomIOExpander;
        ReefAngel.CustomVar[3]=0;
        ReefAngel.CustomVar[4]=InternalMemory.read(199);
        ReefAngel.CustomVar[5]=AlertNonCritical;
        ReefAngel.CustomVar[6]=AlertCritical;   
        ReefAngel.CustomVar[7]=ATOBrutePort;
       
        if ( ReefAngel.CustomVar[0]== 1 )
          {
            ReefAngel.Relay.RelayMaskOff=~(Port4Bit);
          }

        //*****Begin WC Additions

        // If menu equals waterchange mode
        // then we start the automatic water change
        // Otherwise we ignore and proceed
        if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
          {
            AutoWaterChange();
          }
       
        //*****End WC Additions
       
       
        //*****Begin ATO By Salinity Additions
       
        if (ReefAngel.Params.Salinity<300)
          {
            ATOBrutePort=Port7;
          }
        else
          {
            ATOBrutePort=Port2;
          }
        ReefAngel.StandardATO(ATOBrutePort,40 );
        if (iochannel2flag == 1)
          {
            ReefAngel.Relay.RelayMaskOff=~(Port7Bit);
          }
        if (iochannel4flag == 1)
          {
            ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
          }
         
        //*****End ATO By Salinity Additions


        //*****Begin Custom IO Expander Additions

        //*****End Custom IO Expander Additions


        ////// Place your custom code above here

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


    //*****Begin Custom Menu Additions

    //Mask LED's On. Forces LED's On Full Blast
    void MenuEntry1()
      {
        InternalMemory.write(199, 2);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights On"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask LED's Off. Forces LED's Off
    void MenuEntry2()
      {
        InternalMemory.write(199, 1);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Off"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask LED's Clear. Remove LED Masking Returns LED's To Normal Schedule
    void MenuEntry3()
      {
        InternalMemory.write(199, 0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Clear"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }
     
    //Start Waterchange Mode
    void MenuEntry4()
      {
        ReefAngel.WaterChangeModeStart();
      }

    //Clear ATO Timeout Flag
    void MenuEntry5()
      {
        ReefAngel.ATOClear();
        ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
      }

    //Clear Overheat Flag
    void MenuEntry6()
      {
        ReefAngel.OverheatClear();
        ReefAngel.DisplayMenuEntry("Clear Overheat");
      }

    //Calibrate PH Probe
    void MenuEntry7()
      {
        ReefAngel.SetupCalibratePH();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }

    //Set clock Date & Time
    void MenuEntry8()
      {
        ReefAngel.SetupDateTime();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }
     
    //*****End Custom Menu Additions


    //*****Begin WC Additions

    void AutoWaterChange()
    {
        // auto water change mode
        // Display Starting Water Change"
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Water Change"); waitForTime(3);

        // Check Saltwater BRUTE for sufficient saltwater on IO Module Port2
        if ( isSWBruteEmpty() )
          {
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Not Enough Saltwater"); waitForTime(3);

            //Abort Water Change if insufficient saltwater
            // Handles the cleanup to return to the main screen
            ReefAngel.ClearScreen(DefaultBGColor);
            ReefAngel.DisplayedMenu = DEFAULT_MENU;
            DrawCustomGraph();
            return;
          }
       
        //Display Disabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");   
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Disabling ATO Pump"); waitForTime(3);

        // turn off ATO pump port to prevent ATO from trying to fill a sump being drained intentionally
        ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
       
        //Display Stopping Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Skimmer"); waitForTime(3);

        // turn off the skimmer port
        ReefAngel.Relay.Off(SkimmerPort);
        ReefAngel.Relay.Write();
       
        //Display Skimmer Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Draining"); waitForTime(3);   

        // wait for 1 minute
        waitForTime(60);

        //Display Skimmer Done Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Done Draining"); waitForTime(3);
       
        //display Stopping Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Return Pump"); waitForTime(3);

        //Stop Return Pump
        ReefAngel.Relay.Off(ReturnPort);
        ReefAngel.Relay.Write();
       
        //Display Draining To Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Draining To Sump"); waitForTime(3);

        //display Sump Filling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Filling"); waitForTime(3);

        // wait for IO Mod Port 1 to be active
        waitForIOChannel(1);

        //display Sump Is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        // display Draining Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Draining Sump"); waitForTime(3);

        //turn on sump drain pump
        ReefAngel.Relay.On(SumpDrainPort);
        ReefAngel.Relay.Write();

        //display Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Draining"); waitForTime(3);

        // wait for sump empty port active, IO Mod Port 0
        waitForIOChannel(0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Empty"); waitForTime(3);

        //display Stopping Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Sump Drain"); waitForTime(3);

        // turn off sump drain
        ReefAngel.Relay.Off(SumpDrainPort);
        ReefAngel.Relay.Write();

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        //display Starting Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Saltwater Pump"); waitForTime(3);

        //turn on Saltwater Pump
        ReefAngel.Relay.On(SWBrutePort);
        ReefAngel.Relay.Write();

        //display Saltwater Pumping
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Saltwater Pumping"); waitForTime(3);

        // wait for sump full float switch active, IO Mod Port 1
        waitForIOChannel(1);

        //display Stop Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stop Saltwater Pump"); waitForTime(3);

        // turn off sw brute pump
        ReefAngel.Relay.Off(SWBrutePort);
        ReefAngel.Relay.Write();   

        //diasplay Sump is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);
       
        //display Starting Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Return Pump"); waitForTime(3);

        // turn on return pump
        ReefAngel.Relay.On(ReturnPort);
        ReefAngel.Relay.Write();

        //display Return Pump Started
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Return Pump Started"); waitForTime(3);

        //display Normalizing Waterlevel
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Waterlevel"); waitForTime(3);

        //waiting 2 minutes for waterlevel to normalize
        waitForTime(120);
       
        //display Starting Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Skimmer"); waitForTime(3);

        //turn on skimmer
        ReefAngel.Relay.On(SkimmerPort);
        ReefAngel.Relay.Write();

        //display Normalizing Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Skimmer"); waitForTime(3);

        //wait for 2 minutes for skimmer to normalize
        waitForTime(120);

        //display Skimmer Normalized
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Normalized"); waitForTime(3);

        //display Enabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Enabling ATO Pump"); waitForTime(3);

        //Enable ATO pump
        ReefAngel.Relay.RelayMaskOff = B11111111;
        ReefAngel.Relay.Write();

        //display Water Change Complete
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Water Change Complete"); waitForTime(3);

        // Handles the cleanup to return to the main screen
        ReefAngel.ClearScreen(DefaultBGColor);
        ReefAngel.DisplayedMenu = DEFAULT_MENU;
        DrawCustomGraph();
    }

    bool isSWBruteEmpty()
    {
      // check status of IO Mod Port 2
      if ( ! ReefAngel.IO.GetChannel(2) )
          return true;
      return false;
    }

    void waitForTime(int seconds)
    {
        bool done = false;
        tm.SetInterval(seconds);
        tm.Start();
        int t = tm.Trigger - now();
        do
        {
          // check the wifi interface
          pingSerial();
          // wait for specified seconds
          if ( (t >= 0) && ! tm.IsTriggered() )
            {
              // TODO finish countdown on screen
              // show countdown on screen
              //LCD.Clear(DefaultBGColor,60+(intlength(t)*5),100,100,108);
              //LCD.DrawText(DefaultFGColor,DefaultBGColor,60,100,t);
              wdt_reset();
              delay(200);
            }
            else
            {
              done = true;
            }
        } while ( !done );
        return;
    }

    void waitForIOChannel(byte channel)
    {
        // TODO complete this function
        do
        {
          wdt_reset();
          // display something on screen
          // check the wifi interface
          pingSerial();
          delay(200);
          // TODO check the IO channel logic
        } while ( ReefAngel.IO.GetChannel(channel) );
    }

    //*****End WC Additions


    //*****Begin Custom IO Expander Additions

        byte expanderRead()
        {
          byte _data=0;
          Wire.requestFrom(0x27, 1);
          if(Wire.available())
            {
            _data = Wire.read();
            CustomIOExpander = _data;
            }
          delay(10);
          return _data;
        }
       
        boolean expanderReadGetChannel(byte channel)
        {
          return bitRead(expanderRead(),channel);
        }

    //*****End Custom IO Expander Additions
       

    void DrawCustomMain()
    {
        int x,y;
        char text[10];
        // Dimming Expansion
        x = 15;
        y = 2;
        for ( int a=0;a<6;a++ )
        {
          if ( a>2 ) x = 75;
          if ( a==3 ) y = 2;
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x,y,"Ch :   " );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+12,y,a );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+24,y,ReefAngel.PWM.GetChannelValue(a) );
          y += 10;
        }
        pingSerial();

        // I/O Expansion
        byte bkcolor;
        x = 14;
        y = 34;
        for ( int a=0;a<6;a++ )
        {
          ReefAngel.LCD.DrawCircleOutline( x+(a*20),y,4,COLOR_MEDIUMORCHID );
          if ( ReefAngel.IO.GetChannel(a) ) bkcolor=COLOR_WHITE; else bkcolor=COLOR_GRAY;
          ReefAngel.LCD.FillCircle( x+(a*20),y,2,bkcolor );
        }
        pingSerial();

        // Parameters
    #if defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params,
        ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
    #else // defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params );
    #endif // defined DisplayLEDPWM && ! defined RemoveAllLights
        pingSerial();

        // Salinity
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,76, "SAL:" );
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,60,76, "L" );   
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,90,76, "H" );       
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,39,76, ReefAngel.Params.Salinity );
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,69,76, T1LowTemp );
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,98,76, T1HighTemp );   
        pingSerial();

        // Main Relay Box
        byte TempRelay = ReefAngel.Relay.RelayData;
        TempRelay &= ReefAngel.Relay.RelayMaskOff;
        TempRelay |= ReefAngel.Relay.RelayMaskOn;
        ReefAngel.LCD.DrawOutletBox( 12, 90, TempRelay );
        pingSerial();

        // Relay Expansion
        TempRelay = ReefAngel.Relay.RelayDataE[0];
        TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
        TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
        ReefAngel.LCD.DrawOutletBox( 12, 104, TempRelay );
        pingSerial();

        // Date and Time
        ReefAngel.LCD.DrawDate( 6, 122 );
        pingSerial();
    }

    void DrawCustomGraph()
    {
    }




180G FOWLR
20GH QT#1
29G QT#2

Image

Posts: 289
Joined: Wed May 16, 2012 9:52 pm
PostPosted: Mon Jun 30, 2014 9:34 pm
Version 106


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 <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


    // Initialize Alert variables
    byte AlertNonCritical=0;
    byte AlertCritical=0;
    byte overheatflag=0;
    byte atoflag=0;
    byte iochannel0flag=0;
    byte iochannel1flag=0;
    byte iochannel2flag=0;
    byte iochannel3flag=0;
    byte iochannel4flag=0;
    byte iochannel5flag=0;


    //*****Begin timing Light mask for auto mask release Additions
    long LightMaskTimerStart;
    long LightMaskTimerElapsed;
    long LightMaskTimerRelease;
    long LightMaskTimerPercentageDivider;   
   
    //*****End timing Light mask for auto mask release

    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions
    int T1LowTemp=999;
    int T1HighTemp=1;
    int T1Read=1;
   

    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

    //*****Begin WaterChange Additions

    // skimmer port
    byte SkimmerPort = Port4;
    // return port
    byte ReturnPort = Port3;
    // sump drain port
    byte SumpDrainPort = Port8;
    // SaltWater brute pump
    byte SWBrutePort = Port7;
    // Timer for countdowns
    TimerClass tm;

    //*****End WaterChange Additions


    //*****Begin ATO By Salinity Additions

    byte ATOBrutePort = Port2;

    //*****End ATO By Salinity Additions


    //*****Begin Custom IO Expander Additions

    byte CustomIOExpander = 255;

    //*****End Custom IO Expander Additions


    ////// Place global variable code above here


    //*****Begin Custom Menu Additions

    #include <avr/pgmspace.h>
    prog_char menu1_label[] PROGMEM = "Mask LED's On";
    prog_char menu2_label[] PROGMEM = "Mask LED's Off";
    prog_char menu3_label[] PROGMEM = "Mask LED's Clear";
    prog_char menu4_label[] PROGMEM = "Water Change";
    prog_char menu5_label[] PROGMEM = "Clear ATO Timeout";
    prog_char menu6_label[] PROGMEM = "Overheat Clear";
    prog_char menu7_label[] PROGMEM = "PH Calibration";
    prog_char menu8_label[] PROGMEM = "Date / Time";

    // Group the menu entries together
    PROGMEM const char *menu_items[] =
      {
        menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label, menu7_label, menu8_label,
      };

    //*****End Custom Menu Additions


    void setup()
    {
        // This must be the first line
        ReefAngel.Init();  //Initialize controller

        //_Compiled_With_Libs_Version_1.1.0
        InternalMemory.write(110, 110);
   
        //_Running_Config_Revision_106
        InternalMemory.write(111, 106);

        //*****Begin Custom Menu Additions... Initialize Custom Menu

        ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));   
        InternalMemory.write(199, 0); //sets the controller to non masked LED mode upon reboot.   

        //*****End Custom Menu Additions


        // Ports toggled in Feeding Mode
        ReefAngel.FeedingModePorts = 0;
        ReefAngel.FeedingModePortsE[0] = 0;
        // Ports toggled when Lights On / Off menu entry selected
        ReefAngel.LightsOnPorts = 0;
        ReefAngel.LightsOnPortsE[0] = Port1Bit | Port2Bit;
        // Ports turned off when Overheat temperature exceeded
        ReefAngel.OverheatShutoffPorts = Port4Bit | Port5Bit | Port6Bit;
        ReefAngel.OverheatShutoffPortsE[0] = 0;
        // Use T1 probe as temperature and overheat functions
        ReefAngel.TempProbe = T1_PROBE;
        ReefAngel.OverheatProbe = T1_PROBE;
        // Set the Overheat temperature setting
        InternalMemory.OverheatTemp_write( 850 );


        // Ports that are always on
        ReefAngel.Relay.On( Port3 );
        ReefAngel.Relay.On( Box1_Port5 );
        ReefAngel.Relay.On( Box1_Port6 );
        ReefAngel.Relay.On( Box1_Port7 );


        ////// Place additional initialization code below here

        ReefAngel.CustomVar[0]=0;
        ReefAngel.CustomVar[1]=0;
        ReefAngel.CustomVar[2]=0;
        ReefAngel.CustomVar[3]=0;
        ReefAngel.CustomVar[4]=0;
        ReefAngel.CustomVar[5]=0;
        ReefAngel.CustomVar[6]=0;   
        ReefAngel.CustomVar[7]=0;   

        //*****Begin timing Light mask for auto mask release Additions
        LightMaskTimerStart=1; //milli value when the lights are masked on or off
        LightMaskTimerElapsed=1; //milli value elapsed since lights were masked on or off
        LightMaskTimerRelease=10800000; //if light mask is set and forgotten, clear the mask after 10,800,000 milli (3 Hours)
        LightMaskTimerPercentageDivider=LightMaskTimerRelease / 100 ;
   
        //*****End timing Light mask for auto mask release Additions


        ////// Place additional initialization code above here
    }

    void loop()
    {
        ReefAngel.StandardFan( Port1,790,820 );
        ReefAngel.Relay.DelayedOn( Port4,1 );
        ReefAngel.WavemakerRandom( Port5,30,100 );
        ReefAngel.StandardHeater( Port6,750,760 );
        ReefAngel.StandardHeater( Box1_Port3,750,760 );
        ReefAngel.StandardHeater( Box1_Port4,750,760 );


    //*****Begin Custom Menu Additions

      // Removes LED's from a "MASKED" State
      if ( InternalMemory.read(199) == 0 )
        {
          ReefAngel.PWM.SetChannel( 0, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch0 to Parabola math
          ReefAngel.PWM.SetChannel( 1, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch1 to Parabola math
          ReefAngel.PWM.SetChannel( 3, PWMSlope(2,0,7,30,0,50,0,0) ); //Opens/closes 5V relay on Ch3 that shorts\opens dimmer leads on Ch0 LED driver to turn Driver on/off
          ReefAngel.PWM.SetChannel( 4, PWMSlope(0,0,14,0,0,50,0,0) ); //Opens/closes 5V relay on Ch4 that shorts\opens dimmer leads on Ch1 LED driver to turn Driver on/off
          ReefAngel.StandardLights( Box1_Port1,13,0,23,0 ); //turns QT Light schedule on if not masked off
          ReefAngel.StandardLights( Box1_Port2,13,0,23,0 ); //turns QT Light schedule on if not masked off
        }

      // MASKS LED's Off
      if ( InternalMemory.read(199) == 1 )
        {
          LightMaskTimerElapsed=millis() - LightMaskTimerStart; //milli value time elapsed while lights are masked Off
          ReefAngel.PWM.SetChannel( 0, 0 ); //Sets LED Drivers on Ch0 to 0%
          ReefAngel.PWM.SetChannel( 1, 0 ); //Sets LED Drivers on Ch1 to 0%
          ReefAngel.PWM.SetChannel( 3, 50 ); //closes 5V relay on Ch3 that shorts dimmer leads on Ch0 LED driver to turn Driver off
          ReefAngel.PWM.SetChannel( 4, 50 ); //closes 5V relay on Ch4 that shorts dimmer leads on Ch1 LED driver to turn Driver off
          ReefAngel.Relay.Off( Box1_Port1 ); //turns QT Lights OFF if masked off
          ReefAngel.Relay.Off( Box1_Port2 ); //turns QT Lights OFF if masked off
            if (LightMaskTimerElapsed > LightMaskTimerRelease) InternalMemory.write(199, 0); //clears forgotten light mask due to timeout.
        }

      // MASKS LED's On
      if ( InternalMemory.read(199) == 2 )
        {
          LightMaskTimerElapsed=millis() - LightMaskTimerStart; //milli value time elapsed while lights are masked On
          ReefAngel.PWM.SetChannel( 0, 100 ); //Sets LED Drivers on Ch0 to 100%
          ReefAngel.PWM.SetChannel( 1, 100 ); //Sets LED Drivers on Ch1 to 100%
          ReefAngel.PWM.SetChannel( 3, 0 ); //Opens 5V relay on Ch3 that removes short on dimmer leads on Ch0 LED driver to turn Driver on
          ReefAngel.PWM.SetChannel( 4, 0 ); //Opens 5V relay on Ch4 that removes short on dimmer leads on Ch1 LED driver to turn Driver on
          ReefAngel.Relay.On( Box1_Port1 ); //turns QT Lights ON if masked on
          ReefAngel.Relay.On( Box1_Port2 ); //turns QT Lights ON if masked on
            if (LightMaskTimerElapsed > LightMaskTimerRelease) InternalMemory.write(199, 0); //clears forgotten light mask due to timeout.
        }

      else
        {
        }
           
    //*****End Custom Menu Additions


    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions

        T1Read = ReefAngel.Params.Temp[T1_PROBE];
          if (T1Read !=0)
            {
              T1LowTemp = min(T1LowTemp, T1Read);
              T1HighTemp = max(T1HighTemp, T1Read);
            }
         
       
    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

       
        overheatflag = InternalMemory.read( Overheat_Exceed_Flag );
        atoflag = InternalMemory.read( ATO_Exceed_Flag );
        iochannel0flag = ! ReefAngel.IO.GetChannel( 0 );
        iochannel1flag = ! ReefAngel.IO.GetChannel( 1 );
        iochannel2flag = ! ReefAngel.IO.GetChannel( 2 );
        iochannel3flag = ! ReefAngel.IO.GetChannel( 3 );
        iochannel4flag = ! ReefAngel.IO.GetChannel( 4 );
        iochannel5flag = ! ReefAngel.IO.GetChannel( 5 );
        AlertNonCritical = atoflag + iochannel2flag + iochannel3flag + iochannel4flag + iochannel5flag;
        AlertCritical = overheatflag + iochannel0flag + iochannel1flag;   
        if ( AlertNonCritical >= 1 ) AlertNonCritical = 5;
        if ( AlertCritical >= 1 ) AlertCritical = 5;   
        ReefAngel.PWM.SetActinic(millis()%60000<100?AlertNonCritical:0);
        ReefAngel.PWM.SetDaylight(millis()%60000<100?AlertNonCritical:0);
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetActinic(millis()%300<100?AlertCritical:0);
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetDaylight(millis()%300<100?AlertCritical:0);   

       
        ////// Place your custom code below here

        ReefAngel.CustomVar[0]=InternalMemory.read(ATO_Exceed_Flag);
        ReefAngel.CustomVar[1]=InternalMemory.read(Overheat_Exceed_Flag);
        ReefAngel.CustomVar[2]=CustomIOExpander;
        ReefAngel.CustomVar[3]=0;
        ReefAngel.CustomVar[4]=InternalMemory.read(199);
        ReefAngel.CustomVar[5]=AlertNonCritical;
        ReefAngel.CustomVar[6]=AlertCritical;   
        ReefAngel.CustomVar[7]=ATOBrutePort;
       
        if ( ReefAngel.CustomVar[0]== 1 )
          {
            ReefAngel.Relay.RelayMaskOff=~(Port4Bit);
          }

        //*****Begin WC Additions

        // If menu equals waterchange mode
        // then we start the automatic water change
        // Otherwise we ignore and proceed
        if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
          {
            AutoWaterChange();
          }
       
        //*****End WC Additions
       
       
        //*****Begin ATO By Salinity Additions
       
        if (ReefAngel.Params.Salinity<300)
          {
            ATOBrutePort=Port7;
          }
        else
          {
            ATOBrutePort=Port2;
          }
        ReefAngel.StandardATO(ATOBrutePort,40 );
        if (iochannel2flag == 1)
          {
            ReefAngel.Relay.RelayMaskOff=~(Port7Bit);
          }
        if (iochannel4flag == 1)
          {
            ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
          }
         
        //*****End ATO By Salinity Additions


        //*****Begin Custom IO Expander Additions

        //*****End Custom IO Expander Additions


        ////// Place your custom code above here

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


    //*****Begin Custom Menu Additions

    //Mask LED's On. Forces LED's On Full Blast
    void MenuEntry1()
      {
        InternalMemory.write(199, 2);
        LightMaskTimerStart=millis(); //milli value when the lights are masked on
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights On"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask LED's Off. Forces LED's Off
    void MenuEntry2()
      {
        InternalMemory.write(199, 1);
        LightMaskTimerStart=millis(); //milli value when the lights are masked off
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Off"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask LED's Clear. Remove LED Masking Returns LED's To Normal Schedule
    void MenuEntry3()
      {
        InternalMemory.write(199, 0);
        LightMaskTimerElapsed=0;
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Clear"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }
     
    //Start Waterchange Mode
    void MenuEntry4()
      {
        ReefAngel.WaterChangeModeStart();
      }

    //Clear ATO Timeout Flag
    void MenuEntry5()
      {
        ReefAngel.ATOClear();
        ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
      }

    //Clear Overheat Flag
    void MenuEntry6()
      {
        ReefAngel.OverheatClear();
        ReefAngel.DisplayMenuEntry("Clear Overheat");
      }

    //Calibrate PH Probe
    void MenuEntry7()
      {
        ReefAngel.SetupCalibratePH();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }

    //Set clock Date & Time
    void MenuEntry8()
      {
        ReefAngel.SetupDateTime();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }
     
    //*****End Custom Menu Additions


    //*****Begin WC Additions

    void AutoWaterChange()
    {
        // auto water change mode
        // Display Starting Water Change"
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Water Change"); waitForTime(3);

        // Check Saltwater BRUTE for sufficient saltwater on IO Module Port2
        if ( isSWBruteEmpty() )
          {
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Not Enough Saltwater"); waitForTime(3);

            //Abort Water Change if insufficient saltwater
            // Handles the cleanup to return to the main screen
            ReefAngel.ClearScreen(DefaultBGColor);
            ReefAngel.DisplayedMenu = DEFAULT_MENU;
            DrawCustomGraph();
            return;
          }
       
        //Display Disabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");   
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Disabling ATO Pump"); waitForTime(3);

        // turn off ATO pump port to prevent ATO from trying to fill a sump being drained intentionally
        ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
       
        //Display Stopping Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Skimmer"); waitForTime(3);

        // turn off the skimmer port
        ReefAngel.Relay.Off(SkimmerPort);
        ReefAngel.Relay.Write();
       
        //Display Skimmer Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Draining"); waitForTime(3);   

        // wait for 1 minute
        waitForTime(60);

        //Display Skimmer Done Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Done Draining"); waitForTime(3);
       
        //display Stopping Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Return Pump"); waitForTime(3);

        //Stop Return Pump
        ReefAngel.Relay.Off(ReturnPort);
        ReefAngel.Relay.Write();
       
        //Display Draining To Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Draining To Sump"); waitForTime(3);

        //display Sump Filling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Filling"); waitForTime(3);

        // wait for IO Mod Port 1 to be active
        waitForIOChannel(1);

        //display Sump Is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        // display Draining Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Draining Sump"); waitForTime(3);

        //turn on sump drain pump
        ReefAngel.Relay.On(SumpDrainPort);
        ReefAngel.Relay.Write();

        //display Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Draining"); waitForTime(3);

        // wait for sump empty port active, IO Mod Port 0
        waitForIOChannel(0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Empty"); waitForTime(3);

        //display Stopping Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Sump Drain"); waitForTime(3);

        // turn off sump drain
        ReefAngel.Relay.Off(SumpDrainPort);
        ReefAngel.Relay.Write();

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        //display Starting Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Saltwater Pump"); waitForTime(3);

        //turn on Saltwater Pump
        ReefAngel.Relay.On(SWBrutePort);
        ReefAngel.Relay.Write();

        //display Saltwater Pumping
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Saltwater Pumping"); waitForTime(3);

        // wait for sump full float switch active, IO Mod Port 1
        waitForIOChannel(1);

        //display Stop Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stop Saltwater Pump"); waitForTime(3);

        // turn off sw brute pump
        ReefAngel.Relay.Off(SWBrutePort);
        ReefAngel.Relay.Write();   

        //diasplay Sump is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);
       
        //display Starting Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Return Pump"); waitForTime(3);

        // turn on return pump
        ReefAngel.Relay.On(ReturnPort);
        ReefAngel.Relay.Write();

        //display Return Pump Started
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Return Pump Started"); waitForTime(3);

        //display Normalizing Waterlevel
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Waterlevel"); waitForTime(3);

        //waiting 2 minutes for waterlevel to normalize
        waitForTime(120);
       
        //display Starting Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Skimmer"); waitForTime(3);

        //turn on skimmer
        ReefAngel.Relay.On(SkimmerPort);
        ReefAngel.Relay.Write();

        //display Normalizing Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Skimmer"); waitForTime(3);

        //wait for 2 minutes for skimmer to normalize
        waitForTime(120);

        //display Skimmer Normalized
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Normalized"); waitForTime(3);

        //display Enabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Enabling ATO Pump"); waitForTime(3);

        //Enable ATO pump
        ReefAngel.Relay.RelayMaskOff = B11111111;
        ReefAngel.Relay.Write();

        //display Water Change Complete
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Water Change Complete"); waitForTime(3);

        // Handles the cleanup to return to the main screen
        ReefAngel.ClearScreen(DefaultBGColor);
        ReefAngel.DisplayedMenu = DEFAULT_MENU;
        DrawCustomGraph();
    }

    bool isSWBruteEmpty()
    {
      // check status of IO Mod Port 2
      if ( ! ReefAngel.IO.GetChannel(2) )
          return true;
      return false;
    }

    void waitForTime(int seconds)
    {
        bool done = false;
        tm.SetInterval(seconds);
        tm.Start();
        int t = tm.Trigger - now();
        do
        {
          // check the wifi interface
          pingSerial();
          // wait for specified seconds
          if ( (t >= 0) && ! tm.IsTriggered() )
            {
              // TODO finish countdown on screen
              // show countdown on screen
              //LCD.Clear(DefaultBGColor,60+(intlength(t)*5),100,100,108);
              //LCD.DrawText(DefaultFGColor,DefaultBGColor,60,100,t);
              wdt_reset();
              delay(200);
            }
            else
            {
              done = true;
            }
        } while ( !done );
        return;
    }

    void waitForIOChannel(byte channel)
    {
        // TODO complete this function
        do
        {
          wdt_reset();
          // display something on screen
          // check the wifi interface
          pingSerial();
          delay(200);
          // TODO check the IO channel logic
        } while ( ReefAngel.IO.GetChannel(channel) );
    }

    //*****End WC Additions


    //*****Begin Custom IO Expander Additions

        byte expanderRead()
        {
          byte _data=0;
          Wire.requestFrom(0x27, 1);
          if(Wire.available())
            {
            _data = Wire.read();
            CustomIOExpander = _data;
            }
          delay(10);
          return _data;
        }
       
        boolean expanderReadGetChannel(byte channel)
        {
          return bitRead(expanderRead(),channel);
        }

    //*****End Custom IO Expander Additions
       

    void DrawCustomMain()
    {
        int x,y;
        char text[10];
        // Dimming Expansion
        x = 15;
        y = 2;
        for ( int a=0;a<6;a++ )
        {
          if ( a>2 ) x = 75;
          if ( a==3 ) y = 2;
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x,y,"Ch :   " );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+12,y,a );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+24,y,ReefAngel.PWM.GetChannelValue(a) );
          y += 10;
        }
        pingSerial();

        // I/O Expansion
        byte bkcolor;
        x = 14;
        y = 34;
        for ( int a=0;a<6;a++ )
        {
          ReefAngel.LCD.DrawCircleOutline( x+(a*20),y,4,COLOR_MEDIUMORCHID );
          if ( ReefAngel.IO.GetChannel(a) ) bkcolor=COLOR_WHITE; else bkcolor=COLOR_GRAY;
          ReefAngel.LCD.FillCircle( x+(a*20),y,2,bkcolor );
        }
        pingSerial();

        // Parameters
    #if defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params,
        ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
    #else // defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params );
    #endif // defined DisplayLEDPWM && ! defined RemoveAllLights
        pingSerial();

        // Salinity
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,73, "SAL:" );
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,60,73, "L" );   
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,90,73, "H" );       
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,82, "LMT%:" );
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,39,73, ReefAngel.Params.Salinity );
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,69,73, T1LowTemp );
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,98,73, T1HighTemp );   
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, "    " );
        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, 100 - (LightMaskTimerElapsed / LightMaskTimerPercentageDivider));
        pingSerial();

        // Main Relay Box
        byte TempRelay = ReefAngel.Relay.RelayData;
        TempRelay &= ReefAngel.Relay.RelayMaskOff;
        TempRelay |= ReefAngel.Relay.RelayMaskOn;
        ReefAngel.LCD.DrawOutletBox( 12, 90, TempRelay );
        pingSerial();

        // Relay Expansion
        TempRelay = ReefAngel.Relay.RelayDataE[0];
        TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
        TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
        ReefAngel.LCD.DrawOutletBox( 12, 104, TempRelay );
        pingSerial();

        // Date and Time
        ReefAngel.LCD.DrawDate( 6, 122 );
        pingSerial();
    }

    void DrawCustomGraph()
    {
    }




180G FOWLR
20GH QT#1
29G QT#2

Image

Posts: 289
Joined: Wed May 16, 2012 9:52 pm
PostPosted: Mon Jun 30, 2014 9:35 pm
Version 107

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 <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


    // Initialize Alert variables
    byte AlertNonCritical=0;
    byte AlertCritical=0;
    byte overheatflag=0;
    byte atoflag=0;
    byte iochannel0flag=0;
    byte iochannel1flag=0;
    byte iochannel2flag=0;
    byte iochannel3flag=0;
    byte iochannel4flag=0;
    byte iochannel5flag=0;


    //*****Begin Light Mask Timer Additions
    byte LightMaskRemaining=0;
    byte CurrentLightMask=0;
    byte PreviousLightMask=255;
    byte IgnoreMaskDuration; //manual switch to disable automatic Light Mask timeout (0=normal, != 0 = Ignore Light Mask timeout)
    byte MaskDuration; //Mask timer length in minutes 0 - 255
    long TargetMillis; //End of Timer in Millis
    long CurrentMillis; //Current Time in Millis
    long InitialMillis; //Start Time in Millis
   
    //*****End Light Mask Timer Additions


    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions
    int T1LowTemp=999;
    int T1HighTemp=1;
    int T1Read=1;
 
    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

    //*****Begin WaterChange Additions

    // skimmer port
    byte SkimmerPort = Port4;
    // return port
    byte ReturnPort = Port3;
    // sump drain port
    byte SumpDrainPort = Port8;
    // SaltWater brute pump
    byte SWBrutePort = Port7;
    // Timer for countdowns
    TimerClass tm;

    //*****End WaterChange Additions


    //*****Begin ATO By Salinity Additions

    byte ATOBrutePort = Port2;

    //*****End ATO By Salinity Additions


    //*****Begin Custom IO Expander Additions

    byte CustomIOExpander = 255;

    //*****End Custom IO Expander Additions


    ////// Place global variable code above here


    //*****Begin Custom Menu Additions

    #include <avr/pgmspace.h>
    prog_char menu1_label[] PROGMEM = "Mask LED's On";
    prog_char menu2_label[] PROGMEM = "Mask LED's Off";
    prog_char menu3_label[] PROGMEM = "Mask LED's Clear";
    prog_char menu4_label[] PROGMEM = "Water Change";
    prog_char menu5_label[] PROGMEM = "Clear ATO Timeout";
    prog_char menu6_label[] PROGMEM = "Overheat Clear";
    prog_char menu7_label[] PROGMEM = "PH Calibration";
    prog_char menu8_label[] PROGMEM = "Date / Time";

    // Group the menu entries together
    PROGMEM const char *menu_items[] =
      {
        menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label, menu7_label, menu8_label,
      };

    //*****End Custom Menu Additions


    void setup()
    {
        // This must be the first line
        ReefAngel.Init();  //Initialize controller

        //_Compiled_With_Libs_Version_1.1.0
        InternalMemory.write(110, 110);
   
        //_Running_Config_Revision_107
        InternalMemory.write(111, 107);

        //*****Begin Custom Menu Additions... Initialize Custom Menu

        ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));   

        //*****End Custom Menu Additions

        //*****Begin Light Mask Timer Additions

        if (InternalMemory.read(199) !=0) (InternalMemory.write(199, 0)); //sets the controller to non masked LED mode upon reboot.   

        //*****End Light Mask Timer Additions




        // Ports toggled in Feeding Mode
        ReefAngel.FeedingModePorts = 0;
        ReefAngel.FeedingModePortsE[0] = 0;
        // Ports toggled when Lights On / Off menu entry selected
        ReefAngel.LightsOnPorts = 0;
        ReefAngel.LightsOnPortsE[0] = Port1Bit | Port2Bit;
        // Ports turned off when Overheat temperature exceeded
        ReefAngel.OverheatShutoffPorts = Port4Bit | Port5Bit | Port6Bit;
        ReefAngel.OverheatShutoffPortsE[0] = 0;
        // Use T1 probe as temperature and overheat functions
        ReefAngel.TempProbe = T1_PROBE;
        ReefAngel.OverheatProbe = T1_PROBE;
        // Set the Overheat temperature setting
        InternalMemory.OverheatTemp_write( 850 );


        // Ports that are always on
        ReefAngel.Relay.On( Port3 );
        ReefAngel.Relay.On( Box1_Port5 );
        ReefAngel.Relay.On( Box1_Port6 );
        ReefAngel.Relay.On( Box1_Port7 );


        ////// Place additional initialization code below here

        ReefAngel.CustomVar[0]=0;
        ReefAngel.CustomVar[1]=0;
        ReefAngel.CustomVar[2]=0;
        ReefAngel.CustomVar[3]=0;
        ReefAngel.CustomVar[4]=0;
        ReefAngel.CustomVar[5]=0;
        ReefAngel.CustomVar[6]=0;   
        ReefAngel.CustomVar[7]=0;   

        ////// Place additional initialization code above here
    }

    void loop()
    {
        ReefAngel.StandardFan( Port1,790,820 );
        ReefAngel.Relay.DelayedOn( Port4,1 );
        ReefAngel.WavemakerRandom( Port5,30,100 );
        ReefAngel.StandardHeater( Port6,750,760 );
        ReefAngel.StandardHeater( Box1_Port3,750,760 );
        ReefAngel.StandardHeater( Box1_Port4,750,760 );


    //*****Begin Custom Menu Additions
    //*****Begin Light Mask Timer Additions                   

      //LightMaskRemaining = ( TargetMillis - CurrentMillis ) / 3600000;//Display Light Mask Time Remaining in Hours
      LightMaskRemaining = ( TargetMillis - CurrentMillis ) / 60000;//Display Light Mask Time Remaining in Minutes         
      //LightMaskRemaining = ( TargetMillis - CurrentMillis ) / 1000;//Display Light Mask Time Remaining in seconds
      CurrentLightMask = InternalMemory.read(199);//reads current light mask setting
      MaskDuration = InternalMemory.read (198);  //Mask timer length in minutes 0 - 255 (0:00 - 4:15)       
      IgnoreMaskDuration = InternalMemory.read (197); //manual switch to disable automatic Light Mask timeout (0=normal, != 0 = Ignore Light Mask timeout)
      CurrentMillis = millis();//update the timer to the current count
     
        // Removes LED's from a "MASKED" State
      if ( CurrentLightMask == 0 )
        {
          ReefAngel.PWM.SetChannel( 0, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch0 to Parabola math
          ReefAngel.PWM.SetChannel( 1, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch1 to Parabola math
          ReefAngel.PWM.SetChannel( 3, PWMSlope(2,0,7,30,0,50,0,0) ); //Opens/closes 5V relay on Ch3 that shorts\opens dimmer leads on Ch0 LED driver to turn Driver on/off
          ReefAngel.PWM.SetChannel( 4, PWMSlope(0,0,14,0,0,50,0,0) ); //Opens/closes 5V relay on Ch4 that shorts\opens dimmer leads on Ch1 LED driver to turn Driver on/off
          ReefAngel.StandardLights( Box1_Port1,13,0,23,0 ); //turns QT Light schedule on if not masked off
          ReefAngel.StandardLights( Box1_Port2,13,0,23,0 ); //turns QT Light schedule on if not masked off
        }

      if ( PreviousLightMask != CurrentLightMask )//Checks if the light mask setting has been changed
        {

          //Checks if light mask value has been set to an invalid value by direct memory access and clears (sets to 0) mask if not valid
        if ( CurrentLightMask > 2 )
          {
            InternalMemory.write(199, 0); //clears light mask if value is not valid.
          }
 
        // MASKS LED's Off
        if ( CurrentLightMask == 1 )
          {
            TargetMillis = CurrentMillis + ( MaskDuration * 60000 ); //Set the duration of the mask timer in minutes ( 1 - 255 )
            ReefAngel.PWM.SetChannel( 0, 0 ); //Sets LED Drivers on Ch0 to 0%
            ReefAngel.PWM.SetChannel( 1, 0 ); //Sets LED Drivers on Ch1 to 0%
            ReefAngel.PWM.SetChannel( 3, 50 ); //closes 5V relay on Ch3 that shorts dimmer leads on Ch0 LED driver to turn Driver off
            ReefAngel.PWM.SetChannel( 4, 50 ); //closes 5V relay on Ch4 that shorts dimmer leads on Ch1 LED driver to turn Driver off
            ReefAngel.Relay.Off( Box1_Port1 ); //turns QT Lights OFF if masked off
            ReefAngel.Relay.Off( Box1_Port2 ); //turns QT Lights OFF if masked off
          }

        // MASKS LED's On
        if ( CurrentLightMask == 2 )
          {
            TargetMillis = CurrentMillis + ( MaskDuration * 60000 ); //Set the duration of the mask timer in minutes ( 1 - 255 )
            ReefAngel.PWM.SetChannel( 0, 100 ); //Sets LED Drivers on Ch0 to 100%
            ReefAngel.PWM.SetChannel( 1, 100 ); //Sets LED Drivers on Ch1 to 100%
            ReefAngel.PWM.SetChannel( 3, 0 ); //Opens 5V relay on Ch3 that removes short on dimmer leads on Ch0 LED driver to turn Driver on
            ReefAngel.PWM.SetChannel( 4, 0 ); //Opens 5V relay on Ch4 that removes short on dimmer leads on Ch1 LED driver to turn Driver on
            ReefAngel.Relay.On( Box1_Port1 ); //turns QT Lights ON if masked on
            ReefAngel.Relay.On( Box1_Port2 ); //turns QT Lights ON if masked on
          }
       
        PreviousLightMask = CurrentLightMask;
        }

        if ( CurrentLightMask != 0 )// Checks if lights are masked on or off
          {
            if ( IgnoreMaskDuration == 0 )//Checks if Light mask timer ignore byte is active
              {
                if ( CurrentMillis > TargetMillis )//checks if Light mask timeout has expired.
                  {
                    InternalMemory.write(199, 0); //clears forgotten light mask due to timeout.
                    CurrentMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
                    TargetMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
                  }

                else
                  {
                  }         

              }
             
            else
              {
                CurrentMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
                TargetMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
              }

          }             

        else
          {
            CurrentMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
            TargetMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
          }
             
             
    //*****End Custom Menu Additions
    //*****End Light Mask Timer Additions

    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions

        T1Read = ReefAngel.Params.Temp[T1_PROBE];
          if (T1Read !=0)//Debounce for Low Temperature reading 0 at startup
            {
              T1LowTemp = min(T1LowTemp, T1Read);//Tracks Low Temperature
              T1HighTemp = max(T1HighTemp, T1Read);//Tracks High Temperature
            }
         
    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

       
        overheatflag = InternalMemory.read( Overheat_Exceed_Flag );
        atoflag = InternalMemory.read( ATO_Exceed_Flag );
        iochannel0flag = ! ReefAngel.IO.GetChannel( 0 );
        iochannel1flag = ! ReefAngel.IO.GetChannel( 1 );
        iochannel2flag = ! ReefAngel.IO.GetChannel( 2 );
        iochannel3flag = ! ReefAngel.IO.GetChannel( 3 );
        iochannel4flag = ! ReefAngel.IO.GetChannel( 4 );
        iochannel5flag = ! ReefAngel.IO.GetChannel( 5 );
        AlertNonCritical = atoflag + iochannel2flag + iochannel3flag + iochannel4flag + iochannel5flag;
        AlertCritical = overheatflag + iochannel0flag + iochannel1flag;   
        if ( AlertNonCritical >= 1 ) AlertNonCritical = 5;
        if ( AlertCritical >= 1 ) AlertCritical = 5;   
        ReefAngel.PWM.SetActinic(millis()%60000<100?AlertNonCritical:0);
        ReefAngel.PWM.SetDaylight(millis()%60000<100?AlertNonCritical:0);
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetActinic(millis()%300<100?AlertCritical:0);
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetDaylight(millis()%300<100?AlertCritical:0);   

       
        ////// Place your custom code below here

        ReefAngel.CustomVar[0]=InternalMemory.read(ATO_Exceed_Flag);
        ReefAngel.CustomVar[1]=InternalMemory.read(Overheat_Exceed_Flag);
        ReefAngel.CustomVar[2]=CustomIOExpander;
        ReefAngel.CustomVar[3]=0;
        ReefAngel.CustomVar[4]=LightMaskRemaining;
        ReefAngel.CustomVar[5]=AlertNonCritical;
        ReefAngel.CustomVar[6]=AlertCritical;   
        ReefAngel.CustomVar[7]=ATOBrutePort;
       
        if ( ReefAngel.CustomVar[0]== 1 )
          {
            ReefAngel.Relay.RelayMaskOff=~(Port4Bit);
          }

        //*****Begin WC Additions

        // If menu equals waterchange mode
        // then we start the automatic water change
        // Otherwise we ignore and proceed
        if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
          {
            AutoWaterChange();
          }
       
        //*****End WC Additions
       
       
        //*****Begin ATO By Salinity Additions
       
        if (ReefAngel.Params.Salinity<300)
          {
            ATOBrutePort=Port7;
          }
        else
          {
            ATOBrutePort=Port2;
          }
        ReefAngel.StandardATO(ATOBrutePort,40 );
        if (iochannel2flag == 1)
          {
            ReefAngel.Relay.RelayMaskOff=~(Port7Bit);
          }
        if (iochannel4flag == 1)
          {
            ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
          }
         
        //*****End ATO By Salinity Additions

        ////// Place your custom code above here

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


    //*****Begin Custom Menu Additions

    //Mask Lights On. Forces Lights's On Full Blast
    void MenuEntry1()
      {
        InternalMemory.write(199, 2);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights On"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask Lights Off. Forces Lights Off
    void MenuEntry2()
      {
        InternalMemory.write(199, 1);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Off"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask Lights Clear. Remove Light Masking Returns Lights to normal schedule
    void MenuEntry3()
      {
        InternalMemory.write(199, 0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Clear"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }
     
    //Start Waterchange Mode
    void MenuEntry4()
      {
        ReefAngel.WaterChangeModeStart();
      }

    //Clear ATO Timeout Flag
    void MenuEntry5()
      {
        ReefAngel.ATOClear();
        ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
      }

    //Clear Overheat Flag
    void MenuEntry6()
      {
        ReefAngel.OverheatClear();
        ReefAngel.DisplayMenuEntry("Clear Overheat");
      }

    //Calibrate PH Probe
    void MenuEntry7()
      {
        ReefAngel.SetupCalibratePH();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }

    //Set clock Date & Time
    void MenuEntry8()
      {
        ReefAngel.SetupDateTime();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }
     
    //*****End Custom Menu Additions


    //*****Begin Water Change Additions

    void AutoWaterChange()
    {
        // auto water change mode
        // Display Starting Water Change"
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Water Change"); waitForTime(3);

        // Check Saltwater BRUTE for sufficient saltwater on IO Module Port2
        if ( isSWBruteEmpty() )
          {
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Not Enough Saltwater"); waitForTime(3);

            //Abort Water Change if insufficient saltwater
            // Handles the cleanup to return to the main screen
            ReefAngel.ClearScreen(DefaultBGColor);
            ReefAngel.DisplayedMenu = DEFAULT_MENU;
            DrawCustomGraph();
            return;
          }
       
        //Display Disabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");   
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Disabling ATO Pump"); waitForTime(3);

        // turn off ATO pump port to prevent ATO from trying to fill a sump being drained intentionally
        ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
       
        //Display Stopping Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Skimmer"); waitForTime(3);

        // turn off the skimmer port
        ReefAngel.Relay.Off(SkimmerPort);
        ReefAngel.Relay.Write();
       
        //Display Skimmer Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Draining"); waitForTime(3);   

        // wait for 1 minute
        waitForTime(60);

        //Display Skimmer Done Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Done Draining"); waitForTime(3);
       
        //display Stopping Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Return Pump"); waitForTime(3);

        //Stop Return Pump
        ReefAngel.Relay.Off(ReturnPort);
        ReefAngel.Relay.Write();
       
        //Display Draining To Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Draining To Sump"); waitForTime(3);

        //display Sump Filling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Filling"); waitForTime(3);

        // wait for IO Mod Port 1 to be active
        waitForIOChannel(1);

        //display Sump Is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        // display Draining Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Draining Sump"); waitForTime(3);

        //turn on sump drain pump
        ReefAngel.Relay.On(SumpDrainPort);
        ReefAngel.Relay.Write();

        //display Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Draining"); waitForTime(3);

        // wait for sump empty port active, IO Mod Port 0
        waitForIOChannel(0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Empty"); waitForTime(3);

        //display Stopping Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Sump Drain"); waitForTime(3);

        // turn off sump drain
        ReefAngel.Relay.Off(SumpDrainPort);
        ReefAngel.Relay.Write();

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        //display Starting Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Saltwater Pump"); waitForTime(3);

        //turn on Saltwater Pump
        ReefAngel.Relay.On(SWBrutePort);
        ReefAngel.Relay.Write();

        //display Saltwater Pumping
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Saltwater Pumping"); waitForTime(3);

        // wait for sump full float switch active, IO Mod Port 1
        waitForIOChannel(1);

        //display Stop Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stop Saltwater Pump"); waitForTime(3);

        // turn off sw brute pump
        ReefAngel.Relay.Off(SWBrutePort);
        ReefAngel.Relay.Write();   

        //diasplay Sump is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);
       
        //display Starting Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Return Pump"); waitForTime(3);

        // turn on return pump
        ReefAngel.Relay.On(ReturnPort);
        ReefAngel.Relay.Write();

        //display Return Pump Started
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Return Pump Started"); waitForTime(3);

        //display Normalizing Waterlevel
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Waterlevel"); waitForTime(3);

        //waiting 2 minutes for waterlevel to normalize
        waitForTime(120);
       
        //display Starting Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Skimmer"); waitForTime(3);

        //turn on skimmer
        ReefAngel.Relay.On(SkimmerPort);
        ReefAngel.Relay.Write();

        //display Normalizing Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Skimmer"); waitForTime(3);

        //wait for 2 minutes for skimmer to normalize
        waitForTime(120);

        //display Skimmer Normalized
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Normalized"); waitForTime(3);

        //display Enabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Enabling ATO Pump"); waitForTime(3);

        //Enable ATO pump
        ReefAngel.Relay.RelayMaskOff = B11111111;
        ReefAngel.Relay.Write();

        //display Water Change Complete
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Water Change Complete"); waitForTime(3);

        // Handles the cleanup to return to the main screen
        ReefAngel.ClearScreen(DefaultBGColor);
        ReefAngel.DisplayedMenu = DEFAULT_MENU;
        DrawCustomGraph();
    }

    bool isSWBruteEmpty()
    {
      // check status of IO Mod Port 2
      if ( ! ReefAngel.IO.GetChannel(2) )
          return true;
      return false;
    }

    void waitForTime(int seconds)
    {
        bool done = false;
        tm.SetInterval(seconds);
        tm.Start();
        int t = tm.Trigger - now();
        do
        {
          // check the wifi interface
          pingSerial();
          // wait for specified seconds
          if ( (t >= 0) && ! tm.IsTriggered() )
            {
              wdt_reset();
              delay(200);
            }
            else
            {
              done = true;
            }
        } while ( !done );
        return;
    }

    void waitForIOChannel(byte channel)
    {
        // TODO complete this function
        do
        {
          wdt_reset();
          // display something on screen
          // check the wifi interface
          pingSerial();
          delay(200);
          // TODO check the IO channel logic
        } while ( ReefAngel.IO.GetChannel(channel) );
    }

    //*****End Water Change Additions


    //*****Begin Custom IO Expander Additions

        byte expanderRead()
        {
          byte _data=0;
          Wire.requestFrom(0x27, 1);
          if(Wire.available())
            {
            _data = Wire.read();
            CustomIOExpander = _data;
            }
          delay(10);
          return _data;
        }
       
        boolean expanderReadGetChannel(byte channel)
        {
          return bitRead(expanderRead(),channel);
        }

    //*****End Custom IO Expander Additions
       

    void DrawCustomMain()
    {
        int x,y;
        char text[10];
        // Dimming Expansion
        x = 15;
        y = 2;
        for ( int a=0;a<6;a++ )
        {
          if ( a>2 ) x = 75;
          if ( a==3 ) y = 2;
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x,y,"Ch :   " );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+12,y,a );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+24,y,ReefAngel.PWM.GetChannelValue(a) );
          y += 10;
        }
        pingSerial();

        // I/O Expansion
        byte bkcolor;
        x = 14;
        y = 34;
        for ( int a=0;a<6;a++ )
        {
          ReefAngel.LCD.DrawCircleOutline( x+(a*20),y,4,COLOR_MEDIUMORCHID );
          if ( ReefAngel.IO.GetChannel(a) ) bkcolor=COLOR_WHITE; else bkcolor=COLOR_GRAY;
          ReefAngel.LCD.FillCircle( x+(a*20),y,2,bkcolor );
        }
        pingSerial();

        // Parameters
    #if defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params,
        ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
    #else // defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params );
    #endif // defined DisplayLEDPWM && ! defined RemoveAllLights
        pingSerial();

        // Salinity
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,73, "SAL:" );//Display Salinity
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,82, "LMTR:" );//Display Light Mask Time Remaining
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, "  Hours." );//Clear screen video from data location before new data draw         
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, "    Min." );//Clear screen video from data location before new data draw
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, "      Sec." );//Clear screen video from data location before new data draw         
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, ( TargetMillis - CurrentMillis ) / 3600000 );//Display Light Mask Time Remaining in Hours
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, ( TargetMillis - CurrentMillis ) / 60000 );//Display Light Mask Time Remaining in Minutes         
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, ( TargetMillis - CurrentMillis ) / 1000 );//Display Light Mask Time Remaining in seconds
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,60,73, "L:" );//Display Low Temperature   
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,96,73, "H:" );//Display High Temperature       
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,39,73, ReefAngel.Params.Salinity );//Display Salinity
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,72,73, T1LowTemp );//Display Low Temperature
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,108,73, T1HighTemp );//Display High Temperature   

        pingSerial();

        // Main Relay Box
        byte TempRelay = ReefAngel.Relay.RelayData;
        TempRelay &= ReefAngel.Relay.RelayMaskOff;
        TempRelay |= ReefAngel.Relay.RelayMaskOn;
        ReefAngel.LCD.DrawOutletBox( 12, 90, TempRelay );
        pingSerial();

        // Relay Expansion
        TempRelay = ReefAngel.Relay.RelayDataE[0];
        TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
        TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
        ReefAngel.LCD.DrawOutletBox( 12, 104, TempRelay );
        pingSerial();

        // Date and Time
        ReefAngel.LCD.DrawDate( 6, 122 );
        pingSerial();
    }

    void DrawCustomGraph()
    {
    }




180G FOWLR
20GH QT#1
29G QT#2

Image

Posts: 289
Joined: Wed May 16, 2012 9:52 pm
PostPosted: Mon Jun 30, 2014 9:36 pm
Version 108

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 <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


    // Initialize Alert variables
    byte AlertATOPump=0;
    byte AlertNonCritical=0;
    byte AlertCritical=0;
    byte overheatflag=0;
    byte atoflag=0;
    byte iochannel0flag=0;
    byte iochannel1flag=0;
    byte iochannel2flag=0;
    byte iochannel3flag=0;
    byte iochannel4flag=0;
    byte iochannel5flag=0;


    //*****Begin Light Mask Timer Additions
    byte LightMaskRemaining=0;
    byte CurrentLightMask=0;
    byte PreviousLightMask=255;
    byte IgnoreMaskDuration; //manual switch to disable automatic Light Mask timeout (0=normal, != 0 = Ignore Light Mask timeout)
    byte MaskDuration; //Mask timer length in minutes 0 - 255
    long TargetMillis; //End of Timer in Millis
    long CurrentMillis; //Current Time in Millis
    long InitialMillis; //Start Time in Millis
   
    //*****End Light Mask Timer Additions


    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions
    int T1LowTemp=999;
    int T1HighTemp=1;
    int T1Read=1;
 
    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

    //*****Begin WaterChange Additions

    // skimmer port
    byte SkimmerPort = Port4;
    // return port
    byte ReturnPort = Port3;
    // sump drain port
    byte SumpDrainPort = Port8;
    // SaltWater brute pump
    byte SWBrutePort = Port7;
    // Timer for countdowns
    TimerClass tm;

    //*****End WaterChange Additions


    //*****Begin ATO By Salinity Additions

    byte ATOBrutePort = Port7;
    char ATOBruteText[ ] = "ATOSW";
   
    //*****End ATO By Salinity Additions


    //*****Begin Custom IO Expander Additions

    byte CustomIOExpander = 255;

    //*****End Custom IO Expander Additions


    ////// Place global variable code above here


    //*****Begin Custom Menu Additions

    #include <avr/pgmspace.h>
    prog_char menu1_label[] PROGMEM = "Mask LED's On";
    prog_char menu2_label[] PROGMEM = "Mask LED's Off";
    prog_char menu3_label[] PROGMEM = "Mask LED's Clear";
    prog_char menu4_label[] PROGMEM = "Water Change";
    prog_char menu5_label[] PROGMEM = "Clear ATO Timeout";
    prog_char menu6_label[] PROGMEM = "Overheat Clear";
    prog_char menu7_label[] PROGMEM = "PH Calibration";
    prog_char menu8_label[] PROGMEM = "Date / Time";

    // Group the menu entries together
    PROGMEM const char *menu_items[] =
      {
        menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label, menu7_label, menu8_label,
      };

    //*****End Custom Menu Additions


    void setup()
    {
        // This must be the first line
        ReefAngel.Init();  //Initialize controller

        //_Compiled_With_Libs_Version_1.1.0
        InternalMemory.write(110, 110);
   
        //_Running_Config_Revision_108 06/29/2014
        InternalMemory.write(111, 108);

        //*****Begin Custom Menu Additions... Initialize Custom Menu

        ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));   

        //*****End Custom Menu Additions

        //*****Begin Light Mask Timer Additions

        if (InternalMemory.read(199) !=0) (InternalMemory.write(199, 0)); //sets the controller to non masked LED mode upon reboot.   

        //*****End Light Mask Timer Additions




        // Ports toggled in Feeding Mode
        ReefAngel.FeedingModePorts = 0;
        ReefAngel.FeedingModePortsE[0] = 0;
        // Ports toggled when Lights On / Off menu entry selected
        ReefAngel.LightsOnPorts = 0;
        ReefAngel.LightsOnPortsE[0] = Port1Bit | Port2Bit;
        // Ports turned off when Overheat temperature exceeded
        ReefAngel.OverheatShutoffPorts = Port4Bit | Port5Bit | Port6Bit;
        ReefAngel.OverheatShutoffPortsE[0] = 0;
        // Use T1 probe as temperature and overheat functions
        ReefAngel.TempProbe = T1_PROBE;
        ReefAngel.OverheatProbe = T1_PROBE;
        // Set the Overheat temperature setting
        InternalMemory.OverheatTemp_write( 850 );


        // Ports that should always be on/off at startup
        ReefAngel.Relay.On( Port3 );//Turns 180G Return Pump ON if controller reboots
        ReefAngel.Relay.Off( Port2 );//Turns 180G RO/DI Topoff OFF if controller reboots
        ReefAngel.Relay.Off( Port7 );//Turns 180G SW Topoff OFF if controller reboots
        ReefAngel.Relay.Off( Port8 );//Turns 180G Sump Drain OFF if controller reboots
        ReefAngel.Relay.On( Box1_Port5 );//Turns 20GH QT Return Pump ON if controller reboots
        ReefAngel.Relay.On( Box1_Port6 );//Turns 29G QT Return Pump ON if controller reboots
        ReefAngel.Relay.On( Box1_Port7 );//Turns 20GH QT MaxiJet Pump ON if controller reboots
        ReefAngel.Relay.On( Box1_Port8 );//Turns 29G QT MaxiJet Pump ON if controller reboots
       

        ////// Place additional initialization code below here

        ReefAngel.CustomVar[0]=0;
        ReefAngel.CustomVar[1]=0;
        ReefAngel.CustomVar[2]=0;
        ReefAngel.CustomVar[3]=0;
        ReefAngel.CustomVar[4]=0;
        ReefAngel.CustomVar[5]=0;
        ReefAngel.CustomVar[6]=0;   
        ReefAngel.CustomVar[7]=0;
   
   
        ////// Place additional initialization code above here
    }

    void loop()
    {
        ReefAngel.StandardFan( Port1,790,820 );
        ReefAngel.Relay.DelayedOn( Port4,1 );
        ReefAngel.WavemakerRandom( Port5,30,100 );
        ReefAngel.StandardHeater( Port6,750,760 );
        ReefAngel.StandardHeater( Box1_Port3,750,760 );
        ReefAngel.StandardHeater( Box1_Port4,750,760 );


    //*****Begin Custom Menu Additions
    //*****Begin Light Mask Timer Additions                   

      //LightMaskRemaining = ( TargetMillis - CurrentMillis ) / 3600000;//Display Light Mask Time Remaining in Hours
      LightMaskRemaining = ( TargetMillis - CurrentMillis ) / 60000;//Display Light Mask Time Remaining in Minutes         
      //LightMaskRemaining = ( TargetMillis - CurrentMillis ) / 1000;//Display Light Mask Time Remaining in seconds
      CurrentLightMask = InternalMemory.read(199);//reads current light mask setting
      MaskDuration = InternalMemory.read (198);  //Mask timer length in minutes 0 - 255 (0:00 - 4:15)       
      IgnoreMaskDuration = InternalMemory.read (197); //manual switch to disable automatic Light Mask timeout (0=normal, != 0 = Ignore Light Mask timeout)
      CurrentMillis = millis();//update the timer to the current count
     
        // Removes LED's from a "MASKED" State
      if ( CurrentLightMask == 0 )
        {
          ReefAngel.PWM.SetChannel( 0, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch0 to Parabola math
          ReefAngel.PWM.SetChannel( 1, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch1 to Parabola math
          ReefAngel.PWM.SetChannel( 3, PWMSlope(2,0,7,30,0,50,0,0) ); //Opens/closes 5V relay on Ch3 that shorts\opens dimmer leads on Ch0 LED driver to turn Driver on/off
          ReefAngel.PWM.SetChannel( 4, PWMSlope(0,0,14,0,0,50,0,0) ); //Opens/closes 5V relay on Ch4 that shorts\opens dimmer leads on Ch1 LED driver to turn Driver on/off
          ReefAngel.StandardLights( Box1_Port1,13,0,23,0 ); //turns QT Light schedule on if not masked off
          ReefAngel.StandardLights( Box1_Port2,13,0,23,0 ); //turns QT Light schedule on if not masked off
        }

      if ( PreviousLightMask != CurrentLightMask )//Checks if the light mask setting has been changed
        {

          //Checks if light mask value has been set to an invalid value by direct memory access and clears (sets to 0) mask if not valid
        if ( CurrentLightMask > 2 )
          {
            InternalMemory.write(199, 0); //clears light mask if value is not valid.
          }
 
        // MASKS LED's Off
        if ( CurrentLightMask == 1 )
          {
            TargetMillis = CurrentMillis + ( MaskDuration * 60000 ); //Set the duration of the mask timer in minutes ( 1 - 255 )
            ReefAngel.PWM.SetChannel( 0, 0 ); //Sets LED Drivers on Ch0 to 0%
            ReefAngel.PWM.SetChannel( 1, 0 ); //Sets LED Drivers on Ch1 to 0%
            ReefAngel.PWM.SetChannel( 3, 50 ); //closes 5V relay on Ch3 that shorts dimmer leads on Ch0 LED driver to turn Driver off
            ReefAngel.PWM.SetChannel( 4, 50 ); //closes 5V relay on Ch4 that shorts dimmer leads on Ch1 LED driver to turn Driver off
            ReefAngel.Relay.Off( Box1_Port1 ); //turns QT Lights OFF if masked off
            ReefAngel.Relay.Off( Box1_Port2 ); //turns QT Lights OFF if masked off
          }

        // MASKS LED's On
        if ( CurrentLightMask == 2 )
          {
            TargetMillis = CurrentMillis + ( MaskDuration * 60000 ); //Set the duration of the mask timer in minutes ( 1 - 255 )
            ReefAngel.PWM.SetChannel( 0, 100 ); //Sets LED Drivers on Ch0 to 100%
            ReefAngel.PWM.SetChannel( 1, 100 ); //Sets LED Drivers on Ch1 to 100%
            ReefAngel.PWM.SetChannel( 3, 0 ); //Opens 5V relay on Ch3 that removes short on dimmer leads on Ch0 LED driver to turn Driver on
            ReefAngel.PWM.SetChannel( 4, 0 ); //Opens 5V relay on Ch4 that removes short on dimmer leads on Ch1 LED driver to turn Driver on
            ReefAngel.Relay.On( Box1_Port1 ); //turns QT Lights ON if masked on
            ReefAngel.Relay.On( Box1_Port2 ); //turns QT Lights ON if masked on
          }
       
        PreviousLightMask = CurrentLightMask;
        }

        if ( CurrentLightMask != 0 )// Checks if lights are masked on or off
          {
            if ( IgnoreMaskDuration == 0 )//Checks if Light mask timer ignore byte is active
              {
                if ( CurrentMillis > TargetMillis )//checks if Light mask timeout has expired.
                  {
                    InternalMemory.write(199, 0); //clears forgotten light mask due to timeout.
                    CurrentMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
                    TargetMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
                  }

                else
                  {
                  }         

              }
             
            else
              {
                CurrentMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
                TargetMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
              }

          }             

        else
          {
            CurrentMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
            TargetMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
          }
             
             
    //*****End Custom Menu Additions
    //*****End Light Mask Timer Additions

    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions

        T1Read = ReefAngel.Params.Temp[T1_PROBE];
          if (T1Read !=0)//Debounce for Low Temperature reading 0 at startup
            {
              T1LowTemp = min(T1LowTemp, T1Read);//Tracks Low Temperature
              T1HighTemp = max(T1HighTemp, T1Read);//Tracks High Temperature
            }
         
    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions


        overheatflag = InternalMemory.read( Overheat_Exceed_Flag );
        atoflag = InternalMemory.read( ATO_Exceed_Flag );
        iochannel0flag = ! ReefAngel.IO.GetChannel( 0 );
        iochannel1flag = ! ReefAngel.IO.GetChannel( 1 );
        iochannel2flag = ! ReefAngel.IO.GetChannel( 2 );
        iochannel3flag = ! ReefAngel.IO.GetChannel( 3 );
        iochannel4flag = ! ReefAngel.IO.GetChannel( 4 );
        iochannel5flag = ! ReefAngel.IO.GetChannel( 5 );
        AlertATOPump = ReefAngel.Relay.Status(Port2);
        AlertNonCritical = atoflag + iochannel2flag + iochannel3flag + iochannel4flag + iochannel5flag;
        AlertCritical = AlertATOPump + overheatflag + iochannel0flag + iochannel1flag;   
        if ( AlertNonCritical >= 1 ) AlertNonCritical = 25;
        if ( AlertCritical >= 1 ) AlertCritical = 25;   
        if ( AlertNonCritical >= 1 ) ReefAngel.PWM.SetActinic(millis()%60000<100?AlertNonCritical:0);
        if ( AlertNonCritical >= 1 ) ReefAngel.PWM.SetDaylight(millis()%60000<100?AlertNonCritical:0);
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetActinic(millis()%300<100?AlertCritical:0);
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetDaylight(millis()%300<100?AlertCritical:0);   

       
        ////// Place your custom code below here

        ReefAngel.CustomVar[0]=LightMaskRemaining;
        ReefAngel.CustomVar[1]=AlertCritical;
        ReefAngel.CustomVar[2]=AlertNonCritical;
        ReefAngel.CustomVar[3]=ATOBrutePort;
//        ReefAngel.CustomVar[4]=
//        ReefAngel.CustomVar[5]=
//        ReefAngel.CustomVar[6]=   
//        ReefAngel.CustomVar[7]=
       
        if ( InternalMemory.read(ATO_Exceed_Flag)== 1 )
          {
            ReefAngel.Relay.RelayMaskOff=~(Port4Bit);
          }

        //*****Begin WC Additions

        // If menu equals waterchange mode
        // then we start the automatic water change
        // Otherwise we ignore and proceed
        if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
          {
            AutoWaterChange();
          }
       
        //*****End WC Additions
       
       
        //*****Begin ATO By Salinity Additions
       
        if (ReefAngel.Params.Salinity<300)//if salinity is low switch to Saltwater ATO
          {
            ReefAngel.StandardATO(Port7,40 );//ATO Port is now Saltwater Port7
            ReefAngel.Relay.Off(Port2);//Turn off RO/DI Port2
            ATOBrutePort=Port7;
            char ATOBruteText[ ] = "ATOSW";
          }
        else//if Salinity is high switch to RO/DI Topoff
          {
            ReefAngel.StandardATO(Port2,40 );//ATO Port is now RO/DI Port2
            ReefAngel.Relay.Off(Port7);//Turn off Saltwater Port7
            ATOBrutePort=Port2;
            char ATOBruteText[ ] = "ATORO";
          }       
        if (iochannel2flag == 1)//IF ATO Brute is empty do not pump
          {
            ReefAngel.Relay.RelayMaskOff=~(Port7Bit);//Mask Off Saltwater Brute Pump
          }
        if (iochannel4flag == 1)//IF ATO Brute is empty do not pump
          {
            ReefAngel.Relay.RelayMaskOff=~(Port2Bit);//Mask Off RO/DI Brute Pump
          }
         
        //*****End ATO By Salinity Additions

        ////// Place your custom code above here

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


    //*****Begin Custom Menu Additions

    //Mask Lights On. Forces Lights's On Full Blast
    void MenuEntry1()
      {
        InternalMemory.write(199, 2);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights On"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask Lights Off. Forces Lights Off
    void MenuEntry2()
      {
        InternalMemory.write(199, 1);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Off"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask Lights Clear. Remove Light Masking Returns Lights to normal schedule
    void MenuEntry3()
      {
        InternalMemory.write(199, 0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Clear"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }
     
    //Start Waterchange Mode
    void MenuEntry4()
      {
        ReefAngel.WaterChangeModeStart();
      }

    //Clear ATO Timeout Flag
    void MenuEntry5()
      {
        ReefAngel.ATOClear();
        ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
      }

    //Clear Overheat Flag
    void MenuEntry6()
      {
        ReefAngel.OverheatClear();
        ReefAngel.DisplayMenuEntry("Clear Overheat");
      }

    //Calibrate PH Probe
    void MenuEntry7()
      {
        ReefAngel.SetupCalibratePH();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }

    //Set clock Date & Time
    void MenuEntry8()
      {
        ReefAngel.SetupDateTime();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }
     
    //*****End Custom Menu Additions


    //*****Begin Water Change Additions

    void AutoWaterChange()
    {
        // auto water change mode
        // Display Starting Water Change"
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Water Change"); waitForTime(3);

        // Check Saltwater BRUTE for sufficient saltwater on IO Module Port2
        if ( isSWBruteEmpty() )
          {
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Not Enough Saltwater"); waitForTime(3);

            //Abort Water Change if insufficient saltwater
            // Handles the cleanup to return to the main screen
            ReefAngel.ClearScreen(DefaultBGColor);
            ReefAngel.DisplayedMenu = DEFAULT_MENU;
            DrawCustomGraph();
            return;
          }
       
        //Display Disabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");   
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Disabling ATO Pump"); waitForTime(3);

        // turn off ATO pump port to prevent ATO from trying to fill a sump being drained intentionally
        ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
       
        //Display Stopping Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Skimmer"); waitForTime(3);

        // turn off the skimmer port
        ReefAngel.Relay.Off(SkimmerPort);
        ReefAngel.Relay.Write();
       
        //Display Skimmer Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Draining"); waitForTime(3);   

        // wait for 1 minute
        waitForTime(60);

        //Display Skimmer Done Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Done Draining"); waitForTime(3);
       
        //display Stopping Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Return Pump"); waitForTime(3);

        //Stop Return Pump
        ReefAngel.Relay.Off(ReturnPort);
        ReefAngel.Relay.Write();
       
        //Display Draining To Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Draining To Sump"); waitForTime(3);

        //display Sump Filling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Filling"); waitForTime(3);

        // wait for IO Mod Port 1 to be active
        waitForIOChannel(1);

        //display Sump Is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        // display Draining Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Draining Sump"); waitForTime(3);

        //turn on sump drain pump
        ReefAngel.Relay.On(SumpDrainPort);
        ReefAngel.Relay.Write();

        //display Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Draining"); waitForTime(3);

        // wait for sump empty port active, IO Mod Port 0
        waitForIOChannel(0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Empty"); waitForTime(3);

        //display Stopping Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Sump Drain"); waitForTime(3);

        // turn off sump drain
        ReefAngel.Relay.Off(SumpDrainPort);
        ReefAngel.Relay.Write();

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        //display Starting Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Saltwater Pump"); waitForTime(3);

        //turn on Saltwater Pump
        ReefAngel.Relay.On(SWBrutePort);
        ReefAngel.Relay.Write();

        //display Saltwater Pumping
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Saltwater Pumping"); waitForTime(3);

        // wait for sump full float switch active, IO Mod Port 1
        waitForIOChannel(1);

        //display Stop Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stop Saltwater Pump"); waitForTime(3);

        // turn off sw brute pump
        ReefAngel.Relay.Off(SWBrutePort);
        ReefAngel.Relay.Write();   

        //diasplay Sump is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);
       
        //display Starting Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Return Pump"); waitForTime(3);

        // turn on return pump
        ReefAngel.Relay.On(ReturnPort);
        ReefAngel.Relay.Write();

        //display Return Pump Started
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Return Pump Started"); waitForTime(3);

        //display Normalizing Waterlevel
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Waterlevel"); waitForTime(3);

        //waiting 2 minutes for waterlevel to normalize
        waitForTime(120);
       
        //display Starting Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Skimmer"); waitForTime(3);

        //turn on skimmer
        ReefAngel.Relay.On(SkimmerPort);
        ReefAngel.Relay.Write();

        //display Normalizing Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Skimmer"); waitForTime(3);

        //wait for 2 minutes for skimmer to normalize
        waitForTime(120);

        //display Skimmer Normalized
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Normalized"); waitForTime(3);

        //display Enabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Enabling ATO Pump"); waitForTime(3);

        //Enable ATO pump
        ReefAngel.Relay.RelayMaskOff = B11111111;
        ReefAngel.Relay.Write();

        //display Water Change Complete
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Water Change Complete"); waitForTime(3);

        // Handles the cleanup to return to the main screen
        ReefAngel.ClearScreen(DefaultBGColor);
        ReefAngel.DisplayedMenu = DEFAULT_MENU;
        DrawCustomGraph();
    }

    bool isSWBruteEmpty()
    {
      // check status of IO Mod Port 2
      if ( ! ReefAngel.IO.GetChannel(2) )
          return true;
      return false;
    }

    void waitForTime(int seconds)
    {
        bool done = false;
        tm.SetInterval(seconds);
        tm.Start();
        int t = tm.Trigger - now();
        do
        {
          // check the wifi interface
          pingSerial();
          // wait for specified seconds
          if ( (t >= 0) && ! tm.IsTriggered() )
            {
              wdt_reset();
              delay(200);
            }
            else
            {
              done = true;
            }
        } while ( !done );
        return;
    }

    void waitForIOChannel(byte channel)
    {
        // TODO complete this function
        do
        {
          wdt_reset();
          // display something on screen
          // check the wifi interface
          pingSerial();
          delay(200);
          // TODO check the IO channel logic
        } while ( ReefAngel.IO.GetChannel(channel) );
    }

    //*****End Water Change Additions


    //*****Begin Custom IO Expander Additions

        byte expanderRead()
        {
          byte _data=0;
          Wire.requestFrom(0x27, 1);
          if(Wire.available())
            {
            _data = Wire.read();
            CustomIOExpander = _data;
            }
          delay(10);
          return _data;
        }
       
        boolean expanderReadGetChannel(byte channel)
        {
          return bitRead(expanderRead(),channel);
        }

    //*****End Custom IO Expander Additions
       

    void DrawCustomMain()
    {
        int x,y;
        char text[10];
        // Dimming Expansion
        x = 15;
        y = 2;
        for ( int a=0;a<6;a++ )
        {
          if ( a>2 ) x = 75;
          if ( a==3 ) y = 2;
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x,y,"Ch :   " );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+12,y,a );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+24,y,ReefAngel.PWM.GetChannelValue(a) );
          y += 10;
        }
        pingSerial();

        // I/O Expansion
        byte bkcolor;
        x = 14;
        y = 34;
        for ( int a=0;a<6;a++ )
        {
          ReefAngel.LCD.DrawCircleOutline( x+(a*20),y,4,COLOR_MEDIUMORCHID );
          if ( ReefAngel.IO.GetChannel(a) ) bkcolor=COLOR_WHITE; else bkcolor=COLOR_GRAY;
          ReefAngel.LCD.FillCircle( x+(a*20),y,2,bkcolor );
        }
        pingSerial();

        // Parameters
    #if defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params,
        ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
    #else // defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params );
    #endif // defined DisplayLEDPWM && ! defined RemoveAllLights
        pingSerial();

        // Salinity
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,73, "SAL:" );//Display Salinity
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,82, "LMTR:" );//Display Light Mask Time Remaining
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, "  Hours." );//Clear screen video from data location before new data draw         
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, "    Min." );//Clear screen video from data location before new data draw
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, "      Sec." );//Clear screen video from data location before new data draw         
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, ( TargetMillis - CurrentMillis ) / 3600000 );//Display Light Mask Time Remaining in Hours
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, ( TargetMillis - CurrentMillis ) / 60000 );//Display Light Mask Time Remaining in Minutes         
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, ( TargetMillis - CurrentMillis ) / 1000 );//Display Light Mask Time Remaining in seconds
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,96,82, ATOBruteText );
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,60,73, "L:" );//Display Low Temperature   
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,96,73, "H:" );//Display High Temperature       
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,39,73, ReefAngel.Params.Salinity );//Display Salinity
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,72,73, T1LowTemp );//Display Low Temperature
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,108,73, T1HighTemp );//Display High Temperature   

        pingSerial();

        // Main Relay Box
        byte TempRelay = ReefAngel.Relay.RelayData;
        TempRelay &= ReefAngel.Relay.RelayMaskOff;
        TempRelay |= ReefAngel.Relay.RelayMaskOn;
        ReefAngel.LCD.DrawOutletBox( 12, 90, TempRelay );
        pingSerial();

        // Relay Expansion
        TempRelay = ReefAngel.Relay.RelayDataE[0];
        TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
        TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
        ReefAngel.LCD.DrawOutletBox( 12, 104, TempRelay );
        pingSerial();

        // Date and Time
        ReefAngel.LCD.DrawDate( 6, 122 );
        pingSerial();
    }

    void DrawCustomGraph()
    {
    }




180G FOWLR
20GH QT#1
29G QT#2

Image

Posts: 289
Joined: Wed May 16, 2012 9:52 pm
PostPosted: Mon Jun 30, 2014 9:37 pm
Version 109

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 <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


    // Initialize Alert variables
    byte AlertATOPump=0;
    byte AlertNonCritical=0;
    byte AlertCritical=0;
    byte overheatflag=0;
    byte atoflag=0;
    byte iochannel0flag=0;
    byte iochannel1flag=0;
    byte iochannel2flag=0;
    byte iochannel3flag=0;
    byte iochannel4flag=0;
    byte iochannel5flag=0;


    //*****Begin Light Mask Timer Additions
    byte LightMaskRemaining=0;
    byte CurrentLightMask=0;
    byte PreviousLightMask=255;
    byte IgnoreMaskDuration; //manual switch to disable automatic Light Mask timeout (0=normal, != 0 = Ignore Light Mask timeout)
    byte CurrentMaskDuration; //Mask timer length in minutes 0 - 255
    byte PreviousMaskDuration; //Mask timer variable to check for CurrentMaskDuration changes via direct write to memory location 198
    long TargetMillis; //End of Timer in Millis
    long CurrentMillis; //Current Time in Millis
    long InitialMillis; //Start Time in Millis
   
    //*****End Light Mask Timer Additions


    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions
    int T1LowTemp=999;
    int T1HighTemp=1;
    int T1Read=1;
 
    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

    //*****Begin WaterChange Additions

    // skimmer port
    byte SkimmerPort = Port4;
    // return port
    byte ReturnPort = Port3;
    // sump drain port
    byte SumpDrainPort = Port8;
    // SaltWater brute pump
    byte SWBrutePort = Port7;
    // Timer for countdowns
    TimerClass tm;

    //*****End WaterChange Additions


    //*****Begin ATO By Salinity Additions

    byte ATOBrutePort = Port7;
    char ATOBruteText[ ] = "ATOSW";
   
    //*****End ATO By Salinity Additions


    //*****Begin Custom IO Expander Additions

    byte CustomIOExpander = 255;

    //*****End Custom IO Expander Additions


    ////// Place global variable code above here


    //*****Begin Custom Menu Additions

    #include <avr/pgmspace.h>
    prog_char menu1_label[] PROGMEM = "Mask LED's On";
    prog_char menu2_label[] PROGMEM = "Mask LED's Off";
    prog_char menu3_label[] PROGMEM = "Mask LED's Clear";
    prog_char menu4_label[] PROGMEM = "Water Change";
    prog_char menu5_label[] PROGMEM = "Clear ATO Timeout";
    prog_char menu6_label[] PROGMEM = "Overheat Clear";
    prog_char menu7_label[] PROGMEM = "PH Calibration";
    prog_char menu8_label[] PROGMEM = "Date / Time";

    // Group the menu entries together
    PROGMEM const char *menu_items[] =
      {
        menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label, menu7_label, menu8_label,
      };

    //*****End Custom Menu Additions


    void setup()
    {
        // This must be the first line
        ReefAngel.Init();  //Initialize controller

        //_Compiled_With_Libs_Version_1.1.0
        InternalMemory.write(110, 110);
   
        //_Running_Config_Revision_109 06/30/2014
        InternalMemory.write(111, 109);

        //*****Begin Custom Menu Additions... Initialize Custom Menu

        ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));   

        //*****End Custom Menu Additions

        //*****Begin Light Mask Timer Additions

        if (InternalMemory.read(199) !=0) (InternalMemory.write(199, 0)); //sets the controller to non masked LED mode upon reboot.   

        //*****End Light Mask Timer Additions




        // Ports toggled in Feeding Mode
        ReefAngel.FeedingModePorts = 0;
        ReefAngel.FeedingModePortsE[0] = 0;
        // Ports toggled when Lights On / Off menu entry selected
        ReefAngel.LightsOnPorts = 0;
        ReefAngel.LightsOnPortsE[0] = Port1Bit | Port2Bit;
        // Ports turned off when Overheat temperature exceeded
        ReefAngel.OverheatShutoffPorts = Port4Bit | Port5Bit | Port6Bit;
        ReefAngel.OverheatShutoffPortsE[0] = 0;
        // Use T1 probe as temperature and overheat functions
        ReefAngel.TempProbe = T1_PROBE;
        ReefAngel.OverheatProbe = T1_PROBE;
        // Set the Overheat temperature setting
        InternalMemory.OverheatTemp_write( 850 );


        // Ports that should always be on/off at startup
        ReefAngel.Relay.On( Port3 );//Turns 180G Return Pump ON if controller reboots
        ReefAngel.Relay.Off( Port2 );//Turns 180G RO/DI Topoff OFF if controller reboots
        ReefAngel.Relay.Off( Port7 );//Turns 180G SW Topoff OFF if controller reboots
        ReefAngel.Relay.Off( Port8 );//Turns 180G Sump Drain OFF if controller reboots
        ReefAngel.Relay.On( Box1_Port5 );//Turns 20GH QT Return Pump ON if controller reboots
        ReefAngel.Relay.On( Box1_Port6 );//Turns 29G QT Return Pump ON if controller reboots
        ReefAngel.Relay.On( Box1_Port7 );//Turns 20GH QT MaxiJet Pump ON if controller reboots
        ReefAngel.Relay.On( Box1_Port8 );//Turns 29G QT MaxiJet Pump ON if controller reboots
       

        ////// Place additional initialization code below here

        ReefAngel.CustomVar[0]=0;
        ReefAngel.CustomVar[1]=0;
        ReefAngel.CustomVar[2]=0;
        ReefAngel.CustomVar[3]=0;
        ReefAngel.CustomVar[4]=0;
        ReefAngel.CustomVar[5]=0;
        ReefAngel.CustomVar[6]=0;   
        ReefAngel.CustomVar[7]=0;
   
   
        ////// Place additional initialization code above here
    }

    void loop()
    {
        ReefAngel.StandardFan( Port1,790,820 );
        ReefAngel.Relay.DelayedOn( Port4,1 );
        ReefAngel.WavemakerRandom( Port5,30,100 );
        ReefAngel.StandardHeater( Port6,750,760 );
        ReefAngel.StandardHeater( Box1_Port3,750,760 );
        ReefAngel.StandardHeater( Box1_Port4,750,760 );


    //*****Begin Custom Menu Additions
    //*****Begin Light Mask Timer Additions                   

      //LightMaskRemaining = ( TargetMillis - CurrentMillis ) / 3600000;//Display Light Mask Time Remaining in Hours
      LightMaskRemaining = ( TargetMillis - CurrentMillis ) / 60000;//Display Light Mask Time Remaining in Minutes         
      //LightMaskRemaining = ( TargetMillis - CurrentMillis ) / 1000;//Display Light Mask Time Remaining in seconds
      CurrentLightMask = InternalMemory.read(199);//reads current light mask setting
      CurrentMaskDuration = InternalMemory.read (198);  //Mask timer length in minutes 0 - 255 (0:00 - 4:15)       
      IgnoreMaskDuration = InternalMemory.read (197); //manual switch to disable automatic Light Mask timeout (0=normal, != 0 = Ignore Light Mask timeout)
      CurrentMillis = millis();//update the timer to the current count
     
        // Removes LED's from a "MASKED" State
      if ( CurrentLightMask == 0 )
        {
          ReefAngel.PWM.SetChannel( 0, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch0 to Parabola math
          ReefAngel.PWM.SetChannel( 1, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch1 to Parabola math
          ReefAngel.PWM.SetChannel( 3, PWMSlope(2,0,7,30,0,50,0,0) ); //Opens/closes 5V relay on Ch3 that shorts\opens dimmer leads on Ch0 LED driver to turn Driver on/off
          ReefAngel.PWM.SetChannel( 4, PWMSlope(0,0,14,0,0,50,0,0) ); //Opens/closes 5V relay on Ch4 that shorts\opens dimmer leads on Ch1 LED driver to turn Driver on/off
          ReefAngel.StandardLights( Box1_Port1,13,0,23,0 ); //turns QT Light schedule on if not masked off
          ReefAngel.StandardLights( Box1_Port2,13,0,23,0 ); //turns QT Light schedule on if not masked off
        }

      if ( ( PreviousLightMask != CurrentLightMask ) || ( PreviousMaskDuration != CurrentMaskDuration ) )//Checks if the light mask setting or duration has been manually changed
        {

          //Checks if light mask value has been set to an invalid value by direct memory access and clears (sets to 0) mask if not valid
        if ( CurrentLightMask > 2 )
          {
            InternalMemory.write(199, 0); //clears light mask if value is not valid.
          }
 
        // MASKS LED's Off
        if ( CurrentLightMask == 1 )
          {
            TargetMillis = CurrentMillis + ( CurrentMaskDuration * 60000 ); //Set the duration of the mask timer in minutes ( 1 - 255 )
            ReefAngel.PWM.SetChannel( 0, 0 ); //Sets LED Drivers on Ch0 to 0%
            ReefAngel.PWM.SetChannel( 1, 0 ); //Sets LED Drivers on Ch1 to 0%
            ReefAngel.PWM.SetChannel( 3, 50 ); //closes 5V relay on Ch3 that shorts dimmer leads on Ch0 LED driver to turn Driver off
            ReefAngel.PWM.SetChannel( 4, 50 ); //closes 5V relay on Ch4 that shorts dimmer leads on Ch1 LED driver to turn Driver off
            ReefAngel.Relay.Off( Box1_Port1 ); //turns QT Lights OFF if masked off
            ReefAngel.Relay.Off( Box1_Port2 ); //turns QT Lights OFF if masked off
          }

        // MASKS LED's On
        if ( CurrentLightMask == 2 )
          {
            TargetMillis = CurrentMillis + ( CurrentMaskDuration * 60000 ); //Set the duration of the mask timer in minutes ( 1 - 255 )
            ReefAngel.PWM.SetChannel( 0, 100 ); //Sets LED Drivers on Ch0 to 100%
            ReefAngel.PWM.SetChannel( 1, 100 ); //Sets LED Drivers on Ch1 to 100%
            ReefAngel.PWM.SetChannel( 3, 0 ); //Opens 5V relay on Ch3 that removes short on dimmer leads on Ch0 LED driver to turn Driver on
            ReefAngel.PWM.SetChannel( 4, 0 ); //Opens 5V relay on Ch4 that removes short on dimmer leads on Ch1 LED driver to turn Driver on
            ReefAngel.Relay.On( Box1_Port1 ); //turns QT Lights ON if masked on
            ReefAngel.Relay.On( Box1_Port2 ); //turns QT Lights ON if masked on
          }
       
        PreviousLightMask = CurrentLightMask;
        PreviousMaskDuration = CurrentMaskDuration;
        }

        if ( CurrentLightMask != 0 )// Checks if lights are masked on or off
          {
            if ( IgnoreMaskDuration == 0 )//Checks if Light mask timer ignore byte is active
              {
                if ( CurrentMillis > TargetMillis )//checks if Light mask timeout has expired.
                  {
                    InternalMemory.write(199, 0); //clears forgotten light mask due to timeout.
                    CurrentMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
                    TargetMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
                  }

                else
                  {
                  }         

              }
             
            else
              {
                CurrentMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
                TargetMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
              }

          }             

        else
          {
            CurrentMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
            TargetMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
          }
             
             
    //*****End Custom Menu Additions
    //*****End Light Mask Timer Additions

    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions

        T1Read = ReefAngel.Params.Temp[T1_PROBE];
          if (T1Read !=0)//Debounce for Low Temperature reading 0 at startup
            {
              T1LowTemp = min(T1LowTemp, T1Read);//Tracks Low Temperature
              T1HighTemp = max(T1HighTemp, T1Read);//Tracks High Temperature
            }
         
    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions


        overheatflag = InternalMemory.read( Overheat_Exceed_Flag );
        atoflag = InternalMemory.read( ATO_Exceed_Flag );
        iochannel0flag = ! ReefAngel.IO.GetChannel( 0 );
        iochannel1flag = ! ReefAngel.IO.GetChannel( 1 );
        iochannel2flag = ! ReefAngel.IO.GetChannel( 2 );
        iochannel3flag = ! ReefAngel.IO.GetChannel( 3 );
        iochannel4flag = ! ReefAngel.IO.GetChannel( 4 );
        iochannel5flag = ! ReefAngel.IO.GetChannel( 5 );
        AlertATOPump = ReefAngel.Relay.Status(Port2);
        AlertNonCritical = atoflag + iochannel2flag + iochannel3flag + iochannel4flag + iochannel5flag;
        AlertCritical = AlertATOPump + overheatflag + iochannel0flag + iochannel1flag;   
        if ( AlertNonCritical >= 1 ) AlertNonCritical = 25;
        if ( AlertCritical >= 1 ) AlertCritical = 25;   
        if ( AlertNonCritical >= 1 ) ReefAngel.PWM.SetActinic(millis()%60000<100?AlertNonCritical:0);
        if ( AlertNonCritical >= 1 ) ReefAngel.PWM.SetDaylight(millis()%60000<100?AlertNonCritical:0);
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetActinic(millis()%300<100?AlertCritical:0);
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetDaylight(millis()%300<100?AlertCritical:0);   

       
        ////// Place your custom code below here

        ReefAngel.CustomVar[0]=LightMaskRemaining;
        ReefAngel.CustomVar[1]=AlertCritical;
        ReefAngel.CustomVar[2]=AlertNonCritical;
        ReefAngel.CustomVar[3]=ATOBrutePort;
//        ReefAngel.CustomVar[4]=
//        ReefAngel.CustomVar[5]=
//        ReefAngel.CustomVar[6]=   
//        ReefAngel.CustomVar[7]=
       
        if ( InternalMemory.read(ATO_Exceed_Flag)== 1 )
          {
            ReefAngel.Relay.RelayMaskOff=~(Port4Bit);
          }

        //*****Begin WC Additions

        // If menu equals waterchange mode
        // then we start the automatic water change
        // Otherwise we ignore and proceed
        if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
          {
            AutoWaterChange();
          }
       
        //*****End WC Additions
       
       
        //*****Begin ATO By Salinity Additions
       
        if (ReefAngel.Params.Salinity<300)//if salinity is low switch to Saltwater ATO
          {
            ReefAngel.StandardATO(Port7,40 );//ATO Port is now Saltwater Port7
            ReefAngel.Relay.Off(Port2);//Turn off RO/DI Port2
            ATOBrutePort=Port7;
            char ATOBruteText[ ] = "ATOSW";
          }
        else//if Salinity is high switch to RO/DI Topoff
          {
            ReefAngel.StandardATO(Port2,40 );//ATO Port is now RO/DI Port2
            ReefAngel.Relay.Off(Port7);//Turn off Saltwater Port7
            ATOBrutePort=Port2;
            char ATOBruteText[ ] = "ATORO";
          }       
        if (iochannel2flag == 1)//IF ATO Brute is empty do not pump
          {
            ReefAngel.Relay.RelayMaskOff=~(Port7Bit);//Mask Off Saltwater Brute Pump
          }
        if (iochannel4flag == 1)//IF ATO Brute is empty do not pump
          {
            ReefAngel.Relay.RelayMaskOff=~(Port2Bit);//Mask Off RO/DI Brute Pump
          }
         
        //*****End ATO By Salinity Additions

        ////// Place your custom code above here

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


    //*****Begin Custom Menu Additions

    //Mask Lights On. Forces Lights's On Full Blast
    void MenuEntry1()
      {
        InternalMemory.write(199, 2);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights On"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask Lights Off. Forces Lights Off
    void MenuEntry2()
      {
        InternalMemory.write(199, 1);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Off"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask Lights Clear. Remove Light Masking Returns Lights to normal schedule
    void MenuEntry3()
      {
        InternalMemory.write(199, 0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Clear"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }
     
    //Start Waterchange Mode
    void MenuEntry4()
      {
        ReefAngel.WaterChangeModeStart();
      }

    //Clear ATO Timeout Flag
    void MenuEntry5()
      {
        ReefAngel.ATOClear();
        ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
      }

    //Clear Overheat Flag
    void MenuEntry6()
      {
        ReefAngel.OverheatClear();
        ReefAngel.DisplayMenuEntry("Clear Overheat");
      }

    //Calibrate PH Probe
    void MenuEntry7()
      {
        ReefAngel.SetupCalibratePH();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }

    //Set clock Date & Time
    void MenuEntry8()
      {
        ReefAngel.SetupDateTime();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }
     
    //*****End Custom Menu Additions


    //*****Begin Water Change Additions

    void AutoWaterChange()
    {
        // auto water change mode
        // Display Starting Water Change"
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Water Change"); waitForTime(3);

        // Check Saltwater BRUTE for sufficient saltwater on IO Module Port2
        if ( isSWBruteEmpty() )
          {
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Not Enough Saltwater"); waitForTime(3);

            //Abort Water Change if insufficient saltwater
            // Handles the cleanup to return to the main screen
            ReefAngel.ClearScreen(DefaultBGColor);
            ReefAngel.DisplayedMenu = DEFAULT_MENU;
            DrawCustomGraph();
            return;
          }
       
        //Display Disabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");   
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Disabling ATO Pump"); waitForTime(3);

        // turn off ATO pump port to prevent ATO from trying to fill a sump being drained intentionally
        ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
       
        //Display Stopping Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Skimmer"); waitForTime(3);

        // turn off the skimmer port
        ReefAngel.Relay.Off(SkimmerPort);
        ReefAngel.Relay.Write();
       
        //Display Skimmer Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Draining"); waitForTime(3);   

        // wait for 1 minute
        waitForTime(60);

        //Display Skimmer Done Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Done Draining"); waitForTime(3);
       
        //display Stopping Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Return Pump"); waitForTime(3);

        //Stop Return Pump
        ReefAngel.Relay.Off(ReturnPort);
        ReefAngel.Relay.Write();
       
        //Display Draining To Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Draining To Sump"); waitForTime(3);

        //display Sump Filling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Filling"); waitForTime(3);

        // wait for IO Mod Port 1 to be active
        waitForIOChannel(1);

        //display Sump Is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        // display Draining Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Draining Sump"); waitForTime(3);

        //turn on sump drain pump
        ReefAngel.Relay.On(SumpDrainPort);
        ReefAngel.Relay.Write();

        //display Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Draining"); waitForTime(3);

        // wait for sump empty port active, IO Mod Port 0
        waitForIOChannel(0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Empty"); waitForTime(3);

        //display Stopping Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Sump Drain"); waitForTime(3);

        // turn off sump drain
        ReefAngel.Relay.Off(SumpDrainPort);
        ReefAngel.Relay.Write();

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        //display Starting Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Saltwater Pump"); waitForTime(3);

        //turn on Saltwater Pump
        ReefAngel.Relay.On(SWBrutePort);
        ReefAngel.Relay.Write();

        //display Saltwater Pumping
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Saltwater Pumping"); waitForTime(3);

        // wait for sump full float switch active, IO Mod Port 1
        waitForIOChannel(1);

        //display Stop Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stop Saltwater Pump"); waitForTime(3);

        // turn off sw brute pump
        ReefAngel.Relay.Off(SWBrutePort);
        ReefAngel.Relay.Write();   

        //diasplay Sump is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);
       
        //display Starting Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Return Pump"); waitForTime(3);

        // turn on return pump
        ReefAngel.Relay.On(ReturnPort);
        ReefAngel.Relay.Write();

        //display Return Pump Started
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Return Pump Started"); waitForTime(3);

        //display Normalizing Waterlevel
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Waterlevel"); waitForTime(3);

        //waiting 2 minutes for waterlevel to normalize
        waitForTime(120);
       
        //display Starting Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Skimmer"); waitForTime(3);

        //turn on skimmer
        ReefAngel.Relay.On(SkimmerPort);
        ReefAngel.Relay.Write();

        //display Normalizing Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Skimmer"); waitForTime(3);

        //wait for 2 minutes for skimmer to normalize
        waitForTime(120);

        //display Skimmer Normalized
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Normalized"); waitForTime(3);

        //display Enabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Enabling ATO Pump"); waitForTime(3);

        //Enable ATO pump
        ReefAngel.Relay.RelayMaskOff = B11111111;
        ReefAngel.Relay.Write();

        //display Water Change Complete
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Water Change Complete"); waitForTime(3);

        // Handles the cleanup to return to the main screen
        ReefAngel.ClearScreen(DefaultBGColor);
        ReefAngel.DisplayedMenu = DEFAULT_MENU;
        DrawCustomGraph();
    }

    bool isSWBruteEmpty()
    {
      // check status of IO Mod Port 2
      if ( ! ReefAngel.IO.GetChannel(2) )
          return true;
      return false;
    }

    void waitForTime(int seconds)
    {
        bool done = false;
        tm.SetInterval(seconds);
        tm.Start();
        int t = tm.Trigger - now();
        do
        {
          // check the wifi interface
          pingSerial();
          // wait for specified seconds
          if ( (t >= 0) && ! tm.IsTriggered() )
            {
              wdt_reset();
              delay(200);
            }
            else
            {
              done = true;
            }
        } while ( !done );
        return;
    }

    void waitForIOChannel(byte channel)
    {
        // TODO complete this function
        do
        {
          wdt_reset();
          // display something on screen
          // check the wifi interface
          pingSerial();
          delay(200);
          // TODO check the IO channel logic
        } while ( ReefAngel.IO.GetChannel(channel) );
    }

    //*****End Water Change Additions


    //*****Begin Custom IO Expander Additions

        byte expanderRead()
        {
          byte _data=0;
          Wire.requestFrom(0x27, 1);
          if(Wire.available())
            {
            _data = Wire.read();
            CustomIOExpander = _data;
            }
          delay(10);
          return _data;
        }
       
        boolean expanderReadGetChannel(byte channel)
        {
          return bitRead(expanderRead(),channel);
        }

    //*****End Custom IO Expander Additions
       

    void DrawCustomMain()
    {
        int x,y;
        char text[10];
        // Dimming Expansion
        x = 15;
        y = 2;
        for ( int a=0;a<6;a++ )
        {
          if ( a>2 ) x = 75;
          if ( a==3 ) y = 2;
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x,y,"Ch :   " );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+12,y,a );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+24,y,ReefAngel.PWM.GetChannelValue(a) );
          y += 10;
        }
        pingSerial();

        // I/O Expansion
        byte bkcolor;
        x = 14;
        y = 34;
        for ( int a=0;a<6;a++ )
        {
          ReefAngel.LCD.DrawCircleOutline( x+(a*20),y,4,COLOR_MEDIUMORCHID );
          if ( ReefAngel.IO.GetChannel(a) ) bkcolor=COLOR_WHITE; else bkcolor=COLOR_GRAY;
          ReefAngel.LCD.FillCircle( x+(a*20),y,2,bkcolor );
        }
        pingSerial();

        // Parameters
    #if defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params,
        ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
    #else // defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params );
    #endif // defined DisplayLEDPWM && ! defined RemoveAllLights
        pingSerial();

        // Salinity
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,73, "SAL:" );//Display Salinity
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,82, "LMTR:" );//Display Light Mask Time Remaining
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, "  Hours." );//Clear screen video from data location before new data draw         
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, "    Min." );//Clear screen video from data location before new data draw
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, "      Sec." );//Clear screen video from data location before new data draw         
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, ( TargetMillis - CurrentMillis ) / 3600000 );//Display Light Mask Time Remaining in Hours
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, ( TargetMillis - CurrentMillis ) / 60000 );//Display Light Mask Time Remaining in Minutes         
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, ( TargetMillis - CurrentMillis ) / 1000 );//Display Light Mask Time Remaining in seconds
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,96,82, ATOBruteText );
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,60,73, "L:" );//Display Low Temperature   
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,96,73, "H:" );//Display High Temperature       
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,39,73, ReefAngel.Params.Salinity );//Display Salinity
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,72,73, T1LowTemp );//Display Low Temperature
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,108,73, T1HighTemp );//Display High Temperature   

        pingSerial();

        // Main Relay Box
        byte TempRelay = ReefAngel.Relay.RelayData;
        TempRelay &= ReefAngel.Relay.RelayMaskOff;
        TempRelay |= ReefAngel.Relay.RelayMaskOn;
        ReefAngel.LCD.DrawOutletBox( 12, 90, TempRelay );
        pingSerial();

        // Relay Expansion
        TempRelay = ReefAngel.Relay.RelayDataE[0];
        TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
        TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
        ReefAngel.LCD.DrawOutletBox( 12, 104, TempRelay );
        pingSerial();

        // Date and Time
        ReefAngel.LCD.DrawDate( 6, 122 );
        pingSerial();
    }

    void DrawCustomGraph()
    {
    }




180G FOWLR
20GH QT#1
29G QT#2

Image

Posts: 289
Joined: Wed May 16, 2012 9:52 pm
PostPosted: Sun Jul 13, 2014 7:20 pm
Version 110

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 <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


    // Initialize Alert variables
    byte AlertATOPump=0;
    byte AlertNonCritical=0;
    byte AlertCritical=0;
    byte overheatflag=0;
    byte atoflag=0;
    byte iochannel0flag=0;
    byte iochannel1flag=0;
    byte iochannel2flag=0;
    byte iochannel3flag=0;
    byte iochannel4flag=0;
    byte iochannel5flag=0;


    //*****Begin Light Mask Timer Additions
    byte LightMaskRemaining=0;
    byte CurrentLightMask=0;
    byte PreviousLightMask=255;
    byte IgnoreMaskDuration; //manual switch to disable automatic Light Mask timeout (0=normal, != 0 = Ignore Light Mask timeout)
    byte CurrentMaskDuration; //Mask timer length in minutes 0 - 255
    byte PreviousMaskDuration; //Mask timer variable to check for CurrentMaskDuration changes via direct write to memory location 198
    long TargetMillis; //End of Timer in Millis
    long CurrentMillis; //Current Time in Millis
    long InitialMillis; //Start Time in Millis
   
    //*****End Light Mask Timer Additions


    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions
    int T1LowTemp=999;
    int T1HighTemp=1;
    int T1Read=1;
 
    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions

    //*****Begin WaterChange Additions

    // skimmer port
    byte SkimmerPort = Port4;
    // return port
    byte ReturnPort = Port3;
    // sump drain port
    byte SumpDrainPort = Port8;
    // SaltWater brute pump
    byte SWBrutePort = Port7;
    // Timer for countdowns
    TimerClass tm;

    //*****End WaterChange Additions


    //*****Begin ATO By Salinity Additions

    byte ATOBrutePort = Port7;
    char ATOBruteText[ ] = "ATOSW";
   
    //*****End ATO By Salinity Additions


    //*****Begin Custom IO Expander Additions

    byte CustomIOExpander = 255;

    //*****End Custom IO Expander Additions


    ////// Place global variable code above here


    //*****Begin Custom Menu Additions

    #include <avr/pgmspace.h>
    prog_char menu1_label[] PROGMEM = "Mask LED's On";
    prog_char menu2_label[] PROGMEM = "Mask LED's Off";
    prog_char menu3_label[] PROGMEM = "Mask LED's Clear";
    prog_char menu4_label[] PROGMEM = "Water Change";
    prog_char menu5_label[] PROGMEM = "Clear ATO Timeout";
    prog_char menu6_label[] PROGMEM = "Overheat Clear";
    prog_char menu7_label[] PROGMEM = "PH Calibration";
    prog_char menu8_label[] PROGMEM = "Date / Time";

    // Group the menu entries together
    PROGMEM const char *menu_items[] =
      {
        menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label, menu7_label, menu8_label,
      };

    //*****End Custom Menu Additions


    void setup()
    {
        // This must be the first line
        ReefAngel.Init();  //Initialize controller

        //_Compiled_With_Libs_Version_1.1.0
        InternalMemory.write(110, 110);
   
        //_Running_Config_Revision_110 07/10/2014
        InternalMemory.write(111, 109);

        //*****Begin Custom Menu Additions... Initialize Custom Menu

        ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));   

        //*****End Custom Menu Additions

        //*****Begin Light Mask Timer Additions

        if (InternalMemory.read(199) !=0) (InternalMemory.write(199, 0)); //sets the controller to non masked LED mode upon reboot.   

        //*****End Light Mask Timer Additions




        // Ports toggled in Feeding Mode
        ReefAngel.FeedingModePorts = 0;
        ReefAngel.FeedingModePortsE[0] = 0;
        // Ports toggled when Lights On / Off menu entry selected
        ReefAngel.LightsOnPorts = 0;
        ReefAngel.LightsOnPortsE[0] = Port1Bit | Port2Bit;
        // Ports turned off when Overheat temperature exceeded
        ReefAngel.OverheatShutoffPorts = Port4Bit | Port5Bit | Port6Bit;
        ReefAngel.OverheatShutoffPortsE[0] = 0;
        // Use T1 probe as temperature and overheat functions
        ReefAngel.TempProbe = T1_PROBE;
        ReefAngel.OverheatProbe = T1_PROBE;
        // Set the Overheat temperature setting
        InternalMemory.OverheatTemp_write( 850 );


        // Ports that should always be on/off at startup
        ReefAngel.Relay.On( Port3 );//Turns 180G Return Pump ON if controller reboots
        ReefAngel.Relay.Off( Port2 );//Turns 180G RO/DI Topoff OFF if controller reboots
        ReefAngel.Relay.Off( Port7 );//Turns 180G SW Topoff OFF if controller reboots
        ReefAngel.Relay.Off( Port8 );//Turns 180G Sump Drain OFF if controller reboots
        ReefAngel.Relay.On( Box1_Port5 );//Turns 20GH QT Return Pump ON if controller reboots
        ReefAngel.Relay.On( Box1_Port6 );//Turns 29G QT Return Pump ON if controller reboots
        ReefAngel.Relay.On( Box1_Port7 );//Turns 20GH QT MaxiJet Pump ON if controller reboots
        ReefAngel.Relay.On( Box1_Port8 );//Turns 29G QT MaxiJet Pump ON if controller reboots
       

        ////// Place additional initialization code below here

        ReefAngel.CustomVar[0]=0;
        ReefAngel.CustomVar[1]=0;
        ReefAngel.CustomVar[2]=0;
        ReefAngel.CustomVar[3]=0;
        ReefAngel.CustomVar[4]=0;
        ReefAngel.CustomVar[5]=0;
        ReefAngel.CustomVar[6]=0;   
        ReefAngel.CustomVar[7]=0;
   
   
        ////// Place additional initialization code above here
    }

    void loop()
    {
        ReefAngel.StandardFan( Port1,790,820 );
        ReefAngel.Relay.DelayedOn( Port4,1 );
        ReefAngel.WavemakerRandom( Port5,30,100 );
        ReefAngel.StandardHeater( Port6,750,760 );
        ReefAngel.StandardHeater( Box1_Port3,750,760 );
        ReefAngel.StandardHeater( Box1_Port4,750,760 );


    //*****Begin Custom Menu Additions
    //*****Begin Light Mask Timer Additions                   

      //LightMaskRemaining = ( TargetMillis - CurrentMillis ) / 3600000;//Display Light Mask Time Remaining in Hours
      LightMaskRemaining = ( TargetMillis - CurrentMillis ) / 60000;//Display Light Mask Time Remaining in Minutes         
      //LightMaskRemaining = ( TargetMillis - CurrentMillis ) / 1000;//Display Light Mask Time Remaining in seconds
      CurrentLightMask = InternalMemory.read(199);//reads current light mask setting
      CurrentMaskDuration = InternalMemory.read (198);  //Mask timer length in minutes 0 - 255 (0:00 - 4:15)       
      IgnoreMaskDuration = InternalMemory.read (197); //manual switch to disable automatic Light Mask timeout (0=normal, != 0 = Ignore Light Mask timeout)
      CurrentMillis = millis();//update the timer to the current count
     
        // Removes LED's from a "MASKED" State
      if ( CurrentLightMask == 0 )
        {
          ReefAngel.PWM.SetChannel( 0, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch0 to Parabola math
          ReefAngel.PWM.SetChannel( 1, PWMParabola(14,0,23,59,1,100,1) ); //Sets LED Drivers on Ch1 to Parabola math
          ReefAngel.PWM.SetChannel( 3, PWMSlope(2,0,7,30,0,50,0,0) ); //Opens/closes 5V relay on Ch3 that shorts\opens dimmer leads on Ch0 LED driver to turn Driver on/off
          ReefAngel.PWM.SetChannel( 4, PWMSlope(0,0,14,0,0,50,0,0) ); //Opens/closes 5V relay on Ch4 that shorts\opens dimmer leads on Ch1 LED driver to turn Driver on/off
          ReefAngel.StandardLights( Box1_Port1,13,0,23,0 ); //turns QT Light schedule on if not masked off
          ReefAngel.StandardLights( Box1_Port2,13,0,23,0 ); //turns QT Light schedule on if not masked off
        }

      if ( ( PreviousLightMask != CurrentLightMask ) || ( PreviousMaskDuration != CurrentMaskDuration ) )//Checks if the light mask setting or duration has been manually changed
        {

          //Checks if light mask value has been set to an invalid value by direct memory access and clears (sets to 0) mask if not valid
        if ( CurrentLightMask > 2 )
          {
            InternalMemory.write(199, 0); //clears light mask if value is not valid.
          }
 
        // MASKS LED's Off
        if ( CurrentLightMask == 1 )
          {
            TargetMillis = CurrentMillis + ( CurrentMaskDuration * 60000 ); //Set the duration of the mask timer in minutes ( 1 - 255 )
            ReefAngel.PWM.SetChannel( 0, 0 ); //Sets LED Drivers on Ch0 to 0%
            ReefAngel.PWM.SetChannel( 1, 0 ); //Sets LED Drivers on Ch1 to 0%
            ReefAngel.PWM.SetChannel( 3, 50 ); //closes 5V relay on Ch3 that shorts dimmer leads on Ch0 LED driver to turn Driver off
            ReefAngel.PWM.SetChannel( 4, 50 ); //closes 5V relay on Ch4 that shorts dimmer leads on Ch1 LED driver to turn Driver off
            ReefAngel.Relay.Off( Box1_Port1 ); //turns QT Lights OFF if masked off
            ReefAngel.Relay.Off( Box1_Port2 ); //turns QT Lights OFF if masked off
          }

        // MASKS LED's On
        if ( CurrentLightMask == 2 )
          {
            TargetMillis = CurrentMillis + ( CurrentMaskDuration * 60000 ); //Set the duration of the mask timer in minutes ( 1 - 255 )
            ReefAngel.PWM.SetChannel( 0, 100 ); //Sets LED Drivers on Ch0 to 100%
            ReefAngel.PWM.SetChannel( 1, 100 ); //Sets LED Drivers on Ch1 to 100%
            ReefAngel.PWM.SetChannel( 3, 0 ); //Opens 5V relay on Ch3 that removes short on dimmer leads on Ch0 LED driver to turn Driver on
            ReefAngel.PWM.SetChannel( 4, 0 ); //Opens 5V relay on Ch4 that removes short on dimmer leads on Ch1 LED driver to turn Driver on
            ReefAngel.Relay.On( Box1_Port1 ); //turns QT Lights ON if masked on
            ReefAngel.Relay.On( Box1_Port2 ); //turns QT Lights ON if masked on
          }
       
        PreviousLightMask = CurrentLightMask;
        PreviousMaskDuration = CurrentMaskDuration;
        }

        if ( CurrentLightMask != 0 )// Checks if lights are masked on or off
          {
            if ( IgnoreMaskDuration == 0 )//Checks if Light mask timer ignore byte is active
              {
                if ( CurrentMillis > TargetMillis )//checks if Light mask timeout has expired.
                  {
                    InternalMemory.write(199, 0); //clears forgotten light mask due to timeout.
                    CurrentMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
                    TargetMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
                  }

                else
                  {
                  }         

              }
             
            else
              {
                CurrentMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
                TargetMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
              }

          }             

        else
          {
            CurrentMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
            TargetMillis = 0;//sets back to 0 when not being used to prevent display from counting negative time when Light mask is cleared.
          }
             
             
    //*****End Custom Menu Additions
    //*****End Light Mask Timer Additions

    //*****Begin reporting of Maximum\Minimum Temperature on probe T1 Additions

        T1Read = ReefAngel.Params.Temp[T1_PROBE];
          if (T1Read !=0)//Debounce for Low Temperature reading 0 at startup
            {
              T1LowTemp = min(T1LowTemp, T1Read);//Tracks Low Temperature
              T1HighTemp = max(T1HighTemp, T1Read);//Tracks High Temperature
            }
         
    //*****End reporting of Maximum\Minimum Temperature on probe T1 Additions


        overheatflag = InternalMemory.read( Overheat_Exceed_Flag );
        atoflag = InternalMemory.read( ATO_Exceed_Flag );
        iochannel0flag = ! ReefAngel.IO.GetChannel( 0 );
        iochannel1flag = ! ReefAngel.IO.GetChannel( 1 );
        iochannel2flag = ! ReefAngel.IO.GetChannel( 2 );
        iochannel3flag = ! ReefAngel.IO.GetChannel( 3 );
        iochannel4flag = ! ReefAngel.IO.GetChannel( 4 );
        iochannel5flag = ! ReefAngel.IO.GetChannel( 5 );
        AlertATOPump = ReefAngel.Relay.Status(Port2);
        AlertNonCritical = atoflag + iochannel2flag + iochannel3flag + iochannel4flag + iochannel5flag;
        AlertCritical = AlertATOPump + overheatflag + iochannel0flag + iochannel1flag;   
        if ( AlertNonCritical >= 1 ) AlertNonCritical = 25;
        if ( AlertCritical >= 1 ) AlertCritical = 25;   
        if ( AlertNonCritical >= 1 ) ReefAngel.PWM.SetActinic(millis()%60000<100?AlertNonCritical:0);
        else { ReefAngel.PWM.SetActinic(0); }
        if ( AlertNonCritical >= 1 ) ReefAngel.PWM.SetDaylight(millis()%60000<100?AlertNonCritical:0);
        else { ReefAngel.PWM.SetDaylight(0); }
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetActinic(millis()%300<100?AlertCritical:0);
        else { ReefAngel.PWM.SetActinic(0); }
        if ( AlertCritical >= 1 ) ReefAngel.PWM.SetDaylight(millis()%300<100?AlertCritical:0);   
        else { ReefAngel.PWM.SetDaylight(0); }

       
        ////// Place your custom code below here

        ReefAngel.CustomVar[0]=LightMaskRemaining;
        ReefAngel.CustomVar[1]=AlertCritical;
        ReefAngel.CustomVar[2]=AlertNonCritical;
        ReefAngel.CustomVar[3]=ATOBrutePort;
//        ReefAngel.CustomVar[4]=
//        ReefAngel.CustomVar[5]=
//        ReefAngel.CustomVar[6]=   
//        ReefAngel.CustomVar[7]=
       
        if ( InternalMemory.read(ATO_Exceed_Flag)== 1 )
          {
            ReefAngel.Relay.RelayMaskOff=~(Port4Bit);
          }

        //*****Begin WC Additions

        // If menu equals waterchange mode
        // then we start the automatic water change
        // Otherwise we ignore and proceed
        if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
          {
            AutoWaterChange();
          }
       
        //*****End WC Additions
       
       
        //*****Begin ATO By Salinity Additions
       
        if (ReefAngel.Params.Salinity<300)//if salinity is low switch to Saltwater ATO
          {
            ReefAngel.StandardATO(Port7,40 );//ATO Port is now Saltwater Port7
            ReefAngel.Relay.Off(Port2);//Turn off RO/DI Port2
            ATOBrutePort=Port7;
            char ATOBruteText[ ] = "ATOSW";
          }
        else//if Salinity is high switch to RO/DI Topoff
          {
            ReefAngel.StandardATO(Port2,40 );//ATO Port is now RO/DI Port2
            ReefAngel.Relay.Off(Port7);//Turn off Saltwater Port7
            ATOBrutePort=Port2;
            char ATOBruteText[ ] = "ATORO";
          }       
        if (iochannel2flag == 1)//IF ATO Brute is empty do not pump
          {
            ReefAngel.Relay.RelayMaskOff=~(Port7Bit);//Mask Off Saltwater Brute Pump
          }
        if (iochannel4flag == 1)//IF ATO Brute is empty do not pump
          {
            ReefAngel.Relay.RelayMaskOff=~(Port2Bit);//Mask Off RO/DI Brute Pump
          }
         
        //*****End ATO By Salinity Additions

        ////// Place your custom code above here

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


    //*****Begin Custom Menu Additions

    //Mask Lights On. Forces Lights's On Full Blast
    void MenuEntry1()
      {
        InternalMemory.write(199, 2);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights On"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask Lights Off. Forces Lights Off
    void MenuEntry2()
      {
        InternalMemory.write(199, 1);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Off"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }

    //Mask Lights Clear. Remove Light Masking Returns Lights to normal schedule
    void MenuEntry3()
      {
        InternalMemory.write(199, 0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Mask Lights Clear"); waitForTime(2);
        ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
      }
     
    //Start Waterchange Mode
    void MenuEntry4()
      {
        ReefAngel.WaterChangeModeStart();
      }

    //Clear ATO Timeout Flag
    void MenuEntry5()
      {
        ReefAngel.ATOClear();
        ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
      }

    //Clear Overheat Flag
    void MenuEntry6()
      {
        ReefAngel.OverheatClear();
        ReefAngel.DisplayMenuEntry("Clear Overheat");
      }

    //Calibrate PH Probe
    void MenuEntry7()
      {
        ReefAngel.SetupCalibratePH();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }

    //Set clock Date & Time
    void MenuEntry8()
      {
        ReefAngel.SetupDateTime();
        ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
      }
     
    //*****End Custom Menu Additions


    //*****Begin Water Change Additions

    void AutoWaterChange()
    {
        // auto water change mode
        // Display Starting Water Change"
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Water Change"); waitForTime(3);

        // Check Saltwater BRUTE for sufficient saltwater on IO Module Port2
        if ( isSWBruteEmpty() )
          {
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
            ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Not Enough Saltwater"); waitForTime(3);

            //Abort Water Change if insufficient saltwater
            // Handles the cleanup to return to the main screen
            ReefAngel.ClearScreen(DefaultBGColor);
            ReefAngel.DisplayedMenu = DEFAULT_MENU;
            DrawCustomGraph();
            return;
          }
       
        //Display Disabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");   
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Disabling ATO Pump"); waitForTime(3);

        // turn off ATO pump port to prevent ATO from trying to fill a sump being drained intentionally
        ReefAngel.Relay.RelayMaskOff=~(Port2Bit);
       
        //Display Stopping Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Skimmer"); waitForTime(3);

        // turn off the skimmer port
        ReefAngel.Relay.Off(SkimmerPort);
        ReefAngel.Relay.Write();
       
        //Display Skimmer Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Draining"); waitForTime(3);   

        // wait for 1 minute
        waitForTime(60);

        //Display Skimmer Done Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Done Draining"); waitForTime(3);
       
        //display Stopping Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Return Pump"); waitForTime(3);

        //Stop Return Pump
        ReefAngel.Relay.Off(ReturnPort);
        ReefAngel.Relay.Write();
       
        //Display Draining To Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Draining To Sump"); waitForTime(3);

        //display Sump Filling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Filling"); waitForTime(3);

        // wait for IO Mod Port 1 to be active
        waitForIOChannel(1);

        //display Sump Is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        // display Draining Sump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Draining Sump"); waitForTime(3);

        //turn on sump drain pump
        ReefAngel.Relay.On(SumpDrainPort);
        ReefAngel.Relay.Write();

        //display Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Draining"); waitForTime(3);

        // wait for sump empty port active, IO Mod Port 0
        waitForIOChannel(0);
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Empty"); waitForTime(3);

        //display Stopping Sump Draining
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stopping Sump Drain"); waitForTime(3);

        // turn off sump drain
        ReefAngel.Relay.Off(SumpDrainPort);
        ReefAngel.Relay.Write();

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);

        //display Starting Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Start Saltwater Pump"); waitForTime(3);

        //turn on Saltwater Pump
        ReefAngel.Relay.On(SWBrutePort);
        ReefAngel.Relay.Write();

        //display Saltwater Pumping
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Saltwater Pumping"); waitForTime(3);

        // wait for sump full float switch active, IO Mod Port 1
        waitForIOChannel(1);

        //display Stop Saltwater Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Stop Saltwater Pump"); waitForTime(3);

        // turn off sw brute pump
        ReefAngel.Relay.Off(SWBrutePort);
        ReefAngel.Relay.Write();   

        //diasplay Sump is Full
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Is Full"); waitForTime(3);

        //Display Sump Settling
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settling"); waitForTime(3);

        // wait for sump to settle
        waitForTime(30);

        //display Sump Settled
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Sump Settled"); waitForTime(3);
       
        //display Starting Return Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Return Pump"); waitForTime(3);

        // turn on return pump
        ReefAngel.Relay.On(ReturnPort);
        ReefAngel.Relay.Write();

        //display Return Pump Started
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Return Pump Started"); waitForTime(3);

        //display Normalizing Waterlevel
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Waterlevel"); waitForTime(3);

        //waiting 2 minutes for waterlevel to normalize
        waitForTime(120);
       
        //display Starting Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Starting Skimmer"); waitForTime(3);

        //turn on skimmer
        ReefAngel.Relay.On(SkimmerPort);
        ReefAngel.Relay.Write();

        //display Normalizing Skimmer
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Normalizing Skimmer"); waitForTime(3);

        //wait for 2 minutes for skimmer to normalize
        waitForTime(120);

        //display Skimmer Normalized
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Skimmer Normalized"); waitForTime(3);

        //display Enabling ATO Pump
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Enabling ATO Pump"); waitForTime(3);

        //Enable ATO pump
        ReefAngel.Relay.RelayMaskOff = B11111111;
        ReefAngel.Relay.Write();

        //display Water Change Complete
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "                      ");
        ReefAngel.LCD.DrawText(ModeScreenColor, DefaultBGColor, 2, 30, "Water Change Complete"); waitForTime(3);

        // Handles the cleanup to return to the main screen
        ReefAngel.ClearScreen(DefaultBGColor);
        ReefAngel.DisplayedMenu = DEFAULT_MENU;
        DrawCustomGraph();
    }

    bool isSWBruteEmpty()
    {
      // check status of IO Mod Port 2
      if ( ! ReefAngel.IO.GetChannel(2) )
          return true;
      return false;
    }

    void waitForTime(int seconds)
    {
        bool done = false;
        tm.SetInterval(seconds);
        tm.Start();
        int t = tm.Trigger - now();
        do
        {
          // check the wifi interface
          pingSerial();
          // wait for specified seconds
          if ( (t >= 0) && ! tm.IsTriggered() )
            {
              wdt_reset();
              delay(200);
            }
            else
            {
              done = true;
            }
        } while ( !done );
        return;
    }

    void waitForIOChannel(byte channel)
    {
        // TODO complete this function
        do
        {
          wdt_reset();
          // display something on screen
          // check the wifi interface
          pingSerial();
          delay(200);
          // TODO check the IO channel logic
        } while ( ReefAngel.IO.GetChannel(channel) );
    }

    //*****End Water Change Additions


    //*****Begin Custom IO Expander Additions

        byte expanderRead()
        {
          byte _data=0;
          Wire.requestFrom(0x27, 1);
          if(Wire.available())
            {
            _data = Wire.read();
            CustomIOExpander = _data;
            }
          delay(10);
          return _data;
        }
       
        boolean expanderReadGetChannel(byte channel)
        {
          return bitRead(expanderRead(),channel);
        }

    //*****End Custom IO Expander Additions
       

    void DrawCustomMain()
    {
        int x,y;
        char text[10];
        // Dimming Expansion
        x = 15;
        y = 2;
        for ( int a=0;a<6;a++ )
        {
          if ( a>2 ) x = 75;
          if ( a==3 ) y = 2;
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x,y,"Ch :   " );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+12,y,a );
          ReefAngel.LCD.DrawText( COLOR_DARKGOLDENROD,DefaultBGColor,x+24,y,ReefAngel.PWM.GetChannelValue(a) );
          y += 10;
        }
        pingSerial();

        // I/O Expansion
        byte bkcolor;
        x = 14;
        y = 34;
        for ( int a=0;a<6;a++ )
        {
          ReefAngel.LCD.DrawCircleOutline( x+(a*20),y,4,COLOR_MEDIUMORCHID );
          if ( ReefAngel.IO.GetChannel(a) ) bkcolor=COLOR_WHITE; else bkcolor=COLOR_GRAY;
          ReefAngel.LCD.FillCircle( x+(a*20),y,2,bkcolor );
        }
        pingSerial();

        // Parameters
    #if defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params,
        ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
    #else // defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 44, ReefAngel.Params );
    #endif // defined DisplayLEDPWM && ! defined RemoveAllLights
        pingSerial();

        // Salinity
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,73, "SAL:" );//Display Salinity
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,82, "LMTR:" );//Display Light Mask Time Remaining
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, "  Hours." );//Clear screen video from data location before new data draw         
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, "    Min." );//Clear screen video from data location before new data draw
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, "      Sec." );//Clear screen video from data location before new data draw         
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, ( TargetMillis - CurrentMillis ) / 3600000 );//Display Light Mask Time Remaining in Hours
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, ( TargetMillis - CurrentMillis ) / 60000 );//Display Light Mask Time Remaining in Minutes         
//        ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,45,82, ( TargetMillis - CurrentMillis ) / 1000 );//Display Light Mask Time Remaining in seconds
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,96,82, ATOBruteText );
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,60,73, "L:" );//Display Low Temperature   
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,96,73, "H:" );//Display High Temperature       
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,39,73, ReefAngel.Params.Salinity );//Display Salinity
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,72,73, T1LowTemp );//Display Low Temperature
          ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,108,73, T1HighTemp );//Display High Temperature   

        pingSerial();

        // Main Relay Box
        byte TempRelay = ReefAngel.Relay.RelayData;
        TempRelay &= ReefAngel.Relay.RelayMaskOff;
        TempRelay |= ReefAngel.Relay.RelayMaskOn;
        ReefAngel.LCD.DrawOutletBox( 12, 90, TempRelay );
        pingSerial();

        // Relay Expansion
        TempRelay = ReefAngel.Relay.RelayDataE[0];
        TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
        TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
        ReefAngel.LCD.DrawOutletBox( 12, 104, TempRelay );
        pingSerial();

        // Date and Time
        ReefAngel.LCD.DrawDate( 6, 122 );
        pingSerial();
    }

    void DrawCustomGraph()
    {
    }



180G FOWLR
20GH QT#1
29G QT#2

Image

Return to My PDE/INO file

Who is online

Users browsing this forum: No registered users and 1 guest