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 <ReefAngel.h>
// Initialize Buzzer variables
byte buzzer=0;
byte iochannel4flag=0;
////// Place global variable code below here
long buzzerinterval=1000; // interval at which to sound buzzer (milliseconds)
long previousMillis=0;
void CheckReservoirStatus(byte channel, byte pump)
{
if ( ReefAngel.IO.GetChannel(channel) )
{
// If empty, shutoff the port, trigger alert
ReefAngel.CustomVar[channel] = 1;
ReefAngel.Relay.Off(pump);
}
else
{
// If not empty, turn on the port, clear alert
ReefAngel.CustomVar[channel] = 0;
ReefAngel.Relay.On(pump);
}
}
void MyCustomATO(int ATOTimeout)
{
/*
This function works as follows:
When it's time to topoff the system, we check the levels of each
of the three reservoirs. If a reservoir is empty, we set a custom
flag to indicate it's empty on the portal and we do not start that
pump. Otherwise, we clear the custom flag for the reservoir and
start the pump.
The function monitors the switch levels like normal.
Monitor the status of the reservoirs while topping off.
When the high switch is triggered (aka, finished topping off),
ALL ports are turned off regardless of status (doesn't hurt to do this).
If the timeout occurs, the LED light comes on and all ports are
turned off just like when we finish topping off.
*/
unsigned long TempTimeout = ATOTimeout;
TempTimeout *= 60000; /* Try increasing this from 1000, it seems to take the number
of seconds, 255 max, and convert to milliseconds. So, multiply by 60
to make ATOTimeout effectively be minutes?
*/
if ( ReefAngel.LowATO.IsActive() && ( !ReefAngel.LowATO.IsTopping()) )
{
ReefAngel.LowATO.Timer = millis();
ReefAngel.LowATO.StartTopping();
// Check the level of each reservoir
// If empty, set the alert and don't start topping off
// otherwise if not empty, clear the alert and start topping
CheckReservoirStatus(0, Port5);
CheckReservoirStatus(1, Port6);
CheckReservoirStatus(2, Box1_Port5);
}
// Monitor levels while topping off, to prevent a reservoir from running dry
// Might need to remove this check here -- Nope, this seems to work fine.
if ( ReefAngel.LowATO.IsTopping() )
{
CheckReservoirStatus(0, Port5);
CheckReservoirStatus(1, Port6);
CheckReservoirStatus(2, Box1_Port5);
}
if ( ReefAngel.HighATO.IsActive() )
{
ReefAngel.LowATO.StopTopping(); // stop the low ato timer
ReefAngel.Relay.Off(Port5);
ReefAngel.Relay.Off(Port6);
ReefAngel.Relay.Off(Box1_Port5);
}
if ( (millis()-ReefAngel.LowATO.Timer > TempTimeout) && ReefAngel.LowATO.IsTopping() )
{
ReefAngel.LED.On();
#ifdef ENABLE_EXCEED_FLAGS
InternalMemory.write(ATO_Exceed_Flag, 1);
#endif // ENABLE_EXCEED_FLAGS
ReefAngel.Relay.Off(Port5);
ReefAngel.Relay.Off(Port6);
ReefAngel.Relay.Off(Box1_Port5);
#ifdef ENABLE_ATO_LOGGING
// bump the counter if a timeout occurs
AtoEventCount++;
if ( AtoEventCount >= MAX_ATO_LOG_EVENTS ) { AtoEventCount = 0; }
#endif // ENABLE_ATO_LOGGING
}
}
////// Place global variable code above here
void setup()
{
// This must be the first line
ReefAngel.Init(); //Initialize controller
// Ports toggled in Feeding Mode
ReefAngel.FeedingModePorts = 0;
ReefAngel.FeedingModePortsE[0] = Port4Bit | Port7Bit;
// Ports toggled in Water Change Mode
ReefAngel.WaterChangePorts = Port2Bit | Port5Bit | Port6Bit;
ReefAngel.WaterChangePortsE[0] = Port2Bit | Port5Bit | Port6Bit | Port8Bit;
// Ports toggled when Lights On / Off menu entry selected
ReefAngel.LightsOnPorts = Port4Bit | Port8Bit;
ReefAngel.LightsOnPortsE[0] = Port1Bit;
// Ports turned off when Overheat temperature exceeded
ReefAngel.OverheatShutoffPorts = Port2Bit | Port4Bit;
ReefAngel.OverheatShutoffPortsE[0] = Port1Bit | Port2Bit;
// Use T1 probe as temperature and overheat functions
ReefAngel.TempProbe = T1_PROBE;
ReefAngel.OverheatProbe = T1_PROBE;
// Ports that are always on
ReefAngel.Relay.On( Box1_Port4 );
ReefAngel.Relay.On( Box1_Port7 );
ReefAngel.Relay.On( Box1_Port8 );
////// Place additional initialization code below here
////// Place additional initialization code above here
}
void loop()
{
//ReefAngel.Relay.Set( Port1, !ReefAngel.Relay.Status( Port8 ) );
ReefAngel.StandardHeater( Port2,780,790 );
ReefAngel.StandardLights( Port3,9,00,21,00 ); //Plant lights
ReefAngel.DelayedStartLights( Port4 );//ReefAngel.Relay.DelayedOn( Port4 );
//ReefAngel.StandardATO( Port5 );
ReefAngel.Relay.Set( Port7, !ReefAngel.Relay.Status( Port4 ) );
ReefAngel.ActinicLights( Port8 );
ReefAngel.DelayedStartLights( Box1_Port1 );
ReefAngel.StandardHeater( Box1_Port2 );
//ReefAngel.DosingPumpRepeat1( Box1_Port6 );
//iochannel4flag = ReefAngel.IO.GetChannel( 4 );
//buzzer = iochannel4flag;
//if ( buzzer >= 1 ) buzzer = 100;
//ReefAngel.PWM.SetDaylight( buzzer );
////// Place your custom code below here
//Moon light logic
if (( hour()<=9))
ReefAngel.Relay.Off (Port1);
else
ReefAngel.Relay.Set( Port1, !ReefAngel.Relay.Status( Port8 ) );
//ATO function
MyCustomATO(InternalMemory.ATOTimeout_read());
//Notify when sump level is low
if ( ReefAngel.IO.GetChannel(4) )
{
ReefAngel.CustomVar[4]=1;
// If the sump level is about to cavitate the pumps, then sound the alarm
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > buzzerinterval) {
// save the last time the buzzer turned on
previousMillis = currentMillis;
// if the buzzer is off turn it on and vice-versa:
if (ReefAngel.PWM.GetDaylightValue() == 0)
ReefAngel.PWM.SetDaylight(25);
else
ReefAngel.PWM.SetDaylight(0);
}
}
else
{
// Turn the buzzer off when the sump level is above cavitation levels
ReefAngel.PWM.SetDaylight(0);
ReefAngel.CustomVar[4]=0;
}
//If the ATO float switch is stuck, and the topoff pump timeout flag is set, then set C5=1
ReefAngel.CustomVar[5]=InternalMemory.read(ATO_Exceed_Flag); //Note that this value should be either 0 or 1, but for some reason is 254 or 255.
//Vodka dosing
if ( ReefAngel.IO.GetChannel(3) ) //Check there is vodka in the reservoir
{
ReefAngel.Relay.Off(Box1_Port6); //If no vodka, then set a variable and turn off the port
ReefAngel.CustomVar[3]=1;
}
else //If there is vodka, then dose
{
ReefAngel.CustomVar[3]=0;
ReefAngel.DosingPumpRepeat1(Box1_Port6);
}
//Monitor the water level in the display
ReefAngel.CustomVar[6]=ReefAngel.IO.GetChannel(5);
////// Place your custom code above here
// This should always be the last line
ReefAngel.Portal( "btorrenga" );
ReefAngel.ShowInterface();
}
void DrawCustomMain()
{
int x,y;
char text[10];
// I/O Expansion
byte bkcolor;
x = 14;
y = 11;
for ( int a=0;a<6;a++ )
{
ReefAngel.LCD.DrawCircleOutline( x+(a*20),y,4,COLOR_MEDIUMORCHID );
if ( ReefAngel.IO.GetChannel(a) ) bkcolor=COLOR_WHITE; else bkcolor=COLOR_GRAY;
ReefAngel.LCD.FillCircle( x+(a*20),y,2,bkcolor );
}
pingSerial();
// Parameters
#if defined DisplayLEDPWM && ! defined RemoveAllLights
ReefAngel.LCD.DrawMonitor( 15, 26, ReefAngel.Params,
ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
ReefAngel.LCD.DrawMonitor( 15, 26, ReefAngel.Params );
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
pingSerial();
// Salinity
ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,15,63, "SAL:" );
ReefAngel.LCD.DrawText( COLOR_DARKKHAKI,DefaultBGColor,39,63, ReefAngel.Params.Salinity );
pingSerial();
// Main Relay Box
byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox( 12, 82, TempRelay );
pingSerial();
// Relay Expansion
TempRelay = ReefAngel.Relay.RelayDataE[0];
TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
ReefAngel.LCD.DrawOutletBox( 12, 101, TempRelay );
pingSerial();
// Date and Time
ReefAngel.LCD.DrawDate( 6, 122 );
pingSerial();
}
void DrawCustomGraph()
{
}