Code: Select all
    #include <RA_ATO.h>
    #include <RF.h>
    #include <ReefAngel_Features.h>
    #include <Globals.h>
    #include <RA_Wifi.h>
    #include <Wire.h>
    #include <OneWire.h>
    #include <Time.h>
    #include <DS1307RTC.h>fafa
    #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>fa
    #include <IO.h>
    #include <ORP.h>
    #include <PH.h>
    #include <WaterLevel.h>
    #include <ReefAngel.h>
    ////// Place global variable code below here
      byte myRFMode=0;
        byte myRFDuration=0;
        byte myRFSpeed=0;
    ////// Place global variable code above here
    void setup()
    {
        // This must be the first line
        ReefAngel.Init();  //Initialize controller
        // Ports toggled in Feeding Mode
    ReefAngel.WaterChangePorts = Port1Bit | Port8Bit; // Turn off Ports 5 and 6 when Feeding Mode is activated
      ReefAngel.FeedingModePorts = Port1Bit | Port6Bit | Port8Bit; // Turn off Ports 1, 6, 7 and 8 when Water Change Mode is activated
      ReefAngel.LightsOnPorts = Port2Bit | Port3Bit | Port4Bit| Port5Bit;
      ReefAngel.OverheatShutoffPorts = Port2Bit |Port3Bit | Port4Bit | Port5Bit | Port7Bit; // Turn off Ports 3,
        ReefAngel.TempProbe = T3_PROBE;
        ReefAngel.OverheatProbe = T3_PROBE;
        // Set the Overheat temperature setting
        InternalMemory.OverheatTemp_write( 825 );
        // Ports that are always on
        ReefAngel.Relay.On( Port1 );
        ReefAngel.Relay.On( Box1_Port2 );  // Razor Led
        ReefAngel.Relay.On( Box1_Port4 ); // Sump Equipment - UV, Pump
        ReefAngel.Relay.On( Box1_Port5 ); // MP40s   
        ReefAngel.Relay.On( Box1_Port6 ); // JBJ
        ////// Place additional initialization code below here
       
        ////// Place additional initialization code above here
    }
    void loop()
    {
      //  Port1 Return pump...  on all the time!!!
          ReefAngel.Relay.Set( Port2, !ReefAngel.Relay.Status( Port4 ) ); //Refuge
      //  Port3 ...  not used
          ReefAngel.StandardLights( Port4,10,0,20,0 ); //ATI Actinic
          ReefAngel.StandardLights( Port5,11,0,19,0 );  //ATI Daylight
          ReefAngel.StandardLights( Port6,10,0,20,0 );  //ATI Fan
          ReefAngel.StandardHeater( Port7,778,790 ); //Heater
          ReefAngel.Relay.DelayedOn( Port8,2 ); //Skimmer
         
          //box 2
          ReefAngel.Relay.Off( Box1_Port1); // Lunar Hub Not used   Port #9
    //   Box1_Port2 Razor_LED (Sump)...  on all the time!!!      Port #10
          ReefAngel.Relay.Off( Box1_Port3); // Start with the relay off       Port #11
                  if (hour()>=5 && hour()<10) ReefAngel.Relay.On(Box1_Port3); // Moonlight Between 5-10am turn the relay on
                  if (hour()>=20 && hour()<=23) ReefAngel.Relay.On(Box1_Port3); // From 8pm-Midnight turn the relay on
    //   Box1_Port4 Ecotech MP_40 Pumps  on all the time!!!      Port #12
    //   Box1_Port5 Razor_LED (Sump)...  on all the time!!!      Port #13
    //   Box1_Port6 JBJ ATO ...          on all the time!!!      Port #14
         ReefAngel.Relay.Off( Box1_Port7);  // ALK Doser ...      Port #15
         ReefAngel.Relay.Off( Box1_Port8);  // Calc Doser ...     Port #16
    ReefAngel.PWM.SetDaylight( MoonPhase() );
    // ReefAngel.PWM.SetDaylight(PWMParabola(20,0,23,0,0, MoonPhase(),0 ));
        ReefAngel.RF.UseMemory = false;
        ReefAngel.RF.SetMode( ReefCrest,85,10 );
        ////// Place your custom code below here
       
       
          ReefAngel.RF.UseMemory = false;
          if (hour()>=6 && hour()<11)
            myRFSetMode(ReefCrest,85,10);
          else if (hour()>=11 && hour()<13)
            myRFSetMode(ReefCrest,85,10);
          else if (hour()>=13 && hour()<16)
            myRFSetMode(Smart_NTM,85,15);
          else if (hour()>=16 && hour()<19)
            myRFSetMode(ReefCrest,65,10);
          else
            myRFSetMode(Lagoon,40,10);
             
         
           
        // Hardcode PH calibrations
         //ReefAngel.PHMin=544; // PH7.0
         //ReefAngel.PHMax=830; // PH10.0
         RunDosingPumps();
         LogDosingPumps();
        ////// Place your custom code above here
        // This should always be the last line
        ReefAngel.Portal( "ecam" );
        ReefAngel.ShowInterface();
    }
    void DrawCustomMain()
    {
        pingSerial();
        // Parameters
    #if defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 48, ReefAngel.Params,
        ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
    #else // defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 48, ReefAngel.Params );
    #endif // defined DisplayLEDPWM && ! defined RemoveAllLights
        pingSerial();
        // Main Relay Box
        byte TempRelay = ReefAngel.Relay.RelayData;
        TempRelay &= ReefAngel.Relay.RelayMaskOff;
        TempRelay |= ReefAngel.Relay.RelayMaskOn;
        ReefAngel.LCD.DrawOutletBox( 12, 94, TempRelay );
        pingSerial();
        // Date and Time
        ReefAngel.LCD.DrawDate( 6, 122 );
        pingSerial();
    }
    /////////////////////////////////////////
    // Define Your dosing pumps
    /////////////////////////////////////////
    #define numDPumps 2
    byte pumpRelays[numDPumps]={ Box1_Port7, Box1_Port8 };
    int DPVolume[numDPumps]={ 3, 3 } ; // 1ml for each alk and calcium
    int DPRepeat[numDPumps]={ 240, 240 } ; // Repeat every 4 hrs 5x a day
    /////////////////////////////////////////
    // Define Calibration here
    /////////////////////////////////////////
    int CalTime[numDPumps]={ 600, 600 }; // 10 minutes / 10 minutes
    int CalVol[numDPumps]={ 350, 300 }; // 350ml / 300ml... .58 / .5
    /////////////////////////////////////////
    // Function: RunDosingPumps()
    /////////////////////////////////////////
    void RunDosingPumps() {
      float rate;
      int calcTime[numDPumps];
      for (int i=0;i < numDPumps; i++) {
        rate=(float)CalVol[i]/CalTime[i];
        calcTime[i]=DPVolume[i]/rate/(1440/DPRepeat[i]);
        // Run the pumps
        ReefAngel.DosingPumpRepeat(pumpRelays[i], i*20, DPRepeat[i], calcTime[i]); // Offset between each pump is 20 minutes
      }
      // Display Time calculated in portal
      ReefAngel.CustomVar[0]=calcTime[0];
      ReefAngel.CustomVar[1]=calcTime[1];
    }
    /////////////////////////////////////////
    // Function: LogDosingPumps()
    /////////////////////////////////////////
    void LogDosingPumps() {
      static time_t pumpTimer[numDPumps];
      static boolean pumpStatus[numDPumps];
      float rate;
      for (int i=0;i< numDPumps;i++) {
        if (ReefAngel.Relay.Status(pumpRelays[i])) {
          if (!pumpStatus[i]) {
            pumpTimer[i]=now()-pumpTimer[i]; // Pump was off, timer is now a time
            pumpStatus[i]=true;
          }
        } else {
          if (pumpStatus[i]) {
            pumpTimer[i]=now()-pumpTimer[i]; // Pump was on, timer is now a timer
            pumpStatus[i]=false;
       
            rate=(float)CalVol[i]/CalTime[i];
            // Report How much volume has been dosed per day.
            // Could make this in minutes... excercise for the reader..
            ReefAngel.CustomVar[2]=pumpTimer[0]*rate;
            ReefAngel.CustomVar[3]=pumpTimer[1]*rate; 
          }
        }
     
        // Clear timer at end of day
        if (now()%SECS_PER_DAY==SECS_PER_DAY-1) pumpTimer[i]=0;
      } 
    }
        void DrawCustomGraph()
        {
        }
        void myRFSetMode(byte m, byte s, byte d)
        {
          if (m!=myRFMode || s!=myRFSpeed || d!=myRFDuration || millis()<5000)
          {
            myRFMode=m;
            myRFSpeed=s;
            myRFDuration=d;
            ReefAngel.RF.SetMode(m,s,d);
          }
        }
