CODE CHECK

Do you have a question on how to do something.
Ask in here.
Post Reply
CASPAR
Posts: 56
Joined: Wed May 09, 2012 12:24 pm

CODE CHECK

Post by CASPAR »

Can someone please check this code for me? Im hoping it is the current code i am using but dont want to mess things up. I think this is it, supposed to have the storm effects and ATO function and also am using port 5 & 6 for just a timer to control 2 small pumps for a water change.

CODE IS BELOW:

#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 <AI.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <Salinity.h>
#include <PH.h>
#include <WaterLevel.h>
#include <ReefAngel.h>

prog_char menu1_label[] PROGMEM = "Feeding Mode";
prog_char menu2_label[] PROGMEM = "Water Change Mode";
prog_char menu3_label[] PROGMEM = "Cloud On Demand";
prog_char menu4_label[] PROGMEM = "Clear ATO Timeout";
prog_char menu5_label[] PROGMEM = "Set Clock";
prog_char menu6_label[] PROGMEM = "Calibrate pH";
PROGMEM const char *menu_items[] = {
menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label};

////// Place global variable code below here


byte DaylightPWMValue=0;
boolean ForceCloud=false;

void MenuEntry1()
{
ReefAngel.FeedingModeStart();
}
void MenuEntry2()
{
ReefAngel.WaterChangeModeStart();
}
void MenuEntry3()
{
ForceCloud=true;
ReefAngel.DisplayedMenu=RETURN_MAIN_MODE;
}
void MenuEntry4()
{
ReefAngel.ATOClear();
ReefAngel.DisplayedMenu=RETURN_MAIN_MODE;
}
void MenuEntry5()
{
ReefAngel.SetupDateTime();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry6()
{
ReefAngel.SetupCalibratePH();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}



void DrawCustomMain()
{
byte x = 6;
byte y = 2;
byte t;
char text[10];

// Parameters

ReefAngel.LCD.DrawDate(6, 2);
ReefAngel.LCD.Clear(COLOR_INDIGO, 1, 11, 132, 11);
pingSerial();

ReefAngel.LCD.DrawText(COLOR_INDIGO,255, 1, 102, "----------------------");
ReefAngel.LCD.DrawText(COLOR_INDIGO,255, 1, 126, "----------------------");
ReefAngel.LCD.DrawText(COLOR_BLACK,255,56,110, "ATO");
ReefAngel.LCD.DrawText(COLOR_BLUE,255, 2, 109, "*");
ReefAngel.LCD.DrawText(COLOR_BLUE,255, 2, 121, "*");
ReefAngel.LCD.DrawText(COLOR_GREEN,255, 45, 111, "H");
ReefAngel.LCD.DrawText(COLOR_GREEN,255, 45, 121, "I");
ReefAngel.LCD.DrawText(COLOR_GREEN,255, 77, 111, "L");
ReefAngel.LCD.DrawText(COLOR_GREEN,255, 77, 121, "O");
ReefAngel.LCD.DrawText(COLOR_BLUE,255, 126, 109, "*");
ReefAngel.LCD.DrawText(COLOR_BLUE,255, 126, 121, "*");


ReefAngel.LCD.DrawText(COLOR_RED,255,14,30,"TANK");
ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
ReefAngel.LCD.DrawLargeText(COLOR_GREEN, 255, 10, 40, text, Num8x16);
pingSerial();

ReefAngel.LCD.DrawText(COLOR_RED,255,95,30,"PH");
ConvertNumToString(text, ReefAngel.Params.PH, 100);
ReefAngel.LCD.DrawLargeText(COLOR_GREEN, 255, 85, 40, text, Num8x16);
pingSerial();
// Main Relay Box
byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 85, TempRelay);
pingSerial();


ReefAngel.LCD.DrawText(COLOR_RED,255,8,58,"LED TEMP");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T2_PROBE], COLOR_NAVY, 15, 68, 10);

ReefAngel.LCD.DrawText(COLOR_RED,255,92,58,"ROOM");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T3_PROBE], COLOR_NAVY, 92, 68, 10);

ReefAngel.LCD.DrawText(COLOR_RED,255,10,110, "White");
ReefAngel.LCD.DrawText(COLOR_BLUE,255, 32, 119, "%");
ReefAngel.LCD.DrawText(COLOR_BLACK,255,12,119, ReefAngel.PWM.GetDaylightValue());
//ReefAngel.PWM.GetDaylightValue(),
ReefAngel.LCD.DrawText(COLOR_RED,255,90,110, "Blue");
ReefAngel.LCD.DrawText(COLOR_BLUE,255, 114, 119, "%");
ReefAngel.LCD.DrawText(COLOR_BLACK,255,92,119, ReefAngel.PWM.GetActinicValue());


