My almost completed pde

Share you PDE file with our community
User avatar
JNieuwenhuizen
Posts: 96
Joined: Thu Feb 16, 2012 12:39 am
Location: South Africa

Re: My almost completed pde

Post by JNieuwenhuizen »

Hi Roberto.

I have had no change to have a look at this, will do sometime today or tommorow.

For anyone else interrested, I have posted the code.

I have to split it into 2 posts, as its big.

Does the "bool fOverrideRF = false;" not need to be "boolean fOverrideRF = false;"

First Half :

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 <ReefAngel.h>
#include <avr/pgmspace.h>>
//***************************************************************************************************************************************************************************
//-------------------------------------------------------------------------- Screen set-up ---------------------------------------------------------------------------------
#define NumScreens 7
int ScreenID=0;
//***************************************************************************************************************************************************************************
//---------------------------------------------------------------------------- PWM Cloud -----------------------------------------------------------------------------------
boolean ForceCloud=false;
boolean ForceLightning=false;
//
//***************************************************************************************************************************************************************************
//--------------------------------------------------------------------------- PWM Channels ----------------------------------------------------------------------------------
#define LEDWhiteBlue  0
#define LEDWhiteBlue1 1
#define LEDWhiteBlue2 2
#define LEDWhiteBlue3 3
#define MixedLED 4
#define LEDMoonlights 5
//***************************************************************************************************************************************************************************
//--------------------------------------------------------------------- Start of Global Variables ---------------------------------------------------------------------------
byte ChannelValue[]=
{
    0,0,0,0,0,0
};
byte SeasonsVar[]=
{
    0,0,0,0,0,0
};
byte MoonPWMValue;
byte vtechmode = 0;
bool fOverrideRF = false;
byte DayAge;
byte ThisPhase;
int JulianDate(int,int,int);
double MoonAge(int,int,int);
byte MoonState();
boolean bFeeding=false;
byte x,y;
int maxTemp=0;
int minTemp=2000;
int maxPH=600;
int minPH=900;
char text[10];
int v;
int moonlight=0;
long calcSec(long,long);
long calcTime(long,long);
short Ndays;
int rhour = 0, rmin = 0, shour = 0, smin = 0;
byte TempRelay =15;
byte TempRelay2=15;
static byte lightningchance=0;
byte cloudduration=0;
int cloudstart=0;
//***************************************************************************************************************************************************************************
//----------------------------------------------------------------------- Custom Menu Code ----------------------------------------------------------------------------------
prog_char menu1_label[] PROGMEM = "Food!!";
prog_char menu2_label[] PROGMEM = "Cleanup";
prog_char menu3_label[] PROGMEM = "ATO Clear";
prog_char menu4_label[] PROGMEM = "Force Storm";
prog_char menu5_label[] PROGMEM = "PH Calibration";
prog_char menu6_label[] PROGMEM = "Salty Calibration";
prog_char menu7_label[] PROGMEM = "Vortech Modes";
prog_char menu8_label[] PROGMEM = "Sump On";
prog_char menu9_label[] PROGMEM = "Sumo Off";

void MenuEntry1()
{
    ReefAngel.FeedingModeStart();
}
void MenuEntry2()
{
    ReefAngel.WaterChangeModeStart();
}
void MenuEntry3()
{
    ReefAngel.ATOClear();
    ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
}
void MenuEntry4()
{
    ForceCloud=true;
    ForceLightning=true;
    ReefAngel.DisplayedMenu=RETURN_MAIN_MODE;
}
void MenuEntry5()
{
    ReefAngel.SetupCalibratePH();
    ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry6()
{
    ReefAngel.SetupCalibrateSalinity();
    ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry7()
{
    // TODO complete this function
    /*
    Need to have an override variable inside the loop that forces a specific mode whenever
    the menu is toggled.  This should mimic the PWM override.
    */
    /*
    Cycle through the modes.
    Use the Internal Memory values OR create a switch statement that has default values
    for Speed and Duration based on the modes being switched to.
    Once at the end of the modes,
        return to constant mode (begining)
        resume normal operations
    */
    fOverrideRF = true;
    vtechmode++;
    if ( vtechmode == 7 ) vtechmode = 9;
    if ( vtechmode > 9 ) { vtechmode = 0; fOverrideRF = false; }
    // 1st parameter is Mode, 2nd is speed, 3rd is duration
    ReefAngel.RF.SetMode(vtechmode, InternalMemory.RFSpeed_read(), InternalMemory.RFDuration_read());
    ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
}
void MenuEntry8()
{
ReefAngel.Relay.RelayMaskOn = ReefAngel.LightsOnPorts;
#ifdef RelayExp
for ( byte i = 0; i < MAX_RELAY_EXPANSION_MODULES; i++ )
{
    ReefAngel.Relay.RelayMaskOnE[i] = ReefAngel.LightsOnPortsE[i];
}
#endif  // RelayExp
ReefAngel.Relay.Write();
}

void MenuEntry9()
{
ReefAngel.Relay.RelayMaskOn = 0;
#ifdef RelayExp
for ( byte i = 0; i < MAX_RELAY_EXPANSION_MODULES; i++ )
{
    ReefAngel.Relay.RelayMaskOnE[i] = 0;
}
#endif  // RelayExp
ReefAngel.Relay.Write();
}
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------- Grouped Menu Entries ----------------------------------------------------------------------------
PROGMEM const char *menu_items[] =
{
    menu1_label, menu2_label, menu3_label,
    menu4_label, menu5_label, menu6_label,
    menu7_label,menu8_label,menu9_label
};
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------- Custom Main -------------------------------------------------------------------------------
void DrawCircleOutline(byte x, byte y, byte radius, byte bordercolor);
void FillCircle(byte x, byte y, byte radius, byte fillcolor);
void DrawCircleOutletBox(byte x, byte y, byte RelayData, bool reverse = false);
//***************************************************************************************************************************************************************************
//-------------------------------------------------------------------------- Analog Clock constants -------------------------------------------------------------------------
const float pi = 3.141592653;
byte clock_center_x = 65;
byte clock_center_y = 65;
byte clock_radius = 55;
byte secondhand_radius = 33;
float secondangle;
byte secondend_x;
byte secondend_y;
float minuteangle;
float hourangle;
//***************************************************************************************************************************************************************************
//--------------------------------------------------------------------------- Analog Clock Structure ------------------------------------------------------------------------
int minutebase_radius = 3;
int minutehand_radius = 33;
int hourbase_radius = 3;
int hourhand_radius = 25;
int seconds_hand_x, seconds_hand_y, minutes_hand_x, minutes_hand_y, hours_hand_x, hours_hand_y;
int hours_hand_base_x, hours_hand_base_y, hours_hand_base_x1, hours_hand_base_y1;
int minutes_hand_base_x, minutes_hand_base_y, minutes_hand_base_x1, minutes_hand_base_y1;
int minutebase_x, minutebase_y, minutebase_x1, minutebase_y1;
int minuteend_x, minuteend_y;
int hourbase_x, hourbase_y, hourbase_x1, hourbase_y1;
int hourend_x, hourend_y;
float minfloat;
//***************************************************************************************************************************************************************************
//--------------------------------------------------------------------------------Time Stamp --------------------------------------------------------------------------------
time_t tsmax=now();
time_t tsmin=now();
time_t PHmax=now();
time_t PHmin=now();
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------ Draw Minutes Hand --------------------------------------------------------------------------
void draw_minute(int color)
{
    Drawline(minutebase_x, minutebase_y, minutebase_x1, minutebase_y1, color);
    Drawline(minutebase_x, minutebase_y, minuteend_x, minuteend_y, color);
    Drawline(minutebase_x1, minutebase_y1, minuteend_x, minuteend_y, color);
}
//***************************************************************************************************************************************************************************
//--------------------------------------------------------------------------- Draw Hour Hand --------------------------------------------------------------------------------
void draw_hour(int color)
{
    Drawline(hourbase_x, hourbase_y, hourbase_x1, hourbase_y1, color);
    Drawline(hourbase_x, hourbase_y, hourend_x, hourend_y, color);
    Drawline(hourbase_x1, hourbase_y1, hourend_x, hourend_y, color);
}
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------ Draw Line ----------------------------------------------------------------------------------
void Drawline (int x0, int y0, int x1, int y1, int color)
{
    int dy = y1 - y0;
    int dx = x1 - x0;
    int stepx, stepy;
    if (dy < 0)
    {
        dy = -dy;
        stepy = -1;
    }
    else
    {
        stepy = 1;
    }
    if (dx < 0)
    {
        dx = -dx;
        stepx = -1;
    }
    else
    {
        stepx = 1;
    }
    dy <<= 1; // dy is now 2*dy
    dx <<= 1; // dx is now 2*dx
    ReefAngel.LCD.PutPixel(color, x0, y0);
    if (dx > dy)
    {
        int fraction = dy - (dx >> 1); // same as 2*dy - dx
        while (x0 != x1)
        {
            if (fraction >= 0)
            {
                y0 += stepy;
                fraction -= dx; // same as fraction -= 2*dx
            }
            x0 += stepx;
            fraction += dy; // same as fraction -= 2*dy
            ReefAngel.LCD.PutPixel(color, x0, y0);
        }
    }
    else
    {
        int fraction = dx - (dy >> 1);
        while (y0 != y1)
        {
            if (fraction >= 0)
            {
                x0 += stepx;
                fraction -= dy;
            }
            y0 += stepy;
            fraction += dx;
            ReefAngel.LCD.PutPixel(color, x0, y0);
        }
    }
}
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------ Draw Time ----------------------------------------------------------------------------------
void DrawTime(byte x, byte y, byte FGcolor, byte BGcolor, time_t ts)
{
    char text[13];
    char temp[]="  ";
    strcpy(text,"");
    itoa(hourFormat12(ts),temp,10);
    if (temp[1]==0) strcat(text,"0");
    strcat(text,temp);
    strcat(text,":");
    itoa(minute(ts),temp,10);
    if (temp[1]==0) strcat(text,"0");
    strcat(text,temp);
    strcat(text,":");
    itoa(second(ts),temp,10);
    if (temp[1]==0) strcat(text,"0");
    strcat(text,temp);
    if (isAM(ts))
    {
        strcat(text," AM");
    }
    else
    {
        strcat(text," PM");
    }
    ReefAngel.LCD.DrawText(FGcolor, BGcolor, x, y, text);
}
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------ Draw Circle --------------------------------------------------------------------------------
void DrawCircle(int a, int b, int r, byte color)
{
    int f = 1 - r;
    int ddF_x = 1;
    int ddF_y = -2 * r;
    int x = 0;
    int y = r;

    ReefAngel.LCD.PutPixel(color, a, b+r);
    ReefAngel.LCD.PutPixel(color ,a, b-r);
    ReefAngel.LCD.PutPixel(color, a+r, b);
    ReefAngel.LCD.PutPixel(color, a-r, b);
    while (x<y)
    {
        if (f >= 0)
        {
            y--;
            ddF_y += 2;
            f += ddF_y;
        }
        x++;
        ddF_x += 2;
        f += ddF_x;

        ReefAngel.LCD.PutPixel(color, a + x, b + y);
        ReefAngel.LCD.PutPixel(color, a - x, b + y);
        ReefAngel.LCD.PutPixel(color, a + x, b - y);
        ReefAngel.LCD.PutPixel(color, a - x, b - y);
        ReefAngel.LCD.PutPixel(color, a + y, b + x);
        ReefAngel.LCD.PutPixel(color, a - y, b + x);
        ReefAngel.LCD.PutPixel(color, a + y, b - x);
        ReefAngel.LCD.PutPixel(color, a - y, b - x);
    }
}
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------ Draw Weekly ------------------------------------------------------------------------------
void DrawWeeklyAvg (byte hr, int sensor, byte color, byte x, byte y, byte z)
{
    const int numReadings = 7;
    int dailyread;
    int readings[numReadings];      // the readings from the analog input
    int index = 0;                  // the index of the current reading
    int total = 0;                  // the running total
    int average = 0;                // the average
    if (hour()==hr && minute()==0 && second()==0)
    {
        dailyread=sensor;
        total= total - readings[index];   // subtract the last reading:
        readings[index] = dailyread;   // read from the sensor:
        total= total + readings[index];   // add the reading to the total:
        index = index + 1;  // advance to the next position in the array:
        if (index >= numReadings)     // if we're at the end of the array...
            index = 0;       // ...wrap around to the beginning:
        average = total / numReadings;    // calculate the average:
        delay (1000);
        ReefAngel.LCD.DrawSingleMonitor(average, color, x, y, z);
    }
}
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------ Draw Daily ---------------------------------------------------------------------------------
void DrawDailyAvg (int sensor, byte color, byte x, byte y, byte z)
{
    const int numReadings = 24;
    int dailyread;
    int readings[numReadings];      // the readings from the analog input
    int index = 0;                  // the index of the current reading
    int total = 0;                  // the running total
    int average = 0;                // the average
    if (minute()==0 && second()==0)
    {
        dailyread=sensor;
        total= total - readings[index];   // subtract the last reading:
        readings[index] = dailyread;   // read from the sensor:
        total= total + readings[index];   // add the reading to the total:
        index = index + 1;  // advance to the next position in the array:
        if (index >= numReadings)     // if we're at the end of the array...
            index = 0;       // ...wrap around to the beginning:
        average = total / numReadings;    // calculate the average:
        delay (1000);
        ReefAngel.LCD.DrawSingleMonitor(average, color, x, y, z);
    }
}

void DrawCustomMain()
{
    // Refresh is called at start of ShowInterface.
    // ShowInterface calls DrawCustomMain
    switch (ScreenID)
    {
//---------------------------------------------------------------------------- Screen Code 1--------------------------------------------------------------------------------
        case 0:

            //Top Banner
            ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank   ", Font8x8); //Top Banner
            // Display T1 Header Text
            ReefAngel.LCD.DrawLargeText(COLOR_STEELBLUE,255,5,15,"Sump Temp", Font8x8);
            // Display the T1 Temp Value
            char text[7];
            ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
            ReefAngel.LCD.Clear(255, 10, 25, 50, 60);
            if (ReefAngel.Params.Temp[T1_PROBE]>270) ReefAngel.LCD.DrawHugeNumbers(COLOR_RED, 255, 10, 25, text);
            else if (ReefAngel.Params.Temp[T1_PROBE]>270) ReefAngel.LCD.DrawHugeNumbers(COLOR_ORANGE, 255, 10, 25, text);
            else ReefAngel.LCD.DrawHugeNumbers(COLOR_MIDNIGHTBLUE, 255, 10, 25, text);
            // Display the T2 Header Text
            ReefAngel.LCD.DrawLargeText(0,255,5,45,"Room Temp", Font8x8);
            // Display the T2 Temp Value
            ReefAngel.LCD.Clear(255, 90, 50, 132, 60);
            ConvertNumToString(text, ReefAngel.Params.Temp[T2_PROBE], 10);
            ReefAngel.LCD.DrawLargeText(COLOR_MIDNIGHTBLUE, 255, 90, 45, text, Num8x8);
            // Display pH Header Text
            ReefAngel.LCD.DrawLargeText(COLOR_LIMEGREEN,255,95,15,"pH", Font8x8);
            // Display pH Value
            ConvertNumToString(text, ReefAngel.Params.PH, 100); // check code
            ReefAngel.LCD.Clear(0, 65, 62 , 65, 62);
            if (ReefAngel.Params.PH>840 || ReefAngel.Params.PH<790) ReefAngel.LCD.DrawLargeText(COLOR_RED, 255, 85, 25, text, Num8x8);
            else if (ReefAngel.Params.PH>830 || ReefAngel.Params.PH<800) ReefAngel.LCD.DrawLargeText(COLOR_ORANGE, 255, 85, 25, text, Num8x8);
            else ReefAngel.LCD.DrawLargeText(COLOR_MIDNIGHTBLUE, 255, 85, 25, text, Num8x8);
            // Display Vortech Mode
            ReefAngel.LCD.DrawLargeText(0,255,5,55,"Vortech", Font8x8);
            // Display EcoSmart Mode Value
            ReefAngel.LCD.Clear(255, 66, 60, 132, 70);
            if (vtechmode == 0) ReefAngel.LCD.DrawLargeText(COLOR_LIMEGREEN,255, 66, 55,"Constant");
            else if(vtechmode == 1) ReefAngel.LCD.DrawLargeText(COLOR_GOLD,255, 66, 55,"Lagoon");
            else if (vtechmode == 2) ReefAngel.LCD.DrawLargeText(COLOR_GOLD,255, 80, 55,"RCM");
            else if (vtechmode == 3) ReefAngel.LCD.DrawLargeText(COLOR_CORNFLOWERBLUE,255, 80, 55,"Short");
            else if (vtechmode == 4) ReefAngel.LCD.DrawLargeText(COLOR_PINK,255, 66, 55,"Long");
            else if (vtechmode == 5) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255, 80, 55,"NTM");
            else if (vtechmode == 6) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255, 80, 55,"TSM");
            else if (vtechmode == 9) ReefAngel.LCD.DrawLargeText(COLOR_GRAY,255, 80, 55,"Night");
// Display Salinity
            ReefAngel.LCD.DrawLargeText(0,255,64,114,"Salinity", Font8x8);
// Display Salinity Value
            ReefAngel.LCD.Clear(255, 82, 85, 65, 95);
            ConvertNumToString(text, ReefAngel.Params.Salinity, 10);
            ReefAngel.LCD.DrawLargeText(COLOR_LIMEGREEN, 255, 85, 122, text, Num8x8);
//Start Moon Phase,Cloud or Storm Display
            SeasonsVar[0]=ChannelValue[LEDWhiteBlue];
            SeasonsVar[1]=rhour;
            SeasonsVar[2]=rmin;
            SeasonsVar[3]=shour;
            SeasonsVar[4]=smin;
            SeasonsVar[5]=cloudstart/60;
            SeasonsVar[6]=cloudstart%60;
            SeasonsVar[7]=cloudduration;
            SeasonsVar[8]=lightningchance;
            SeasonsVar[9]=ChannelValue[LEDWhiteBlue1];
            SeasonsVar[10]=ChannelValue[LEDWhiteBlue2];
            SeasonsVar[11]=ChannelValue[LEDWhiteBlue3];
            SeasonsVar[12]=ChannelValue[MixedLED];
            SeasonsVar[13]=ChannelValue[LEDMoonlights];
//Start Moon Phase,Cloud or Storm Display
            if (SeasonsVar[13] > 0)//if moon phase is active display state and pwm %
            {
                DayAge = MoonAge(day(), month(), year());
                MoonState(DayAge);
                char* ThisPhaseLabel[]= {"New","Waxing C","First Q","Waxing G","Full","Waning G","Last Q","Waning C"};
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,70,105,ThisPhaseLabel[ThisPhase]);
            }
            else if (SeasonsVar[5] > 0) //or if there is a cloud display clouds instead
            {
                if (SeasonsVar[8] > 0) ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,60,85, "Storm"); //decide between dislaying storm or cloud based on lightningchance
                else ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,95,85,"Cloud");
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,60,95, SeasonsVar[5]);
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,75,94, ":");
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,80,95, SeasonsVar[6]);
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,93,95,"Lnt");
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,113,95, SeasonsVar[7]);
            }
            else if (hour() >8 || hour() <14 && SeasonsVar[5,6,7] <= 0)
            {
                ReefAngel.LCD.DrawLargeText(COLOR_ORANGERED,255,3,65, "Sunrise",Font8x8);
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,3,75, SeasonsVar[0]);
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,20,74, ":");
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,24,75, SeasonsVar[9]);
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,41,74, ":");
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,45,75, SeasonsVar[10]);
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,66,75, "|");
            }
            else if (hour() >14 || hour() <22 && SeasonsVar[5,6,7] <=0)
            {
                ReefAngel.LCD.DrawLargeText(COLOR_ORANGE,255,75,65, "Sunset",Font8x8);
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,70,75, SeasonsVar[0]);
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,87,74, ":");
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,91,75, SeasonsVar[9]);
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,108,74, ":");
                ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,112,75, SeasonsVar[10]);
            }
            //End Display Moon Phase Display

            // Display Main and Expansion Relay Box
            TempRelay = ReefAngel.Relay.RelayData;
            TempRelay &= ReefAngel.Relay.RelayMaskOff;
            TempRelay |= ReefAngel.Relay.RelayMaskOn;
            ReefAngel.LCD.DrawCircleOutletBox(10,90, TempRelay);
            pingSerial();

            TempRelay2 = ReefAngel.Relay.RelayDataE[0];
            TempRelay2 &= ReefAngel.Relay.RelayMaskOffE[0];
            TempRelay2 |= ReefAngel.Relay.RelayMaskOnE[0];
            ReefAngel.LCD.DrawCircleOutletBox(40,90, TempRelay2);
            pingSerial();
            break;
