JerkyJunky's Starter Screen

Share you PDE file with our community

Posts: 12
Joined: Wed Nov 07, 2012 10:08 am
PostPosted: Fri Nov 16, 2012 6:37 pm
Been a fun couple days programming in a new screen for my RA. Here is what I have so far:

http://i.imgur.com/9UVk9.jpg

The wavemaker stuff is filler until I get an actual unit, but the rest is legit. Here is the code:

Code: Select all
#include <ReefAngel_Features.h>
#include <Globals.h>
#include <RA_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <InternalEEPROM.h>
#include <RA_NokiaLCD.h>
#include <RA_ATO.h>
#include <RA_Joystick.h>
#include <LED.h>
#include <RA_TempSensor.h>
#include <Relay.h>
#include <RA_PWM.h>
#include <Timer.h>
#include <Memory.h>
#include <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <ReefAngel.h>

////// Place global variable code below here
#define FONT_8x16

////// Place global variable code above here


void setup()
{
    // This must be the first line
    ReefAngel.Init();  //Initialize controller
    ReefAngel.AddStandardMenu();  // Add Standard Menu

    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = Port5Bit;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = Port5Bit | Port8Bit;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = 0;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = 0;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;
    // Set the Overheat temperature setting
    InternalMemory.OverheatTemp_write( 800 );


    // Ports that are always on
    ReefAngel.Relay.On( Port5 );
    ReefAngel.Relay.On( Port6 );
    ReefAngel.Relay.On( Port7 );
    ReefAngel.Relay.On( Port8 );

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

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

void loop()
{
    ReefAngel.StandardLights( Port1,19,45,8,15 );
    ReefAngel.StandardLights( Port3,19,59,8,1 );
    ReefAngel.StandardLights( Port4,7,59,20,1 );
    ReefAngel.PWM.SetDaylight( PWMSlope(8,0,20,0,15,100,60,0) );
    ReefAngel.PWM.SetActinic( PWMSlope(20,0,8,0,15,100,60,0) );
    ////// Place your custom code below here
   

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

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

void DrawCustomMain()
{
    byte offset = 3;
    byte waterLevel = ReefAngel.WaterLevel.GetLevel();
    byte dispLights = ReefAngel.PWM.GetDaylightValue();
    byte sumpLights = ReefAngel.PWM.GetActinicValue();
    byte TempRelay = ReefAngel.Relay.RelayData;
    byte atoPort = 3;
    TempRelay &= ReefAngel.Relay.RelayMaskOff;
    TempRelay |= ReefAngel.Relay.RelayMaskOn;
    char text[10];
   
   
    // Header = Title + Date and Time
    ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 15, offset, "JerkyJunky's Reef");
    ReefAngel.LCD.DrawDate(6, offset + 10);
    ReefAngel.LCD.Clear(COLOR_GREEN, 1, offset + 20, 128, offset + 20);
    offset = 26;
    pingSerial();
   
    // Main Relay Box & Parameters
    ReefAngel.LCD.DrawCircleOutletBoxHorizontal(2, offset, TempRelay);
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 50, offset, "Temp:");
    ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
    ReefAngel.LCD.DrawLargeText(COLOR_PURPLE, 255, 49, offset + 9, text, Font8x16);
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 101, offset, "pH:");
    ConvertNumToString(text, ReefAngel.Params.PH, 100);
    ReefAngel.LCD.DrawLargeText(COLOR_ORANGE, 255, 93, offset + 9, text, Font8x16);
    ReefAngel.LCD.Clear(COLOR_GREEN, 1, offset + 23, 128, offset + 23);
    offset = offset + 27;
    pingSerial();

    // Lights
    if (dispLights > 0)
      ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 10, offset, "Display");
    else
      ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 10, offset, "Display");
    if (sumpLights > 0)
      ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 72, offset, "Refugium");
    else
      ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 72, offset, "Refugium");
    ConvertNumToString(text, dispLights, 1);
    strcat(text, "%");
    ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 15, offset + 9, text, Font8x16);
    ConvertNumToString(text, sumpLights, 1);
    strcat(text, "%");
    ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 95, offset + 9, text, Font8x16);
    ReefAngel.LCD.Clear(COLOR_GREEN, 1, offset + 24, 128, offset + 24);
    offset = offset + 27;
    pingSerial();
   

    // Water Level & ATO
    if (waterLevel >= 100)
    {
    ReefAngel.LCD.DrawText(COLOR_BLUE, DefaultBGColor, 5, offset, "Tank Level");
    ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 25, offset + 9, "Full", Font8x16);
    }
    else if (waterLevel >= 50)
    {
    ReefAngel.LCD.DrawText(COLOR_ORANGE, DefaultBGColor, 5, offset, "Tank Level");
    ConvertNumToString(text, waterLevel, 1);
    strcat(text, "%");
    ReefAngel.LCD.Clear(DefaultBGColor, 1, offset + 9, 128, offset + 18);
    ReefAngel.LCD.DrawLargeText(COLOR_ORANGE, DefaultBGColor, 25, offset + 9, text, Font8x16);
    }
    else
    {
    ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 5, offset, "Tank Level");
    ConvertNumToString(text, waterLevel, 1);
    strcat(text, "%");
    ReefAngel.LCD.DrawLargeText(COLOR_RED, DefaultBGColor, 25, offset + 9, text, Font8x16);   
    }
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 70, offset + 2, "ATO:");
    if (ReefAngel.LowATO.IsActive())
    {
       ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 95, offset + 2, "Avail");
    }
    else
    {
       ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 95, offset + 2, "Empty");
    }
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 72, offset + 12, "Pump:");
    if ((TempRelay&(1<<(atoPort - 1)))==1<<(atoPort - 1))
    {
        ReefAngel.LCD.Clear(DefaultBGColor, 102, offset + 12, 128, offset + 21);       
       ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 102, offset + 12, "On");
    }
    else
    {
       ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 102, offset + 12, "Off");
    }
    ReefAngel.LCD.Clear(COLOR_GREEN, 1, offset + 24, 128, offset + 24);
    offset = offset + 27;
    pingSerial();

    // Wavemaker
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 8, offset, "Vortech Mode");
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 95, offset, "Speed");
    ReefAngel.LCD.DrawLargeText(COLOR_ORANGE, DefaultBGColor, 5, offset + 9, "Reef Crest", Font8x16);
    ReefAngel.LCD.DrawLargeText(COLOR_GREEN, DefaultBGColor, 98, offset + 9, "XX%", Font8x16);

}