if (ReefAngel.HighATO.IsActive())
ReefAngel.LCD.FillCircle(57,122,3,COLOR_RED);
else
ReefAngel.LCD.FillCircle(57,122,3,COLOR_GREEN);

if (ReefAngel.LowATO.IsActive())
ReefAngel.LCD.FillCircle(70,122,3,COLOR_RED);
else
ReefAngel.LCD.FillCircle(70,122,3,COLOR_GREEN);

//ReefAngel.PWM.GetActinicValue());

//ReefAngel.LCD.DrawMonitor(15, 60, ReefAngel.Params,
//ReefAngel.PWM.GetDaylightValue(),
//ReefAngel.PWM.GetActinicValue());

}
void DrawCustomGraph()
{
}

bool atoSpanReached; //flag to determine if the controller has been running long enough to start ATO functionality
////// Place global variable code above here


void setup()
{
// This must be the first line
ReefAngel.Init(); //Initialize controller
ReefAngel.UseFlexiblePhCalibration();
ReefAngel.PHMin=305;
ReefAngel.PHMax=995;
ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));
ReefAngel.AddDateTimeMenu();
ReefAngel.AddCustomColors();




// Use T1 probe as temperature and overheat functions
ReefAngel.TempProbe = T1_PROBE;
ReefAngel.OverheatProbe = T1_PROBE;
// Set the Overheat temperature setting
InternalMemory.OverheatTemp_write( 790 );
// Ports toggled when Lights On / Off menu entry selected
ReefAngel.LightsOnPorts = Port1Bit;



// Ports that are always on
ReefAngel.Relay.On( Port4 );



////// Place additional initialization code below here


////// Place additional initialization code above here
}

void loop()
{
ReefAngel.StandardLights( Port1,11,25,18,35 );
ReefAngel.StandardHeater( T1_PROBE,Port2,775,785 );
ReefAngel.StandardLights( Port3,18,30,11,30 );
ReefAngel.StandardLights( Port5,11,5,11,6 );
ReefAngel.StandardLights( Port6,11,0,11,1 );
ReefAngel.StandardLights( Port7,13,0,17,0 );



ReefAngel.LCD.BacklightOn();


ReefAngel.PWM.SetActinic( PWMSlope(11,30,18,30,11,40,60,0) );

DaylightPWMValue=PWMSlope(12,30,17,30,11,12,60,0);
CheckCloud();
ReefAngel.PWM.SetDaylight(DaylightPWMValue);

////// Place your custom code below here


////// Place your custom code above here

// This should always be the last line
ReefAngel.Portal( "CASPAR" );
ReefAngel.ShowInterface();
}





int x,y;
char text[10];
// Parameters
#if defined DisplayLEDPWM && ! defined RemoveAllLights


#else // defined DisplayLEDPWM && ! defined RemoveAllLights
ReefAngel.LCD.DrawMonitor( 15, 62, ReefAngel.Params );
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights


// Main Relay Box
byte TempRelay = ReefAngel.Relay.RelayData;