//***************************************************************************************************************************************************************************
//---------------------------------------------------------------------------- Screen Code 2---------------------------------------------------------------------------------
        case 1:  //Temperature detail screen with sump and room temp, 24 hr. max/min, time stamps, and graph
            ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank ", Font8x8); //Top Banner
            ReefAngel.LCD.DrawLargeText(0,255,10,15,"Temp Details", Font8x8);
            ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,33,"Sump:");
            ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T1_PROBE], COLOR_BLACK, 36, 33, 10);
            ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,43,"HI:");
            ReefAngel.LCD.DrawSingleMonitor(maxTemp, 0, 23, 43, 10);
            ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,48,43,"at");
            DrawTime(60,43,0, COLOR_WHITE,tsmax);
            ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,53,"LO:");
            ReefAngel.LCD.DrawSingleMonitor(minTemp, 0, 23, 53, 10);
            ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,48,53,"at");
            DrawTime(60,53,0,COLOR_WHITE, tsmin);
            ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,63,"Range:");
            ReefAngel.LCD.DrawSingleMonitor((maxTemp-minTemp), COLOR_BLACK, 46, 63, 10);
            ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,69,63,"Degrees C");
            ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,73,"Avg:");
            DrawDailyAvg(ReefAngel.Params.Temp[T1_PROBE], COLOR_BLACK, 43, 73, 1);
            ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,83,"WeeklyAvg:");
            DrawWeeklyAvg(12,ReefAngel.Params.Temp[T1_PROBE], COLOR_BLACK, 66, 83, 1);
            ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor, 86,83,"at noon");
            ReefAngel.LCD.DrawText(T2TempColor,DefaultBGColor, 5 ,93,"Room:");
            ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T2_PROBE], COLOR_BLACK, 36, 93, 10);
            break;

//***************************************************************************************************************************************************************************
//---------------------------------------------------------------------------- Screen Code 3---------------------------------------------------------------------------------
        case 2:  //pH details
            ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank ", Font8x8); //Top Banner
            ReefAngel.LCD.DrawLargeText(0,255,20,15,"pH Details", Font8x8);
            ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,33,"pH:");
            ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.PH, COLOR_BLACK, 36, 33, 100);
            ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,43,"HI:");
            ReefAngel.LCD.DrawSingleMonitor(maxPH, 0, 23, 43, 100);
            ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,48,43,"at");
            DrawTime(60,43,0, COLOR_WHITE,PHmax);
            ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,53,"LO:");
            ReefAngel.LCD.DrawSingleMonitor(minPH, 0, 23, 53, 100);
            ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,48,53,"at");
            DrawTime(60,53,0,COLOR_WHITE, PHmin);
            ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,63,"Range:");
            ReefAngel.LCD.DrawSingleMonitor((maxPH-minPH), COLOR_BLACK, 46, 63, 100);
            ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,73,"Avg:");
            DrawDailyAvg(ReefAngel.Params.PH, COLOR_BLACK, 43, 73, 100);
            ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,83,"WeeklyAvg:");
            DrawWeeklyAvg(12,ReefAngel.Params.PH, COLOR_BLACK, 66, 83, 100);
            ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 86,83,"at noon");
            ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,93,"WeeklyAvg:");
            DrawWeeklyAvg(0,ReefAngel.Params.PH, COLOR_BLACK, 66, 93, 100);
            ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 86,93,"at midnt");
            break;
//***************************************************************************************************************************************************************************
//---------------------------------------------------------------------------- Screen Code 4---------------------------------------------------------------------------------
        case 3:  //relay box key
            ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank ", Font8x8); //Top Banner
            TempRelay = ReefAngel.Relay.RelayData;
            TempRelay &= ReefAngel.Relay.RelayMaskOff;
            TempRelay |= ReefAngel.Relay.RelayMaskOn;
            ReefAngel.LCD.DrawCircleOutletBox(56,46,TempRelay);
            pingSerial();
            ReefAngel.LCD.DrawLargeText(0,255,27,20,"RelayBox 1", Font8x8);
            ReefAngel.LCD.DrawLargeText(0,255,3,44,"LDFan", Font8x8); //1
         // ReefAngel.LCD.DrawLargeText(0,255,7,54,"ATU", Font8x8); //3
            ReefAngel.LCD.DrawLargeText(0,255,7,64,"ATU", Font8x8); //5
            ReefAngel.LCD.DrawLargeText(0,255,7,74,"Salty", Font8x8); //7
            ReefAngel.LCD.DrawLargeText(0,255,75,44,"Skimer", Font8x8);  //2
            ReefAngel.LCD.DrawLargeText(0,255,75,54,"Reactr", Font8x8);  //4
            ReefAngel.LCD.DrawLargeText(0,255,75,64,"Heatr", Font8x8); //6
            ReefAngel.LCD.DrawLargeText(0,255,75,74,"Relay", Font8x8);  //8
            break;
//***************************************************************************************************************************************************************************
//---------------------------------------------------------------------------- Screen Code 5---------------------------------------------------------------------------------
        case 4:  //relay box key
            ReefAngel.Refresh();
            ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank ", Font8x8); //Top Banner
            TempRelay2 = ReefAngel.Relay.RelayDataE[0];
            TempRelay2 &= ReefAngel.Relay.RelayMaskOffE[0];
            TempRelay2 |= ReefAngel.Relay.RelayMaskOnE[0];
            ReefAngel.LCD.DrawCircleOutletBox(56,46,TempRelay2);
            pingSerial();
            ReefAngel.LCD.DrawLargeText(0,255,27,20,"RelayBox 2", Font8x8);
            ReefAngel.LCD.DrawLargeText(0,255,7,44,"VTech", Font8x8);//1
            ReefAngel.LCD.DrawLargeText(0,255,3,54,"Return", Font8x8);//3
         // ReefAngel.LCD.DrawLargeText(0,255,7,64,"Day1", Font8x8);//5
         // ReefAngel.LCD.DrawLargeText(0,255,7,74,"Day3", Font8x8);//7
            ReefAngel.LCD.DrawLargeText(0,255,75,44,"VTech", Font8x8);//2
            ReefAngel.LCD.DrawLargeText(0,255,75,54,"SumpL", Font8x8);//4
         // ReefAngel.LCD.DrawLargeText(0,255,75,64,"Day2", Font8x8);//6
            ReefAngel.LCD.DrawLargeText(0,255,75,74,"LED", Font8x8);//8
            break;