void DrawCustomGraph()
{
}


Now to add in the cloud logic, the sunrise by location code, the ATO controls, and the heater settings. WHEW! Going to be a fun weekend. :D
User avatar
Posts: 5330
Joined: Fri Jul 20, 2012 9:42 am
PostPosted: Fri Nov 16, 2012 6:42 pm
Looks great!

Posts: 12
Joined: Wed Nov 07, 2012 10:08 am
PostPosted: Fri Nov 16, 2012 6:50 pm
Thanks! Still some errors that will pop up I already know of. I'm not clearing everything that needs to be so I'll get some artifacts I'm sure. Sucks the tank is still cycling and I can't play fully with the lights and cloud settings for a bit. Darn bacteria refusing to breed! :(
User avatar
Posts: 2602
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
PostPosted: Fri Nov 16, 2012 8:14 pm
nice and busy screen. it has all the stuff you need. Looking good!

Posts: 12
Joined: Wed Nov 07, 2012 10:08 am
PostPosted: Tue Nov 20, 2012 9:23 pm
Here is the next version of my display:

http://i.imgur.com/7zyND.jpg

As you can see, I have completed the Event Previewer area, and have it accurately (or so it seems) predicting the next lighting effect be it sunrise, sunset, dawn, dusk, cloud, or sunlight. It also should be saying the correct ETA as well. The bottom diag numbers are time of dawn tomorrow.

Here is the code I used to get it. I also have heavily modified cloud code. I've added in a min/max cloud fade chance. It also no longer used the ReversePWMSlope. Any feedback would be welcome! :-)

Code: Select all
#include <ReefAngel_Features.h>
#include <Globals.h>
#include <RA_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <InternalEEPROM.h>
#include <RA_NokiaLCD.h>
#include <RA_ATO.h>
#include <RA_Joystick.h>
#include <LED.h>
#include <RA_TempSensor.h>
#include <Relay.h>
#include <RA_PWM.h>
#include <Timer.h>
#include <Memory.h>
#include <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <ReefAngel.h>
#include <SunLocation.h>

////// Place global variable code below here
#define FONT_8x16
SunLocation sl;
time_t nextEvent = 0, timeSunRise, timeSunSet, nextCloud = 0;
String nextEventName;
boolean isCloudy = false;

//Cloud Defines:
   // Frequency in days based on the day of the month - number 2 means every 2 days, for example (day 2,4,6 etc)
#define Clouds_Every_X_Days 1

  // Percentage chance of a cloud happening today
#define Cloud_Chance_per_Day 50

  // 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 30

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

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

   // Time in minutes for the fade of a cloud to take affect
#define Cloud_Fade_Duration 3

   // Minimum fade of cloud
#define Min_Cloud_Fade 20

   // Maximum fade of cloud
#define Max_Cloud_Fade 70

  // Only start the cloud effect after this setting
//#define Start_Cloud_After NumMins(10,30)

  // Always end the cloud effect before this setting
//#define End_Cloud_Before NumMins(17,30)

  // Percentage chance of a lightning happen for every cloud
#define Lightning_Chance_per_Cloud 0

byte cloudChance=0;
byte cloudDuration=0;
time_t cloudStart=0;
byte numClouds=0;
byte lightningChance=0;
byte cloudIndex=0;
byte lightningStatus=0;
byte cloudFade = 0;

////// Place global variable code above here


void setup()
{
    // This must be the first line
    ReefAngel.Init();  //Initialize controller
    ReefAngel.AddStandardMenu();  // Add Standard Menu

    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = Port5Bit;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = Port5Bit | Port8Bit;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = 0;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = 0;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;
    // Set the Overheat temperature setting
    InternalMemory.OverheatTemp_write( 800 );

    ReefAngel.Relay.On( Port2 );
    ReefAngel.Relay.On( Port5 );
    ReefAngel.Relay.On( Port6 );
    ReefAngel.Relay.On( Port7 );
    ReefAngel.Relay.On( Port8 );

    if (nextEvent == 0) {GetNextEvent();}

}


void loop()
{
   //Moonlights
    ReefAngel.StandardLights(Port1, hour(timeSunSet - 900), minute(timeSunSet - 900), hour(timeSunRise + 900), minute(timeSunRise + 900));
   //Sump Lights
    ReefAngel.StandardLights(Port3, hour(timeSunSet - 60), minute(timeSunSet - 60), hour(timeSunRise + 60), minute(timeSunRise + 60));
   //Display Lights
    ReefAngel.StandardLights(Port4, hour(timeSunRise - 60), minute(timeSunRise - 60), hour(timeSunSet + 60), minute(timeSunSet + 60));
    //Sun Pattern for Display
    ReefAngel.PWM.SetDaylight(PWMSlope(hour(timeSunRise), minute(timeSunRise), hour(timeSunSet), minute(timeSunSet), 15, 100, 30, 0));
    //Sun Pattern for Sump
    ReefAngel.PWM.SetActinic(PWMSlope(hour(timeSunSet), minute(timeSunSet), hour(timeSunRise), minute(timeSunRise), 15, 100, 30, 0));
   
    ////// Place your custom code below here
    if (now() >= nextEvent) { GetNextEvent(); }
    if (isCloudy)
    {
       ReefAngel.PWM.SetDaylight(PWMSlope(hour(cloudStart), minute(cloudStart), hour(cloudStart + cloudDuration), minute(cloudStart + cloudDuration), 100, cloudFade, 3, 100));
    }
    ReefAngel.Portal("jerkyjunky");
    ////// Place your custom code above here

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


void GetNextEvent()
{
      if (nextEvent == 0)
      {
         sl.CalSun();
         timeSunRise = sl.GetSunRise();
         timeSunSet = sl.GetSunSet();
      }
      if (now() < timeSunRise - 1800)
      {
         nextEventName = "Dawn";
         nextEvent = timeSunRise - 1800;
      }
      else if (now() < timeSunRise)
      {
         sl.CalSun();
         cloudChance = 255;
         GetNextCloud();
         timeSunRise = sl.GetSunRise();
         timeSunSet = sl.GetSunSet();
         nextEventName = "Sunrise";
         nextEvent = timeSunRise;
      }
      else if (now() >= timeSunSet + 1800)
      {
         nextEventName = "Dawn";
                        sl.GetTomorrowSunRise(&timeSunRise);
         nextEvent = timeSunRise - 1800;
      }
      else if (now() >= timeSunSet)
      {      
         nextEventName = "Dusk";
         nextEvent = timeSunSet + 1800;
      }
      else
      {
         if ((now() > nextCloud) && (nextCloud > 0))
         {
            nextEventName = "Cloud";
            nextEvent = nextCloud;
         }
         else if ((now() >= nextCloud) && (nextCloud > 0))
         {
            isCloudy = true;
            cloudFade = random(Min_Cloud_Fade, Max_Cloud_Fade);
            nextEventName = "Sun";
            nextEvent = nextCloud + cloudDuration;
         }
         else if (isCloudy)
         {
            isCloudy = false;
            cloudIndex++;
            GetNextCloud();
            if (nextCloud > 0)
            {
               nextEvent = nextCloud;
               nextEventName = "Cloud";
            }
            else
            {
               nextEventName = "Sunset";
               nextEvent = timeSunSet;
            }
         }
         else
         {
            nextEventName = "Sunset";
            nextEvent = timeSunSet;
         }
      }
}


void GetNextCloud()
{
      //Init - Ran by GetNextEvent() at Dawn once per day by setting cloudChance to 255
      if (cloudChance == 255)
      {
         //is today cloudy?
         cloudChance = random(100);
         if ((cloudChance > Cloud_Chance_per_Day) || ((day() % Clouds_Every_X_Days) != 0))
         {
            cloudChance = 0;
         }
         else
         {
            time_t t = now();
            numClouds = random(Min_Clouds_per_Day, Max_Clouds_per_Day);
            cloudStart = t - ((hour(t) * 3600) + (minute(t) * 60) + second(t));
            cloudStart += (random(timeSunRise, timeSunRise + ((timeSunSet - timeSunRise) / (numClouds * 2)))) * 60;
            cloudDuration = (random(Min_Cloud_Duration, Max_Cloud_Duration)) * 60;
            lightningChance = random(100);
            if (lightningChance > Lightning_Chance_per_Cloud) lightningChance = 0;
         }
      }
      else
      {
         if (cloudIndex < numClouds)
         {
            time_t t = now();
            cloudStart = t - ((hour(t) * 3600) + (minute(t) * 60) + second(t));
            cloudStart += (random(timeSunRise + (((timeSunSet - timeSunRise) / (numClouds * 2)) * cloudIndex * 2), (timeSunRise + (((timeSunSet - timeSunRise) / (numClouds * 2)) * cloudIndex * 2)) + ((timeSunSet - timeSunRise) / (numClouds * 2)))) * 60;
            cloudDuration = (random(Min_Cloud_Duration, Max_Cloud_Duration)) * 60;
            lightningChance = random(100);
            if (lightningChance > Lightning_Chance_per_Cloud) lightningChance = 0;
         }
         else
         {
            cloudStart = 0;
            cloudDuration = 0;
            cloudIndex = 0;
         }
      }
}


void DrawCustomMain()
{
    byte offset = 3;
    byte waterLevel = ReefAngel.WaterLevel.GetLevel();
    byte dispLights = ReefAngel.PWM.GetDaylightValue();
    byte sumpLights = ReefAngel.PWM.GetActinicValue();
    byte TempRelay = ReefAngel.Relay.RelayData;
    byte atoPort = 3;
    TempRelay &= ReefAngel.Relay.RelayMaskOff;
    TempRelay |= ReefAngel.Relay.RelayMaskOn;
    char text[10];
   
   
    // Header = Title + Date and Time
    ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 15, offset, "JerkyJunky's Reef");
    ReefAngel.LCD.DrawDate(6, offset + 10);
    ReefAngel.LCD.Clear(COLOR_GREEN, 1, offset + 20, 128, offset + 20);
    offset = 26;
    pingSerial();
   
    // Main Relay Box & Parameters
    ReefAngel.LCD.Clear(DefaultBGColor, 1, offset, 45, offset + 21);
    ReefAngel.LCD.DrawCircleOutletBoxHorizontal(2, offset, TempRelay);
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 50, offset, "Temp:");
    ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
    ReefAngel.LCD.DrawLargeText(COLOR_PURPLE, 255, 49, offset + 9, text, Font8x16);
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 101, offset, "pH:");
    ConvertNumToString(text, ReefAngel.Params.PH, 100);
    ReefAngel.LCD.DrawLargeText(COLOR_ORANGE, 255, 93, offset + 9, text, Font8x16);
    offset = offset + 23;
    pingSerial();


    // Water Level & ATO
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 5, offset, "Tank Level");
    if (waterLevel >= 100)
    {
    ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 19, offset + 9, "Full", Font8x16);
    }
    else if (waterLevel >= 50)
    {
    ConvertNumToString(text, waterLevel, 1);
    strcat(text, "%");
    ReefAngel.LCD.Clear(DefaultBGColor, 1, offset + 9, 60, offset + 22);
    ReefAngel.LCD.DrawLargeText(COLOR_ORANGE, DefaultBGColor, 23, offset + 9, text, Font8x16);
    }
    else
    {
    ConvertNumToString(text, waterLevel, 1);
    strcat(text, "%");
    ReefAngel.LCD.Clear(DefaultBGColor, 1, offset + 9, 60, offset + 22);
    ReefAngel.LCD.DrawLargeText(COLOR_RED, DefaultBGColor, 23, offset + 9, text, Font8x16);   
    }
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 70, offset + 2, "ATO:");
    if (ReefAngel.LowATO.IsActive())
    {
       ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 95, offset + 2, "Avail");
    }
    else
    {
       ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 95, offset + 2, "Empty");
    }
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 72, offset + 12, "Pump:");
    if ((TempRelay&(1<<(atoPort - 1)))==1<<(atoPort - 1))
    {
        ReefAngel.LCD.Clear(DefaultBGColor, 102, offset + 12, 128, offset + 21);       
       ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 102, offset + 12, "On");
    }
    else
    {
       ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 102, offset + 12, "Off");
    }
    ReefAngel.LCD.Clear(COLOR_GREEN, 1, offset + 24, 128, offset + 24);
    offset = offset + 27;
    pingSerial();
   
   
    // Lights
    if (dispLights > 0)
      ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 10, offset, "Display");
    else
      ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 10, offset, "Display");
    if (sumpLights > 0)
      ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 72, offset, "Refugium");
    else
      ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 72, offset, "Refugium");
    ReefAngel.LCD.Clear(DefaultBGColor, 1, offset + 9, 128, offset + 22);
    ConvertNumToString(text, dispLights, 1);
    strcat(text, "%");
    if (strlen(text) == 5)
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 10, offset + 9, text, Font8x16);
    else if (strlen(text) == 4)
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 14, offset + 9, text, Font8x16);
    else if (strlen(text) == 3)
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 18, offset + 9, text, Font8x16);
    else
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 22, offset + 9, text, Font8x16);
    ConvertNumToString(text, sumpLights, 1);
    strcat(text, "%");
    if (strlen(text) == 5)
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 80, offset + 9, text, Font8x16);
    else if (strlen(text) == 4)
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 84, offset + 9, text, Font8x16);
    else if (strlen(text) == 3)
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 88, offset + 9, text, Font8x16);
    else
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 92, offset + 9, text, Font8x16);
    offset = offset + 25;
    pingSerial();
   
    ReefAngel.LCD.Clear(DefaultBGColor, 1, offset, 128, offset + 17);
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 2, offset, "Next Event:");
    nextEventName.toCharArray(text, 10);
    ReefAngel.LCD.DrawText(COLOR_BLUE, DefaultBGColor, 70, offset, text);
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 2, offset + 9, "Time Until:");
    if (nextEvent > now())
    {
      ConvertNumToString(text, hour(nextEvent - now()), 1);
      strcat(text, ":");
      ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 75, offset + 9, text);
      ConvertNumToString(text, minute(nextEvent - now()), 1);
      ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 95, offset + 9, text);
    }
    else
    {
      ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 75, offset + 9, "NOW!");
    }
    pingSerial();
   
    ConvertNumToString(text, hour(timeSunSet) , 1);
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 2, offset + 18, text);
    ConvertNumToString(text, minute(timeSunSet) , 1);
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 70, offset + 18, text);

}