//*********************************************************************************************************************************
// Random Cloud/Thunderstorm effects function
void CheckCloud()
{

// ------------------------------------------------------------
// Change the values below to customize your cloud/storm effect

// Frequency in days based on the day of the month - number 2 means every 2 days, for example (day 2,4,6 etc)
// For testing purposes, you can use 1 and cause the cloud to occur everyday
#define Clouds_Every_X_Days 4

// Percentage chance of a cloud happening today
// For testing purposes, you can use 100 and cause the cloud to have 100% chance of happening
#define Cloud_Chance_per_Day 100

// Minimum number of minutes for cloud duration. Don't use max duration of less than 6
#define Min_Cloud_Duration 7

// Maximum number of minutes for the cloud duration. Don't use max duration of more than 255
#define Max_Cloud_Duration 15

// Minimum number of clouds that can happen per day
#define Min_Clouds_per_Day 1

// Maximum number of clouds that can happen per day
#define Max_Clouds_per_Day 2

// Only start the cloud effect after this setting
// In this example, start could after 11:30am
#define Start_Cloud_After NumMins(11,30)

// Always end the cloud effect before this setting
// In this example, end could before 8:00pm
#define End_Cloud_Before NumMins(18,30)

// Percentage chance of a lightning happen for every cloud
// For testing purposes, you can use 100 and cause the lightning to have 100% chance of happening
#define Lightning_Change_per_Cloud 100

// Note: Make sure to choose correct values that will work within your PWMSLope settings.
// For example, in our case, we could have a max of 5 clouds per day and they could last for 50 minutes.
// Which could mean 250 minutes of clouds. We need to make sure the PWMSlope can accomodate 250 minutes of effects or unforseen resul
// could happen.
// Also, make sure that you can fit double those minutes between Start_Cloud_After and End_Cloud_Before.
// In our example, we have 510 minutes between Start_Cloud_After and End_Cloud_Before, so double the 250 minutes (or 500 minutes) can
// fit in that 510 minutes window.
// It's a tight fit, but it did.

//#define printdebug // Uncomment this for debug print on Serial Monitor window
#define forcecloudcalculation // Uncomment this to force the cloud calculation to happen in the boot process.


// Change the values above to customize your cloud/storm effect
// ------------------------------------------------------------
// Do not change anything below here

static byte cloudchance=255;
static byte cloudduration=0;
static int cloudstart=0;
static byte numclouds=0;
static byte lightningchance=0;
static byte cloudindex=0;
static byte lightningstatus=0;
static int LastNumMins=0;
// Every day at midnight, we check for chance of cloud happening today
if (hour()==0 && minute()==0 && second()==0) cloudchance=255;

#ifdef forcecloudcalculation
if (cloudchance==255)
#else
if (hour()==0 && minute()==0 && second()==1 && cloudchance==255)
#endif
{
//Pick a random number between 0 and 99
cloudchance=random(100);
// if picked number is greater than Cloud_Chance_per_Day, we will not have clouds today
if (cloudchance>Cloud_Chance_per_Day) cloudchance=0;
// Check if today is day for clouds.
if ((day()%Clouds_Every_X_Days)!=0) cloudchance=0;
// If we have cloud today
if (cloudchance)
{
// pick a random number for number of clouds between Min_Clouds_per_Day and Max_Clouds_per_Day
numclouds=random(Min_Clouds_per_Day,Max_Clouds_per_Day);
// pick the time that the first cloud will start
// the range is calculated between Start_Cloud_After and the even distribuition of clouds on this day.
cloudstart=random(Start_Cloud_After,Start_Cloud_After+((End_Cloud_Before-Start_Cloud_After)/(numclouds*2)));
// pick a random number for the cloud duration of first cloud.
cloudduration=random(Min_Cloud_Duration,Max_Cloud_Duration);
//Pick a random number between 0 and 99
lightningchance=random(100);
// if picked number is greater than Lightning_Change_per_Cloud, we will not have lightning today
if (lightningchance>Lightning_Change_per_Cloud) lightningchance=0;
}
}
// Now that we have all the parameters for the cloud, let's create the effect
if (ForceCloud)
{
ForceCloud=false;
cloudchance=1;
cloudduration=10;
lightningchance=1;
cloudstart=NumMins(hour(),minute())+1;
}
if (cloudchance)
{
//is it time for cloud yet?
if (NumMins(hour(),minute())>=cloudstart && NumMins(hour(),minute())<(cloudstart+cloudduration))
{
DaylightPWMValue=ReversePWMSlope(cloudstart,cloudstart+cloudduration,DaylightPWMValue,12,60);
ReefAngel.Relay.Off( Port8 );
if (lightningchance && (NumMins(hour(),minute())==(cloudstart+(cloudduration/2))) && second()<50)
{
ReefAngel.Relay.On( Port8 );
if (random(100)<20) lightningstatus=1;
else lightningstatus=0;
if (lightningstatus)
{
DaylightPWMValue=85;
}
else
{
DaylightPWMValue=0;
}
delay(1);
}
}
if (NumMins(hour(),minute())>(cloudstart+cloudduration))
{
cloudindex++;
if (cloudindex < numclouds)
{
cloudstart=random(Start_Cloud_After+(((End_Cloud_Before-Start_Cloud_After)/(numclouds*2))*cloudindex*2),(Start_Cloud_After+(((End_Cloud_Before-Start_Cloud_After)/(numclouds*2))*cloudindex*2))+((End_Cloud_Before-Start_Cloud_After)/(numclouds*2)));
// pick a random number for the cloud duration of first cloud.
cloudduration=random(Min_Cloud_Duration,Max_Cloud_Duration);
//Pick a random number between 0 and 99
lightningchance=random(100);
// if picked number is greater than Lightning_Change_per_Cloud, we will not have lightning today
if (lightningchance>Lightning_Change_per_Cloud) lightningchance=0;
}
}
}

if (LastNumMins!=NumMins(hour(),minute()))
{
LastNumMins=NumMins(hour(),minute());
ReefAngel.LCD.Clear(255,0,120,132,132);
ReefAngel.LCD.DrawText(COLOR_BLUE,255,4,16,"CL");
ReefAngel.LCD.DrawText(0,255,20,16,"00:00");
ReefAngel.LCD.DrawText(COLOR_BLUE,255,75,16,"Li");
ReefAngel.LCD.DrawText(0,255,95,16,"00:00");
ReefAngel.LCD.DrawText(COLOR_BLUE,255,44,30,"Duration");

if (cloudchance && (NumMins(hour(),minute())<cloudstart))
{
int x=0;
if ((cloudstart/60)>=10) x=20;
else x=26;
ReefAngel.LCD.DrawText(COLOR_RED,255,x,16,(cloudstart/60));
if ((cloudstart%60)>=10) x=38;
else x=44;
ReefAngel.LCD.DrawText(COLOR_RED,255,x,16,(cloudstart%60));
}
ReefAngel.LCD.DrawText(COLOR_GREEN,255,62,40,cloudduration);
if (lightningchance)
{
int x=0;
if (((cloudstart+(cloudduration/2))/60)>=10) x=95;
else x=101;
ReefAngel.LCD.DrawText(COLOR_PURPLE,255,x,16,((cloudstart+(cloudduration/2))/60));
if (((cloudstart+(cloudduration/2))%60)>=10) x=113;
else x=119;
ReefAngel.LCD.DrawText(COLOR_PURPLE,255,x,16,((cloudstart+(cloudduration/2))%60));
}
}
}