//***************************************************************************************************************************************************************************
//---------------------------------------------------------------------------- Screen Code 6---------------------------------------------------------------------------------
        case 5:  //setclock
            // Analog clock is modified from the original source by Jeff Miller
            // Author: Jeff Miller   http://arduinofun.blogspot.com/
            ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank ", Font8x8); //Top Banner
            // Frame
            DrawCircle(clock_center_x, clock_center_y, clock_radius, COLOR_CORNFLOWERBLUE);
            DrawCircle(clock_center_x, clock_center_y, clock_radius - 1, COLOR_CORNFLOWERBLUE);
            DrawCircle(clock_center_x, clock_center_y, clock_radius - 2, COLOR_CORNFLOWERBLUE);
            // Face Tick Marks  (x = r cos theta, y = r sin theta)
            for (byte r=0; r < 12; r++)
            {
                float angle = (2 * pi / 12)*r;
                int tick_x_out = (clock_radius - 8) * cos (angle) + clock_center_x;
                int tick_y_out = (clock_radius - 8) * sin (angle) + clock_center_y;
                int tick_x_in = clock_radius *.72 * cos (angle) + clock_center_x;
                int tick_y_in = clock_radius * .72 * sin (angle) + clock_center_y;
                Drawline(tick_x_in, tick_y_in, tick_x_out, tick_y_out, COLOR_CORNFLOWERBLUE);
            }
            // Face Characters
            ReefAngel.LCD.DrawLargeText(0,255,clock_center_x - 8,106," 6", Font8x8);
            ReefAngel.LCD.DrawLargeText(0,255,clock_center_x - 8, 25,"12", Font8x8);
            ReefAngel.LCD.DrawLargeText(0,255,clock_center_x + 34,clock_center_y," 3", Font8x8);
            ReefAngel.LCD.DrawLargeText(0,255,clock_center_x - 50, clock_center_y - 4,"9 ", Font8x8);
            // Draw Seconds Hand
            secondangle = (2 * pi / 60) * second();
            if (second() > 15)
            {
                secondangle = secondangle -1.57;
            }
            else
            {
                secondangle = secondangle +4.71;
            }
            Drawline(clock_center_x, clock_center_y, secondend_x, secondend_y, WHITE);
            secondend_x = secondhand_radius * cos (secondangle) + clock_center_x;
            secondend_y = secondhand_radius * sin (secondangle) + clock_center_y;
            Drawline(clock_center_x, clock_center_y, secondend_x, secondend_y, BLACK);
// Redraw minutes hand since the section closest to the center gets erased by the seconds hand
            draw_minute(BLACK);
// Redraw hour hand
            draw_hour(BLACK);
// Draw Minutes Hand
            minuteangle = (2 * pi / 60) * minute();
            if (minute() > 15)
            {
                minuteangle = minuteangle -1.57;
            }
            else
            {
                minuteangle = minuteangle +4.71;
            }
            // Erase old minutes Hand
            draw_minute(WHITE);
            // Calculate Minute Hand Base
            minutebase_x = minutebase_radius * cos (minuteangle - pi/2) + clock_center_x;
            minutebase_y = minutebase_radius * sin (minuteangle - pi/2) + clock_center_y;
            minutebase_x1 = minutebase_radius * cos (minuteangle + pi/2) + clock_center_x;
            minutebase_y1 = minutebase_radius * sin (minuteangle + pi/2) + clock_center_y;
// Calculate Minute Hand Point
            minuteend_x = minutehand_radius * cos (minuteangle) + clock_center_x;
            minuteend_y = minutehand_radius * sin (minuteangle) + clock_center_y;
// Draw new minutes Hand
            draw_minute(BLACK);
// Redraw hour hand
            draw_hour(BLACK);
// Draw Hour Hand
            minfloat = minute(); // Convert minute short to float
            hourangle = (2 * pi / 12) * ((hourFormat12()) + (minfloat/60)); // Find angle for hour hand
            hourangle = hourangle -1.57;
// Erase old Hour Hand
            draw_hour(WHITE);
// Calculate hour Hand Base
            hourbase_x = hourbase_radius * cos (hourangle - pi/2) + clock_center_x;
            hourbase_y = hourbase_radius * sin (hourangle - pi/2) + clock_center_y;
            hourbase_x1 = hourbase_radius * cos (hourangle + pi/2) + clock_center_x;
            hourbase_y1 = hourbase_radius * sin (hourangle + pi/2) + clock_center_y;
// Calculate hour Hand Point
            hourend_x = hourhand_radius * cos (hourangle) + clock_center_x;
            hourend_y = hourhand_radius * sin (hourangle) + clock_center_y;
// Draw new hours Hand
            draw_hour(BLACK);
            ReefAngel.LCD.DrawDate(5,121);
            break;
//***************************************************************************************************************************************************************************
//---------------------------------------------------------------------------- Screen Code 7---------------------------------------------------------------------------------
        case 6: // Vortech Setup
            ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank ", Font8x8); //Top Banner
            ReefAngel.LCD.DrawText(0,255,20,50,"Assigning Slaves");
            ReefAngel.RF.SetMode(Slave_Start,0,0);
            if (ReefAngel.Joystick.IsButtonPressed())
            {
                ReefAngel.RF.SetMode(Slave_Stop,0,0);
                ReefAngel.LCD.DrawText(0,255,50,60,"Done");
            }
            break;

    }
}

void DrawCustomGraph()
{}

//***************************************************************************************************************************************************************************
Last edited by JNieuwenhuizen on Sat May 12, 2012 9:08 am, edited 1 time in total.
User avatar
JNieuwenhuizen
Posts: 96
Joined: Thu Feb 16, 2012 12:39 am
Location: South Africa

Re: My almost completed pde

Post by JNieuwenhuizen »

Second Half:

Code: Select all

//------------------------------------------------------------------------------ Begin Setup --------------------------------------------------------------------------------
void setup()
{
    ReefAngel.Init();  //Initialize controller
    ReefAngel.Timer[LCD_TIMER].SetInterval(180);
    ReefAngel.Timer[LCD_TIMER].Start();  // start timer
    ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));
    ReefAngel.SetTemperatureUnit(1);
    ReefAngel.FeedingModePorts = 0;
    ReefAngel.WaterChangePorts = Port1Bit | Port2Bit | Port3Bit | Port6Bit | Box1_Port1 | Box1_Port2;
    ReefAngel.OverheatShutoffPorts = Port6Bit;
    ReefAngel.LightsOnPorts = Box1_Port4;
//------------------------------------------------------------------------- Ports that are always on ------------------------------------------------------------------------
  ReefAngel.Relay.On(Port1);
  ReefAngel.Relay.On(Port4);
  ReefAngel.Relay.On(Port7);
  ReefAngel.Relay.On(Port8);
  ReefAngel.Relay.On(Box1_Port1);
  ReefAngel.Relay.On(Box1_Port2);
  ReefAngel.Relay.On(Box1_Port3);
  ReefAngel.Relay.On(Box1_Port8);
}
//***************************************************************************************************************************************************************************
void loop()
{
    CheckCloud();
//--------------------------------------------------------------------------- Specific Functions ----------------------------------------------------------------------------
    ReefAngel.Relay.DelayedOn(Port2, 2);
    ReefAngel.Relay.DelayedOn(Box1_Port1, 2);
    ReefAngel.Relay.DelayedOn(Box1_Port2, 2);
    ReefAngel.StandardATO(Port5);
    ReefAngel.StandardHeater(Port6);
    ReefAngel.MoonLights(Box1_Port4);//SumpLight
    ReefAngel.Portal("JNieuwenhuizen","Evandre1");
    //---------------------------------------------------------------------------- PWM Channel Set -----------------------------------------------------------------------------
    ReefAngel.PWM.SetChannel(0,ChannelValue[LEDWhiteBlue]);
    ReefAngel.PWM.SetChannel(1,ChannelValue[LEDWhiteBlue1]);
    ReefAngel.PWM.SetChannel(2,ChannelValue[LEDWhiteBlue2]);
    ReefAngel.PWM.SetChannel(3,ChannelValue[LEDWhiteBlue3]);
    ReefAngel.PWM.SetChannel(4,ChannelValue[MixedLED]);
    ReefAngel.PWM.SetChannel(5,ChannelValue[LEDMoonlights]);
    
//------------------------------------------------------------------------------ Multiple Screens ----------------------------------------------------------------------------
    setTime(hour(),minute(),second(),day(),month(),year());
    // update the min & max temps and min & max ph
    if (now()%86400==0)
    {
        minTemp=ReefAngel.Params.Temp[T1_PROBE];
        maxTemp=ReefAngel.Params.Temp[T1_PROBE];
        minPH=ReefAngel.Params.PH;
        maxPH=ReefAngel.Params.PH;
    }
    if (ReefAngel.Params.Temp[T1_PROBE]<minTemp)
    {
        minTemp=ReefAngel.Params.Temp[T1_PROBE];
        tsmin=now();
    }
    if (ReefAngel.Params.Temp[T1_PROBE]>maxTemp)
    {
        maxTemp=ReefAngel.Params.Temp[T1_PROBE];
        tsmax=now();
    }
    if (ReefAngel.Params.PH<minPH)
    {
        minPH=ReefAngel.Params.PH;
        PHmin=now();
    }
    if (ReefAngel.Params.PH>maxPH)
    {
        maxPH=ReefAngel.Params.PH;
        PHmax=now();
    }
    if (ReefAngel.Joystick.IsLeft())
    {
        ReefAngel.ClearScreen(DefaultBGColor);
        ScreenID--;
    }
    if (ReefAngel.Joystick.IsRight())
    {
        ReefAngel.ClearScreen(DefaultBGColor);
        ScreenID++;
    }
    if (ScreenID<0) ScreenID=NumScreens;
    if (ScreenID>=NumScreens) ScreenID=0;

//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------- PWM Channels ------------------------------------------------------------------------------------
    if (SeasonsVar[13]=MoonPWMValue);
    MoonPWMValue=MoonPhase();
    if (hour()>=22 || hour()<=8)
        MoonPWMValue=PWMSlope(22,00,8,00,1,MoonPhase(),10,1);
    if (SeasonsVar[0]>=1) MoonPWMValue=0;
    ReefAngel.PWM.SetChannel(5,MoonPWMValue);
    ReefAngel.PWM.Expansion(LEDWhiteBlue,int(ChannelValue[LEDWhiteBlue]));
    ReefAngel.PWM.Expansion(LEDWhiteBlue1,int(ChannelValue[LEDWhiteBlue1]));
    ReefAngel.PWM.Expansion(LEDWhiteBlue2,int(ChannelValue[LEDWhiteBlue2]));
    ReefAngel.PWM.Expansion(LEDWhiteBlue3,int(ChannelValue[LEDWhiteBlue3]));
    ReefAngel.PWM.Expansion(MixedLED,int(ChannelValue[MixedLED]));
    ReefAngel.PWM.Expansion(LEDMoonlights,int(ChannelValue[LEDMoonlights]));

//------------------------------------------------------------------- End PWM Expansion Code for Slope ---------------------------------------------------------------------
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------ Start Time-of-Day Based Functions ----------------------------------------------------------------------
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These are the mode numbers for the RF Expansion Module for reference ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //#define Constant      0
    //#define Random1       1 // Lagoonal
    //#define Random2       2 // Reef Crest
    //#define ShortWave     3
    //#define LongWave      4
    //#define Smart_NTM     5 // Nutrient Transport Mode
    //#define Smart_TSM     6 // Tidal Swell Mode
    //#define Feeding_Start 7
    //#define Feeding_Stop  8
    //#define Night         9
    //#define Slave_Start   97
    //#define Slave_Stop    98
    //#define None          99
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    // RF Override
    if ( ! fOverrideRF )
    {
        // RF Mode is not being overridden, AKA Normal operation mode
//----------------------------------------------------------------- Start RF Daytime Control ------------------------------------------------------------------------------
        if (hour() >=8 && hour() <= 14)
        {
            ReefAngel.RF.UseMemory=false;
            ReefAngel.RF.SetMode(Smart_NTM,80,7);
            vtechmode = Smart_NTM;
        }
        if (hour() >=14 && hour() <= 22)
        {
            ReefAngel.RF.UseMemory=false;
            ReefAngel.RF.SetMode(Random2,60,7);
            vtechmode = Random2;
        }

//--------------------------------------------------------------- Start RF Nightmode Control -----------------------------------------------------------------------------
        if (hour()>=22 || hour()<8) // Defining "Nightmode" hours for VorTech = between 10 PM and 8 AM
        {
            ReefAngel.RF.UseMemory=false;
            ReefAngel.RF.SetMode(Night,15,0);
            vtechmode = Night;
        }
        else
        {
            ReefAngel.RF.SetMode(Feeding_Stop,0,0); //Temp fix for coming out of Night mode
            ReefAngel.RF.UseMemory=false;
            ReefAngel.RF.SetMode(Smart_NTM,80,7);
            vtechmode = Smart_NTM;
        }
    }  // if fOverrideRF

    ReefAngel.ShowInterface();
}

//***************************************************************************************************************************************************************************
//-------------------------------------------------- Random Cloud/Thunderstorm effects function -----------------------------------------------------------------------------
//------------------------------------------------------- From Roberto - THANKS ROBERTO! ------------------------------------------------------------------------------------
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_5_Days 1
    // 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 25
    // 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 3
    // Maximum number of clouds that can happen per day
#define Max_Clouds_per_Day 6
    // Only start the cloud effect after this setting
    // In this example, start could after 11:30am
#define Start_Cloud_After NumMins(12,00)
    // Always end the cloud effect before this setting
    // In this example, end could before 4:30pm
#define End_Cloud_Before NumMins(18,0)
    // 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 25
    // Channels used by the actinic LEDs on the PWM Expansion module
    // These channels will not be dimmed when the cloud effect is triggered
    // Number is a binary form. B001100 means channel 2 and 3 are used for actinics
#define Actinic_Channels B000000
    // Channels used by the daylight LEDs on the PWM Expansion module
    // These channels will be used for the spike when lightning effect is triggered
    // Number is a binary form. B000011 means channel 0 and 1 are used for daylights
#define Daylight_Channels B001000
    // 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(26);
        // 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_5_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(36);
            // 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 (cloudchance)
    {
        //is it time for cloud yet?
//is it time for cloud yet?
        if (NumMins(hour(),minute())>=cloudstart && NumMins(hour(),minute())<(cloudstart+cloudduration))
        {
            // let's go through all channels to pick which ones will be dimmed
            for (int a=0; a<6; a++)
            {
                if (bitRead(Actinic_Channels,a)==0)
                {
                    // this will slope down the channel from the current PWM to 0 within 3minutes.
                    // then it will stay at 0 for the duration of the cycle
                    // and finally slope up from 0 to PWM value within 3 minutes
                    // it is basically an inversed slope
                    ChannelValue[a]=ReversePWMSlope(cloudstart,cloudstart+cloudduration,ChannelValue[a],0,180);
                }
            }
            if (lightningchance && (NumMins(hour(),minute())==(cloudstart+(cloudduration/2))) && second()<5)
            {
                for (int b=0; b<6; b++)
                {
                    if (bitRead(Daylight_Channels,b)==1)
                    {
                        if (random(100)<20) lightningstatus=1;
                        else lightningstatus=0;
                        if (lightningstatus) ChannelValue[b]=100;
                        else ChannelValue[b]=0;
                        //delay(10);
                    }
                    else
                    {
                        ChannelValue[b]=20;
                    }
                }
            }
        }
        if (NumMins(hour(),minute())>(cloudstart+cloudduration))
        {
            cloudindex++;
            if (cloudindex < numclouds)
                ReefAngel.RF.UseMemory=true;
            {
                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;
            }
        }
    }
}
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;
}