void DrawCustomGraph()
{
}

Posts: 11845
Joined: Fri Mar 18, 2011 6:47 pm
PostPosted: Wed Nov 21, 2012 11:21 am
Pretty cool :)
Roberto.

Posts: 240
Joined: Thu Sep 01, 2011 8:44 pm
PostPosted: Thu Nov 29, 2012 9:25 pm
Like it! I especially like how you tucked the relay circles up in the corner...
Image

Posts: 12
Joined: Wed Nov 07, 2012 10:08 am
PostPosted: Wed Dec 05, 2012 3:53 pm
Thanks! The code for it should be in the other how do I area if you wanted just that how to bit. :-)

I've edited a bit more and fixed some issues with the clouds not processing correctly. Also added in the ATO bit. I have a bucket on the side of my stand with RODI water in it and a pump. The pump has a float switch on it so I know if I'm about to suck air or not (LowATO). There is also an emergency float in the sump to act as a redundant check to the water sensor kit (HighATO). Other than that cleaned it up a bit and added better comments here and there.

Code: Select all
#include <ReefAngel_Features.h>
#include <Globals.h>
#include <RA_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <InternalEEPROM.h>
#include <RA_NokiaLCD.h>
#include <RA_ATO.h>
#include <RA_Joystick.h>
#include <LED.h>
#include <RA_TempSensor.h>
#include <Relay.h>
#include <RA_PWM.h>
#include <Timer.h>
#include <Memory.h>
#include <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <ReefAngel.h>
#include <SunLocation.h>