byte ReversePWMSlope(long cstart,long cend,byte PWMStart,byte PWMEnd, byte clength)
{
long n=elapsedSecsToday(now());
cstart*=60;
cend*=60;
if (n<cstart) return PWMStart;
if (n>=cstart && n<=(cstart+clength)) return map(n,cstart,cstart+clength,PWMStart,PWMEnd);
if (n>(cstart+clength) && n<(cend-clength)) return PWMEnd;
if (n>=(cend-clength) && n<=cend) return map(n,cend-clength,cend,PWMEnd,PWMStart);
if (n>cend) return PWMStart;
}
Image
User avatar
brennyn21
Posts: 122
Joined: Mon Nov 23, 2020 5:40 pm

Re: CODE CHECK

Post by brennyn21 »

Hi Casper, looking at your code I fixed the Menu Options as it was changed how they were declared in the libraries a while back.
Right now the code does indeed have Storm Function, Light Control, Heater Control and Timed scheduled ports I will list them out below. I don't see anything for the ATO function if you need help setting that up it is pretty easy.

Relay Box Port1 Timer turning on at 11:25am and turning off at 6:35pm

Code: Select all

ReefAngel.StandardLights( Port1,11,25,18,35 );
Heater Control using T1 Probe and Port 2 on the Relay Box turning on at 77.5 and off at 78.5

Code: Select all

ReefAngel.StandardHeater( T1_PROBE,Port2,775,785 );
Relay Box Port3 turning on at 6:30 Pm and off at 11:30 am

Code: Select all

ReefAngel.StandardLights( Port3,18,30,11,30 );
Relay Box Port5 turning on at 11:06 Am and off at 11:06 Am

Code: Select all

ReefAngel.StandardLights( Port5,11,5,11,6 );
Relay Box Port6 turning on at 11:00 Am and off at 11:01 Am

Code: Select all

ReefAngel.StandardLights( Port6,11,0,11,1 );
Relay Box Port7 turning on at 1:00 Pm and off at 5:00 Pm

Code: Select all

ReefAngel.StandardLights( Port7,13,0,17,0 );
Full Code with Menu declaration Fix.

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 <AI.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <Salinity.h>
#include <PH.h>
#include <WaterLevel.h>
#include <ReefAngel.h>
#include <avr/pgmspace.h>

// Group the menu entries together
const char menu1_label[] PROGMEM = "Feeding Mode";
const char menu2_label[] PROGMEM = "Water Change Mode";
const char menu3_label[] PROGMEM = "Cloud On Demand";
const char menu4_label[] PROGMEM = "Clear ATO Timeout";
const char menu5_label[] PROGMEM = "Set Clock";
const char menu6_label[] PROGMEM = "Calibrate pH";

PROGMEM const char * const menu_items[] = {menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label};

////// Place global variable code below here


byte DaylightPWMValue=0;
boolean ForceCloud=false;