//----------------------------------------------------------------- End Cloud & Lighting ------------------------------------------------------------------------------------
//***************************************************************************************************************************************************************************
//----------------------------------------------------------- Calculators for Seasons function ------------------------------------------------------------------------------
long calcSec(long hr, long minu) //if (hour()==hr && minute()==minu);
{
    long totalseconds;
    totalseconds= (hr*3600)+(minu*60);
    return totalseconds;
}
long calcTime(long seconds1, long seconds2) //if (second()==seconds1 && second()==seconds2);
{
    long timediff=abs(seconds1-seconds2);
    return timediff;
}

void DayNumber(unsigned int y, unsigned int m, unsigned int d)
{
    int days[]=
    {
        0,31,59,90,120,151,181,212,243,273,304,334
    };    // Number of days at the beginning of the month in a not leap year.
    //Start to calculate the number of day
    if (m==1 || m==2)
    {
        Ndays = days[(m-1)] +d;            //for any type of year, it calculate the number of days for January or february
    }            // Now, try to calculate for the other months
    else if ((y % 4 == 0 && y % 100 != 0) ||  y % 400 == 0)   //those are the conditions to have a leap year
    {
        Ndays = days[(m-1)]+d+1;     // if leap year, calculate in the same way but increasing one day
    }
    else                   //if not a leap year, calculate in the normal way, such as January or February
    {
        Ndays = days[(m-1)]+d;
    }
}
//End calculators
//***************************************************************************************************************************************************************************
//Calculate Sunrise/set by date & predefined season & rise/set times
void Seasons()
{
    //Set the hour you want the calculations of rise an set to be based on
    int UserRiseHour = 8;
    int UserSetHour =  22;

#define forceseasoncalculation
    static byte ssn , ssnp = 0 , ssnpt ;
    long stime, wstime, vstime, wrtime, rtime, vrtime;
    int wrhour,wrmin,wrsec,wshour,wsmin,wssec,rsec,ssec,vrhour,vrmin,vrsec,vshour,vsmin,vssec;
    int iDiffrise = 0;
    int iDiffset = 0;
    int risediffperday = 0;
    int setdiffperday = 0;
    int totalrise = 0;
    int totalset = 0;
    byte s=0;
    int DaysPerYear;
    //rise and set times set by hour and minute. there are 4 seasons however there are 8 highs & lows in rise and set throughout the year
    //first spot is second half of winter starting jan 1st - DO NOT CHANGE
    int risehour[8]= {UserRiseHour+1,UserRiseHour+1,UserRiseHour+1,UserRiseHour,UserRiseHour,UserRiseHour-1,UserRiseHour,UserRiseHour};/*{
    7,7,7,6,6,5,6,6      };*/
    int riseminute[8]=
    {
        00,30,00,30,00,30,00,30
    };
    int sethour[8] = {UserSetHour-2,UserSetHour-1,UserSetHour-1,UserSetHour,UserSetHour,UserSetHour,UserSetHour,UserSetHour-1};/*{
    17,18,18,19,19,19,19,18      };*/
    int setminute[8] =
    {
        30,00,30,00,00,30,00,00
    };

    if (hour()==0 && minute()==0 && second()==0) ssnp=0;
#ifdef forceseasoncalculation
    if (ssnp==0)
#else
    if (hour()==0 && minute()==0 && second()==1 && ssnp==0)
#endif
    {
        //leapyear or not to define DaysPerYear - DO NOT CHANGE
        if (year()%4 == 0 && !(year()%100 == 0 && year()%400 != 0))
        {
            DaysPerYear=366;
        }
        else
        {
            DaysPerYear = 365;
        }
        //Call Day Number Calc to determin day ie december 31st on a non leap year is day 365 - DO NOT CHANGE
        DayNumber(year(),month(),day());
        //define days between beginning, middle and end of seasons high peaks -  DO NOT CHANGE
        int seasons[9] = {0,45,96,135,187,238,283,328,DaysPerYear};
        //define season and array pulling variable - DO NOT CHANGE
        for (s=0; seasons[s] < Ndays; s++) ssn = s+1, ssnpt = s+1, ssnp = s;
        //set loop on array time pulling variable to go back to beginning instead of increasing array size - DO NOT CHANGE
        if (ssn >= 7) ssn = 0;

        //differece in seconds between two rise/set array times pulled - DO NOT CHANGE
        long rise1 = calcSec(risehour[ssn],riseminute[ssn]);
        long rise2 = calcSec(risehour[ssnp],riseminute[ssnp]);
        iDiffrise = calcTime(rise1, rise2);
        long set1 = calcSec(sethour[ssn],setminute[ssn]);
        long set2 = calcSec(sethour[ssnp],setminute[ssnp]);
        iDiffset = calcTime(set1,set2);

        //calculate new sunrise/set difference from array value & last group of code - DO NOT CHANGE
        risediffperday = iDiffrise/(seasons[ssnpt]-seasons[ssnp]);
        totalrise = risediffperday*(Ndays - seasons[ssnp]);
        setdiffperday = iDiffset/(seasons[ssnpt]-seasons[ssnp]);
        totalset = setdiffperday*(Ndays - seasons[ssnp]);

        //creating time in seconds for main sun rise/set number - DO NOT CHANGE
        rtime=calcSec(risehour[ssnp],riseminute[ssnp]);
        if (ssnp == 0 || ssnp == 2 || ssnp == 4 || ssnp == 6)
        {
            rtime -= totalrise;
        }
        else
        {
            rtime += totalrise;
        }
        stime=calcSec(sethour[ssnp],setminute[ssnp]);
        if (ssnp == 1 || ssnp == 3 || ssnp == 5 || ssnp == 7)
        {
            stime -= totalset;
        }
        else
        {
            stime += totalset;
        }

        //These are the off set times, standard rtime and stime are for Royal Blues & Blues
        // DO NOT CHANGE the operators in these equations ie +-
        // The number is in seconds (1200) change this number to change the offset for each color
        wrtime = rtime + 1200;
        wstime = stime - 1200;
        vrtime = rtime - 1200;
        vstime = stime + 1200;

        //turning seconds back to Hours:Minutes:Seconds
        //Blues
        rhour=rtime/3600;
        rtime=rtime%3600;
        rmin=rtime/60;
        rtime=rtime%60;
        rsec=rtime;
        if(rsec > 30) rmin++;
        shour=stime/3600;
        stime=stime%3600;
        smin=stime/60;
        stime=stime%60;
        ssec=stime;
        if(ssec > 30) smin++;
        //White
        wrhour = wrtime/3600;
        wrtime=wrtime%3600;
        wrmin=wrtime/60;
        wrtime=wrtime%60;
        wrsec=wrtime;
        if(wrsec>30) wrmin++;
        wshour = wstime/3600;
        wstime=wstime%3600;
        wsmin=wstime/60;
        wstime=wstime%60;
        wssec=wstime;
        if(wssec>30) wsmin++;
        //Violet
        vrhour = vrtime/3600;
        vrtime=vrtime%3600;
        vrmin=vrtime/60;
        vrtime=vrtime%60;
        vrsec=vrtime;
        if(vrsec>30) vrmin++;
        vshour = vstime/3600;
        vstime=vstime%3600;
        vsmin=vstime/60;
        vstime=vstime%60;
        vssec=vstime;
        if(vssec>30) vsmin++;



        //time for each active led channel to pull for sunrise - DO NOT CHANGE
        int Sunrise[2]=
        {
            rhour,rmin
        };
        int Sunset[2]=
        {
            shour,smin
        };
        int whSunrise[2]=
        {
            wrhour,wrmin
        };
        int whSunset [2]=
        {
            wshour,wsmin
        };
        int vSunrise[2]=
        {
            vrhour,vrmin
        };
        int vSunset [2]=
        {
            vshour,vsmin
        };

        //This is the PWM Slope for each channel, each channel pulls an array value from above(hour,minute) to use, how you set them is up to you.
        //Just always use a Rise hour in a Rise spot, always a set hour in a set spot ect ect
        ChannelValue[LEDWhiteBlue]=PWMSlope(vSunrise[1],vSunrise[2],vSunset[1],vSunset[2],0,50,180,ChannelValue[LEDWhiteBlue]);
        ChannelValue[LEDWhiteBlue1]=PWMSlope(whSunrise[1],whSunrise[2],whSunset[1],whSunset[2],0,50,180,ChannelValue[LEDWhiteBlue1]);
        ChannelValue[LEDWhiteBlue2]=PWMSlope(Sunrise[1],Sunrise[2],Sunset[1],Sunset[2],0,50,180,ChannelValue[LEDWhiteBlue2]);
        ChannelValue[LEDWhiteBlue3]=PWMSlope(Sunrise[1],Sunrise[2],Sunset[1],Sunset[2],0,50,180,ChannelValue[LEDWhiteBlue3]);
        ChannelValue[MixedLED]=PWMSlope(Sunrise[1],Sunrise[2],whSunset[1],whSunset[2],0,50,180,ChannelValue[MixedLED]);
      //return Sunrise, Sunset, whSunrise,whSunset,vSunrise,vSunset;


    }
}
//------------------------------------------------------------------- End Seasons Calculation -------------------------------------------------------------------------------
//***************************************************************************************************************************************************************************
int JulianDate(int d, int m, int y)
{
    int mm, yy;
    int k1, k2, k3;
    int j;

    yy = y - (int)((12 - m) / 10);
    mm = m + 9;
    if (mm >= 12)
    {
        mm = mm - 12;
    }
    k1 = (int)(365.25 * (yy + 4712));
    k2 = (int)(30.6001 * mm + 0.5);
    k3 = (int)((int)((yy / 100) + 49) * 0.75) - 38;
    // 'j' for dates in Julian calendar:
    j = k1 + k2 + d + 59;
    if (j > 2299160)
    {
        // For Gregorian calendar:
        j = j - k3; // 'j' is the Julian date at 12h UT (Universal Time)
    }
    return j;
}

double MoonAge(int d, int m, int y)
{
    int j = JulianDate(d, m, y);
    //Calculate the approximate phase of the moon
    int ip = (j + 4.867) / 29.53059;
    ip = ip - abs(ip);
    //After several trials I've seen to add the following lines,
    //which gave the result was not bad
    if(ip < 0.5)
        int ag = ip * 29.53059 + 29.53059 / 2;
    else
        int ag = ip * 29.53059 - 29.53059 / 2;
    // Moon's age in days
    byte ag = abs(ag) + 1;
    return ag;
}

byte MoonState(byte D)
{
    switch(D)
    {
        case 1:
            0, 29;
            ThisPhase = 0;
        case 2:
            1, 2, 3, 4, 5, 6;
            ThisPhase = 1;
        case 3:
            7;
            ThisPhase = 2;
        case 4:
            8, 9, 10, 11, 12, 13;
            ThisPhase = 3;
        case 5:
            14;
            ThisPhase = 4;
        case 6:
            15, 16, 17, 18, 19, 20, 21;
            ThisPhase = 5;
        case 7:
            22;
            ThisPhase = 6;
        case 8:
            23, 24, 25, 26, 27, 28;
            ThisPhase = 7;
        default:
            return 0;
    }
}

All I am still having a problem with(except vortech menu) is the Sunrise, SunSet, Storm, Lightning and MoonCycle on Case 0 screen, it should only display either sunrise if its early day, sunset if its late afternoon, storm is there is a storm, lightning if there is a strike on the way, or storm and lightning when both is due or current moon cycle.

I think my IF statement are wrong.
User avatar
JNieuwenhuizen
Posts: 96
Joined: Thu Feb 16, 2012 12:39 am
Location: South Africa

Re: My almost completed pde

Post by JNieuwenhuizen »

Ok

So I started from scratch here - the other code is a bit complex for me

This is my new pde
#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 <ReefAngel.h>
#include <avr/pgmspace.h>>
//***************************************************************************************************************************************************************************
//-------------------------------------------------------------------------- Screen set-up ---------------------------------------------------------------------------------
#define NumScreens 7
int ScreenID=0;
//***************************************************************************************************************************************************************************
//---------------------------------------------------------------------------- PWM Cloud -----------------------------------------------------------------------------------
boolean ForceCloud=false;
boolean ForceLightning=false;
//
//***************************************************************************************************************************************************************************
//--------------------------------------------------------------------------- PWM Channels ----------------------------------------------------------------------------------
#define LEDPWM0 0
#define LEDPWM1 1
#define LEDPWM2 2
#define LEDPWM3 3
#define LEDPWM4 4
#define LEDPWM5 5

//***************************************************************************************************************************************************************************
//--------------------------------------------------------------------- Start of Global Variables ---------------------------------------------------------------------------
byte ChannelValue[]={0,0,0,0,0,0};
byte PWMChannel[]={0,0,0,0,0,0};
byte MoonPWMValue;
byte vtechmode = 0;
boolean fOverrideRF = false;
byte DayAge;
byte ThisPhase;
char* ThisPhaseLabel[]={
"New","Waxing C","First Q","Waxing G","Full","Waning Gibbous","Last Q","Waning C"};
int JulianDate(int,int,int);
double MoonAge(int,int,int);
byte MoonState();
boolean bFeeding=false;
byte x,y;
int maxTemp=0;
int minTemp=2000;
int maxPH=600;
int minPH=900;
int moonlight=0;
byte TempRelay =15;
byte TempRelay2=15;
static byte lightningchance=0;
byte cloudduration=0;
int cloudstart=0;
//***************************************************************************************************************************************************************************
//----------------------------------------------------------------------- Custom Menu Code ----------------------------------------------------------------------------------
prog_char menu1_label[] PROGMEM = "Food!!";
prog_char menu2_label[] PROGMEM = "Cleanup";
prog_char menu3_label[] PROGMEM = "ATO Clear";
prog_char menu4_label[] PROGMEM = "Force Storm";
prog_char menu5_label[] PROGMEM = "PH Calibration";
prog_char menu6_label[] PROGMEM = "Salty Calibration";
prog_char menu7_label[] PROGMEM = "Vortech Modes";
prog_char menu8_label[] PROGMEM = "Sump On";
prog_char menu9_label[] PROGMEM = "Sumo Off";

