Here is my code:
Code: Select all
#include <ReefAngel_Features.h>
#include <Globals.h>
#include <RA_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <InternalEEPROM.h>
#include <RA_NokiaLCD.h>
#include <RA_ATO.h>
#include <RA_Joystick.h>
#include <LED.h>
#include <RA_TempSensor.h>
#include <Relay.h>
#include <RA_PWM.h>
#include <Timer.h>
#include <Memory.h>
#include <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
//#include <Salinity.h>
//#include <RF.h>
#include <IO.h>
//#include <ORP.h>
#include <AI.h>
#include <PH.h>
//#include <WaterLevel.h>
//#include <Humidity.h>
#include <DCPump.h>
//#include <PAR.h>
#include <ReefAngel.h>
////// Place global variable code below here
// Define Custom Memory Locations
#define Mem_B_MoonOffset 100
#define Mem_B_Vacation 101
#define Mem_B_AutoFeed 102
#define Mem_B_AutoFeedPress 103
#define Mem_B_AutoFeedRepeat 104
#define Mem_B_AutoFeedOffset 105
#define Mem_I_WCFillTime 106
byte wc_status = 0;
time_t ato_endfill;
byte ato_topping = 0;
void init_memory() {
// Initialize Custom Memory Locations
InternalMemory.write(Mem_B_Vacation,false);
InternalMemory.write(Mem_B_AutoFeed,true);
InternalMemory.write(Mem_B_AutoFeedPress,2);
InternalMemory.write(Mem_B_AutoFeedRepeat,4);
InternalMemory.write(Mem_B_AutoFeedOffset,3);
InternalMemory.write_int(Mem_I_WCFillTime,1200 ); //How long topoff is allowed to run
}
// Define Relay Ports by Name
#define Daylight 1
#define LEDLights 2
#define ATODrain 3
#define Feeder 4
#define Mixer 5
#define Topoff 6
#define Ferts 7
#define Filter 8
////// Place global variable code above here
void setup()
{
// This must be the first line
ReefAngel.Init(); //Initialize controller
ReefAngel.Use2014Screen(); // Let's use 2014 Screen
// Ports toggled in Feeding Mode
ReefAngel.FeedingModePorts = 0;
// Ports toggled in Water Change Mode
ReefAngel.WaterChangePorts = 0;
// Ports toggled when Lights On / Off menu entry selected
ReefAngel.LightsOnPorts = 0;
// Ports turned off when Overheat temperature exceeded
ReefAngel.OverheatShutoffPorts = 0;
// Use T1 probe as temperature and overheat functions
ReefAngel.TempProbe = T1_PROBE;
// Ports that are always on
ReefAngel.Relay.Auto(Filter);
////// Place additional initialization code below here
ato_endfill = now()+15; //add delay to ato startup
// Ports that default off
ReefAngel.Relay.Off(Topoff);
ReefAngel.Relay.Off(ATODrain);
ReefAngel.Relay.Off(Feeder);
ReefAngel.Relay.Off(Mixer);
ReefAngel.CustomLabels[0]="Daylight";
ReefAngel.CustomLabels[1]="LED";
ReefAngel.CustomLabels[2]="Drain";
ReefAngel.CustomLabels[3]="Feeder";
ReefAngel.CustomLabels[4]="Mixer";
ReefAngel.CustomLabels[5]="Topoff";
ReefAngel.CustomLabels[6]="Ferts";
ReefAngel.CustomLabels[7]="Filter";
ReefAngel.Relay.On(Filter);
////// Place additional initialization code above here
}
void loop()
{
ReefAngel.StandardLights( LEDLights,9,0,21,0 );
ReefAngel.StandardLights( Daylight,10,30,20,30 );
ReefAngel.PWM.SetActinic( PWMSlope(9,0,20,0,15,100,60,15) );
////// Place your custom code below here
//Automation
//RunFeeder();
//RUN ONCE A DAY AT 7 AM FOR 40 MIN
ReefAngel.DosingPumpRepeat(ATODrain,660,1440,2400 );
//Water Change
if (ReefAngel.Relay.Status(ATODrain) ){
wc_status = 1;
}
if (wc_status > 0 ){
AutoWaterChange();
}
//Keep Water topped off
AutoTopOff();
////// Place your custom code above here
// This should always be the last line
ReefAngel.Portal( "diverjoe" );
ReefAngel.DDNS("75");
ReefAngel.ShowInterface();
}
void AutoTopOff(){
//run for 15 sec any time float valve is turned on and WC drain is not active
if (ato_endfill < now() && wc_status != 1 && ato_topping){
ReefAngel.Relay.On(Topoff);
}
else{
ReefAngel.Relay.Off(Topoff);
ato_topping = 0;
if ( ReefAngel.HighATO.IsActive() && !ato_topping){
ato_endfill = now() + 15;
ato_topping = 1;
}
}
}
void RunFeeder() {
boolean autoFeed;
static time_t t;
int press, repeat, offset;
autoFeed=InternalMemory.read(Mem_B_AutoFeed);
press=InternalMemory.read(Mem_B_AutoFeedPress);
repeat=InternalMemory.read(Mem_B_AutoFeedRepeat)*SECS_PER_HOUR;
offset=InternalMemory.read(Mem_B_AutoFeedOffset)*SECS_PER_HOUR;
ReefAngel.Relay.Set(Feeder, autoFeed);
if (ReefAngel.Relay.Status(Feeder)!=autoFeed) {
autoFeed=ReefAngel.Relay.Status(Feeder);
InternalMemory.write(Mem_B_AutoFeed, autoFeed);
ReefAngel.Relay.Auto(Feeder);
}
if (autoFeed) {
if (((hour() > 9 && hour() < 20)) && (now()+offset)%repeat==0) {
t=now();
}
}
if (ReefAngel.Relay.isMaskOn(Feeder)) {
ReefAngel.Relay.Auto(Feeder);
t=now()-now()%20; // One feeding has already happened.
}
// Press the button once every 20 seconds
if (now()-t < press*20) {
ReefAngel.Relay.Set(Feeder,now()%20==0);
} else {
ReefAngel.Relay.Off(Feeder);
}
}
void AutoWaterChange() {
int NowMins;
static time_t t;
if (wc_status == 1) {
ReefAngel.Relay.Override(Topoff,0);
ReefAngel.Relay.Off(Topoff);
//ReefAngel.Relay.Override(Filter,0);
ReefAngel.Relay.Off(Filter);
t = now();
}
if(ReefAngel.LowATO.IsActive() && wc_status == 1)
{
wc_status = 2; //Enter Mix mode
ReefAngel.Relay.Auto(ATODrain);
ReefAngel.Relay.Off(ATODrain);
ReefAngel.Relay.On(Mixer);
ReefAngel.Relay.Auto(Topoff);
//ReefAngel.Relay.On(Topoff);
t = now();
}
//Ferts Mode
if ( wc_status == 2){
if (now() - t > SECS_PER_MIN * 6){
wc_status = 3; //enter Ferts mode
ReefAngel.Relay.Off(Mixer);
ReefAngel.Relay.On(Ferts);
t = now();
}
}
//ferts Mode
if ( wc_status == 3){
if (now() - t > 15){
ReefAngel.Relay.Off(Ferts);
ReefAngel.Relay.Auto(Filter);
ReefAngel.Relay.On(Filter);
wc_status = 0;
}
}
}
// Disable masks for things that should not be turned on by mistake
void LockPorts() {
ReefAngel.AddPortOverrides();
}