void MenuEntry1()
{
ReefAngel.FeedingModeStart();
}
void MenuEntry2()
{
ReefAngel.WaterChangeModeStart();
}
void MenuEntry3()
{
ForceCloud=true;
ReefAngel.DisplayedMenu=RETURN_MAIN_MODE;
}
void MenuEntry4()
{
ReefAngel.ATOClear();
ReefAngel.DisplayedMenu=RETURN_MAIN_MODE;
}
void MenuEntry5()
{
ReefAngel.SetupDateTime();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry6()
{
ReefAngel.SetupCalibratePH();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}



void DrawCustomMain()
{
byte x = 6;
byte y = 2;
byte t;
char text[10];

// Parameters

ReefAngel.LCD.DrawDate(6, 2);
ReefAngel.LCD.Clear(COLOR_INDIGO, 1, 11, 132, 11);
pingSerial();

ReefAngel.LCD.DrawText(COLOR_INDIGO,255, 1, 102, "----------------------");
ReefAngel.LCD.DrawText(COLOR_INDIGO,255, 1, 126, "----------------------");
ReefAngel.LCD.DrawText(COLOR_BLACK,255,56,110, "ATO");
ReefAngel.LCD.DrawText(COLOR_BLUE,255, 2, 109, "*");
ReefAngel.LCD.DrawText(COLOR_BLUE,255, 2, 121, "*");
ReefAngel.LCD.DrawText(COLOR_GREEN,255, 45, 111, "H");
ReefAngel.LCD.DrawText(COLOR_GREEN,255, 45, 121, "I");
ReefAngel.LCD.DrawText(COLOR_GREEN,255, 77, 111, "L");
ReefAngel.LCD.DrawText(COLOR_GREEN,255, 77, 121, "O");
ReefAngel.LCD.DrawText(COLOR_BLUE,255, 126, 109, "*");
ReefAngel.LCD.DrawText(COLOR_BLUE,255, 126, 121, "*");


ReefAngel.LCD.DrawText(COLOR_RED,255,14,30,"TANK");
ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
ReefAngel.LCD.DrawLargeText(COLOR_GREEN, 255, 10, 40, text, Num8x16);
pingSerial();

ReefAngel.LCD.DrawText(COLOR_RED,255,95,30,"PH");
ConvertNumToString(text, ReefAngel.Params.PH, 100);
ReefAngel.LCD.DrawLargeText(COLOR_GREEN, 255, 85, 40, text, Num8x16);
pingSerial();
// Main Relay Box
byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 85, TempRelay);
pingSerial();


ReefAngel.LCD.DrawText(COLOR_RED,255,8,58,"LED TEMP");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T2_PROBE], COLOR_NAVY, 15, 68, 10);

ReefAngel.LCD.DrawText(COLOR_RED,255,92,58,"ROOM");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T3_PROBE], COLOR_NAVY, 92, 68, 10);

ReefAngel.LCD.DrawText(COLOR_RED,255,10,110, "White");
ReefAngel.LCD.DrawText(COLOR_BLUE,255, 32, 119, "%");
ReefAngel.LCD.DrawText(COLOR_BLACK,255,12,119, ReefAngel.PWM.GetDaylightValue());
//ReefAngel.PWM.GetDaylightValue(),
ReefAngel.LCD.DrawText(COLOR_RED,255,90,110, "Blue");
ReefAngel.LCD.DrawText(COLOR_BLUE,255, 114, 119, "%");
ReefAngel.LCD.DrawText(COLOR_BLACK,255,92,119, ReefAngel.PWM.GetActinicValue());


if (ReefAngel.HighATO.IsActive())
ReefAngel.LCD.FillCircle(57,122,3,COLOR_RED);
else
ReefAngel.LCD.FillCircle(57,122,3,COLOR_GREEN);

if (ReefAngel.LowATO.IsActive())
ReefAngel.LCD.FillCircle(70,122,3,COLOR_RED);
else
ReefAngel.LCD.FillCircle(70,122,3,COLOR_GREEN);

//ReefAngel.PWM.GetActinicValue());

//ReefAngel.LCD.DrawMonitor(15, 60, ReefAngel.Params,
//ReefAngel.PWM.GetDaylightValue(),
//ReefAngel.PWM.GetActinicValue());

}
void DrawCustomGraph()
{
}

bool atoSpanReached; //flag to determine if the controller has been running long enough to start ATO functionality
////// Place global variable code above here


void setup()
{
// This must be the first line
ReefAngel.Init(); //Initialize controller
ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));

