Code: Select all
/* Auxillary LCD monitor connected to the ReefAngel Controller (328)
requires a custom cable to connect from I2C main to the serial port
The following features are enabled for this File:
#define DisplayLEDPWM
#define RelayExp
#define InstalledRelayExpansionModules 1
#define CUSTOM_MAIN
#define COLORS_PDE
#define FONT_8x8
#define NUMBERS_8x8
#define NUMBERS_16x16
*/
#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 <ReefAngel.h>
#include <IO.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <avr/wdt.h>
//screen set-up
#define NumScreens 9
int ScreenID=0;
//define for data over I2C
int maxTemp=0;
int minTemp=2000;
int maintemp=800;
int roomtemp=780;
int sumptemp=780;
int ph=700;
int maxPH=600;
int minPH=900;
int moonlight=0;
byte TempRelay =15;
byte TempRelay2=15;
int wavetime=0;
int wavetime2=0;
int flow0=0;
int flow1=0;
int flow2=0;
int wmaker2;
byte mhour;
byte mminute;
byte msecond;
byte mday;
byte mmonth;
int myear;
byte Overflow;
byte Reservoir;
byte LATO;
byte HATO;
byte level;
byte atos;
//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();
int mastertime;
// Moon Global Variables - Thanks Deckoz2302!
byte ThisPhase;
double AG;
double IP;
byte MoonPWMValue;
long YY, MM, K1, K2, K3, JD;
// 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);
}
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);
}
}}
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);
}
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);
}
}
void FillCircle(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;
for (int i=b-r; i<=b+r; i++)
{
ReefAngel.LCD.PutPixel(color, a, i);
}
while (x<y)
{
if (f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
for (int i=b-y; i<=b+y; i++)
{
ReefAngel.LCD.PutPixel(color, a+x, i);
ReefAngel.LCD.PutPixel(color, a-x, i);
}
for (int i=b-x; i<=b+x; i++)
{
ReefAngel.LCD.PutPixel(color,a+y, i);
ReefAngel.LCD.PutPixel(color,a-y, i);
}
}
}
void DrawCircleBox (byte x, byte y, byte RelayData)
{
byte b = 0;
byte c = 0;
byte d = 0;
for (byte a=0;a<2;a++)
{
DrawCircle ((a*10)+x,y+30,5,COLOR_BLACK);
if ((RelayData&(1<<a))==1<<a)
{
FillCircle((a*10)+x,y+30,3,OutletOnBGColor);
}
else
{
FillCircle((a*10)+x,y+30,3,OutletOffBGColor);
}
}
for (byte a=2;a<4;a++)
{
b=(a-2)*10;
DrawCircle (b+x,y+20,5,COLOR_BLACK);
if ((RelayData&(1<<a))==1<<a)
{
FillCircle(b+x,y+20,3,OutletOnBGColor);
}
else
{
FillCircle(b+x,y+20,3,OutletOffBGColor);
}
}
for (byte a=4;a<6;a++)
{
c=(a-4)*10;
DrawCircle (c+x,y+10,5,COLOR_BLACK);
if ((RelayData&(1<<a))==1<<a)
{
FillCircle(c+x,y+10,3,OutletOnBGColor);
}
else
{
FillCircle(c+x,y+10,3,OutletOffBGColor);
}
}
for (byte a=6;a<8;a++)
{
d=(a-6)*10;
DrawCircle (d+x,y,5,COLOR_BLACK);
if ((RelayData&(1<<a))==1<<a)
{
FillCircle(d+x,y,3,OutletOnBGColor);
}
else
{
FillCircle(d+x,y,3,OutletOffBGColor);
}
}
}
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);
}
}
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 setup()
{
ReefAngel.Init(); //Initialize controller and start web banner timer
setTime(19,59,0,6,3,12);
Wire.begin(10); // I2C address 10
Wire.onReceive(receiveEvent);
ReefAngel.Timer[LCD_TIMER].SetInterval(180);
ReefAngel.Timer[LCD_TIMER].Start(); // start timer
}
void loop()
{
setTime(mhour,mminute,msecond,mday,mmonth,myear);
if ( ReefAngel.Timer[LCD_TIMER].IsTriggered() ) // process screensaver timeout
{// Screensaver timeout expired
ReefAngel.LCD.BacklightOff();
}
if ( ReefAngel.Joystick.IsButtonPressed())
{// turn the backlight on
ReefAngel.LCD.BacklightOn();
}
// TODO check Timer[LCD_TIMER] code
if ( ReefAngel.Timer[LCD_TIMER].Trigger == 0 )
{
ReefAngel.Timer[LCD_TIMER].Start();
return;
}// update the min and max temps
if (now()%86400==0)
{
minTemp=maintemp;
maxTemp=maintemp;
}
if (maintemp<minTemp)
{
minTemp=maintemp;
tsmin=now();
}
if (maintemp>maxTemp)
{
maxTemp=maintemp;
tsmax=now();
}
// update the min and max pH
if (now()%86400==0)
{
minPH=ph;
maxPH=ph;
}
if (ph<minPH)
{
minPH=ph;
PHmin=now();
}
if (ph>maxPH)
{
maxPH=ph;
PHmax=now();
}
if (ReefAngel.Joystick.IsLeft() || ReefAngel.Joystick.IsDown())
{
ReefAngel.ClearScreen(DefaultBGColor);
ScreenID--;
}
if (ReefAngel.Joystick.IsRight() || ReefAngel.Joystick.IsUp())
{
ReefAngel.ClearScreen(DefaultBGColor);
ScreenID++;
}
if (ScreenID<0) ScreenID=NumScreens;
if (ScreenID>=NumScreens) ScreenID=0;
switch (ScreenID)
{
case 0: //Initial first screen
ReefAngel.Refresh();
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 0, " ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Jon's Reef Tank ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(0,255,100,120,"#1", Font8x8);
// Display Temp Text
ReefAngel.LCD.DrawLargeText(0,255,30,15,"Tank Temp", Font8x8);
// Display the T1 temp
char text[7];
ConvertNumToString(text, maintemp, 10);
ReefAngel.LCD.Clear(255, 35, 25, 50, 60);
if (maintemp>830) ReefAngel.LCD.DrawHugeNumbers(COLOR_RED, 255, 35, 25, text);
else if (maintemp>830) ReefAngel.LCD.DrawHugeNumbers(COLOR_ORANGE, 255, 35, 25, text);
else ReefAngel.LCD.DrawHugeNumbers(COLOR_MIDNIGHTBLUE, 255, 35, 25, text);
// Display pH Text
ReefAngel.LCD.DrawLargeText(0,255,82,85," pH ", Font8x8);
// Display pH Value
ConvertNumToString(text, ph, 100);
ReefAngel.LCD.Clear(255, 65, 95, 132, 115);
if (ph>840 || ph<790) ReefAngel.LCD.DrawHugeNumbers(COLOR_RED, 255, 65, 95, text);
else if (ph>830 || ph<800) ReefAngel.LCD.DrawHugeNumbers(COLOR_ORANGE, 255, 65, 95, text);
else ReefAngel.LCD.DrawHugeNumbers(COLOR_MIDNIGHTBLUE, 255, 65, 95, text);
// Display Sump Temp
ReefAngel.LCD.DrawLargeText(0,255,8,50,"Sump Temp", Font8x8);
ReefAngel.LCD.Clear(255, 90, 50, 132, 60);
ConvertNumToString(text, sumptemp, 10);
ReefAngel.LCD.DrawLargeText(COLOR_MIDNIGHTBLUE, 255, 90, 50, text, Num8x8);
// Display Room Temp
ReefAngel.LCD.DrawLargeText(0,255,8,60,"Room Temp", Font8x8);
ReefAngel.LCD.Clear(255, 90, 60, 132, 70);
ConvertNumToString(text, roomtemp, 10);
ReefAngel.LCD.DrawLargeText(COLOR_MIDNIGHTBLUE, 255, 90, 60, text, Num8x8);
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
DrawCircleBox (10,90,TempRelay);
DrawCircleBox (40,90,TempRelay2);
break;
case 1: //same as first screen with position changes
ReefAngel.Refresh();
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 0, " ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Jon's Reef Tank ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(0,255,100,120,"#2", Font8x8);
// Display Temp Text
ReefAngel.LCD.DrawLargeText(0,255,30,15," pH ", Font8x8);
// Display the T1 temp
ConvertNumToString(text, ph, 100);
ReefAngel.LCD.Clear(255, 35, 25, 50, 50);
if (ph>830) ReefAngel.LCD.DrawHugeNumbers(COLOR_RED, 255, 35, 25, text);
else if (ph>830) ReefAngel.LCD.DrawHugeNumbers(COLOR_ORANGE, 255, 35, 25, text);
else ReefAngel.LCD.DrawHugeNumbers(COLOR_MIDNIGHTBLUE, 255, 35, 25, text);
// Display pH Text
ReefAngel.LCD.DrawLargeText(0,255,25,105,"Tank", Font8x8);
// Display pH Value
ConvertNumToString(text, maintemp, 10);
ReefAngel.LCD.Clear(255, 65, 95, 132, 115);
if (maintemp>840 || ph<790) ReefAngel.LCD.DrawHugeNumbers(COLOR_RED, 255, 65, 95, text);
else if (maintemp>830 || ph<800) ReefAngel.LCD.DrawHugeNumbers(COLOR_ORANGE, 255, 65, 95, text);
else ReefAngel.LCD.DrawHugeNumbers(COLOR_MIDNIGHTBLUE, 255, 65, 95, text);
// Display Flow0
ReefAngel.LCD.DrawLargeText(0,255,8,50,"Pump1Flow", Font8x8);
ReefAngel.LCD.Clear(255, 90, 50, 132, 60);
ConvertNumToString(text, flow0, 10);
ReefAngel.LCD.DrawLargeText(COLOR_MIDNIGHTBLUE, 255, 90, 50, text, Num8x8);
// Display Flow1
ReefAngel.LCD.DrawLargeText(0,255,8,60,"Pump2Flow", Font8x8);
ReefAngel.LCD.Clear(255, 90, 60, 132, 70);
ConvertNumToString(text, flow1, 10);
ReefAngel.LCD.DrawLargeText(COLOR_MIDNIGHTBLUE, 255, 90, 60, text, Num8x8);
// Display light level
ReefAngel.LCD.DrawLargeText(0,255,8,70,"Moonlight", Font8x8);
ReefAngel.LCD.Clear(255, 90, 70, 132, 90);
ConvertNumToString(text, moonlight, 1);
ReefAngel.LCD.DrawLargeText(COLOR_MIDNIGHTBLUE, 255, 90, 70, text, Num8x8);
// moonphase------------------------------------------------------------
YY = (year()) - floor((12 - (month())) / 10);
MM = (month()) + 9;
if (MM >= 12)
{
MM = MM - 12;
}
K1 = floor(365.25 * (YY + 4712));
K2 = floor(30.6 * MM + 0.5);
K3 = floor(floor((YY / 100) + 49) * 0.75) - 38;
JD = K1 + K2 + (day()) + 59;
if (JD > 2299160)
{
JD = JD - K3;
}
IP = (JD - 2451550.1) / 29.530588853;
IP = IP - floor(IP);
if (IP < 0)
{
IP = IP + 1;
}
AG = IP*29.53;
if (AG < 1.84) ReefAngel.LCD.DrawLargeText(DPColor,DefaultBGColor, 5, 80,"New", Font8x8);
else if (AG < 5.53) ReefAngel.LCD.DrawLargeText(DPColor,DefaultBGColor, 5, 80,"Waxing Crescent", Font8x8);
else if (AG < 9.92) ReefAngel.LCD.DrawLargeText(DPColor,DefaultBGColor, 5, 80,"First Quarter", Font8x8);
else if (AG < 12.91) ReefAngel.LCD.DrawLargeText(DPColor,DefaultBGColor, 5, 80,"Waxing Gibbous", Font8x8);
else if (AG < 16.61) ReefAngel.LCD.DrawLargeText(DPColor,DefaultBGColor, 5, 80,"Full", Font8x8);
else if (AG < 20.30) ReefAngel.LCD.DrawLargeText(DPColor,DefaultBGColor, 5, 80,"Waning gibbous", Font8x8);
else if (AG < 23.99) ReefAngel.LCD.DrawLargeText(DPColor,DefaultBGColor, 5, 80,"Last Quarter", Font8x8);
else if (AG < 27.68) ReefAngel.LCD.DrawLargeText(DPColor,DefaultBGColor, 5, 80,"Waning Crescent", Font8x8);
else ReefAngel.LCD.DrawLargeText(DPColor,DefaultBGColor, 5, 80,"New") ;
break;
case 2: //Temperature detail screen with sump and room temp, 24 hr. max/min, time stamps, and graph
ReefAngel.Refresh();
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 0, " ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Jon's Reef Tank ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(0,255,100,120,"#3", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,10,15,"Temp Details", Font8x8);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,33,"TANK:");
ReefAngel.LCD.DrawSingleMonitor(maintemp, 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,"degreesF");
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,73,"Avg:");
DrawDailyAvg(maintemp, COLOR_BLACK, 43, 73, 1);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,83,"WeeklyAvg:");
DrawWeeklyAvg(12,maintemp, COLOR_BLACK, 66, 83, 1);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor, 86,83,"at noon");
ReefAngel.LCD.DrawText(T2TempColor,DefaultBGColor, 5 ,93,"R00M:");
ReefAngel.LCD.DrawSingleMonitor(roomtemp, COLOR_BLACK, 36, 93, 10);
ReefAngel.LCD.DrawText(T3TempColor,DefaultBGColor, 5, 103,"SUMP:");
ReefAngel.LCD.DrawSingleMonitor(sumptemp, COLOR_BLACK, 36, 103, 10);
ReefAngel.LCD.DrawLargeText(0,255,100,120,"#3", Font8x8);
break;
case 3: //pH details
ReefAngel.Refresh();
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 0, " ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Jon's Reef Tank ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(0,255,100,120,"#4", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,20,15,"pH Details", Font8x8);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,33,"pH:");
ReefAngel.LCD.DrawSingleMonitor(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(ph, COLOR_BLACK, 43, 73, 100);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5,83,"WeeklyAvg:");
DrawWeeklyAvg(12,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,ph, COLOR_BLACK, 66, 93, 100);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 86,93,"at midnt");
break;
case 4: //relay box key
ReefAngel.Refresh();
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 0, " ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Jon's Reef Tank ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(0,255,100,120,"#5", Font8x8);
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
DrawCircleBox (56,46,TempRelay);
ReefAngel.LCD.DrawLargeText(0,255,27,20,"RelayBox 1", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,44,"MainP", Font8x8); //7
ReefAngel.LCD.DrawLargeText(0,255,7,54,"WaveL", Font8x8); //5
ReefAngel.LCD.DrawLargeText(0,255,7,64,"MH LT", Font8x8); //3
ReefAngel.LCD.DrawLargeText(0,255,7,74,"Heat2", Font8x8); //1
ReefAngel.LCD.DrawLargeText(0,255,75,44,"Fans", Font8x8); //8
ReefAngel.LCD.DrawLargeText(0,255,75,54,"WaveR", Font8x8); //6
ReefAngel.LCD.DrawLargeText(0,255,75,64,"StdLT", Font8x8); //4
ReefAngel.LCD.DrawLargeText(0,255,75,74,"Heat1", Font8x8); //2
break;
case 5: //relay box key
ReefAngel.Refresh();
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 0, " ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Jon's Reef Tank ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(0,255,100,120,"#6", Font8x8);
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
DrawCircleBox (56,46,TempRelay2);
ReefAngel.LCD.DrawLargeText(0,255,27,20,"RelayBox 2", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,44,"Dose1", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,54,"Wave3", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,64," ATO", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,74,"Chill", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,75,44,"Dose2", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,75,54,"Wave4", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,75,64,"PO4", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,75,74,"Chill", Font8x8);
break;
case 6: //level sensors
ReefAngel.Refresh();
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 0, " ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Jon's Reef Tank ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(0,255,100,120,"#7", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,20,20,"Level Sensors", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,44," Overflow", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,54,"Reservoir", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,64," Low ATO", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,74," High ATO", Font8x8);
if (level == 0)
{
Overflow = 0;
Reservoir = 0;
}
else if (level == 1)
{
Overflow = 1;
Reservoir = 0;
}
else if (level == 2)
{
Overflow = 0;
Reservoir = 1;
}
else if (level == 3)
{
Overflow = 1;
Reservoir = 1;
}
if (atos == 0)
{
HATO = 1;
LATO = 1;
}
else if (atos == 1)
{
HATO = 1;
LATO = 0;
}
else if (atos == 2)
{
HATO = 0;
LATO = 1;
}
else if (atos == 3)
{
HATO = 0;
LATO = 0;
}
DrawCircle (90,48,5,COLOR_BLACK);
if (Overflow == 1)
{
FillCircle(90,48,3,OutletOnBGColor);
ReefAngel.LCD.Clear(255, 100, 44, 132, 54);
}
else if (Overflow == 0)
{
FillCircle(90,48,3,OutletOffBGColor);
ReefAngel.LCD.DrawLargeText(OutletOffBGColor,255,100,44,"HIGH", Font8x8);
}
DrawCircle (90,58,5,COLOR_BLACK);
if (Reservoir == 1)
{
FillCircle(90,58,3,OutletOffBGColor);
ReefAngel.LCD.DrawLargeText(OutletOffBGColor,255,100,54,"FILL", Font8x8);
}
else if (Reservoir == 0)
{
FillCircle(90,58,3,OutletOnBGColor);
ReefAngel.LCD.Clear(255, 100, 54, 132, 64);
}
DrawCircle (90,68,5,COLOR_BLACK);
if (LATO == 1)
{
FillCircle(90,68,3,OutletOffBGColor);
ReefAngel.LCD.DrawLargeText(OutletOffBGColor,255,100,64,"FILL", Font8x8);
}
else if (LATO == 0)
{
FillCircle(90,68,3,OutletOnBGColor);
ReefAngel.LCD.Clear(255, 100, 64, 132, 74);
}
DrawCircle (90,78,5,COLOR_BLACK);
if (HATO == 1)
{
FillCircle(90,78,3,OutletOnBGColor);
ReefAngel.LCD.Clear(255, 100, 74, 132, 84);
}
else if (HATO == 0)
{
FillCircle(90,78,3,OutletOffBGColor);
ReefAngel.LCD.DrawLargeText(OutletOffBGColor,255,100,74,"LOW", Font8x8);
}
break;
case 7: //setclock
// Analog clock is modified from the original source by Jeff Miller
// Author: Jeff Miller http://arduinofun.blogspot.com/
ReefAngel.Refresh();
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 0, " ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Jon's 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.DrawLargeText(0,255,110,110,"#8", Font8x8);
ReefAngel.LCD.DrawDate(5,121);
break;
case 8: //menu
ReefAngel.Refresh();
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 0, " ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 1, " Jon's Reef Tank ", Font8x8); //Top Banner
ReefAngel.LCD.DrawLargeText(0,255,100,120,"#9", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,20,15,"Power Heads", Font8x8);
ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 8, 33,"Top wave:");
ReefAngel.LCD.Clear(255,78,33,103,43);
ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 8, 108,"Side wave:");
ReefAngel.LCD.Clear(255,78,108,103,120);
ReefAngel.LCD.DrawText(0,DefaultBGColor, 78, 108, wavetime);
// ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 104, 113,TempRelay2);
ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 104, 108,"sec");
if ((TempRelay&(1<<5))==1<<5)
{
ReefAngel.LCD.Clear(255,5,75,90,105);
ReefAngel.LCD.DrawLargeText(0,255,90,75,"<---", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,90,85,"<---", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,90,95,"<---", Font8x8);
}
else if ((TempRelay&(1<<6))==1<<6)
{
ReefAngel.LCD.Clear(255,45,75,130,105);
ReefAngel.LCD.DrawLargeText(0,255,5,75,"--->", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,5,85,"--->", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,5,95,"--->", Font8x8);
}
else
{
ReefAngel.LCD.Clear(255,5,75,45,105);
ReefAngel.LCD.Clear(255,45,75,130,105);
ReefAngel.LCD.DrawLargeText(0,255,45,85," ~~~", Font8x8);
}
if ((TempRelay2&(1<<5))==1<<5)
{
ReefAngel.LCD.Clear(255,80,45,100,65);
ReefAngel.LCD.DrawLargeText(0,255,40,45,"|", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,40,55,"v", Font8x8);
}
else if ((TempRelay2&(1<<6))==1<<6)
{
ReefAngel.LCD.Clear(255,40,45,60,65);
ReefAngel.LCD.DrawLargeText(0,255,80,45,"|", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,80,55,"v", Font8x8);
}
else
{
ReefAngel.LCD.Clear(255,40,45,100,65);
}
break;
}
}
void receiveEvent(int howMany)
{
if (howMany==32) // Our custom protocol is 13 bytes
{
byte cmd1,cmd2,cmd3,cmd4,cmd5,cmd6,cmd7,cmd8,cmd9,cmd10;
byte cmd11,cmd12,cmd13,cmd14,cmd15,cmd16,cmd17,cmd18,cmd19,cmd20;
byte cmd21,cmd22,cmd23,cmd24,cmd25,cmd26,cmd27,cmd28,cmd29,cmd30;
byte cmd31,cmd32;
cmd1=Wire.read();
cmd2=Wire.read();
cmd3=Wire.read();
cmd4=Wire.read();
cmd5=Wire.read();
cmd6=Wire.read();
cmd7=Wire.read();
cmd8=Wire.read();
cmd9=Wire.read();
cmd10=Wire.read();
cmd11=Wire.read();
cmd12=Wire.read();
cmd13=Wire.read();
cmd14=Wire.read();
cmd15=Wire.read();
cmd16=Wire.read();
cmd17=Wire.read();
cmd18=Wire.read();
cmd19=Wire.read();
cmd20=Wire.read();
cmd21=Wire.read();
cmd22=Wire.read();
cmd23=Wire.read();
cmd24=Wire.read();
cmd25=Wire.read();
cmd26=Wire.read();
cmd27=Wire.read();
cmd28=Wire.read();
cmd29=Wire.read();
cmd30=Wire.read();
cmd31=Wire.read();
cmd32=Wire.read();
if (cmd1=='$' && cmd2=='$' && cmd3=='$') // the first 3 bytes of the custom protocol are $$$ to ensure it's coming from RA
{
maintemp=(cmd4<<8)+cmd5;
sumptemp=(cmd6<<8)+cmd7;
roomtemp=(cmd8<<8)+cmd9;
ph=(cmd10<<8)+cmd11;
wavetime=(cmd12<<8)+cmd13;
moonlight=(cmd14<<8)+cmd15;
level=cmd16;
atos=cmd17;
TempRelay=cmd18;
TempRelay2=cmd19;
flow0=(cmd20<<8)+cmd21;
flow1=(cmd22<<8)+cmd23;
flow2=(cmd24<<8)+cmd25;
mhour=cmd26;
mminute=cmd27;
msecond=cmd28;
mday=cmd29;
mmonth=cmd30;
myear=(cmd31<<8)+cmd32;
}
}
else
for (int a=0;a<howMany;a++)
Wire.read(); // if the number of bytes is not 32, discard everything
}