////// Place global variable code below here
#define FONT_8x16
SunLocation sl;
time_t nextEvent = 0, timeSunRise, timeSunSet, nextCloud = 0;
String nextEventName;
boolean isCloudy = false;
boolean isATOAvail = false;
byte atoPort = 0;;

//Cloud Defines:
  // Frequency in days based on the day of the month - number 2 means every 2 days, for example (day 2,4,6 etc)
#define Clouds_Every_X_Days 1

  // Percentage chance of a cloud happening today
#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 30

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

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

  // Time in minutes for the fade of a cloud to take affect
#define Cloud_Fade_Duration 3

  // Minimum fade of cloud
#define Min_Cloud_Fade 20

  // Maximum fade of cloud
#define Max_Cloud_Fade 70

byte cloudChance=0;
byte cloudDuration=0;
byte numClouds=0;
byte cloudIndex=0;
byte cloudFade = 0;

////// Place global variable code above here


void setup()
{
   //This must be the first line
   ReefAngel.Init();  //Initialize controller
   ReefAngel.AddStandardMenu();  // Add Standard Menu

   //Ports toggled in Feeding Mode
   ReefAngel.FeedingModePorts = Port7Bit;
   //Ports toggled in Water Change Mode
   ReefAngel.WaterChangePorts = Port8Bit;
   //Ports toggled when Lights On / Off menu entry selected
   ReefAngel.LightsOnPorts = 0;
   //Ports turned off when Overheat temperature exceeded
   ReefAngel.OverheatShutoffPorts = 0;
   //Use T1 probe as temperature and overheat functions
   ReefAngel.TempProbe = T1_PROBE;
   ReefAngel.OverheatProbe = T1_PROBE;
   //Set the Overheat temperature setting
   InternalMemory.OverheatTemp_write(800);
   //Set the port ATO is on numerically
   atoPort = 6;

   //Enable LED driver board fan
   ReefAngel.Relay.On( Port2 );
   //Enable heater port - Currently not used
   ReefAngel.Relay.On( Port5 );
   //Enable skimmer
   ReefAngel.Relay.On( Port7 );
   //Enable return pump
   ReefAngel.Relay.On( Port8 );

   //Get an event at startup
   if (nextEvent == 0) {GetNextEvent();}

}


