Here is my current PDE File.
It has a few extras such as:
1. Reuse of the same PWM port to run moonlights at night and LEDs by day.
2. Automatic skimmer clean out.
3. Shutdown the skimmer if the water level is too high.
4. A "High Noon" phase for the white LEDs that turns them on extra hard in the middle of the day.
5. The top fans run periodically to clear out humidity from the enclosed hood.
6. Use of a single relay to run white and blue LEDs.
Code: Select all
#include <ReefAngel_Features.h>
#include <ReefAngel_Globals.h>
#include <ReefAngel_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <ReefAngel_EEPROM.h>
#include <ReefAngel_NokiaLCD.h>
#include <ReefAngel_ATO.h>
#include <ReefAngel_Joystick.h>
#include <ReefAngel_LED.h>
#include <ReefAngel_TempSensor.h>
#include <ReefAngel_Relay.h>
#include <ReefAngel_PWM.h>
#include <ReefAngel_Timer.h>
#include <ReefAngel_Memory.h>
#include <ReefAngel.h>
// Labels for the web banner
#include <avr/pgmspace.h>
prog_char id_label[] PROGMEM = "edvalson";
prog_char probe1_label[] PROGMEM = "Water";
prog_char probe2_label[] PROGMEM = "Lights";
prog_char probe3_label[] PROGMEM = "Room";
prog_char relay1_label[] PROGMEM = "ATO";
prog_char relay2_label[] PROGMEM = "LEDS";
prog_char relay3_label[] PROGMEM = "FANS";
prog_char relay4_label[] PROGMEM = "WAVES";
prog_char relay5_label[] PROGMEM = "SKIMMER";
prog_char relay6_label[] PROGMEM = "SKUPPER";
prog_char relay7_label[] PROGMEM = "HEATER";
prog_char relay8_label[] PROGMEM = "SUMP";
PROGMEM const char *webbanner_items[] = {
id_label, probe1_label, probe2_label, probe3_label, relay1_label, relay2_label,
relay3_label, relay4_label, relay5_label, relay6_label, relay7_label, relay8_label,
};
#define ATO Port1
#define LEDS Port2
#define FANS Port3
#define WAVEMAKERS Port4
#define SKIMMER Port5
#define SKUPPER Port6
#define HEATER Port7
#define SUMP Port8
byte whitePwmSlope = 0;
byte bluePwmSlope = 0;
boolean runSkimmer = true;
#define START_HIGH_NOON 14
#define END_HIGH_NOON 17
void setup()
{
ReefAngel.Init(); //Initialize controller
// Initialize and start the web banner timer
ReefAngel.LoadWebBanner(pgm_read_word(&(webbanner_items[0])), SIZE(webbanner_items));
ReefAngel.Timer[4].SetInterval(180); // set interval to 180 seconds
ReefAngel.Timer[4].Start();
// Ports that are always on
ReefAngel.Relay.On(SUMP);
ReefAngel.Relay.On(WAVEMAKERS);
ReefAngel.OverheatShutoffPorts = B00000000;
ReefAngel.FeedingModePorts = B00001000;
ReefAngel.WaterChangePorts = B10011000;
}
void loop()
{
ReefAngel.ShowInterface();
ReefAngel.StandardHeater(HEATER);
// run the fans for 1 minute every half hour to keep the humidity out of the hood
if (minute()%30 == 0)
{
ReefAngel.Relay.On(FANS);
}
else
{
ReefAngel.StandardFan(FANS);
}
// figure out the light slopes
bluePwmSlope = PWMSlope(InternalMemory.StdLightsOnHour_read(),InternalMemory.StdLightsOnMinute_read(),InternalMemory.StdLightsOffHour_read(),InternalMemory.StdLightsOffMinute_read(),0,InternalMemory.LEDPWMActinic_read(),90, bluePwmSlope);
// if we are in the high noon phase of the day, ramp the whites clear up to 100, ignoring the value in memory. I wish we had a 3rd value in memory
if (hour() >= START_HIGH_NOON && hour() <= END_HIGH_NOON)
whitePwmSlope = PWMSlope(START_HIGH_NOON, 0 , END_HIGH_NOON, 0 , InternalMemory.LEDPWMDaylight_read(), 100, 20, whitePwmSlope);
else
whitePwmSlope = PWMSlope(InternalMemory.MHOnHour_read(),InternalMemory.MHOnMinute_read(),InternalMemory.MHOffHour_read(),InternalMemory.MHOffMinute_read(),0,InternalMemory.LEDPWMDaylight_read(),60, whitePwmSlope);
// if either PWM slopes are on, turn on the lights
if (bluePwmSlope >= 5 || whitePwmSlope >= 10)
{
ReefAngel.PWM.SetDaylight(whitePwmSlope);
ReefAngel.PWM.SetActinic(bluePwmSlope);
ReefAngel.Relay.On (LEDS);
}
// otherwise if it is really night, turn on moonlights
else if (whitePwmSlope < 5)
{
ReefAngel.PWM.SetDaylight(MoonPhase());
ReefAngel.Relay.Off (LEDS);
}
// but if it is just getting close to night turn off the daylight(moonlight) to avoid a brief flash of white light
else
{
ReefAngel.PWM.SetDaylight(0);
ReefAngel.Relay.Off (LEDS);
}
runSkimmer = true;
// clean out the skimmer for one minute every 4 hours.
if ((hour()%4)==0)
{
if (minute()==0)
{
ReefAngel.Relay.On(SKUPPER);
}
else if (minute() == 1)
{
runSkimmer = false;
}
else
{
ReefAngel.Relay.Off(SKUPPER);
}
}
// If the High ATO isn't active turn off the ATO and the Skimmer
// this means the water level is too high.
// This should only happen if things go wrong
if (!ReefAngel.HighATO.IsActive())
{
ReefAngel.Relay.Off(ATO);
runSkimmer = false;
}
else
{
ReefAngel.SingleATOLow (ATO);
}
// update the skimmer with the runSkimmer value
if (runSkimmer)
{
// let things settle down before the skimmer turns on.
ReefAngel.Relay.DelayedOn(SKIMMER, 5);
}
else
{
ReefAngel.Relay.Off(SKIMMER);
}
// write it all to the relays
ReefAngel.Relay.Write();
// Web Banner stuff
if(ReefAngel.Timer[4].IsTriggered())
{
ReefAngel.Timer[4].Start();
ReefAngel.WebBanner();
}
}