Code: Select all
#include <Salinity.h>
#include <Relay.h>
#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>
#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 <RF.h>
#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
ReefAngel.WaterChangePorts = Port3Bit | Port7Bit| Port8Bit| Box1_Port1| Box1_Port4| Box1_Port6; // Turn off Return, UV, Skimmer, Heater, Sump Equipment, ATO
ReefAngel.FeedingModePorts = Port3Bit | Port8Bit; // Turn off Return and Skimmer
ReefAngel.LightsOnPorts = Port2Bit | Box1_Port2; //Turn on ATI lights, Fan and Fuge Light
ReefAngel.OverheatShutoffPorts = Port4Bit |Box1_Port1; // ATI Lights and Heaters
ReefAngel.TempProbe = T3_PROBE;
ReefAngel.OverheatProbe = T3_PROBE;
InternalMemory.OverheatTemp_write( 825 ); // Set the Overheat temperature setting
// Ports that are always on
////// Place additional initialization code below here
////// Place additional initialization code above here
}
void loop()
{
//Box1
ReefAngel.Relay.Off(Port1); // Port1 Acropower Dosing ...
ReefAngel.Relay.Off(Port2); // Port2 Fuge Light
if (hour()>=23 && hour()<7) ReefAngel.Relay.On(Port2); // Fuge Between 11pm-7am turn the relay on
ReefAngel.Relay.On(Port3); // Port3 Return Pump -- Always on
ReefAngel.Relay.Off(Port4); // Port4 Not Used
ReefAngel.Relay.Off(Port5); // Port5 Not Used
ReefAngel.Relay.Off(Port6); // Port6 Not Used
ReefAngel.Relay.On(Port7); // Port7 UV Lamp -- Always on
ReefAngel.Relay.DelayedOn( Port8,5 ); // Port8 Skimmer -- 5 min delay start
//box 2 (Box1_Portxx)
ReefAngel.StandardHeater( Box1_Port1,778,790 ); // Box1_Port1 Heater
ReefAngel.Relay.On(Box1_Port2); // Box1_Port2 Razor_LED (Sump) -- Always on
ReefAngel.Relay.Off(Box1_Port3); // Box1_Port3 Not Used
ReefAngel.Relay.On(Box1_Port4); // Box1_Port4 Sump Equipment-- Always on
ReefAngel.Relay.On(Box1_Port5); // Box1_Port5 MP40s -- Always on
// ReefAngel.Relay.Off(Box1_Port6); // Box1_Port6 ATO Top off (RODI)
ReefAngel.SingleATO(true,Box1_Port6,60,0); // ATO Low port with 60 seconds timeout
// ReefAngel.SingleATOHigh(true,Box1_Port6,300,0); // ATO Low port with 5 min timeout (200 mls per min, 3,785mls in a gallon)
ReefAngel.Relay.Off( Box1_Port7); // Box1_Port7 ALK Doser
ReefAngel.Relay.Off( Box1_Port8); // Box1_Port8 Calc Doser
// Old Code
//moonlight dimming
// if (hour()>=6 && hour()<10) ReefAngel.PWM.SetDaylight( PWMParabola(6,0,10,0,9,100,9) ); // Moonlight Between 5-10am turn the relay on
// if (hour()>=20 && hour()<=23) ReefAngel.PWM.SetDaylight( PWMParabola(20,0,23,0,100,0,100) ); // From 8pm-Midnight turn the relay on
// else ReefAngel.PWM.SetDaylight(0);
// ReefAngel.Relay.Set( Port2, !ReefAngel.Relay.Status( Port4 ) ); //Refuge opposite of Actinic
// ReefAngel.Relay.Off( Box1_Port3); // Start with the relay off Port #11 Moonlight
//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
// ReefAngel.PWM.SetDaylight( PWMSlope(20,0,23,0,100,0,180,100) );
// ReefAngel.PWM.SetDaylight( PWMSlope(6,0,10,0,9,100,240,9) );
//ReefAngel.Relay.off(Box1_Port3);
// if (hour()>=10 || hour()<20) ReefAngel.PWM.SetDaylight(0);
// ReefAngel.PWM.SetDaylight( MoonPhase()+10 );
// ReefAngel.PWM.SetDaylight(PWMParabola(20,0,23,0,0, MoonPhase(),0 ));
//ReefAngel.PWM.SetDaylight(PWMSlope(6,0,23,0,0,100,240,0));
//if (hour()>=5 && hour()<20) ReefAngel.PWM.SetDaylight(0);
//ReefAngel.PWM.SetDaylight( PWMParabola(20,0,23,0,100,0,100) );
//ReefAngel.PWM.SetDaylight( PWMParabola(6,0,10,0,9,100,9) );
////// 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,50);
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();
char text[10];
ConvertNumToString(text, ReefAngel.Params.Salinity, 10);
strcat(text," ");
ReefAngel.LCD.DrawText(DefaultFGColor,DefaultBGColor,15,93,"Salinity:");
ReefAngel.LCD.DrawText(DefaultFGColor,DefaultBGColor,75,93,text);
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 4
byte pumpRelays[numDPumps]={ Box1_Port7, Box1_Port8,Port1Bit,Box1_Port6 };
int DPVolume[numDPumps]={ 17, 17, 7} ; // 1ml for each alk and calcium - total volume for the day
int DPRepeat[numDPumps]={ 360, 360, 360 } ; // Repeat every 4 hrs 6x a day --- in mins
/////////////////////////////////////////
// Define Calibration here
/////////////////////////////////////////
int CalTime[numDPumps]={ 600, 600, 600,600 }; // 10 minutes / 10 minutes
int CalVol[numDPumps]={ 350, 300,384,120000 }; // 350ml / 300ml... .58 / .5/.64
/////////////////////////////////////////
// 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*5, DPRepeat[i], calcTime[i]); // Offset between each pump is 5 minutes
}
// Display Time calculated in portal
ReefAngel.CustomVar[0]=calcTime[0];
ReefAngel.CustomVar[1]=calcTime[1];
ReefAngel.CustomVar[2]=calcTime[2];
ReefAngel.CustomVar[3]=calcTime[3];
}
/////////////////////////////////////////
// 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[3]=pumpTimer[0]*rate;
ReefAngel.CustomVar[4]=pumpTimer[1]*rate;
ReefAngel.CustomVar[5]=pumpTimer[2]*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);
}
}