void loop()
{
   //Moonlights
   ReefAngel.StandardLights(Port1, hour(timeSunSet - 90), minute(timeSunSet - 90), hour(timeSunRise + 90), minute(timeSunRise + 90));
   
   //Sump Lights
   ReefAngel.StandardLights(Port3, hour(timeSunSet - 60), minute(timeSunSet - 60), hour(timeSunRise + 60), minute(timeSunRise + 60));
   
   //Display Lights
   ReefAngel.StandardLights(Port4, hour(timeSunRise - 1860), minute(timeSunRise - 1860), hour(timeSunSet + 1860), minute(timeSunSet + 1860));
   
   //Sun Pattern for Sump
   ReefAngel.PWM.SetActinic(PWMSlope(hour(timeSunSet), minute(timeSunSet), hour(timeSunRise), minute(timeSunRise), 15, 100, 30, 0));
   
   //Sun Pattern for Display
   if (isCloudy)
   {
      ReefAngel.PWM.SetDaylight(PWMSlope(hour(nextCloud), minute(nextCloud), hour(nextCloud + cloudDuration), minute(nextCloud + cloudDuration), 100, cloudFade, 3, 100));
   }
   else
   {
      ReefAngel.PWM.SetDaylight(PWMSlope(hour(timeSunRise - 1800), minute(timeSunRise - 1800), hour(timeSunSet + 1800), minute(timeSunSet + 1800), 15, 100, 30, 0));
   }
   
   //ATO code
   //check emergency float switch detector in sump for overfilling
   if (ReefAngel.HighATO.IsActive())
   {
      ReefAngel.Relay.Off(Port6);
   }
   //else check status of top off bucket
   //check if bucket level is too low to pump from or if water in sump is getting too high
   else if ((ReefAngel.LowATO.IsActive() == false) || (ReefAngel.WaterLevel.GetLevel() > 90))
   {
      ReefAngel.Relay.Off(Port6);
   }
   //check if pump should be enabled
   else if ((ReefAngel.LowATO.IsActive()) && (ReefAngel.WaterLevel.GetLevel() <= 80))
   {
      ReefAngel.Relay.On(Port6);
   }

   //Event logic
   //if we just past the current event, go get another
   if (now() >= nextEvent) { GetNextEvent(); }
   
   // This should always be the last line
   ReefAngel.ShowInterface();
}