void MenuEntry1()
{
ReefAngel.FeedingModeStart();
}
void MenuEntry2()
{
ReefAngel.WaterChangeModeStart();
}
void MenuEntry3()
{
ReefAngel.ATOClear();
ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
}
void MenuEntry4()
{
ForceCloud=true;
ForceLightning=true;
ReefAngel.DisplayedMenu=RETURN_MAIN_MODE;
}
void MenuEntry5()
{
ReefAngel.SetupCalibratePH();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry6()
{
ReefAngel.SetupCalibrateSalinity();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry7()
{
// TODO complete this function
/*
Need to have an override variable inside the loop that forces a specific mode whenever
the menu is toggled. This should mimic the PWM override.
*/
/*
Cycle through the modes.
Use the Internal Memory values OR create a switch statement that has default values
for Speed and Duration based on the modes being switched to.
Once at the end of the modes,
return to constant mode (begining)
resume normal operations
*/
fOverrideRF = true;
vtechmode++;
if ( vtechmode == 7 ) vtechmode = 9;
if ( vtechmode > 9 ) { vtechmode = 0; fOverrideRF = false; }
// 1st parameter is Mode, 2nd is speed, 3rd is duration
ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
}
void MenuEntry8()
{
ReefAngel.Relay.RelayMaskOn = ReefAngel.LightsOnPorts;
#ifdef RelayExp
for ( byte i = 0; i < MAX_RELAY_EXPANSION_MODULES; i++ )
{
ReefAngel.Relay.RelayMaskOnE = ReefAngel.LightsOnPortsE;
}
#endif // RelayExp
ReefAngel.Relay.Write();
}

void MenuEntry9()
{
ReefAngel.Relay.RelayMaskOn = 0;
#ifdef RelayExp
for ( byte i = 0; i < MAX_RELAY_EXPANSION_MODULES; i++ )
{
ReefAngel.Relay.RelayMaskOnE = 0;
}
#endif // RelayExp
ReefAngel.Relay.Write();
}
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------- Grouped Menu Entries ----------------------------------------------------------------------------
PROGMEM const char *menu_items[] =
{
menu1_label, menu2_label, menu3_label,
menu4_label, menu5_label, menu6_label,
menu7_label,menu8_label,menu9_label
};
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------- Custom Main -------------------------------------------------------------------------------
void DrawCircleOutline(byte x, byte y, byte radius, byte bordercolor);
void FillCircle(byte x, byte y, byte radius, byte fillcolor);
void DrawCircleOutletBox(byte x, byte y, byte RelayData, bool reverse = false);
//***************************************************************************************************************************************************************************
//-------------------------------------------------------------------------- Analog Clock constants -------------------------------------------------------------------------
const float pi = 3.141592653;
byte clock_center_x = 65;
byte clock_center_y = 65;
byte clock_radius = 55;
byte secondhand_radius = 33;
float secondangle;
byte secondend_x;
byte secondend_y;
float minuteangle;
float hourangle;
//***************************************************************************************************************************************************************************
//--------------------------------------------------------------------------- Analog Clock Structure ------------------------------------------------------------------------
int minutebase_radius = 3;
int minutehand_radius = 33;
int hourbase_radius = 3;
int hourhand_radius = 25;
int seconds_hand_x, seconds_hand_y, minutes_hand_x, minutes_hand_y, hours_hand_x, hours_hand_y;
int hours_hand_base_x, hours_hand_base_y, hours_hand_base_x1, hours_hand_base_y1;
int minutes_hand_base_x, minutes_hand_base_y, minutes_hand_base_x1, minutes_hand_base_y1;
int minutebase_x, minutebase_y, minutebase_x1, minutebase_y1;
int minuteend_x, minuteend_y;
int hourbase_x, hourbase_y, hourbase_x1, hourbase_y1;
int hourend_x, hourend_y;
float minfloat;
//***************************************************************************************************************************************************************************
//--------------------------------------------------------------------------------Time Stamp --------------------------------------------------------------------------------
time_t tsmax=now();
time_t tsmin=now();
time_t PHmax=now();
time_t PHmin=now();
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------ Draw Minutes Hand --------------------------------------------------------------------------
void draw_minute(int color)
{
Drawline(minutebase_x, minutebase_y, minutebase_x1, minutebase_y1, color);
Drawline(minutebase_x, minutebase_y, minuteend_x, minuteend_y, color);
Drawline(minutebase_x1, minutebase_y1, minuteend_x, minuteend_y, color);
}
//***************************************************************************************************************************************************************************
//--------------------------------------------------------------------------- Draw Hour Hand --------------------------------------------------------------------------------
void draw_hour(int color)
{
Drawline(hourbase_x, hourbase_y, hourbase_x1, hourbase_y1, color);
Drawline(hourbase_x, hourbase_y, hourend_x, hourend_y, color);
Drawline(hourbase_x1, hourbase_y1, hourend_x, hourend_y, color);
}
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------ Draw Line ----------------------------------------------------------------------------------
void Drawline (int x0, int y0, int x1, int y1, int color)
{
int dy = y1 - y0;
int dx = x1 - x0;
int stepx, stepy;
if (dy < 0)
{
dy = -dy;
stepy = -1;
}
else
{
stepy = 1;
}
if (dx < 0)
{
dx = -dx;
stepx = -1;
}
else
{
stepx = 1;
}
dy <<= 1; // dy is now 2*dy
dx <<= 1; // dx is now 2*dx
ReefAngel.LCD.PutPixel(color, x0, y0);
if (dx > dy)
{
int fraction = dy - (dx >> 1); // same as 2*dy - dx
while (x0 != x1)
{
if (fraction >= 0)
{
y0 += stepy;
fraction -= dx; // same as fraction -= 2*dx
}
x0 += stepx;
fraction += dy; // same as fraction -= 2*dy
ReefAngel.LCD.PutPixel(color, x0, y0);
}
}
else
{
int fraction = dx - (dy >> 1);
while (y0 != y1)
{
if (fraction >= 0)
{
x0 += stepx;
fraction -= dy;
}
y0 += stepy;
fraction += dx;
ReefAngel.LCD.PutPixel(color, x0, y0);
}
}
}
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------ Draw Time ----------------------------------------------------------------------------------
void DrawTime(byte x, byte y, byte FGcolor, byte BGcolor, time_t ts)
{
char text[13];
char temp[]=" ";
strcpy(text,"");
itoa(hourFormat12(ts),temp,10);
if (temp[1]==0) strcat(text,"0");
strcat(text,temp);
strcat(text,":");
itoa(minute(ts),temp,10);
if (temp[1]==0) strcat(text,"0");
strcat(text,temp);
strcat(text,":");
itoa(second(ts),temp,10);
if (temp[1]==0) strcat(text,"0");
strcat(text,temp);
if (isAM(ts))
{
strcat(text," AM");
}
else
{
strcat(text," PM");
}
ReefAngel.LCD.DrawText(FGcolor, BGcolor, x, y, text);
}
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------ Draw Circle --------------------------------------------------------------------------------
void DrawCircle(int a, int b, int r, byte color)
{
int f = 1 - r;
int ddF_x = 1;
int ddF_y = -2 * r;
int x = 0;
int y = r;

ReefAngel.LCD.PutPixel(color, a, b+r);
ReefAngel.LCD.PutPixel(color ,a, b-r);
ReefAngel.LCD.PutPixel(color, a+r, b);
ReefAngel.LCD.PutPixel(color, a-r, b);
while (x<y)
{
if (f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;

ReefAngel.LCD.PutPixel(color, a + x, b + y);
ReefAngel.LCD.PutPixel(color, a - x, b + y);
ReefAngel.LCD.PutPixel(color, a + x, b - y);
ReefAngel.LCD.PutPixel(color, a - x, b - y);
ReefAngel.LCD.PutPixel(color, a + y, b + x);
ReefAngel.LCD.PutPixel(color, a - y, b + x);
ReefAngel.LCD.PutPixel(color, a + y, b - x);
ReefAngel.LCD.PutPixel(color, a - y, b - x);
}
}
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------ Draw Weekly ------------------------------------------------------------------------------
void DrawWeeklyAvg (byte hr, int sensor, byte color, byte x, byte y, byte z)
{
const int numReadings = 7;
int dailyread;
int readings[numReadings]; // the readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
if (hour()==hr && minute()==0 && second()==0)
{
dailyread=sensor;
total= total - readings[index]; // subtract the last reading:
readings[index] = dailyread; // read from the sensor:
total= total + readings[index]; // add the reading to the total:
index = index + 1; // advance to the next position in the array:
if (index >= numReadings) // if we're at the end of the array...
index = 0; // ...wrap around to the beginning:
average = total / numReadings; // calculate the average:
delay (1000);
ReefAngel.LCD.DrawSingleMonitor(average, color, x, y, z);
}
}
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------ Draw Daily ---------------------------------------------------------------------------------
void DrawDailyAvg (int sensor, byte color, byte x, byte y, byte z)
{
const int numReadings = 24;
int dailyread;
int readings[numReadings]; // the readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
if (minute()==0 && second()==0)
{
dailyread=sensor;
total= total - readings[index]; // subtract the last reading:
readings[index] = dailyread; // read from the sensor:
total= total + readings[index]; // add the reading to the total:
index = index + 1; // advance to the next position in the array:
if (index >= numReadings) // if we're at the end of the array...
index = 0; // ...wrap around to the beginning:
average = total / numReadings; // calculate the average:
delay (1000);
ReefAngel.LCD.DrawSingleMonitor(average, color, x, y, z);
}
}

void DrawCustomMain()
{
// Refresh is called at start of ShowInterface.
// ShowInterface calls DrawCustomMain
switch (ScreenID)
{
//---------------------------------------------------------------------------- Screen Code 1--------------------------------------------------------------------------------
case 0:
//Top Banner
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank ", Font8x8); //Top Banner
// Display T1 Header Text
ReefAngel.LCD.DrawLargeText(COLOR_STEELBLUE,255,5,15,"Sump Temp", Font8x8);
// Display the T1 Temp Value
char text[7];
ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
ReefAngel.LCD.Clear(255, 10, 25, 50, 60);
if (ReefAngel.Params.Temp[T1_PROBE]>290) ReefAngel.LCD.DrawHugeNumbers(COLOR_RED, 255, 10, 25, text);
else if (ReefAngel.Params.Temp[T1_PROBE]>270) ReefAngel.LCD.DrawHugeNumbers(COLOR_ORANGE, 255, 10, 25, text);
else ReefAngel.LCD.DrawHugeNumbers(COLOR_MIDNIGHTBLUE, 255, 10, 25, text);
// Display the T2 Header Text
ReefAngel.LCD.DrawLargeText(0,255,5,45,"Room Temp", Font8x8);
// Display the T2 Temp Value
ReefAngel.LCD.Clear(255, 90, 50, 132, 60);
ConvertNumToString(text, ReefAngel.Params.Temp[T2_PROBE], 10);
ReefAngel.LCD.DrawLargeText(COLOR_MIDNIGHTBLUE, 255, 90, 45, text, Num8x8);
// Display pH Header Text
ReefAngel.LCD.DrawLargeText(COLOR_LIMEGREEN,255,95,15,"pH", Font8x8);
// Display pH Value
ConvertNumToString(text, ReefAngel.Params.PH, 100);
ReefAngel.LCD.Clear(0, 65, 62 , 65, 62);
if (ReefAngel.Params.PH>840 || ReefAngel.Params.PH<790) ReefAngel.LCD.DrawLargeText(COLOR_RED, 255, 85, 25, text, Num8x8);
else if (ReefAngel.Params.PH>830 || ReefAngel.Params.PH<800) ReefAngel.LCD.DrawLargeText(COLOR_ORANGE, 255, 85, 25, text, Num8x8);
else ReefAngel.LCD.DrawLargeText(COLOR_MIDNIGHTBLUE, 255, 85, 25, text, Num8x8);

//****************************************************************************************************************************************************************************
//------------------------------------------------------------------ Display Vortech Mode ------------------------------------------------------------------------------------

ReefAngel.LCD.DrawLargeText(0,255,5,55,"Vortech", Font8x8);

//****************************************************************************************************************************************************************************
//---------------------------------------------------------------- Display EcoSmart Mode Value -------------------------------------------------------------------------------

ReefAngel.LCD.Clear(255, 66, 60, 132, 70);
if (vtechmode == 0) ReefAngel.LCD.DrawLargeText(COLOR_LIMEGREEN,255, 66, 55,"Constant");
else if(vtechmode == 1) ReefAngel.LCD.DrawLargeText(COLOR_GOLD,255, 66, 55,"Lagoon");
else if (vtechmode == 2) ReefAngel.LCD.DrawLargeText(COLOR_GOLD,255, 80, 55,"RCM");
else if (vtechmode == 3) ReefAngel.LCD.DrawLargeText(COLOR_CORNFLOWERBLUE,255, 80, 55,"Short");
else if (vtechmode == 4) ReefAngel.LCD.DrawLargeText(COLOR_PINK,255, 66, 55,"Long");
else if (vtechmode == 5) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255, 80, 55,"NTM");
else if (vtechmode == 6) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255, 80, 55,"TSM");
else if (vtechmode == 9) ReefAngel.LCD.DrawLargeText(COLOR_GRAY,255, 80, 55,"Night");

//****************************************************************************************************************************************************************************
//------------------------------------------------------------------- Display Salinity ---------------------------------------------------------------------------------------

ReefAngel.LCD.DrawLargeText(0,255,64,114,"Salinity", Font8x8);

//****************************************************************************************************************************************************************************
//----------------------------------------------------------------- Display Salinity Value -----------------------------------------------------------------------------------

ReefAngel.LCD.Clear(255, 82, 85, 65, 95);
ConvertNumToString(text, ReefAngel.Params.Salinity, 10);
ReefAngel.LCD.DrawLargeText(COLOR_LIMEGREEN, 255, 85, 122, text, Num8x8);

//*****************************************************************************************************************************************************************************
//-----------------------------------------------------------Start Moon Phase,Cloud or Storm Display---------------------------------------------------------------------------
if (ReefAngel.PWM.ExpansionChannel[6] > 0);
{
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,70,105,MoonPhaseLabel());

}
if (ReefAngel.PWM.ExpansionChannel[0] > 0 && (hour() < 14 ) )
{
ReefAngel.LCD.DrawLargeText(COLOR_ORANGERED,255,3,65, "Sunrise",Font8x8);
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,3,75, ReefAngel.PWM.ExpansionChannel[0]);
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,20,74, ":");
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,24,75, ReefAngel.PWM.ExpansionChannel[1]);
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,41,74, ":");
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,45,75, ReefAngel.PWM.ExpansionChannel[2]);
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,66,75, "|");
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,70,75, ReefAngel.PWM.ExpansionChannel[3]);
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,87,74, ":");
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,91,75, ReefAngel.PWM.ExpansionChannel[4]);
}
else if (ReefAngel.PWM.ExpansionChannel[0] > 0 && (hour() > 14 ))
{
ReefAngel.LCD.DrawLargeText(COLOR_ORANGERED,255,3,65, "Sunrise",Font8x8);
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,3,75, ReefAngel.PWM.ExpansionChannel[0]);
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,20,74, ":");
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,24,75, ReefAngel.PWM.ExpansionChannel[1]);
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,41,74, ":");
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,45,75, ReefAngel.PWM.ExpansionChannel[2]);
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,66,75, "|");
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,70,75, ReefAngel.PWM.ExpansionChannel[3]);
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,87,74, ":");
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,91,75, ReefAngel.PWM.ExpansionChannel[4]);
}

