Custom Main Screens
Re: Custom Main Screens
Yes, I added it I think Roberto took the pull request...
Re: Custom Main Screens
Really Cool design but, i can't find where did you post the code...SuperDodge wrote:
Here's where my screen seems to have settled at during my first week of tinkering with my Reef Angel.
The line that says "Lagoon" will eventually update with my Vortech status (when I save some coin for the RF adapter. The line is always centered
The line that says "Clear Skies" will update to say "Cloudy(XX:XX)" or "Storms(XX:XX)" if there is a cloud or a cloud with lightning coming. This line is always centered.
The moon status updates throughout the month and is always centered.
The line that says W:100% B:100% R:100% updates in real-time to reflect all three channels on my AI Nano fixture. The line is always centered as the position of the numbers changes depending on the number of digits.
THANKS TO EVERYONE WHO PROVIDED GREAT CODE AND IDEAS THROUGHOUT THIS THREAD!
CODE REMOVED BECAUSE I FOUND AN ERROR - WILL REPOST WHEN FIXED
Re: Custom Main Screens
Can anybody help me with this code? I don't know what's wrong but i can't get the DrawHugeNumbers working, i don't get any error just no highlight and obviously doesn't work, also i have like a flashing display, very anoint...
//CUSTOM SCREEM
void DrawCustomMain()
{
byte x = 6;
byte y = 2;
byte t;
ReefAngel.LCD.DrawLargeText(COLOR_ORANGE, COLOR_WHITE, 6, 5, " SEANTADEZ");
ReefAngel.LCD.DrawDate(6, 118);
ReefAngel.LCD.Clear(COLOR_BLACK, 1, 17, 132, 17);
pingSerial();
x = 12;
y += MENU_START_ROW+1;
ReefAngel.LCD.DrawText(COLOR_DARKTURQUOISE, COLOR_WHITE, x, y+6, "TEMP. PH");
char text[7];
ConvertNumToString(text, ReefAngel.Params.PH, 100);
ReefAngel.LCD.Clear(DefaultBGColor, x+16, y+65, x+65, y+16);
ReefAngel.LCD.DrawLargeText(PHColor, DefaultBGColor, x+75, y+18, text);
pingSerial();
ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
y += MENU_START_ROW*2;
x = 10;
ReefAngel.LCD.Clear(DefaultBGColor,x,y,x+(16*4),y+16);
pingSerial();
ReefAngel.LCD.DrawHugeNumbers(T1TempColor, DefaultBGColor, x, y, text);
pingSerial();
x += (16*4) + 8;
ReefAngel.LCD.DrawText(COLOR_DARKTURQUOISE,DefaultBGColor,8,y+25,"Room:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T2_PROBE], COLOR_BLUE,
9, y+35, 10);
//*** Doser's Status ***********
boolean Dose1On = ReefAngel.Relay.Status(Port1);
boolean Dose2On = ReefAngel.Relay.Status(Port2);
//*** End Doser Status ********
// ***** START DOSING IF IS CALCIUM THEN....
if (Dose1On)
{
ReefAngel.LCD.DrawText(COLOR_DARKTURQUOISE,DefaultBGColor,58,y+25," Adding:");
ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 58,y+35, " CALC. ");
}
// ****** **** START DOSING IF IS ALK THEN....
if (Dose2On)
{
ReefAngel.LCD.DrawText(COLOR_DARKTURQUOISE,DefaultBGColor,58,y+25," Adding:");
ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 58,y+35, "ALK");
}
else
{
ReefAngel.LCD.DrawText(COLOR_DARKTURQUOISE,DefaultBGColor,58,y+25," Adding:");
ReefAngel.LCD.DrawText(COLOR_BLUE, DefaultBGColor, 58,y+35, "Nothing");
}
//**** end doser status ********
byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 93, TempRelay);
}
void DrawCustomGraph()
{
}
//End
//CUSTOM SCREEM
void DrawCustomMain()
{
byte x = 6;
byte y = 2;
byte t;
ReefAngel.LCD.DrawLargeText(COLOR_ORANGE, COLOR_WHITE, 6, 5, " SEANTADEZ");
ReefAngel.LCD.DrawDate(6, 118);
ReefAngel.LCD.Clear(COLOR_BLACK, 1, 17, 132, 17);
pingSerial();
x = 12;
y += MENU_START_ROW+1;
ReefAngel.LCD.DrawText(COLOR_DARKTURQUOISE, COLOR_WHITE, x, y+6, "TEMP. PH");
char text[7];
ConvertNumToString(text, ReefAngel.Params.PH, 100);
ReefAngel.LCD.Clear(DefaultBGColor, x+16, y+65, x+65, y+16);
ReefAngel.LCD.DrawLargeText(PHColor, DefaultBGColor, x+75, y+18, text);
pingSerial();
ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
y += MENU_START_ROW*2;
x = 10;
ReefAngel.LCD.Clear(DefaultBGColor,x,y,x+(16*4),y+16);
pingSerial();
ReefAngel.LCD.DrawHugeNumbers(T1TempColor, DefaultBGColor, x, y, text);
pingSerial();
x += (16*4) + 8;
ReefAngel.LCD.DrawText(COLOR_DARKTURQUOISE,DefaultBGColor,8,y+25,"Room:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T2_PROBE], COLOR_BLUE,
9, y+35, 10);
//*** Doser's Status ***********
boolean Dose1On = ReefAngel.Relay.Status(Port1);
boolean Dose2On = ReefAngel.Relay.Status(Port2);
//*** End Doser Status ********
// ***** START DOSING IF IS CALCIUM THEN....
if (Dose1On)
{
ReefAngel.LCD.DrawText(COLOR_DARKTURQUOISE,DefaultBGColor,58,y+25," Adding:");
ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor, 58,y+35, " CALC. ");
}
// ****** **** START DOSING IF IS ALK THEN....
if (Dose2On)
{
ReefAngel.LCD.DrawText(COLOR_DARKTURQUOISE,DefaultBGColor,58,y+25," Adding:");
ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, 58,y+35, "ALK");
}
else
{
ReefAngel.LCD.DrawText(COLOR_DARKTURQUOISE,DefaultBGColor,58,y+25," Adding:");
ReefAngel.LCD.DrawText(COLOR_BLUE, DefaultBGColor, 58,y+35, "Nothing");
}
//**** end doser status ********
byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 93, TempRelay);
}
void DrawCustomGraph()
{
}
//End
Re: Custom Main Screens
The huge numbers are showing just fine.
What do you mean with can't get it working?
The flashing is because you are erasing and painting something over in the same spot.
It flashes because you erase white and paint red, so the white and red causes it to look like it's flashing.
You just have to be careful with painting and erasing. When in doubt, it is easier to erase in a different color other than white to clearly see where you are erasing. I usually use red or green and then I change to white when I'm satisfied with the positioning of what I'm erasing.
This is the line that is doing that:
What do you mean with can't get it working?
The flashing is because you are erasing and painting something over in the same spot.
It flashes because you erase white and paint red, so the white and red causes it to look like it's flashing.
You just have to be careful with painting and erasing. When in doubt, it is easier to erase in a different color other than white to clearly see where you are erasing. I usually use red or green and then I change to white when I'm satisfied with the positioning of what I'm erasing.
This is the line that is doing that:
Code: Select all
ReefAngel.LCD.Clear(DefaultBGColor, x+16, y+65, x+65, y+16);
Roberto.
Re: Custom Main Screens
Great i figured it out it's working great for the last few days. thanks a lot. I'm learning
Re: Custom Main Screens
Got my tank going and started diving in further into my Reef Angel.
Here is what Display looks like, I modified reefer's code. I added the center channel and added code to display the offset speed of the antisync pump
Here is what Display looks like, I modified reefer's code. I added the center channel and added code to display the offset speed of the antisync pump
Code: Select all
//Custom Main, Graph & Menu
static unsigned long PumpSpeed = InternalMemory.DCPumpSpeed_read(); //Sets Value to pump speed
static int PumpOffset = (PumpSpeed*1.10); //Change Value to match AntiSyncOffset value
void DrawCustomMain() {
byte x = 6;
byte y = 2;
byte t;
char text[7];
ReefAngel.LCD.DrawLargeText(COLOR_BLACK,COLOR_WHITE, 6, 2, " GugsJr's Reef");
ReefAngel.LCD.DrawDate(6, 118);
ReefAngel.LCD.Clear(COLOR_BLACK, 1, 17, 132, 17);
pingSerial();
ReefAngel.LCD.DrawLargeText(COLOR_BLUE,COLOR_WHITE, 24,16,"Jebao Mode:");
if (now()%SECS_PER_DAY<52200|| now()%SECS_PER_DAY >=1800) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,28,26,"Night Mode");
else if (InternalMemory.DCPumpMode_read()==Lagoon) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,42,26,"Lagoon");
else if (InternalMemory.DCPumpMode_read()==ReefCrest) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,25,26,"Reef Crest");
else if (InternalMemory.DCPumpMode_read()==ShortPulse) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,22,26,"Short Pulse");
else if (InternalMemory.DCPumpMode_read()==LongPulse) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,25,26,"Long Pulse");
else if (InternalMemory.DCPumpMode_read()==NutrientTransport) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,8,26,"Nutrient Trnsp.");
else if (InternalMemory.DCPumpMode_read()==TidalSwell) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,23,26,"Tidal Swell");
else if (InternalMemory.DCPumpMode_read()==Custom) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,23,26,"Custom");
else if (InternalMemory.DCPumpMode_read()==Else) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,23,26,"Tidal Else");
else if (InternalMemory.DCPumpMode_read()==Sine) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,23,26,"Sine");
else if (InternalMemory.DCPumpMode_read()==Gyre) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,23,26,"Gyre");
else if (InternalMemory.DCPumpMode_read()== Constant) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,35,27,"Constant");
ReefAngel.LCD.DrawLargeText(0,255,17,36,"Display");
ReefAngel.LCD.DrawLargeText(0,255,17,49,"Temp");
ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
ReefAngel.LCD.DrawHugeText(COLOR_RED, 255, 12, 65, text, Num12x16);
pingSerial();
ReefAngel.LCD.DrawLargeText(0,255,100,45,"pH");
ConvertNumToString(text, ReefAngel.Params.PH, 100);
ReefAngel.LCD.DrawLargeText(COLOR_BLUE, 255, 89, 65, text, Num8x8);
pingSerial();
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,5,80, "Jebao");
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,10,89, "Left");
ReefAngel.LCD.DrawText(COLOR_BLACK,255,16,100, InternalMemory.DCPumpSpeed_read());
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,50,80, "Jebao");
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,49,89, "Center");
ReefAngel.LCD.DrawText(COLOR_BLACK,255,59,100, PumpOffset);
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,93,80, "Jebao");
ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,88,89, " Right");
ReefAngel.LCD.DrawText(COLOR_BLACK,255,100,100, InternalMemory.DCPumpSpeed_read());
pingSerial();
}
void DrawCustomGraph()
{
}
Re: Custom Main Screens
Since I am redoing my 75g saltwater tank and making upgrades, I decided my controller's main screen needed an "update". So, I worked out a new custom screen and figured I would share with everybody.
I have a maxspect gyre xf230 that is controlled via the Daylight port. I have a specific mode that I run it at during the "night" hours. I have created a specific set of internal memory locations just for the night modes.
___TEST CODE___ at the top is changed to the current date and time when it's running normally.
I have T2 and T3 set to only display when the probes are connected.
I have the Water Level Expansion and Salinity Expansion on my tank, so those values are included.
Water is the water level attachment that I have for my reservoir tank.
The screenshot is a test screen. I have hard coded values when I enabled the test mode that way I can get a better idea of how the screen layout is.
I took the bar graph code from the "2014 home screen" in the libraries and shrunk it down to half the size, so I can squeeze it in smaller spaces.
The word "Constant" is the current mode the DC Pump is running in and the bar with number is the speed of the pump on the Daylight channel.
I'm using the standard outlet box but have thought about switching over to the horizontal circle outlet box. I haven't looked at the circle outlets for a long time, so I'm not sure if I will do it or not.
Anyways, here's the FULL code that I'm running. I'm including my FULL code since I had to create extra functions to get what I wanted done.
Enjoy!
I have a maxspect gyre xf230 that is controlled via the Daylight port. I have a specific mode that I run it at during the "night" hours. I have created a specific set of internal memory locations just for the night modes.
___TEST CODE___ at the top is changed to the current date and time when it's running normally.
I have T2 and T3 set to only display when the probes are connected.
I have the Water Level Expansion and Salinity Expansion on my tank, so those values are included.
Water is the water level attachment that I have for my reservoir tank.
The screenshot is a test screen. I have hard coded values when I enabled the test mode that way I can get a better idea of how the screen layout is.
I took the bar graph code from the "2014 home screen" in the libraries and shrunk it down to half the size, so I can squeeze it in smaller spaces.
The word "Constant" is the current mode the DC Pump is running in and the bar with number is the speed of the pump on the Daylight channel.
I'm using the standard outlet box but have thought about switching over to the horizontal circle outlet box. I haven't looked at the circle outlets for a long time, so I'm not sure if I will do it or not.
Anyways, here's the FULL code that I'm running. I'm including my FULL code since I had to create extra functions to get what I wanted done.
Code: Select all
// RA+ for 75 Gallon tank
//
// Updated: 6/18/2017
//
// Expansion Modules Added:
// Expansion Hub
// Salinity
// Water Level
//
// Features:
// T1 - Tank Temperature probe
// T2 - Room Temperature probe
// AP - N/A
// DP - Gyre XF230
// Water Level - Water Level of reservoir
// PH - probe in sump
// Salinity - probe in sump
//
//
// Ports:
// 1 - Skimmer
// 2 - WM Left
// 3 - Heater
// 4 - Return
// 5 - Maxspect Gyre XF230
// 6 - PhosBan 150 Reactor
// 7 - Hydra 26 HD Power Supply
// 8 - Hydra 26 HD Power Supply
//
//
#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 <Salinity.h>
#include <WaterLevel.h>
#include <DCPump.h>
#include <ReefAngel.h>
// Global variables
// used for test controller
//#define __TEST__
// starting point for left edge of screen
#define LEFT_EDGE 8
// DC Pump mode text strings
String PUMP_MODES[] = {"Constant","Lagoon","ReefCrest","Short Pulse","Long Pulse","Nutrient",
"Tidal Swell","Feeding","","Night","","Custom","Else","Sine","Gyre"};
// graphics for the water level bar
const unsigned PROGMEM char BAR_CENTER[] = {0x92, 0x92, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0xDB, 0xB6, 0xB6, 0xB6, 0xB6};
const unsigned PROGMEM char BAR_WL_LEFT[] = {0x29, 0x29, 0x2A, 0x72, 0x72, 0x96};
const unsigned PROGMEM char BAR_WL_RIGHT[] = {0x6E, 0x92, 0x96, 0xDB, 0xDB, 0xDB};
const unsigned PROGMEM char BAR_DP_LEFT[] = {0xAB, 0xAB, 0xAF, 0xD3, 0xD7, 0xFB};
const unsigned PROGMEM char BAR_DP_RIGHT[] = {0xB7, 0xB7, 0xB7, 0xDB, 0xDB, 0xDB};
// Memory Locaitons
#define CURT_MEMORY 50
#define DCPUMP_NIGHT_MODE CURT_MEMORY
#define DCPUMP_NIGHT_SPEED DCPUMP_NIGHT_MODE + 1
#define DCPUMP_NIGHT_DURATION DCPUMP_NIGHT_MODE + 2
#define DCPUMP_NIGHT_THRESHOLD DCPUMP_NIGHT_MODE + 3
// Custom functions
boolean isNightTime();
void checkCustomMemoryValues();
uint8_t DCPumpNightMode_read();
uint8_t DCPumpNightSpeed_read();
uint8_t DCPumpNightDuration_read();
uint8_t DCPumpNightThreshold_read();
uint8_t CustomRead(int address);
void CustomWrite(int address, const uint8_t value);
void setup()
{
ReefAngel.Init(); //Initialize controller
checkCustomMemoryValues();
ReefAngel.AddWifi();
ReefAngel.AddStandardMenu();
ReefAngel.AddSalinityExpansion();
// Default Salinity compensation
ReefAngel.Salinity.SetCompensation(0);
ReefAngel.WaterChangePorts = Port4Bit;
ReefAngel.OverheatShutoffPorts = Port3Bit | Port7Bit | Port8Bit;
ReefAngel.OverheatProbe = T1_PROBE;
// Feeding and water change mode speeds
ReefAngel.DCPump.FeedingSpeed = 0;
ReefAngel.DCPump.WaterChangeSpeed = 0;
// Ports that are always on
ReefAngel.Relay.On(Port1); // Skimmer
ReefAngel.Relay.On(Port4); // Return
ReefAngel.Relay.On(Port5); // Gyre XF230
ReefAngel.Relay.On(Port6); // PhosBan Reactor
ReefAngel.Relay.On(Port7); // Hydra 26 HD
ReefAngel.Relay.On(Port8); // Hydra 26 HD
// Ports that are not in use
ReefAngel.Relay.Off(Port2);
}
void loop()
{
ReefAngel.StandardHeater(Port3);
ReefAngel.DCPump.DaylightChannel = Sync;
/*
Night mode - use alternate memory locations
Day mode - default memory locations
*/
if ( isNightTime() ) {
// force in either Constant mode or Long Pulse mode
// use the nighttime memory locations
ReefAngel.DCPump.UseMemory = false;
ReefAngel.DCPump.Mode = DCPumpNightMode_read();
ReefAngel.DCPump.Speed = DCPumpNightSpeed_read();
ReefAngel.DCPump.Duration = DCPumpNightDuration_read();
ReefAngel.DCPump.Threshold = DCPumpNightThreshold_read();
} else {
// use default memory values for the modes
ReefAngel.DCPump.UseMemory = true;
}
ReefAngel.ShowInterface();
}
#define LINE1 19
#define LINE2 47
#define LINE3 70
#define WL_BAR_OFFSET 41
#define DC_BAR_OFFSET 4
void DrawCustomMain()
{
// Fonts in use: NUMBERS_16x16, FONT_8x16
byte x = 6;
byte y = 3;
byte t;
char text[11];
boolean fNight = isNightTime();
#ifdef __TEST__
ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor, x, y, "_____TEST CODE_____");
#else
// Date & time
ReefAngel.LCD.DrawDate(x, y);
#endif // __TEST__
// Divider line
ReefAngel.LCD.Clear(COLOR_BLACK, 1, 11, 128, 11);
// Draw T1
ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
x = 8;
y = LINE1; // 19
// NOTE huge numbers are 16x16 (width x height)
ReefAngel.LCD.Clear(DefaultBGColor, x, y, x+64, y+16);
ReefAngel.LCD.DrawHugeNumbers(T1TempColor, DefaultBGColor, x, y, text);
// Draw T2
// NOTE 4 digits for T1 (16 width, 16*4 pixels)
x = 80;
#ifdef __TEST__
ReefAngel.Params.Temp[T2_PROBE] = 810;
#endif // __TEST__
if(ReefAngel.Params.Temp[T2_PROBE] > 0) {
ReefAngel.LCD.DrawText(T2TempColor, DefaultBGColor, x, y, "T2:");
// NOTE "T2:" is 3 chars of 5 pixels each (15 pixels), plus 2 pixels space after, start on 3rd pixel
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T2_PROBE], T2TempColor, x+18, y, 10);
} else {
// No, T2, clear the entire space for it
ReefAngel.LCD.Clear(DefaultBGColor, x, y, x+38, y+8);
}
// Draw T3 if present
y = 29;
#ifdef __TEST__
ReefAngel.Params.Temp[T3_PROBE] = 796;
#endif // __TEST__
if(ReefAngel.Params.Temp[T3_PROBE] > 0) {
ReefAngel.LCD.DrawText(T3TempColor, DefaultBGColor, x, y, "T3:");
// NOTE "T3:" is 3 chars of 5 pixels each (15 pixels), plus 2 pixels space after, start on 3rd pixel
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T3_PROBE], T3TempColor, x+18, y, 10);
} else {
// No, T3, clear the entire space for it
ReefAngel.LCD.Clear(DefaultBGColor, x, y, x+38, y+8);
}
// Draw PH
y = LINE2;
#ifdef __TEST__
strcpy(text, "8.20");
#else
ConvertNumToString(text, ReefAngel.Params.PH, 100);
#endif // __TEST__
// NOTE ph max is X.XX, 4 digits
ReefAngel.LCD.DrawLargeText(PHColor, DefaultBGColor, 3, y, "pH:", Font8x16);
x = 29;
// TODO confirm width to clear
ReefAngel.LCD.Clear(DefaultBGColor, x, y, x+32, y+16);
ReefAngel.LCD.DrawLargeText(PHColor, DefaultBGColor, x, y, text, Font8x16);
// Draw Salinity
#ifdef __TEST__
strcpy(text, "35.0");
#else
ConvertNumToString(text, ReefAngel.Params.Salinity, 10);
#endif // __TEST__
// NOTE Salinity max is XX.X, 4 digits
x = 69;
// TODO confirm width to clear
ReefAngel.LCD.Clear(DefaultBGColor, x, y, x+32, y+16);
ReefAngel.LCD.DrawLargeText(COLOR_CRIMSON, DefaultBGColor, x, y, text, Font8x16);
ReefAngel.LCD.DrawLargeText(COLOR_CRIMSON, DefaultBGColor, 102, y, "ppt", Font8x16);
pingSerial();
// Draw Water Level Box (used code from libraries)
y = LINE3;
// TODO determine color to use for WATER level (COLOR_ROYALBLUE)
ReefAngel.LCD.DrawText(COLOR_ROYALBLUE, DefaultBGColor, 8, y, "Water");
#ifdef __TEST__
t = 79;
#else
t = ReefAngel.WaterLevel.GetLevel(0);
#endif // __TEST__
// sanity check, ensure level isn't greater than 100
if(t > 100) {
t = 100;
}
x = 99;
// draw value to the right of the bar
ReefAngel.LCD.DrawText(COLOR_ROYALBLUE, DefaultBGColor, 99, y, " ");
sprintf(text, "%d%%", t);
ReefAngel.LCD.DrawText(COLOR_ROYALBLUE, DefaultBGColor, 99, y, text);
// Water level is truncated to 50 pixels instead of 100
// Every 2% equals 1 pixel
// divide water level by 2
t = t / 2;
byte b;
// draw the image to the left of the center line, filled bar background
for(b = 0; b < t; b++)
{
// swidth,sheight, X, Y, img
ReefAngel.LCD.DrawImage(1, 6, b + WL_BAR_OFFSET, y + 2, BAR_WL_LEFT);
}
// draw the center image, indicator
ReefAngel.LCD.DrawImage(2, 6, t + WL_BAR_OFFSET, y + 2, BAR_CENTER);
// draw the image to the right of the center line, unfilled bar background
for(b = t; b < 50; b++)
{
ReefAngel.LCD.DrawImage(1, 6, b + WL_BAR_OFFSET + 2, y + 2, BAR_WL_RIGHT);
}
// Draw DC Pump Mode (next line)
y = 88;
x = 4;
if (fNight) {
t = DCPumpNightMode_read();
} else {
t = InternalMemory.DCPumpMode_read();
}
// copy the string from the global array into a buffer of 11 chars for display on screen
PUMP_MODES[t].toCharArray(text, 11);
// NOTE text is max of 11 chars, 11*5=55 pixels
ReefAngel.LCD.Clear(DefaultBGColor, x, y, x+55, y+8);
ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, x, y, text);
// Draw Day/Night schedule (same line as pump mode)
// NOTE Center text in available space between column 72 and 128
if (fNight) {
strcpy(text, "Night");
b = COLOR_BLACK;
t = COLOR_WHITE;
x = 82;
} else {
strcpy(text, "Day");
b = DefaultBGColor;
t = COLOR_BLACK;
x = 90;
}
// clear entire space with the background color
// clear bigger space than just for the text to line up
// the bottom of the square with the dc pump speed bar
ReefAngel.LCD.Clear(b, 74, y, 128, y+18);
ReefAngel.LCD.DrawLargeText(t, b, x, y+1, text, Font8x16);
// Draw DC Pump Speed bar
y = 98;
x = 58;
#ifdef __TEST__
t = 65;
#else
t = ReefAngel.PWM.GetDaylightValue();
#endif // __TEST__
ReefAngel.LCD.Clear(DefaultBGColor, x, y, x+15, y+8);
ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, x, y, t);
// scale bar to be half width, divide value by 2
t = t / 2;
for(b = 0; b < t; b++)
{
ReefAngel.LCD.DrawImage(1, 6, b + DC_BAR_OFFSET, y + 2, BAR_DP_LEFT);
}
ReefAngel.LCD.DrawImage(2, 6, t + DC_BAR_OFFSET, y + 2, BAR_CENTER);
for(b = t; b < 50; b++)
{
ReefAngel.LCD.DrawImage(1, 6, b + DC_BAR_OFFSET + 2, y + 2, BAR_DP_RIGHT);
}
// Draw outlet bar
t = ReefAngel.Relay.RelayData;
t &= ReefAngel.Relay.RelayMaskOff;
t |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 112, t);
pingSerial();
}
void DrawCustomGraph()
{
}
boolean isNightTime()
{
boolean fResult = false;
byte bOffHour = InternalMemory.StdLightsOffHour_read();
byte bOffMinute = InternalMemory.StdLightsOffMinute_read();
byte bOnHour = InternalMemory.StdLightsOnHour_read();
byte bOnMinute = InternalMemory.StdLightsOnMinute_read();
/*
If current hour is off hour and current minute is equal or after off minute, night time is true
if current hour is after off hour, night time is true
(beyond midnight, aka early hours in morning, overnight wrap)
if current hour is before on hour, night time is true
if current hour is on hour and current minute is before off minute, night time is true
*/
if ( ((hour() == bOffHour) && (minute() >= bOffMinute)) ||
(hour() > bOffHour) ||
(hour() < bOnHour) ||
((hour() == bOnHour) && (minute() < bOnMinute)) )
{
fResult = true;
}
return fResult;
}
void checkCustomMemoryValues()
{
if ( DCPumpNightMode_read() > 14 )
{
// Default to Constant Mode
CustomWrite(DCPUMP_NIGHT_MODE, 0);
}
if ( DCPumpNightSpeed_read() > 100 )
{
// Default to 0 speed
CustomWrite(DCPUMP_NIGHT_SPEED, 0);
}
if ( DCPumpNightDuration_read() > 100 )
{
// Default to 0 duration
CustomWrite(DCPUMP_NIGHT_DURATION, 0);
}
if ( DCPumpNightThreshold_read() > 100 )
{
// Default to 30 threshold
CustomWrite(DCPUMP_NIGHT_THRESHOLD, 30);
}
}
uint8_t DCPumpNightMode_read()
{
return CustomRead(DCPUMP_NIGHT_MODE);
}
uint8_t DCPumpNightSpeed_read()
{
return CustomRead(DCPUMP_NIGHT_SPEED);
}
uint8_t DCPumpNightDuration_read()
{
return CustomRead(DCPUMP_NIGHT_DURATION);
}
uint8_t DCPumpNightThreshold_read()
{
return CustomRead(DCPUMP_NIGHT_THRESHOLD);
}
uint8_t CustomRead(int address)
{
#if not defined __SAM3X8E__
return eeprom_read_byte((unsigned char *) address);
#else
return SPIEEPROM.Read(address);
#endif
}
void CustomWrite(int address, const uint8_t value)
{
if (CustomRead(address) != value )
{
#if not defined __SAM3X8E__
eeprom_write_byte((unsigned char *) address, value);
#else
SPIEEPROM.Write(address, value);
#endif
}
}