void GetNextEvent()
{
   //check if called from setup and if so establish current day's params
   if (nextEvent == 0)
   {
      sl.CalSun();
      timeSunRise = sl.GetSunRise();
      timeSunSet = sl.GetSunSet();
   }
   //WHEN IS IT?!?!?
   //Before the sun starts peeking over the horizon?
   if (now() < timeSunRise - 1800)
   {
      nextEventName = "Dawn";
      nextEvent = timeSunRise - 1800;
   }
   //Is the sun rising?
   //Use this time to figure out if today will be cloudy since we can kind of see the sky now
   else if (now() < timeSunRise)
   {
      sl.CalSun();
      cloudChance = 255;
      GetNextCloud();
      timeSunRise = sl.GetSunRise();
      timeSunSet = sl.GetSunSet();
      nextEventName = "Sunrise";
      nextEvent = timeSunRise;
   }
   //Is it after the sun has fully set?
   else if (now() >= timeSunSet + 1800)
   {
      nextEventName = "Dawn";
      sl.GetTomorrowSunRise(&timeSunRise);
      nextEvent = timeSunRise - 1800;
   }
   //Is the sun starting to descend?
   else if (now() >= timeSunSet)
   {      
      nextEventName = "Dusk";
      nextEvent = timeSunSet + 1800;
   }
   //Sun is up.  What now?  Clouds perhaps?
   else
   {
      //If clouds today, are we before a cloud?
      if ((now() < nextCloud) && (nextCloud > 0))
      {
         nextEventName = "Cloud";
         nextEvent = nextCloud;
      }
      //We have just entered a cloud zone
      else if ((now() >= nextCloud) && (nextCloud > 0))
      {
         isCloudy = true;
         cloudFade = random(Min_Cloud_Fade, Max_Cloud_Fade);
         nextEventName = "Sun";
         nextEvent = nextCloud + cloudDuration;
      }
      //We are leaving a cloud zone, but are there more?  Find out.
      else if (isCloudy)
      {
         isCloudy = false;
         cloudIndex++;
         GetNextCloud();
         if (nextCloud > 0)
         {
            nextEvent = nextCloud;
            nextEventName = "Cloud";
         }
         else
         {
            nextEventName = "Sunset";
            nextEvent = timeSunSet;
         }
      }
      //Nope, no clouds today.  Get ready for sunset.
      else
      {
         nextEventName = "Sunset";
         nextEvent = timeSunSet;
      }
   }
}