//*****************************************************************************************************************************************************************************
//---------------------------------------------------------- Display Main and Expansion Relay Box -----------------------------------------------------------------------------

TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawCircleOutletBox(10,90, TempRelay);
pingSerial();

TempRelay2 = ReefAngel.Relay.RelayDataE[0];
TempRelay2 &= ReefAngel.Relay.RelayMaskOffE[0];
TempRelay2 |= ReefAngel.Relay.RelayMaskOnE[0];
ReefAngel.LCD.DrawCircleOutletBox(40,90, TempRelay2);
pingSerial();
break;

//***************************************************************************************************************************************************************************
//---------------------------------------------------------------------------- Screen Code 2---------------------------------------------------------------------------------

case 1: //Temperature detail screen with sump and room temp, 24 hr. max/min, time stamps, and graph
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(0,255,10,15,"Temp Details", Font8x8);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,33,"Sump:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T1_PROBE], COLOR_BLACK, 36, 33, 10);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,43,"HI:");
ReefAngel.LCD.DrawSingleMonitor(maxTemp, 0, 23, 43, 10);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,48,43,"at");
DrawTime(60,43,0, COLOR_WHITE,tsmax);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,53,"LO:");
ReefAngel.LCD.DrawSingleMonitor(minTemp, 0, 23, 53, 10);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,48,53,"at");
DrawTime(60,53,0,COLOR_WHITE, tsmin);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,63,"Range:");
ReefAngel.LCD.DrawSingleMonitor((maxTemp-minTemp), COLOR_BLACK, 46, 63, 10);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,69,63,"Degrees C");
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,73,"Avg:");
DrawDailyAvg(ReefAngel.Params.Temp[T1_PROBE], COLOR_BLACK, 43, 73, 1);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,83,"WeeklyAvg:");
DrawWeeklyAvg(12,ReefAngel.Params.Temp[T1_PROBE], COLOR_BLACK, 66, 83, 1);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor, 86,83,"at noon");
ReefAngel.LCD.DrawText(T2TempColor,DefaultBGColor, 5 ,93,"Room:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T2_PROBE], COLOR_BLACK, 36, 93, 10);
break;

//***************************************************************************************************************************************************************************
//---------------------------------------------------------------------------- Screen Code 3---------------------------------------------------------------------------------
case 2: //pH details
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(0,255,20,15,"pH Details", Font8x8);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,33,"pH:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.PH, COLOR_BLACK, 36, 33, 100);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,43,"HI:");
ReefAngel.LCD.DrawSingleMonitor(maxPH, 0, 23, 43, 100);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,48,43,"at");
DrawTime(60,43,0, COLOR_WHITE,PHmax);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,53,"LO:");
ReefAngel.LCD.DrawSingleMonitor(minPH, 0, 23, 53, 100);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,48,53,"at");
DrawTime(60,53,0,COLOR_WHITE, PHmin);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,63,"Range:");
ReefAngel.LCD.DrawSingleMonitor((maxPH-minPH), COLOR_BLACK, 46, 63, 100);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,73,"Avg:");
DrawDailyAvg(ReefAngel.Params.PH, COLOR_BLACK, 43, 73, 100);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,83,"WeeklyAvg:");
DrawWeeklyAvg(12,ReefAngel.Params.PH, COLOR_BLACK, 66, 83, 100);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 86,83,"at noon");
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,93,"WeeklyAvg:");
DrawWeeklyAvg(0,ReefAngel.Params.PH, COLOR_BLACK, 66, 93, 100);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 86,93,"at midnt");
break;

//***************************************************************************************************************************************************************************
//---------------------------------------------------------------------------- Screen Code 4---------------------------------------------------------------------------------

case 3: //relay box key
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank ", Font8x8); //Top Banner
TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawCircleOutletBox(56,46,TempRelay);
pingSerial();
ReefAngel.LCD.DrawLargeText(0,255,27,20,"RelayBox 1", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,3,44,"LDFan", Font8x8); //1
// ReefAngel.LCD.DrawLargeText(0,255,7,54,"ATU", Font8x8); //3
ReefAngel.LCD.DrawLargeText(0,255,7,64,"ATU", Font8x8); //5
ReefAngel.LCD.DrawLargeText(0,255,7,74,"Salty", Font8x8); //7
ReefAngel.LCD.DrawLargeText(0,255,75,44,"Skimer", Font8x8); //2
ReefAngel.LCD.DrawLargeText(0,255,75,54,"Reactr", Font8x8); //4
ReefAngel.LCD.DrawLargeText(0,255,75,64,"Heatr", Font8x8); //6
ReefAngel.LCD.DrawLargeText(0,255,75,74,"Relay", Font8x8); //8
break;

//***************************************************************************************************************************************************************************
//---------------------------------------------------------------------------- Screen Code 5---------------------------------------------------------------------------------

case 4: //relay box key
ReefAngel.Refresh();
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank ", Font8x8); //Top Banner
TempRelay2 = ReefAngel.Relay.RelayDataE[0];
TempRelay2 &= ReefAngel.Relay.RelayMaskOffE[0];
TempRelay2 |= ReefAngel.Relay.RelayMaskOnE[0];
ReefAngel.LCD.DrawCircleOutletBox(56,46,TempRelay2);
pingSerial();
ReefAngel.LCD.DrawLargeText(0,255,27,20,"RelayBox 2", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,44,"VTech", Font8x8);//1
ReefAngel.LCD.DrawLargeText(0,255,3,54,"Return", Font8x8);//3
// ReefAngel.LCD.DrawLargeText(0,255,7,64,"Day1", Font8x8);//5
// ReefAngel.LCD.DrawLargeText(0,255,7,74,"Day3", Font8x8);//7
ReefAngel.LCD.DrawLargeText(0,255,75,44,"VTech", Font8x8);//2
ReefAngel.LCD.DrawLargeText(0,255,75,54,"SumpL", Font8x8);//4
// ReefAngel.LCD.DrawLargeText(0,255,75,64,"Day2", Font8x8);//6
ReefAngel.LCD.DrawLargeText(0,255,75,74,"LED", Font8x8);//8
break;

//***************************************************************************************************************************************************************************
//---------------------------------------------------------------------------- Screen Code 6---------------------------------------------------------------------------------

case 5: //setclock
// Analog clock is modified from the original source by Jeff Miller
// Author: Jeff Miller http://arduinofun.blogspot.com/
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank ", Font8x8); //Top Banner
// Frame
DrawCircle(clock_center_x, clock_center_y, clock_radius, COLOR_CORNFLOWERBLUE);
DrawCircle(clock_center_x, clock_center_y, clock_radius - 1, COLOR_CORNFLOWERBLUE);
DrawCircle(clock_center_x, clock_center_y, clock_radius - 2, COLOR_CORNFLOWERBLUE);
// Face Tick Marks (x = r cos theta, y = r sin theta)
for (byte r=0; r < 12; r++)
{
float angle = (2 * pi / 12)*r;
int tick_x_out = (clock_radius - 8) * cos (angle) + clock_center_x;
int tick_y_out = (clock_radius - 8) * sin (angle) + clock_center_y;
int tick_x_in = clock_radius *.72 * cos (angle) + clock_center_x;
int tick_y_in = clock_radius * .72 * sin (angle) + clock_center_y;
Drawline(tick_x_in, tick_y_in, tick_x_out, tick_y_out, COLOR_CORNFLOWERBLUE);
}
// Face Characters
ReefAngel.LCD.DrawLargeText(0,255,clock_center_x - 8,106," 6", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,clock_center_x - 8, 25,"12", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,clock_center_x + 34,clock_center_y," 3", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,clock_center_x - 50, clock_center_y - 4,"9 ", Font8x8);
// Draw Seconds Hand
secondangle = (2 * pi / 60) * second();
if (second() > 15)
{
secondangle = secondangle -1.57;
}
else
{
secondangle = secondangle +4.71;
}
Drawline(clock_center_x, clock_center_y, secondend_x, secondend_y, WHITE);
secondend_x = secondhand_radius * cos (secondangle) + clock_center_x;
secondend_y = secondhand_radius * sin (secondangle) + clock_center_y;
Drawline(clock_center_x, clock_center_y, secondend_x, secondend_y, BLACK);
// Redraw minutes hand since the section closest to the center gets erased by the seconds hand
draw_minute(BLACK);
// Redraw hour hand
draw_hour(BLACK);
// Draw Minutes Hand
minuteangle = (2 * pi / 60) * minute();
if (minute() > 15)
{
minuteangle = minuteangle -1.57;
}
else
{
minuteangle = minuteangle +4.71;
}
// Erase old minutes Hand
draw_minute(WHITE);
// Calculate Minute Hand Base
minutebase_x = minutebase_radius * cos (minuteangle - pi/2) + clock_center_x;
minutebase_y = minutebase_radius * sin (minuteangle - pi/2) + clock_center_y;
minutebase_x1 = minutebase_radius * cos (minuteangle + pi/2) + clock_center_x;
minutebase_y1 = minutebase_radius * sin (minuteangle + pi/2) + clock_center_y;
// Calculate Minute Hand Point
minuteend_x = minutehand_radius * cos (minuteangle) + clock_center_x;
minuteend_y = minutehand_radius * sin (minuteangle) + clock_center_y;
// Draw new minutes Hand
draw_minute(BLACK);
// Redraw hour hand
draw_hour(BLACK);
// Draw Hour Hand
minfloat = minute(); // Convert minute short to float
hourangle = (2 * pi / 12) * ((hourFormat12()) + (minfloat/60)); // Find angle for hour hand
hourangle = hourangle -1.57;
// Erase old Hour Hand
draw_hour(WHITE);
// Calculate hour Hand Base
hourbase_x = hourbase_radius * cos (hourangle - pi/2) + clock_center_x;
hourbase_y = hourbase_radius * sin (hourangle - pi/2) + clock_center_y;
hourbase_x1 = hourbase_radius * cos (hourangle + pi/2) + clock_center_x;
hourbase_y1 = hourbase_radius * sin (hourangle + pi/2) + clock_center_y;
// Calculate hour Hand Point
hourend_x = hourhand_radius * cos (hourangle) + clock_center_x;
hourend_y = hourhand_radius * sin (hourangle) + clock_center_y;
// Draw new hours Hand
draw_hour(BLACK);
ReefAngel.LCD.DrawDate(5,121);
break;

//***************************************************************************************************************************************************************************
//---------------------------------------------------------------------------- Screen Code 7---------------------------------------------------------------------------------

case 6: // Vortech Setup
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank ", Font8x8); //Top Banner
ReefAngel.LCD.DrawText(0,255,20,50,"Assigning Slaves");
ReefAngel.RF.SetMode(Slave_Start,0,0);
if (ReefAngel.Joystick.IsButtonPressed())
{
ReefAngel.RF.SetMode(Slave_Stop,0,0);
ReefAngel.LCD.DrawText(0,255,50,60,"Done");
}
break;

}
}

void DrawCustomGraph()
{}

