Well, it compiled at least, but did not work as intended. It just set lights at 60/40 no matter what position the port switch was in (on/off/auto). I commented the 60/40 code out for the moment.
Newest code below. Added the virtual ports as "always off", Applied the Status logic to turn on refugium light opposite my daylights, since I have the offsets spread on all 3 lights in 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>
#include <SunLocation.h>
#include <Tide.h>
#include <Moon.h>
#include <WiFiAlert.h>
////// Place global variable code below here
SunLocation sl;
int avgph[10];
unsigned long totalavgph=0;
byte avgindex=0;
void DrawCustomMain()
{
byte x;
byte y = 2;
char text[7];
// *********** CHANGE TEMP READOUT COLOR DEPENDENT ON FAN AND HEATER STATUS ***********
int TempColor; // Color for drawing temperature
boolean HeatOn = ReefAngel.Relay.Status(Port6); // Get the status of the heater relay
if (HeatOn)
{
TempColor = COLOR_NAVY; // Blue text, too cold, heater is on
}
if (!HeatOn)
{
TempColor = COLOR_GREEN; // Green text, no fan or heater on
}
// ***********************************************************************************
int pHColor; // Color for drawing pH
boolean LowpH = (ReefAngel.Params.PH < 780) ; // Check for Low pH Value
boolean HighpH = (ReefAngel.Params.PH > 850); // Check for High pH Value
if (LowpH)
{
pHColor = COLOR_NAVY; // Blue text, Low pH value
}
if (HighpH)
{
pHColor = COLOR_RED; // Red text, High pH value
}
if (!LowpH && !HighpH)
{
pHColor = COLOR_GREEN; // Green text, pH acceptable
}
// ***********************************************************************************
ReefAngel.LCD.DrawLargeText(COLOR_DARKSLATEBLUE,DefaultBGColor, 6, 3, " Thunder Reef",Font8x8); // Put a banner at the top
ReefAngel.LCD.DrawDate(6, 119); // Put the date and time at the bottom
ReefAngel.LCD.Clear(COLOR_BLACK, 1, 12, 132, 12); // Draw a black line under the banner
x = 6;
y += MENU_START_ROW*1.4; // MENU_START_ROW is 10, according to globals.h, so y=2+10+1=13
ReefAngel.LCD.DrawLargeText(COLOR_BLUE, COLOR_WHITE, x, y+1, " Temp pH");
ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10); // Get T1 temp and convert
x = 2;
y += MENU_START_ROW*1.6;
ReefAngel.LCD.DrawHugeNumbers(COLOR_BLACK, TempColor, x, y, text); // Draw the temperature, white numbers on a colored background
ConvertNumToString(text, ReefAngel.Params.PH, 100); // Get pH reading and convert
x = 2;
y = MENU_START_ROW*2.6;
ReefAngel.LCD.DrawHugeNumbers(COLOR_YELLOW, pHColor, x+65, y+6, text); // Put pH on the screen
x += 6;
y += MENU_START_ROW*3.3;
ReefAngel.LCD.DrawLargeText(COLOR_INDIGO,DefaultBGColor,25,y,"Sump Level",Font8x8); // Draw the Sump Float switch status
if (ReefAngel.LowATO.IsActive())
{ReefAngel.LCD.FillCircle(15,y+3,7,COLOR_RED);
}
else
{
ReefAngel.LCD.FillCircle(15,y+3,7,COLOR_GREEN);
}
x += 6;
y += MENU_START_ROW*2.0;
ReefAngel.LCD.DrawLargeText(COLOR_INDIGO,DefaultBGColor,25,y,"Skimmer Cup",Font8x8); // Draw the Skimmer Cup Float switch status
if (ReefAngel.HighATO.IsActive()) {ReefAngel.LCD.FillCircle(15,y+3,7,COLOR_GREEN);
}
else
{
ReefAngel.LCD.FillCircle(15,y+3,7,COLOR_RED);
}
byte TempRelay = ReefAngel.Relay.RelayData; // Code for drawing the relay box
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 100, TempRelay);
}
void DrawCustomGraph()
{
}
////// 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
ReefAngel.FeedingModePorts = Port7Bit; // Ports toggled in Feeding Mode
ReefAngel.WaterChangePorts = Port1Bit | Port5Bit | Port6Bit | Port7Bit | Port8Bit; // Ports toggled in Water Change Mode
ReefAngel.LightsOnPorts = Port2Bit | Port3Bit | Port4Bit; // Ports toggled when Lights On / Off menu entry selected
ReefAngel.OverheatShutoffPorts = Port2Bit | Port3Bit | Port4Bit | Port6Bit | Port7Bit; // Ports turned off when Overheat temperature exceeded
ReefAngel.TempProbe = T1_PROBE; // Use T1 probe as temperature and overheat functions
ReefAngel.OverheatProbe = T1_PROBE;
InternalMemory.OverheatTemp_write( 830 ); // Set the Overheat temperature setting
// Ports that are always on
ReefAngel.Relay.On( Port1 );
// Virtual Ports that are always off
ReefAngel.Relay.Off( Box1_Port1);
ReefAngel.Relay.Off( Box1_Port2);
ReefAngel.Relay.Off( Box1_Port3);
ReefAngel.Relay.Off( Box1_Port4);
ReefAngel.Relay.Off( Box1_Port5);
ReefAngel.Relay.Off( Box1_Port6);
ReefAngel.Relay.Off( Box1_Port7);
ReefAngel.Relay.Off( Box1_Port8);
// Delayed start for skimmer to allow sump level to return to normal after water change
ReefAngel.Relay.DelayedOn( Port7,4 );
////// Place additional initialization code below here
sl.Init(28.5700, -81.6800); // Lat/long for Clermont, FL
sl.SetOffset(-3,0,-3,0); // rise_hour, rise_seconds, set_hour, set_seconds (set 1 hr later for better viewing time)
randomSeed(now()%SECS_PER_DAY);
//Custom Variable [0] = Month/Season
ReefAngel.CustomLabels[0]="Return";
ReefAngel.CustomLabels[1]="Daylights";
ReefAngel.CustomLabels[2]="Actinics";
ReefAngel.CustomLabels[3]="Fuge Light";
ReefAngel.CustomLabels[4]="Alk Dosing";
ReefAngel.CustomLabels[5]="Heater";
ReefAngel.CustomLabels[6]="Skimmer";
ReefAngel.CustomLabels[7]="ATO RoDi";
// Virtual Ports reserved for custom lighting functions and effects
ReefAngel.CustomLabels[8]="Lights 60/40";
ReefAngel.CustomLabels[9]="Not Used";
ReefAngel.CustomLabels[10]="Not Used";
ReefAngel.CustomLabels[11]="Not Used";
ReefAngel.CustomLabels[12]="Weather";
ReefAngel.CustomLabels[13]="Weather";
ReefAngel.CustomLabels[14]="Weather";
ReefAngel.CustomLabels[15]="Weather";
////// Place additional initialization code above here
}
void loop()
{
// seasonal temperatures
SeasonalTemps();
// Lights on Dimming Expansion. (Left=East, Right=West)
ReefAngel.PWM.Channel0PWMParabola(0,-30); // Actinic Left - Starts at Sunrise, ends 30 minutes before Sunset
ReefAngel.PWM.Channel2PWMParabola(-15,-15); // Actinic Center - Starts 15 minute after Sunrise, ends 15 minutes before Sunset
ReefAngel.PWM.Channel4PWMParabola(-30,0); // Actinic Right - Starts 30 minutes after Sunrise, ends at Sunset
ReefAngel.PWM.Channel1PWMParabola(-150,-180); // Daylight Left - Starts 150 minutes after Sunrise, ends 180 minutes before Sunset
ReefAngel.PWM.Channel3PWMParabola(-165,-165); // Daylight Center - Starts 165 minutes after Sunrise, ends 165 minutes before Sunset
ReefAngel.PWM.Channel5PWMParabola(-180,-150); // Daylight Right - Starts 180 minutes after Sunrise, ends 150 minutes before Sunset
// Turn Actinic outlet on if any % is >= 2
(ReefAngel.PWM.GetChannelValue(0)>=2 || ReefAngel.PWM.GetChannelValue(2)>=2 || ReefAngel.PWM.GetChannelValue(4)>=2) ? ReefAngel.Relay.On( Port3 ) : ReefAngel.Relay.Off( Port3 );
// Turn Daylight outlet on if any % is >=2
(ReefAngel.PWM.GetChannelValue(1)>=2 || ReefAngel.PWM.GetChannelValue(3)>=2 || ReefAngel.PWM.GetChannelValue(5)>=2) ? ReefAngel.Relay.On( Port2 ) : ReefAngel.Relay.Off( Port2 );
ReefAngel.Relay.Set(Port4, !ReefAngel.Relay.Status(Port2)); // Refugium light. Opposite Whites.
ReefAngel.DosingPumpRepeat( Port5,0,10,18 );
// Virtual Port Functions
//if (ReefAngel.Relay.Status( Box1_Port1 )); // Set Lights 60/40
//{
//ReefAngel.PWM.SetChannel(0,60); // Actinic Left
//ReefAngel.PWM.SetChannel(2,60); // Actinic Center
//ReefAngel.PWM.SetChannel(4,60); // Actinic Right
//ReefAngel.PWM.SetChannel(1,40); // Daylight Left
//ReefAngel.PWM.SetChannel(3,40); // Daylight Center
//ReefAngel.PWM.SetChannel(5,40); // Daylight Right
//}
////// Place your custom code below here
// Alk Dosing (1 tbs Baked Baking soda per gal), Port 5. Between 9pm & 9am, Every 10 minutes run for 18 seconds.
if (hour()>=9 && hour()<21) ReefAngel.Relay.Off(Port5);
// WP-25 powerheads schedule
if (hour()>=9 && hour()<13)
{
ReefAngel.PWM.SetDaylight( ReefCrestMode(52,12,true) ); // reefcrest at 52% +/- 12% on sync mode (Day Mode)
ReefAngel.PWM.SetActinic( ReefCrestMode(52,12,false) ); // reefcrest at 52% +/- 12% on Anti-sync mode (Day mode)
}
else if (hour()>=13 && hour()<18)
{
ReefAngel.PWM.SetDaylight( ShortPulseMode(1,68,408,true) ); // Short pulse at 68% with 408ms pulse on sync mode (3/4" surface wave)
ReefAngel.PWM.SetActinic( ShortPulseMode(1,68,408,false) ); // Short pulse at 68% with 408ms pulse on Anti-sync mode (3/4" surface wave)
}
else if (hour()>=18 && hour()<19)
{
ReefAngel.PWM.SetDaylight( LongPulseMode(35,70,2,true) ); // Long Pulse 35% ramping up to 70% for 2 seconds on sync mode (nutrient transport)
ReefAngel.PWM.SetActinic( LongPulseMode(35,70,2,false) ); // Long Pulse 35% ramping up to 70% for 2 seconds on Anti-sync mode (nutrient transport)
}
else if (hour()>=19 && hour()<20)
{
ReefAngel.PWM.SetDaylight( ReefCrestMode(52,12,true) ); // reefcrest at 52% +/- 12% on sync mode (Day Mode)
ReefAngel.PWM.SetActinic( ReefCrestMode(52,12,false) ); // reefcrest at 52% +/- 12% on Anti-sync mode (Day mode)
}
else
{
ReefAngel.PWM.SetDaylight( ReefCrestMode(48,8,true) ); // reefcrest at 48% +/- 8% on sync mode (night Mode)
ReefAngel.PWM.SetActinic( ReefCrestMode(48,8,false) ); // reefcrest at 48% +/- 8% on Anti-sync mode (night mode)
}
if( ReefAngel.DisplayedMenu==FEEDING_MODE )
{
ReefAngel.PWM.SetActinic( LongPulseMode(1,37,1,true) );
ReefAngel.PWM.SetDaylight( LongPulseMode(1,37,1,true) );
}
if( ReefAngel.DisplayedMenu==WATERCHANGE_MODE )
{
ReefAngel.PWM.SetActinic(35);
ReefAngel.PWM.SetDaylight(35);
}
// enter feeding mode at 11am & 5pm
if ( (hour()==11 && minute()==0 && second()==0))
{
ReefAngel.FeedingModeStart(); // turn on feeding mode
}
if ( (hour()==17 && minute()==0 && second()==0))
{
ReefAngel.FeedingModeStart(); // turn on feeding mode
}
if(ReefAngel.HighATO.IsActive()) // Float switch in Skimmer Locker
{
ReefAngel.Relay.DelayedOn( Port7,4 );
}
else
{
ReefAngel.Relay.Off(Port7); // Turn off Skimmer when locker full.
}
// ATO, Port 8 is ATO using Clear RoDi
ReefAngel.SingleATO(true,Port8,400,0); // Sump switch. If ATO/RoDi runs for 400 seconds, then shut off and send alert.
{
sl.CheckAndUpdate(); // handle updating sunrise and sunset values
}
////// Place your custom code above here
// This should always be the last line
ReefAngel.Portal( "DmnYnkee" );
ReefAngel.ShowInterface();
}
void SeasonalTemps ()
{
static int heatArray[][2] = { {796,800}, // default in case of error in month=0 (June)
{781,785},//January (winter) // 78.3
{784,788},//February (winter) // 78.6
{787,791},//March (early spring) // 78.9
{790,794},//April (spring) // 79.2
{793,797},//May (spring) // 79.5
{796,800},//June (early summer) // 79.8
{799,803},//July (summer) // 80.1
{802,806},//August (summer) // 80.4
{798,802},//September (early fall) // 80.0
{794,798},//October (fall) // 79.6
{790,794},//November (fall) // 79.2
{786,790} };//December (early winter) // 78.8
ReefAngel.StandardHeater( Port6,heatArray[month()][0],heatArray[month()][1]);
}//end seasonalTemps