void GetNextCloud()
{
      //Init - Ran by GetNextEvent() at Dawn once per day by setting cloudChance to 255
      if (cloudChance == 255)
      {
         //Is today cloudy?
         cloudChance = random(100);
         if (cloudChance <= Cloud_Chance_per_Day)
         {
            time_t t = now();
            int minSunRise = 0, minSunSet = 0;
            minSunRise = (hour(timeSunRise) * 60) + minute(timeSunRise);
            minSunSet = (hour(timeSunSet) * 60) + minute(timeSunSet);
            numClouds = random(Min_Clouds_per_Day, Max_Clouds_per_Day);
            nextCloud = t - ((hour(t) * 3600) + (minute(t) * 60) + second(t));
            nextCloud += (random(minSunRise, minSunRise + ((minSunSet - minSunRise) / (numClouds * 2)))) * 60;
            cloudDuration = (random(Min_Cloud_Duration, Max_Cloud_Duration)) * 60;
         }
      }
      //We must have picked a cloudy day, but are there more?
      else
      {
         if (cloudIndex < numClouds)
         {
            time_t t = now();
            int minSunRise = 0, minSunSet = 0;
            minSunRise = (hour(timeSunRise) * 60) + minute(timeSunRise);
            minSunSet = (hour(timeSunSet) * 60) + minute(timeSunSet);
            nextCloud = t - ((hour(t) * 3600) + (minute(t) * 60) + second(t));
            nextCloud += (random(minSunRise + (((minSunSet - minSunRise) / (numClouds * 2)) * cloudIndex * 2), (minSunRise + (((minSunSet - minSunRise) / (numClouds * 2)) * cloudIndex * 2)) + ((minSunSet - minSunRise) / (numClouds * 2)))) * 60;
            cloudDuration = (random(Min_Cloud_Duration, Max_Cloud_Duration)) * 60;
         }
         //Nope, out of clouds for today
         else
         {
            nextCloud = 0;
            cloudDuration = 0;
            cloudIndex = 0;
         }
      }
}