//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------ Begin Setup --------------------------------------------------------------------------------
void setup()
{
ReefAngel.Init(); //Initialize controller
ReefAngel.Timer[LCD_TIMER].SetInterval(180);
ReefAngel.Timer[LCD_TIMER].Start(); // start timer
ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));
ReefAngel.SetTemperatureUnit(1);
ReefAngel.FeedingModePorts = 0;
ReefAngel.WaterChangePorts = Port1Bit | Port2Bit | Port3Bit | Port6Bit | Box1_Port1 | Box1_Port2;
ReefAngel.OverheatShutoffPorts = Port6Bit;
ReefAngel.LightsOnPorts = Box1_Port4;
//------------------------------------------------------------------------- Ports that are always on ------------------------------------------------------------------------
ReefAngel.Relay.On(Port1);
ReefAngel.Relay.On(Port4);
ReefAngel.Relay.On(Port7);
ReefAngel.Relay.On(Port8);
ReefAngel.Relay.On(Box1_Port1);
ReefAngel.Relay.On(Box1_Port2);
ReefAngel.Relay.On(Box1_Port3);
ReefAngel.Relay.On(Box1_Port7);
ReefAngel.Relay.On(Box1_Port8);
}
//***************************************************************************************************************************************************************************
void loop()
{
CheckCloud();
//--------------------------------------------------------------------------- Specific Functions ----------------------------------------------------------------------------
ReefAngel.Relay.DelayedOn(Port2, 2);
ReefAngel.Relay.DelayedOn(Box1_Port1, 2);
ReefAngel.Relay.DelayedOn(Box1_Port2, 2);
ReefAngel.StandardATO(Port5);
ReefAngel.StandardHeater(Port6);
ReefAngel.MoonLights(Box1_Port4);//SumpLight
ReefAngel.Portal("JNieuwenhuizen");
//------------------------------------------------------------------------------ Multiple Screens ----------------------------------------------------------------------------
setTime(hour(),minute(),second(),day(),month(),year());
// update the min & max temps and min & max ph
if (now()%86400==0)
{
minTemp=ReefAngel.Params.Temp[T1_PROBE];
maxTemp=ReefAngel.Params.Temp[T1_PROBE];
minPH=ReefAngel.Params.PH;
maxPH=ReefAngel.Params.PH;
}
if (ReefAngel.Params.Temp[T1_PROBE]<minTemp)
{
minTemp=ReefAngel.Params.Temp[T1_PROBE];
tsmin=now();
}
if (ReefAngel.Params.Temp[T1_PROBE]>maxTemp)
{
maxTemp=ReefAngel.Params.Temp[T1_PROBE];
tsmax=now();
}
if (ReefAngel.Params.PH<minPH)
{
minPH=ReefAngel.Params.PH;
PHmin=now();
}
if (ReefAngel.Params.PH>maxPH)
{
maxPH=ReefAngel.Params.PH;
PHmax=now();
}
if (ReefAngel.Joystick.IsLeft())
{
ReefAngel.ClearScreen(DefaultBGColor);
ScreenID--;
}
if (ReefAngel.Joystick.IsRight())
{
ReefAngel.ClearScreen(DefaultBGColor);
ScreenID++;
}
if (ScreenID<0) ScreenID=NumScreens;
if (ScreenID>=NumScreens) ScreenID=0;

//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------- Moon Cycle ------------------------------------------------------------------------------------
MoonPWMValue=MoonPhase();
if (hour()==22 || hour()==6)
MoonPWMValue=PWMSlope(22,00,6,00,0,MoonPhase(),45,0);
if (ReefAngel.PWM.ExpansionChannel[4]) MoonPWMValue=0;
ReefAngel.PWM.SetChannel(5,MoonPWMValue);
//--------------------------------------------------------------------------- End Moon Cycle --------------------------------------------------------------------------------
ReefAngel.PWM.SetChannel(0,PWMParabola(8,30,20,30,10,80,0));
ReefAngel.PWM.SetChannel(1,PWMParabola(9,0,21,0,15,80,0));
ReefAngel.PWM.SetChannel(2,PWMParabola(9,30,21,30,15,80,0));
ReefAngel.PWM.SetChannel(3,PWMParabola(10,0,22,0,15,80,0));
ReefAngel.PWM.SetChannel(4,PWMParabola(10,0,22,0,15,100,0));

for (int a=0;a<6;a++)
{
ReefAngel.PWM.Expansion(a,int(2.55*PWMChannel[a]));
}


//***************************************************************************************************************************************************************************
//------------------------------------------------------------------ Start Time-of-Day Based Functions ----------------------------------------------------------------------
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These are the mode numbers for the RF Expansion Module for reference ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//#define Constant 0
//#define Random1 1 // Lagoonal
//#define Random2 2 // Reef Crest
//#define ShortWave 3
//#define LongWave 4
//#define Smart_NTM 5 // Nutrient Transport Mode
//#define Smart_TSM 6 // Tidal Swell Mode
//#define Feeding_Start 7
//#define Feeding_Stop 8
//#define Night 9
//#define Slave_Start 97
//#define Slave_Stop 98
//#define None 99
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// RF Override
if ( ! fOverrideRF )
{
// RF Mode is not being overridden, AKA Normal operation mode
//----------------------------------------------------------------- Start RF Daytime Control ------------------------------------------------------------------------------
if (hour() >8 && hour() < 14)
{
ReefAngel.RF.UseMemory=false;
ReefAngel.RF.SetMode(Smart_NTM,80,7);
vtechmode = Smart_NTM;
}
else if (hour() >14 && hour() < 22)
{
ReefAngel.RF.UseMemory=false;
ReefAngel.RF.SetMode(Random2,60,7);
vtechmode = Random2;
}

//--------------------------------------------------------------- Start RF Nightmode Control -----------------------------------------------------------------------------
else if (hour()>=22 || hour()<8) // Defining "Nightmode" hours for VorTech = between 10 PM and 8 AM
{
ReefAngel.RF.UseMemory=false;
ReefAngel.RF.SetMode(Night,15,0);
vtechmode = Night;
}
else
{
ReefAngel.RF.SetMode(Feeding_Stop,0,0); //Temp fix for coming out of Night mode
ReefAngel.RF.UseMemory=false;
ReefAngel.RF.SetMode(Smart_NTM,80,7);
vtechmode = Smart_NTM;
ReefAngel.RF.SetMode(vtechmode, InternalMemory.RFSpeed_read(), InternalMemory.RFDuration_read());
}
} // if fOverrideRF

ReefAngel.ShowInterface();
}

//***************************************************************************************************************************************************************************

//-------------------------------------------------- Random Cloud/Thunderstorm effects function -----------------------------------------------------------------------------
//------------------------------------------------------- From Roberto - THANKS ROBERTO! ------------------------------------------------------------------------------------
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_5_Days 1
// 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 25
// 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 3
// Maximum number of clouds that can happen per day
#define Max_Clouds_per_Day 6
// Only start the cloud effect after this setting
// In this example, start could after 11:30am
#define Start_Cloud_After NumMins(12,00)
// Always end the cloud effect before this setting
// In this example, end could before 4:30pm
#define End_Cloud_Before NumMins(18,0)
// 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 25
// Channels used by the actinic LEDs on the PWM Expansion module
// These channels will not be dimmed when the cloud effect is triggered
// Number is a binary form. B001100 means channel 2 and 3 are used for actinics
#define Actinic_Channels B000000
// Channels used by the daylight LEDs on the PWM Expansion module
// These channels will be used for the spike when lightning effect is triggered
// Number is a binary form. B000011 means channel 0 and 1 are used for daylights
#define Daylight_Channels B001000
// 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(26);
// 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_5_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(36);
// 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 (cloudchance)
{
//is it time for cloud yet?
//is it time for cloud yet?
if (NumMins(hour(),minute())>=cloudstart && NumMins(hour(),minute())<(cloudstart+cloudduration))
{
// let's go through all channels to pick which ones will be dimmed
for (int a=0; a<6; a++)
{
if (bitRead(Actinic_Channels,a)==0)
{
// this will slope down the channel from the current PWM to 0 within 3minutes.
// then it will stay at 0 for the duration of the cycle
// and finally slope up from 0 to PWM value within 3 minutes
// it is basically an inversed slope
ChannelValue[a]=ReversePWMSlope(cloudstart,cloudstart+cloudduration,ChannelValue[a],0,180);
}
}
if (lightningchance && (NumMins(hour(),minute())==(cloudstart+(cloudduration/2))) && second()<5)
{
for (int b=0; b<6; b++)
{
if (bitRead(Daylight_Channels,b)==1)
{
if (random(100)<20) lightningstatus=1;
else lightningstatus=0;
if (lightningstatus) ChannelValue=100;
else ChannelValue=0;
//delay(10);
}
else
{
ChannelValue=20;
}
}
}
}
if (NumMins(hour(),minute())>(cloudstart+cloudduration))
{
cloudindex++;
if (cloudindex < numclouds)
ReefAngel.RF.UseMemory=true;
{
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;
}
}
}
}
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;
}

//----------------------------------------------------------------- End Cloud & Lighting ------------------------------------------------------------------------------------
//***************************************************************************************************************************************************************************
char* MoonPhaseLabel()
{
int m,d,y;
int yy,mm;
long K1,K2,K3,J;
double V;
byte PWMvalue;
m = month();
d = day();
y = year();
yy = y-((12-m)/10);
mm = m+9;
if (mm>=12) mm -= 12;
K1 = 365.25*(yy+4712);
K2 = 30.6*mm+.5;
K3 = int(int((yy/100)+49)*.75)-38;
J = K1+K2+d+59-K3;
V = (J-2451550.1)/29.530588853;
V -= floor(V);
if (V<0) V++;
if (V<0.0625) return "New Moon";
else if (V<0.1875) return "Waxing Crescent";
else if (V<0.3125) return "First Quarter";
else if (V<0.4375) return "Waxing Gibbous";
else if (V<0.5625) return "Fuul Moon";
else if (V<0.6875) return "Waning Gibbous";
else if (V<0.8125) return "Last Quarter";
else if (V<0.9375) return "Waning Crescent";
else return "New Moon";
}


Only problem is my Reef Angel now freezes up ? any ideas
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: My almost completed pde

Post by rimai »

I think this line is the problem:

Code: Select all

if (ReefAngel.PWM.ExpansionChannel[6] > 0);
You are going out of bounds.
Roberto.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: My almost completed pde

Post by rimai »

Also, remove these lines:

Code: Select all

 for (int a=0;a<6;a++) 
{
 ReefAngel.PWM.Expansion(a,int(2.55*PWMChannel[a]));
 }
Or your lights will never turn on. You are sending 0s to all channels with this code.
Roberto.
User avatar
JNieuwenhuizen
Posts: 96
Joined: Thu Feb 16, 2012 12:39 am
Location: South Africa

Re: My almost completed pde

Post by JNieuwenhuizen »

My Bad.. Sorry. Now it works!
I do have a question.. on the scetchbook-custommain_pwm

There is a menu function call PWM-> and sub menus

Is there code for it somewhere? how would I replace one of my menus to have that?
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: My almost completed pde

Post by rimai »

Cool.
That PWM menu option was useless and has been even removed on the latest libraries update.
Roberto.
User avatar
JNieuwenhuizen
Posts: 96
Joined: Thu Feb 16, 2012 12:39 am
Location: South Africa

Re: My almost completed pde

Post by JNieuwenhuizen »

Thank You Roberto.

I have a bit of a dellema. my mooncycle is not working , what did I do wrong?

Code: Select all

MoonPWMValue=MoonPhase();
 if (hour()==22 || hour()==6)
 MoonPWMValue=PWMSlope(22,00,6,00,0,MoonPhase(),45,0);
 if (ReefAngel.PWM.ExpansionChannel[0]=1) MoonPWMValue=0;
 ReefAngel.PWM.SetChannel(5,MoonPWMValue);
Last edited by JNieuwenhuizen on Thu May 31, 2012 3:32 pm, edited 2 times in total.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: My almost completed pde

Post by rimai »

What is it doing?
Roberto.
User avatar
JNieuwenhuizen
Posts: 96
Joined: Thu Feb 16, 2012 12:39 am
Location: South Africa

Re: My almost completed pde

Post by JNieuwenhuizen »

Nothing. It does not switch on at all.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: My almost completed pde

Post by rimai »

Let me check during the weekend.
Roberto.
User avatar
JNieuwenhuizen
Posts: 96
Joined: Thu Feb 16, 2012 12:39 am
Location: South Africa

Re: My almost completed pde

Post by JNieuwenhuizen »

So using the new Reef Angel Wizard, I now get the moonlights on, but they stay on as the Wizard generates a bit of code like this

Code: Select all

ReefAngel.PWM.SetChannel( 5, MoonPhase() );
If I try adding times toit like the Parabola code, or PWMslop code, it gives me errors.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: My almost completed pde

Post by rimai »

Code: Select all

  if (hour()>=22 || hour()<6)
    ReefAngel.PWM.SetChannel( 5, MoonPhase() );
  else
    ReefAngel.PWM.SetChannel( 5, 0);
Roberto.
User avatar
JNieuwenhuizen
Posts: 96
Joined: Thu Feb 16, 2012 12:39 am
Location: South Africa

Re: My almost completed pde

Post by JNieuwenhuizen »

Its working now

Thank You
pilonstar
Posts: 64
Joined: Tue Mar 20, 2012 2:56 am

Re: My almost completed pde

Post by pilonstar »

JNieuwenhuizen wrote:Its working now

Thank You
Can you post the code working please? also can you post any pics of the controller?
thank you
Slow down to speed up
Image
Image
User avatar
JNieuwenhuizen
Posts: 96
Joined: Thu Feb 16, 2012 12:39 am
Location: South Africa

Re: My almost completed pde

Post by JNieuwenhuizen »

Hi pilonstar

This code is no more.

Since the PWM module code has been moved to it, my head unit code is as simple as a wizrad generated file, its only the custom main screens, and that is still a work in progress.

As soon as everything works, I'll paste the code for you
User avatar
JNieuwenhuizen
Posts: 96
Joined: Thu Feb 16, 2012 12:39 am
Location: South Africa

Re: My almost completed pde

Post by JNieuwenhuizen »

I have re-done my code in the next Memory and versions upgrades..

I got rid off all the extra screens, and the unwanted stuffs, as I did not use them.

Now, my menus dont work.. what did I do wrong?

My new 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 <ReefAngel.h>

////// Place global variable code below here
//--------------------------------------------------------------------- Start of Global Variables ---------------------------------------------------------------------------
bool fOverrideRF = false;
byte vtechmode = 0;
boolean bFeeding=false;
byte x,y;
byte TempRelay =15;
byte TempRelay2=15;
//***************************************************************************************************************************************************************************
//------------------------------------------------------------------------------- Custom Main -------------------------------------------------------------------------------
void DrawCircleOutline(byte x, byte y, byte radius, byte bordercolor);
void FillCircle(byte x, byte y, byte radius, byte fillcolor);
void DrawCircleOutletBox(byte x, byte y, byte RelayData, bool reverse = false);
//***************************************************************************************************************************************************************************
//----------------------------------------------------------------------- Custom Menu Code ----------------------------------------------------------------------------------
#include <avr/pgmspace.h>
prog_char menu0_label[] PROGMEM = "Food";
prog_char menu1_label[] PROGMEM = "Cleanup";
prog_char menu2_label[] PROGMEM = "ATU Clear";
prog_char menu3_label[] PROGMEM = "pH";
prog_char menu4_label[] PROGMEM = "Salinity";
prog_char menu5_label[] PROGMEM = "Sump On";
prog_char menu6_label[] PROGMEM = "Sump Off";
prog_char menu7_label[] PROGMEM = "Item 8";
prog_char menu8_label[] PROGMEM = "Date/Time";
PROGMEM const char *menu_items[] = {
menu0_label, menu1_label, menu2_label, menu3_label, menu4_label, menu5_label, menu6_label, menu7_label, menu8_label  };