ReefAngel.AddStandardMenu();  // Add Standard Menu
ReefAngel.UseFlexiblePhCalibration();
ReefAngel.PHMin=305;
ReefAngel.PHMax=995;

ReefAngel.AddDateTimeMenu();
ReefAngel.AddCustomColors();




// Use T1 probe as temperature and overheat functions
ReefAngel.TempProbe = T1_PROBE;
ReefAngel.OverheatProbe = T1_PROBE;
// Set the Overheat temperature setting
InternalMemory.OverheatTemp_write( 790 );
// Ports toggled when Lights On / Off menu entry selected
ReefAngel.LightsOnPorts = Port1Bit;



// Ports that are always on
ReefAngel.Relay.On( Port4 );



////// Place additional initialization code below here


////// Place additional initialization code above here
}

void loop()
{
ReefAngel.StandardLights( Port1,11,25,18,35 );
ReefAngel.StandardHeater( T1_PROBE,Port2,775,785 );
ReefAngel.StandardLights( Port3,18,30,11,30 );
ReefAngel.StandardLights( Port5,11,5,11,6 );
ReefAngel.StandardLights( Port6,11,0,11,1 );
ReefAngel.StandardLights( Port7,13,0,17,0 );



ReefAngel.LCD.BacklightOn();


ReefAngel.PWM.SetActinic( PWMSlope(11,30,18,30,11,40,60,0) );

DaylightPWMValue=PWMSlope(12,30,17,30,11,12,60,0);
CheckCloud();
ReefAngel.PWM.SetDaylight(DaylightPWMValue);

////// Place your custom code below here


////// Place your custom code above here

// This should always be the last line
ReefAngel.Portal( "CASPAR" );
ReefAngel.ShowInterface();
}





int x,y;
char text[10];
// Parameters
#if defined DisplayLEDPWM && ! defined RemoveAllLights


#else // defined DisplayLEDPWM && ! defined RemoveAllLights
ReefAngel.LCD.DrawMonitor( 15, 62, ReefAngel.Params );
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights


// Main Relay Box
byte TempRelay = ReefAngel.Relay.RelayData;