void DrawCustomMain()
{
    byte offset = 3;                                                               //Display offset vertically
    byte waterLevel = ReefAngel.WaterLevel.GetLevel();            //Percentage of water height based off sensor (aprox 3-5 inches off top of sump height)
    byte dispLights = ReefAngel.PWM.GetDaylightValue();            //Percentage of lights on display
    byte sumpLights = ReefAngel.PWM.GetActinicValue();            //Percentage of lights on sump
    byte TempRelay = ReefAngel.Relay.RelayData;                        //--------------------
    TempRelay &= ReefAngel.Relay.RelayMaskOff;                        //Setup for relay info
    TempRelay |= ReefAngel.Relay.RelayMaskOn;                           //--------------------
    char text[10];
   
   
    //Header Section - Title + Date and Time
    ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 15, offset, "JerkyJunky's Reef");
    ReefAngel.LCD.DrawDate(6, offset + 10);
    ReefAngel.LCD.Clear(COLOR_GREEN, 1, offset + 20, 128, offset + 20);
    offset = 26;
    pingSerial();
   
    //Main Relay Box & Main Parameters
    ReefAngel.LCD.Clear(DefaultBGColor, 1, offset, 45, offset + 21);
    ReefAngel.LCD.DrawCircleOutletBoxHorizontal(2, offset, TempRelay);
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 50, offset, "Temp:");
    ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
    ReefAngel.LCD.DrawLargeText(COLOR_PURPLE, 255, 49, offset + 9, text, Font8x16);
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 101, offset, "pH:");
    ConvertNumToString(text, ReefAngel.Params.PH, 100);
    ReefAngel.LCD.DrawLargeText(COLOR_ORANGE, 255, 93, offset + 9, text, Font8x16);
    offset = offset + 23;
    pingSerial();


    //Water Level
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 5, offset, "Tank Level");
    ConvertNumToString(text, waterLevel, 1);
    strcat(text, "%");
    if (waterLevel >= 100)
    {
       ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 19, offset + 9, "Full", Font8x16);
    }
    else if (waterLevel >= 90)
    {
         ReefAngel.LCD.Clear(DefaultBGColor, 1, offset + 9, 60, offset + 22);
       ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 23, offset + 9, text, Font8x16);
    }
    else if ((waterLevel < 90) && (waterlevel >=80))
    {
         ReefAngel.LCD.Clear(DefaultBGColor, 1, offset + 9, 60, offset + 22);
         ReefAngel.LCD.DrawLargeText(COLOR_ORANGE, DefaultBGColor, 23, offset + 9, text, Font8x16);   
    }
    else
    {
         ReefAngel.LCD.Clear(DefaultBGColor, 1, offset + 9, 60, offset + 22);
         ReefAngel.LCD.DrawLargeText(COLOR_RED, DefaultBGColor, 23, offset + 9, text, Font8x16);
    }
   
    //ATO - Avail?
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 70, offset + 2, "ATO:");
    if (ReefAngel.LowATO.IsActive())
       ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 95, offset + 2, "Avail");
    else
       ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 95, offset + 2, "Empty");
   
    //ATO - Pump?
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 72, offset + 12, "Pump:");
    if ((TempRelay&(1<<(atoPort - 1)))==1<<(atoPort - 1))
    {
         ReefAngel.LCD.Clear(DefaultBGColor, 102, offset + 12, 128, offset + 21);       
         ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 102, offset + 12, "On");
    }
    else
       ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 102, offset + 12, "Off");
    ReefAngel.LCD.Clear(COLOR_GREEN, 1, offset + 24, 128, offset + 24);
    offset = offset + 27;
    pingSerial();
   
   
    //Lights
    if (dispLights > 0)
      ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 10, offset, "Display");
    else
      ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 10, offset, "Display");
   
    if (sumpLights > 0)
      ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 72, offset, "Refugium");
    else
      ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 72, offset, "Refugium");
   
    ReefAngel.LCD.Clear(DefaultBGColor, 1, offset + 9, 128, offset + 22);
   
    ConvertNumToString(text, dispLights, 1);
    strcat(text, "%");
   
    if (strlen(text) == 5)
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 10, offset + 9, text, Font8x16);
    else if (strlen(text) == 4)
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 14, offset + 9, text, Font8x16);
    else if (strlen(text) == 3)
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 18, offset + 9, text, Font8x16);
    else
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 22, offset + 9, text, Font8x16);
   
    ConvertNumToString(text, sumpLights, 1);
    strcat(text, "%");
   
    if (strlen(text) == 5)
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 80, offset + 9, text, Font8x16);
    else if (strlen(text) == 4)
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 84, offset + 9, text, Font8x16);
    else if (strlen(text) == 3)
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 88, offset + 9, text, Font8x16);
    else
      ReefAngel.LCD.DrawLargeText(COLOR_BLUE, DefaultBGColor, 92, offset + 9, text, Font8x16);
   
    offset = offset + 25;
    pingSerial();
   
    //Events Viewer
    ReefAngel.LCD.Clear(DefaultBGColor, 1, offset, 128, offset + 17);
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 2, offset, "Next Event:");
    nextEventName.toCharArray(text, 10);
    ReefAngel.LCD.DrawText(COLOR_BLUE, DefaultBGColor, 70, offset, text);
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 2, offset + 9, "Time Until:");
    if (nextEvent > now())
    {
      ConvertNumToString(text, hour(nextEvent - now()), 1);
      strcat(text, ":");
      ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 75, offset + 9, text);
      ConvertNumToString(text, minute(nextEvent - now()), 1);
      ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 95, offset + 9, text);
    }
    else
    {
      ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 75, offset + 9, "NOW!");
    }
    pingSerial();
   
    //Diag
    ConvertNumToString(text, hour(nextCloud) , 1);
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 2, offset + 18, text);
    ConvertNumToString(text, cloudChance , 1);
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, 70, offset + 18, text);

}

void DrawCustomGraph()
{
}


Posts: 327
Joined: Tue Mar 22, 2011 12:45 am
Location: San Diego, CA
PostPosted: Sat Dec 08, 2012 4:47 pm
where is the ReefAngel.LCD.DrawCircleOutletBoxHorizontal() function?

Posts: 11845
Joined: Fri Mar 18, 2011 6:47 pm
PostPosted: Sat Dec 08, 2012 5:01 pm
It's not there yet :(
Maybe in the next libraries release
Roberto.
Next

Return to My PDE/INO file

Who is online

Users browsing this forum: No registered users and 2 guests