void MenuEntry1()
{
ReefAngel.DisplayMenuEntry("Item 1");
ReefAngel.FeedingModeStart();

}
void MenuEntry2()
{
ReefAngel.DisplayMenuEntry("Item 2");
ReefAngel.WaterChangeModeStart();

}
void MenuEntry3()
{
ReefAngel.DisplayMenuEntry("Item 3");
ReefAngel.ATOClear();

}
void MenuEntry4()
{
ReefAngel.DisplayMenuEntry("Item 4");
ReefAngel.SetupCalibratePH();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;

}
void MenuEntry5()
{
ReefAngel.DisplayMenuEntry("Item 5");
ReefAngel.SetupCalibrateSalinity();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;

}
void MenuEntry6()
{
ReefAngel.DisplayMenuEntry("Item 6");
ReefAngel.Relay.RelayMaskOn = ReefAngel.LightsOnPorts;
#ifdef RelayExp
for ( byte i = 0; i < MAX_RELAY_EXPANSION_MODULES; i++ )
{
    ReefAngel.Relay.RelayMaskOnE[i] = ReefAngel.LightsOnPortsE[i];
}
#endif  // RelayExp
ReefAngel.Relay.Write();

}
void MenuEntry7()
{
ReefAngel.DisplayMenuEntry("Item 7");
ReefAngel.Relay.RelayMaskOn = 0;
#ifdef RelayExp
for ( byte i = 0; i < MAX_RELAY_EXPANSION_MODULES; i++ )
{
    ReefAngel.Relay.RelayMaskOnE[i] = 0;
}
#endif  // RelayExp
ReefAngel.Relay.Write();

}
void MenuEntry8()
{
ReefAngel.DisplayMenuEntry("Item 8");
  if (!fOverrideRF && vtechmode == 9)
   {
     vtechmode=0;
     ReefAngel.RF.SetMode(Feeding_Stop,0,0); //Temp fix for coming out of Night mode
   }
   else
   {
     vtechmode++;
   }
     
  fOverrideRF = true;
  if ( vtechmode == 7 ) vtechmode = 9;
  if ( vtechmode > 9 ) { 
    vtechmode = 0; 
    fOverrideRF = false; 
  }
  
  // 1st parameter is Mode, 2nd is speed, 3rd is duration
  ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
}
void MenuEntry9()
{
ReefAngel.DisplayMenuEntry("Item 9");
ReefAngel.SetupDateTime();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;

}
void DrawCustomMain()
{
      int x,y;
            //Top Banner
            ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Drop Reef Tank   ", Font8x8); //Top Banner
            // Display T1 Header Text
            ReefAngel.LCD.DrawLargeText(COLOR_STEELBLUE,255,5,15,"Sump Temp", Font8x8);
            // Display the T1 Temp Value
            char text[7];
            ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
            ReefAngel.LCD.Clear(255, 10, 25, 50, 60);
            if (ReefAngel.Params.Temp[T1_PROBE]>290) ReefAngel.LCD.DrawHugeNumbers(COLOR_RED, 255, 10, 25, text);
            else if (ReefAngel.Params.Temp[T1_PROBE]>270) ReefAngel.LCD.DrawHugeNumbers(COLOR_ORANGE, 255, 10, 25, text);
            else ReefAngel.LCD.DrawHugeNumbers(COLOR_MIDNIGHTBLUE, 255, 10, 25, text);
            // Display the T2 Header Text
            ReefAngel.LCD.DrawLargeText(0,255,5,45,"Room Temp", Font8x8);
            // Display the T2 Temp Value
            ReefAngel.LCD.Clear(255, 90, 50, 132, 60);
            ConvertNumToString(text, ReefAngel.Params.Temp[T2_PROBE], 10);
            ReefAngel.LCD.DrawLargeText(COLOR_MIDNIGHTBLUE, 255, 90, 45, text, Num8x8);
            // Display pH Header Text
            ReefAngel.LCD.DrawLargeText(COLOR_LIMEGREEN,255,95,15,"pH", Font8x8);
            // Display pH Value
            ConvertNumToString(text, ReefAngel.Params.PH, 100);
            ReefAngel.LCD.Clear(0, 65, 62 , 65, 62);
            if (ReefAngel.Params.PH>840 || ReefAngel.Params.PH<790) ReefAngel.LCD.DrawLargeText(COLOR_RED, 255, 85, 25, text, Num8x8);
            else if (ReefAngel.Params.PH>830 || ReefAngel.Params.PH<800) ReefAngel.LCD.DrawLargeText(COLOR_ORANGE, 255, 85, 25, text, Num8x8);
            else ReefAngel.LCD.DrawLargeText(COLOR_MIDNIGHTBLUE, 255, 85, 25, text, Num8x8);
            
//****************************************************************************************************************************************************************************
//------------------------------------------------------------------ Display Vortech Mode ------------------------------------------------------------------------------------

            ReefAngel.LCD.DrawLargeText(0,255,5,55,"Vortech", Font8x8); 
            
//****************************************************************************************************************************************************************************            
//---------------------------------------------------------------- Display EcoSmart Mode Value -------------------------------------------------------------------------------

            ReefAngel.LCD.Clear(255, 66, 60, 132, 70);
            if (vtechmode == 0) ReefAngel.LCD.DrawLargeText(COLOR_LIMEGREEN,255, 66, 55,"Constant");
            else if(vtechmode == 1) ReefAngel.LCD.DrawLargeText(COLOR_GOLD,255, 66, 55,"Lagoon");
            else if (vtechmode == 2) ReefAngel.LCD.DrawLargeText(COLOR_GOLD,255, 80, 55,"RCM");
            else if (vtechmode == 3) ReefAngel.LCD.DrawLargeText(COLOR_CORNFLOWERBLUE,255, 80, 55,"Short");
            else if (vtechmode == 4) ReefAngel.LCD.DrawLargeText(COLOR_PINK,255, 66, 55,"Long");
            else if (vtechmode == 5) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255, 80, 55,"NTM");
            else if (vtechmode == 6) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255, 80, 55,"TSM");
            else if (vtechmode == 9) ReefAngel.LCD.DrawLargeText(COLOR_GRAY,255, 80, 55,"Night");
            
//****************************************************************************************************************************************************************************            
//------------------------------------------------------------------- Display Salinity ---------------------------------------------------------------------------------------

            ReefAngel.LCD.DrawLargeText(0,255,64,114,"Salinity", Font8x8);
            
//****************************************************************************************************************************************************************************
//----------------------------------------------------------------- Display Salinity Value -----------------------------------------------------------------------------------

            ReefAngel.LCD.Clear(255, 82, 85, 65, 95);
            ConvertNumToString(text, ReefAngel.Params.Salinity, 10);
            ReefAngel.LCD.DrawLargeText(COLOR_LIMEGREEN, 255, 85, 122, text, Num8x8);
            
//*****************************************************************************************************************************************************************************
//-----------------------------------------------------------Start Moon Phase,Cloud or Storm Display---------------------------------------------------------------------------
/* if (ReefAngel.PWM.Channel[5] > 0);
  {
    ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,70,105,MoonPhaseLabel());

  }
           if (ReefAngel.PWM.ExpansionChannel[0] > 0 && (hour() < 14 ) )
            {
               ReefAngel.LCD.DrawLargeText(COLOR_ORANGERED,255,3,65, "Sunrise",Font8x8);
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,3,75, ReefAngel.PWM.ExpansionChannel[0]);
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,20,74, ":");
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,24,75, ReefAngel.PWM.ExpansionChannel[1]);
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,41,74, ":");
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,45,75, ReefAngel.PWM.ExpansionChannel[2]);
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,66,75, "|");
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,70,75, ReefAngel.PWM.ExpansionChannel[3]);
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,87,74, ":");
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,91,75, ReefAngel.PWM.ExpansionChannel[4]);
            }
           else if (ReefAngel.PWM.ExpansionChannel[0] > 0 && (hour() > 14 ))
            {
               ReefAngel.LCD.DrawLargeText(COLOR_ORANGERED,255,3,65, "Sunrise",Font8x8);
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,3,75, ReefAngel.PWM.ExpansionChannel[0]);
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,20,74, ":");
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,24,75, ReefAngel.PWM.ExpansionChannel[1]);
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,41,74, ":");
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,45,75, ReefAngel.PWM.ExpansionChannel[2]);
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,66,75, "|");
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,70,75, ReefAngel.PWM.ExpansionChannel[3]);
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,87,74, ":");
               ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,91,75, ReefAngel.PWM.ExpansionChannel[4]);
            }
  */         
//*****************************************************************************************************************************************************************************
//---------------------------------------------------------- Display Main and Expansion Relay Box -----------------------------------------------------------------------------

            TempRelay = ReefAngel.Relay.RelayData;
            TempRelay &= ReefAngel.Relay.RelayMaskOff;
            TempRelay |= ReefAngel.Relay.RelayMaskOn;
            ReefAngel.LCD.DrawCircleOutletBox(10,90, TempRelay);
            pingSerial();

            TempRelay2 = ReefAngel.Relay.RelayDataE[0];
            TempRelay2 &= ReefAngel.Relay.RelayMaskOffE[0];
            TempRelay2 |= ReefAngel.Relay.RelayMaskOnE[0];
            ReefAngel.LCD.DrawCircleOutletBox(40,90, TempRelay2);
            pingSerial();
             
//***************************************************************************************************************************************************************************
}
void DrawCustomGraph()
{}
//***************************************************************************************************************************************************************************
void setup()
{
    // This must be the first line
    ReefAngel.Init();  //Initialize controller
    ReefAngel.SetTemperatureUnit( Celsius );  // set to Celsius Temperature

    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = 0;
    ReefAngel.FeedingModePortsE[0] = 0;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = Port2Bit | Port3Bit | Port4Bit | Port5Bit | Port6Bit;
    ReefAngel.WaterChangePortsE[0] = Port1Bit | Port2Bit | Port3Bit;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = 0;
    ReefAngel.LightsOnPortsE[0] = Port4Bit;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = Port5Bit | Port6Bit;
    ReefAngel.OverheatShutoffPortsE[0] = 0;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;


    // Ports that are always on
    ReefAngel.Relay.On( Port1 );
    ReefAngel.Relay.On( Port4 );
    ReefAngel.Relay.On( Port7 );
    ReefAngel.Relay.On( Port8 );
    ReefAngel.Relay.On( Box1_Port1 );
    ReefAngel.Relay.On( Box1_Port2 );
    ReefAngel.Relay.On( Box1_Port3 );
    ReefAngel.Relay.On( Box1_Port7 );
    ReefAngel.Relay.On( Box1_Port8 );
}

void loop()
{
    ReefAngel.Relay.DelayedOn( Port2 );
    ReefAngel.StandardHeater( Port5 );
    ReefAngel.StandardHeater( Port6 );
    ReefAngel.StandardATO( Box1_Port5 );
    ReefAngel.MoonLights( Box1_Port4 );

    //***************************************************************************************************************************************************************************
//------------------------------------------------------------------ Start Time-of-Day Based Functions ----------------------------------------------------------------------
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These are the mode numbers for the RF Expansion Module for reference ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //#define Constant      0
    //#define Random1       1 // Lagoonal
    //#define Random2       2 // Reef Crest
    //#define ShortWave     3
    //#define LongWave      4
    //#define Smart_NTM     5 // Nutrient Transport Mode
    //#define Smart_TSM     6 // Tidal Swell Mode
    //#define Feeding_Start 7
    //#define Feeding_Stop  8
    //#define Night         9
    //#define Slave_Start   97
    //#define Slave_Stop    98
    //#define None          99
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//----------------------------------------------------------------- Start RF Daytime Control ------------------------------------------------------------------------------
      if (!fOverrideRF)
        {
        if (hour() >8 && hour() < 14)
        {
            ReefAngel.RF.UseMemory=false;
            ReefAngel.RF.SetMode(Smart_NTM,80,7);
            vtechmode = Smart_NTM;
        }
       else if (hour() >14 && hour() < 22)
        {
            ReefAngel.RF.UseMemory=false;
            ReefAngel.RF.SetMode(Random2,60,7);
            vtechmode = Random2;
        }

//--------------------------------------------------------------- Start RF Nightmode Control -----------------------------------------------------------------------------
       else if (hour()>=22 || hour()<8) // Defining "Nightmode" hours for VorTech = between 10 PM and 8 AM
        {
            ReefAngel.RF.UseMemory=false;
            ReefAngel.RF.SetMode(Night,10,0);
            vtechmode = Night;
        }
        else
        {
            ReefAngel.RF.SetMode(Feeding_Stop,0,0); //Temp fix for coming out of Night mode
            ReefAngel.RF.UseMemory=false;
            ReefAngel.RF.SetMode(Smart_NTM,80,7);
            vtechmode = Smart_NTM;
            ReefAngel.RF.SetMode(vtechmode, InternalMemory.RFSpeed_read(), InternalMemory.RFDuration_read());
        } 
      }
    else
       {
          ReefAngel.RF.UseMemory=false;
          ReefAngel.RF.SetMode(vtechmode, InternalMemory.RFSpeed_read(), InternalMemory.RFDuration_read());
       }

//***************************************************************************************************************************************************************************    

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


rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: My almost completed pde

Post by rimai »

You are missing one line in the setup() section:

Code: Select all

  ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));
Roberto.
User avatar
JNieuwenhuizen
Posts: 96
Joined: Thu Feb 16, 2012 12:39 am
Location: South Africa

Re: My almost completed pde

Post by JNieuwenhuizen »

Thanx Roberto!
Post Reply