//*********************************************************************************************************************************
// Random Cloud/Thunderstorm effects function
void CheckCloud()
{

// ------------------------------------------------------------
// Change the values below to customize your cloud/storm effect

// Frequency in days based on the day of the month - number 2 means every 2 days, for example (day 2,4,6 etc)
// For testing purposes, you can use 1 and cause the cloud to occur everyday
#define Clouds_Every_X_Days 4

// Percentage chance of a cloud happening today
// For testing purposes, you can use 100 and cause the cloud to have 100% chance of happening
#define Cloud_Chance_per_Day 100

// Minimum number of minutes for cloud duration. Don't use max duration of less than 6
#define Min_Cloud_Duration 7

// Maximum number of minutes for the cloud duration. Don't use max duration of more than 255
#define Max_Cloud_Duration 15

// Minimum number of clouds that can happen per day
#define Min_Clouds_per_Day 1

// Maximum number of clouds that can happen per day
#define Max_Clouds_per_Day 2

// Only start the cloud effect after this setting
// In this example, start could after 11:30am
#define Start_Cloud_After NumMins(11,30)

// Always end the cloud effect before this setting
// In this example, end could before 8:00pm
#define End_Cloud_Before NumMins(18,30)

// Percentage chance of a lightning happen for every cloud
// For testing purposes, you can use 100 and cause the lightning to have 100% chance of happening
#define Lightning_Change_per_Cloud 100

// Note: Make sure to choose correct values that will work within your PWMSLope settings.
// For example, in our case, we could have a max of 5 clouds per day and they could last for 50 minutes.
// Which could mean 250 minutes of clouds. We need to make sure the PWMSlope can accomodate 250 minutes of effects or unforseen resul
// could happen.
// Also, make sure that you can fit double those minutes between Start_Cloud_After and End_Cloud_Before.
// In our example, we have 510 minutes between Start_Cloud_After and End_Cloud_Before, so double the 250 minutes (or 500 minutes) can
// fit in that 510 minutes window.
// It's a tight fit, but it did.

//#define printdebug // Uncomment this for debug print on Serial Monitor window
#define forcecloudcalculation // Uncomment this to force the cloud calculation to happen in the boot process.


// Change the values above to customize your cloud/storm effect
// ------------------------------------------------------------
// Do not change anything below here

static byte cloudchance=255;
static byte cloudduration=0;
static int cloudstart=0;
static byte numclouds=0;
static byte lightningchance=0;
static byte cloudindex=0;
static byte lightningstatus=0;
static int LastNumMins=0;
// Every day at midnight, we check for chance of cloud happening today
if (hour()==0 && minute()==0 && second()==0) cloudchance=255;

#ifdef forcecloudcalculation
if (cloudchance==255)
#else
if (hour()==0 && minute()==0 && second()==1 && cloudchance==255)
#endif
{
//Pick a random number between 0 and 99
cloudchance=random(100);
// if picked number is greater than Cloud_Chance_per_Day, we will not have clouds today
if (cloudchance>Cloud_Chance_per_Day) cloudchance=0;
// Check if today is day for clouds.
if ((day()%Clouds_Every_X_Days)!=0) cloudchance=0;
// If we have cloud today
if (cloudchance)
{
// pick a random number for number of clouds between Min_Clouds_per_Day and Max_Clouds_per_Day
numclouds=random(Min_Clouds_per_Day,Max_Clouds_per_Day);
// pick the time that the first cloud will start
// the range is calculated between Start_Cloud_After and the even distribuition of clouds on this day.
cloudstart=random(Start_Cloud_After,Start_Cloud_After+((End_Cloud_Before-Start_Cloud_After)/(numclouds*2)));
// pick a random number for the cloud duration of first cloud.
cloudduration=random(Min_Cloud_Duration,Max_Cloud_Duration);
//Pick a random number between 0 and 99
lightningchance=random(100);
// if picked number is greater than Lightning_Change_per_Cloud, we will not have lightning today
if (lightningchance>Lightning_Change_per_Cloud) lightningchance=0;
}
}
// Now that we have all the parameters for the cloud, let's create the effect
if (ForceCloud)
{
ForceCloud=false;
cloudchance=1;
cloudduration=10;
lightningchance=1;
cloudstart=NumMins(hour(),minute())+1;
}
if (cloudchance)
{
//is it time for cloud yet?
if (NumMins(hour(),minute())>=cloudstart && NumMins(hour(),minute())<(cloudstart+cloudduration))
{
DaylightPWMValue=ReversePWMSlope(cloudstart,cloudstart+cloudduration,DaylightPWMValue,12,60);
ReefAngel.Relay.Off( Port8 );
if (lightningchance && (NumMins(hour(),minute())==(cloudstart+(cloudduration/2))) && second()<50)
{
ReefAngel.Relay.On( Port8 );
if (random(100)<20) lightningstatus=1;
else lightningstatus=0;
if (lightningstatus)
{
DaylightPWMValue=85;
}
else
{
DaylightPWMValue=0;
}
delay(1);
}
}
if (NumMins(hour(),minute())>(cloudstart+cloudduration))
{
cloudindex++;
if (cloudindex < numclouds)
{
cloudstart=random(Start_Cloud_After+(((End_Cloud_Before-Start_Cloud_After)/(numclouds*2))*cloudindex*2),(Start_Cloud_After+(((End_Cloud_Before-Start_Cloud_After)/(numclouds*2))*cloudindex*2))+((End_Cloud_Before-Start_Cloud_After)/(numclouds*2)));
// pick a random number for the cloud duration of first cloud.
cloudduration=random(Min_Cloud_Duration,Max_Cloud_Duration);
//Pick a random number between 0 and 99
lightningchance=random(100);
// if picked number is greater than Lightning_Change_per_Cloud, we will not have lightning today
if (lightningchance>Lightning_Change_per_Cloud) lightningchance=0;
}
}
}

if (LastNumMins!=NumMins(hour(),minute()))
{
LastNumMins=NumMins(hour(),minute());
ReefAngel.LCD.Clear(255,0,120,132,132);
ReefAngel.LCD.DrawText(COLOR_BLUE,255,4,16,"CL");
ReefAngel.LCD.DrawText(0,255,20,16,"00:00");
ReefAngel.LCD.DrawText(COLOR_BLUE,255,75,16,"Li");
ReefAngel.LCD.DrawText(0,255,95,16,"00:00");
ReefAngel.LCD.DrawText(COLOR_BLUE,255,44,30,"Duration");

if (cloudchance && (NumMins(hour(),minute())<cloudstart))
{
int x=0;
if ((cloudstart/60)>=10) x=20;
else x=26;
ReefAngel.LCD.DrawText(COLOR_RED,255,x,16,(cloudstart/60));
if ((cloudstart%60)>=10) x=38;
else x=44;
ReefAngel.LCD.DrawText(COLOR_RED,255,x,16,(cloudstart%60));
}
ReefAngel.LCD.DrawText(COLOR_GREEN,255,62,40,cloudduration);
if (lightningchance)
{
int x=0;
if (((cloudstart+(cloudduration/2))/60)>=10) x=95;
else x=101;
ReefAngel.LCD.DrawText(COLOR_PURPLE,255,x,16,((cloudstart+(cloudduration/2))/60));
if (((cloudstart+(cloudduration/2))%60)>=10) x=113;
else x=119;
ReefAngel.LCD.DrawText(COLOR_PURPLE,255,x,16,((cloudstart+(cloudduration/2))%60));
}
}
}

byte ReversePWMSlope(long cstart,long cend,byte PWMStart,byte PWMEnd, byte clength)
{
long n=elapsedSecsToday(now());
cstart*=60;
cend*=60;
if (n<cstart) return PWMStart;
if (n>=cstart && n<=(cstart+clength)) return map(n,cstart,cstart+clength,PWMStart,PWMEnd);
if (n>(cstart+clength) && n<(cend-clength)) return PWMEnd;
if (n>=(cend-clength) && n<=cend) return map(n,cend-clength,cend,PWMEnd,PWMStart);
if (n>cend) return PWMStart;
}
Sincerely, Brennyn
CASPAR
Posts: 56
Joined: Wed May 09, 2012 12:24 pm

Re: CODE CHECK

Post by CASPAR »

Thanks brennyn21, how could i add the code for ATO ? My screen display shows the ATO high and lo for the float switches and they alternate when the floats move up and down. They were actually in the sump when i had saltwater setup, but now are still connected but no longer in a sump. I am currently converting to a large FW tank and am gonna use the RA+ to control it. Also when i verify the code above you tweaked i get this error ReefAngel.FeedingModeStart(); REEF ANGEL was not declared in this scope. Any help appreciated
Image
CASPAR
Posts: 56
Joined: Wed May 09, 2012 12:24 pm

Re: CODE CHECK

Post by CASPAR »

This part is in the code above and is what's probably making the display show a change when the floats are moved up or down

if (ReefAngel.HighATO.IsActive())
ReefAngel.LCD.FillCircle(57,122,3,COLOR_RED);
else
ReefAngel.LCD.FillCircle(57,122,3,COLOR_GREEN);

if (ReefAngel.LowATO.IsActive())
ReefAngel.LCD.FillCircle(70,122,3,COLOR_RED);
else
ReefAngel.LCD.FillCircle(70,122,3,COLOR_GREEN);
Image
User avatar
brennyn21
Posts: 122
Joined: Mon Nov 23, 2020 5:40 pm

Re: CODE CHECK

Post by brennyn21 »

Yes that is correct!
Sincerely, Brennyn
CASPAR
Posts: 56
Joined: Wed May 09, 2012 12:24 pm

Re: CODE CHECK

Post by CASPAR »

What about the error i mentioned?
Image
User avatar
brennyn21
Posts: 122
Joined: Mon Nov 23, 2020 5:40 pm

Re: CODE CHECK

Post by brennyn21 »

Make sure you are using the online webwizard. forum.reefangel.com/webwizard
I tried compiling the code and it compiled fine.

As for adding the ATO you can use this line below. Place it in the void loop()
Please change the port to your liking and the 65 is timeout in seconds. so change it to your liking

Code: Select all

ReefAngel.StandardATO( Port1,65 );
Let me know if you have any other issues
Sincerely, Brennyn
CASPAR
Posts: 56
Joined: Wed May 09, 2012 12:24 pm

Re: CODE CHECK

Post by CASPAR »

For the ATO, is that the code i would use if i have both a low level float and a high level float?
Image
User avatar
brennyn21
Posts: 122
Joined: Mon Nov 23, 2020 5:40 pm

Re: CODE CHECK

Post by brennyn21 »

Yes that is the code for using both float switches
Sincerely, Brennyn
CASPAR
Posts: 56
Joined: Wed May 09, 2012 12:24 pm

Re: CODE CHECK

Post by CASPAR »

BRENNYN21,
LOOKING AT MY CODE ABOVE, WHAT ARE MY OPTIONS AS FAR AS CHANGING THE LIGHTING EFFECT FOR THE STORM? I.E. FLASHES, DIMMING ETC ETC WOULD LIKE TO KNOW IF I COULD GET IT TO KIND OF RAMP DOWN THEN GO INTO STORM MODE IF POSSIBLE THEN RAMP BACK TO NORMAL AS IF STORM HAS PASSED.
Image
Post Reply