You need this:
Code: Select all
wdt_reset();
Code: Select all
wdt_reset();
Code: Select all
#include <ReefAngel_Features.h>
#include <ReefAngel_Globals.h>
#include <ReefAngel_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <ReefAngel_EEPROM.h>
#include <ReefAngel_NokiaLCD.h>
#include <ReefAngel_ATO.h>
#include <ReefAngel_Joystick.h>
#include <ReefAngel_LED.h>
#include <ReefAngel_TempSensor.h>
#include <ReefAngel_Relay.h>
#include <ReefAngel_PWM.h>
#include <ReefAngel_Timer.h>
#include <ReefAngel_Memory.h>
#include <ReefAngel.h>
#include <ReefAngel_Colors.h>
#include <ReefAngel_CustomColors.h>
//#include <avr/wdt.h>
int maintemp=800;
int roomtemp=780;
int sumptemp=780;
int ph=700;
byte TempRelay =15;
byte TempRelay2=15;
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,5,COLOR_BLACK);
if ((RelayData&(1<<a))==1<<a)
{
FillCircle((a*10)+x,y,3,OutletOnBGColor);
}
else
{
FillCircle((a*10)+x,y,3,OutletOffBGColor);
}
}
for (byte a=2;a<4;a++)
{
b=(a-2)*10;
DrawCircle (b+x,y+10,5,COLOR_BLACK);
if ((RelayData&(1<<a))==1<<a)
{
FillCircle(b+x,y+10,3,OutletOnBGColor);
}
else
{
FillCircle(b+x,y+10,3,OutletOffBGColor);
}
}
for (byte a=4;a<6;a++)
{
c=(a-4)*10;
DrawCircle (c+x,y+20,5,COLOR_BLACK);
if ((RelayData&(1<<a))==1<<a)
{
FillCircle(c+x,y+20,3,OutletOnBGColor);
}
else
{
FillCircle(c+x,y+20,3,OutletOffBGColor);
}
}
for (byte a=6;a<8;a++)
{
d=(a-6)*10;
DrawCircle (d+x,y+30,5,COLOR_BLACK);
if ((RelayData&(1<<a))==1<<a)
{
FillCircle(d+x,y+30,3,OutletOnBGColor);
}
else
{
FillCircle(d+x,y+30,3,OutletOffBGColor);
}
}
}
void setup()
{
ReefAngel.Init(); //Initialize controller and start web banner timer
Wire.begin(10); // I2C address 8
Wire.onReceive(receiveEvent);
}
void loop()
{
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
// Display Temp Text
ReefAngel.LCD.DrawLargeText(0,255,30,15,"Tank Temp", Font8x8);
// Display the T1 temp value 10,22
char text[7];
ConvertNumToString(text, maintemp, 10);
ReefAngel.LCD.Clear(255, 0, 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);
//pingSerial();
// Display pH Text
ReefAngel.LCD.DrawLargeText(0,255,85,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 Daylight Percentage Text
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);
//****************************************************************************************
if ( ReefAngel.Joystick.IsButtonPressed() )
{
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
// Display Temp Text
ReefAngel.LCD.DrawLargeText(0,255,30,15,"Tank Temp", Font8x8);
// Display the T1 temp value 10,22
char text[7];
ConvertNumToString(text, ph, 10);
ReefAngel.LCD.Clear(255, 0, 25, 50, 60);
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);
//pingSerial();
// Display pH Text
ReefAngel.LCD.DrawLargeText(0,255,85,85,"pH", Font8x8);
// Display pH Value
ConvertNumToString(text, maintemp, 100);
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 Sump Temp
ReefAngel.LCD.DrawLargeText(0,255,8,50,"Pump Flow", Font8x8);
ReefAngel.LCD.Clear(255, 90, 50, 132, 60);
ConvertNumToString(text, sumptemp, 10);
ReefAngel.LCD.DrawLargeText(COLOR_MIDNIGHTBLUE, 255, 90, 50, text, Num8x8);
// Display Daylight Percentage Text
ReefAngel.LCD.DrawLargeText(0,255,8,60,"Lux Level", 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);
}
bool bDone = false;
do
{
// wait indefinitely for a button press
delay(200);
if ( ReefAngel.Joystick.IsButtonPressed() )
{
bDone = true;
}
} while ( ! bDone );
}
void receiveEvent(int howMany)
{
if (howMany==13) // Our custom protocol is 13 bytes
{
byte cmd1, cmd2, cmd3, cmd4, cmd5, cmd6, cmd7, cmd8, cmd9, cmd10, cmd11,cmd12,cmd13;
cmd1=Wire.receive();
cmd2=Wire.receive();
cmd3=Wire.receive();
cmd4=Wire.receive();
cmd5=Wire.receive();
cmd6=Wire.receive();
cmd7=Wire.receive();
cmd8=Wire.receive();
cmd9=Wire.receive();
cmd10=Wire.receive();
cmd11=Wire.receive();
cmd12=Wire.receive();
cmd13=Wire.receive();
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;
TempRelay=cmd12;
TempRelay2=cmd13;
}
}
else
for (int a=0;a<howMany;a++)
Wire.receive(); // if the number of bytes is not 13, discard everything
}
Code: Select all
while ( ! bDone );
Code: Select all
#define NumScreens 2
int ScreenID=0;
void setup()
{
}
void loop()
{
if (ReefAngel.Joystick.IsLeft() || ReefAngel.Joystick.IsDown()) ScreenID--;
if (ReefAngel.Joystick.IsRight() || ReefAngel.Joystick.IsUp()) ScreenID++;
if (ScreenID<0) ScreenID=NumScreens;
if (ScreenID>=NumScreens) ScreenID=0;
switch (ScreenID)
{
case 0:
{
// Draw Screen 0
break;
}
case 1:
{
// Draw Screen 1
break;
}
}
}
Code: Select all
if (ReefAngel.Joystick.IsLeft() || ReefAngel.Joystick.IsDown())
{
ReefAngel.LCD.ClearScreen(DefaultBGColor);
ScreenID--;
}
if (ReefAngel.Joystick.IsRight() || ReefAngel.Joystick.IsUp())
{
ReefAngel.LCD.ClearScreen(DefaultBGColor);
ScreenID--;
}
Code: Select all
#include <ReefAngel_Features.h>
#include <ReefAngel_Globals.h>
#include <ReefAngel_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <ReefAngel_EEPROM.h>
#include <ReefAngel_NokiaLCD.h>
#include <ReefAngel_ATO.h>
#include <ReefAngel_Joystick.h>
#include <ReefAngel_LED.h>
#include <ReefAngel_TempSensor.h>
#include <ReefAngel_Relay.h>
#include <ReefAngel_PWM.h>
#include <ReefAngel_Timer.h>
#include <ReefAngel_Memory.h>
#include <ReefAngel.h>
#include <ReefAngel_Colors.h>
#include <ReefAngel_CustomColors.h>
//#include <avr/wdt.h>
//screen set-up
#define NumScreens 5
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;
byte TempRelay =15;
byte TempRelay2=15;
//time stamp
time_t tsmax=now();
time_t tsmin=now();
void DrawTime(byte x, byte y, byte FGcolor, byte BGcolor, time_t ts)
{
//byte iTimeHourOffset=0;
char text[13];
char temp[]=" ";
strcpy(text,"");
//if (iTimeHour>12) iTimeHourOffset=12;
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,5,COLOR_BLACK);
if ((RelayData&(1<<a))==1<<a)
{
FillCircle((a*10)+x,y,3,OutletOnBGColor);
}
else
{
FillCircle((a*10)+x,y,3,OutletOffBGColor);
}
}
for (byte a=2;a<4;a++)
{
b=(a-2)*10;
DrawCircle (b+x,y+10,5,COLOR_BLACK);
if ((RelayData&(1<<a))==1<<a)
{
FillCircle(b+x,y+10,3,OutletOnBGColor);
}
else
{
FillCircle(b+x,y+10,3,OutletOffBGColor);
}
}
for (byte a=4;a<6;a++)
{
c=(a-4)*10;
DrawCircle (c+x,y+20,5,COLOR_BLACK);
if ((RelayData&(1<<a))==1<<a)
{
FillCircle(c+x,y+20,3,OutletOnBGColor);
}
else
{
FillCircle(c+x,y+20,3,OutletOffBGColor);
}
}
for (byte a=6;a<8;a++)
{
d=(a-6)*10;
DrawCircle (d+x,y+30,5,COLOR_BLACK);
if ((RelayData&(1<<a))==1<<a)
{
FillCircle(d+x,y+30,3,OutletOnBGColor);
}
else
{
FillCircle(d+x,y+30,3,OutletOffBGColor);
}
}
}
void setup()
{
ReefAngel.Init(); //Initialize controller and start web banner timer
Wire.begin(10); // I2C address 10
Wire.onReceive(receiveEvent);
ReefAngel.Timer[LCD_TIMER].SetInterval(120);
ReefAngel.Timer[LCD_TIMER].Start(); // start timer
}
void loop()
{
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();
// DrawTime(60,33);
}
if (maintemp>maxTemp)
{
maxTemp=maintemp;
tsmax=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, 60);
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,82,85,"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 Flow
ReefAngel.LCD.DrawLargeText(0,255,8,50,"Pump Flow", Font8x8);
ReefAngel.LCD.Clear(255, 90, 50, 132, 60);
ConvertNumToString(text, sumptemp, 10);
ReefAngel.LCD.DrawLargeText(COLOR_MIDNIGHTBLUE, 255, 90, 50, text, Num8x8);
// Display light level
ReefAngel.LCD.DrawLargeText(0,255,8,60,"Lux Level", 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 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.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,66,63,"degreesF");
ReefAngel.LCD.DrawText(T2TempColor,DefaultBGColor, 5 ,73,"R00M:");
ReefAngel.LCD.DrawSingleMonitor(roomtemp, COLOR_BLACK, 36, 73, 10);
ReefAngel.LCD.DrawText(T3TempColor,DefaultBGColor, 5, 83,"SUMP:");
ReefAngel.LCD.DrawSingleMonitor(sumptemp, COLOR_BLACK, 36, 83, 10);
ReefAngel.LCD.DrawLargeText(0,255,100,120,"#3", Font8x8);
break;
case 3: //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,"#4", 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,"Heat1", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,54,"MH LT", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,64,"WaveR", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,74,"MainP", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,75,44,"Heat2", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,75,54,"StdLT", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,75,64,"WaveL", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,75,74,"Fans", Font8x8);
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,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,"Dose2", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,64,"WaveA", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,7,74," PO4", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,75,44,"OPEN1", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,75,54,"OPEN2", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,75,64,"Wave2", Font8x8);
ReefAngel.LCD.DrawLargeText(0,255,75,74,"OPEN3", Font8x8);
break;
}
}
void receiveEvent(int howMany)
{
if (howMany==13) // Our custom protocol is 13 bytes
{
byte cmd1, cmd2, cmd3, cmd4, cmd5, cmd6, cmd7, cmd8, cmd9, cmd10, cmd11,cmd12,cmd13;
cmd1=Wire.receive();
cmd2=Wire.receive();
cmd3=Wire.receive();
cmd4=Wire.receive();
cmd5=Wire.receive();
cmd6=Wire.receive();
cmd7=Wire.receive();
cmd8=Wire.receive();
cmd9=Wire.receive();
cmd10=Wire.receive();
cmd11=Wire.receive();
cmd12=Wire.receive();
cmd13=Wire.receive();
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;
TempRelay=cmd12;
TempRelay2=cmd13;
}
}
else
for (int a=0;a<howMany;a++)
Wire.receive(); // if the number of bytes is not 13, discard everything
}
I do as well. I killed a temp extension cable this weekend doing this. Roberto, is there some secret to this problem? Thx in advance.jsclownfish wrote:I also have trouble with the temp connectors getting them off and on without messing them up. -Jon
Code: Select all
/* Main ReefAngelPlus controller with communication for sound,
auxillary monitor, I/O expansion, and extra relaybox, send master time,
flow, buzzer, overflow and reservoir alarms on the I/O
The following features are enabled for this File:
#define DisplayImages
#define SetupExtras
#define DateTimeSetup
#define VersionMenu
#define DisplayLEDPWM
#define wifi
#define RelayExp
#define WDT
#define CUSTOM_MENU
#define CUSTOM_MENU_ENTRIES 9
#define CUSTOM_MAIN
#define COLORS_PDE
#define FONT_8x8
#define NUMBERS_8x8
#define CUSTOM_VARIABLES
*/
#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/pgmspace.h>
//Actinic and Daylight PMW are on the LED moonlights
byte ActinicPWMValue=0;
byte DaylightPWMValue=0;
byte MoonPWMValue;
byte Sound;
int maxTemp=0;
int minTemp=2000;
int maxPH=0;
int minPH=1000;
int flow =0;
int maxflow=0;
int minflow=1000;
//timestamp
time_t mastertime=now();
time_t tsmax=now();
time_t tsmin=now();
time_t PHmax=now();
time_t PHmin=now();
time_t flowmax=now();
time_t flowmin=now();
// Moon Global Variables - Thanks Deckoz2302!
byte ThisPhase;
double AG;
double IP;
long YY, MM, K1, K2, K3, JD;
//wire.write variable number
byte param[2];
//wavemaker dalay variables
byte wmport=Port5;
boolean wmdelay=false;
byte wmpulse=0;
//time variables for time between sounds
long previousMillis = 0;
long interval = 5000; // interval at which a sound can play (milliseconds)
//varibles for input module data
byte IOIn[10];
int Flow0;
int Flow1;
int Flow2;
byte buzz = 1;
byte Overflow = 0;
byte Reservoir = 0;
byte HATO = 0;
byte LATO = 0;
byte wm = 0;
byte level = 0;
byte atos = 0;
byte powerOut;
static int swidth = 90; // change these
static int sheight = 60; // change these
static const prog_int16_t header_data[] PROGMEM = { // add data here
};
void DrawBitmap(int xpos, int ypos) {
int count = 0;
for (int j = 0; j < sheight; j++) {
for (int i = 0; i < swidth; i++) {
ReefAngel.LCD.PutPixel(pgm_read_word_near(header_data + count),xpos+i,ypos+j);
count++;
}
}
}
// Custom Menu Code
prog_char menu1_label[] PROGMEM = "Feeding";
prog_char menu2_label[] PROGMEM = "Water Change";
prog_char menu3_label[] PROGMEM = "pH Calibration";
prog_char menu4_label[] PROGMEM = "pH Detail";
prog_char menu5_label[] PROGMEM = "Temp Detail";
prog_char menu6_label[] PROGMEM = "Date / Time";
prog_char menu7_label[] PROGMEM = "Flow Cells";
prog_char menu8_label[] PROGMEM = "Version";
prog_char menu9_label[] PROGMEM = "Sound Bytes";
PROGMEM const char *menu_items[] = {
menu1_label, menu2_label, menu3_label,
menu4_label, menu5_label, menu6_label,
menu7_label, menu8_label, menu9_label
};
void MenuEntry1()
{
ReefAngel.FeedingModeStart();
}
void MenuEntry2()
{
ReefAngel.WaterChangeModeStart();
}
void MenuEntry3()
{
ReefAngel.SetupCalibratePH();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry4()
{
//pH detail screen with 24 hr. max/min, time stamps, and graph
ReefAngel.ClearScreen(DefaultBGColor);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 5, 13,"PH:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.PH, 0, 36, 13, 100);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5, 23,"HI:");
ReefAngel.LCD.DrawSingleMonitor(maxPH, 0, 23, 23, 100);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 48, 23,"at");
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 5, 33,"LO:");
ReefAngel.LCD.DrawSingleMonitor(minPH, 0, 23, 33, 100);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 48, 33,"at");
DrawTime(60,23,0, COLOR_WHITE,PHmax);
DrawTime(60,33,0,COLOR_WHITE, PHmin);
ReefAngel.LCD.Clear(DefaultBGColor,0,75,131,125);
ReefAngel.LCD.Clear(DefaultFGColor,1,75,1,125);
for (byte i=6; i<=131; i+=3)
{
ReefAngel.LCD.PutPixel(GraphDotLineColor, i, 100);
}
ReefAngel.LCD.DrawSingleGraph(PHColor,1,75,InternalMemory.T1Pointer_read()+360);
pingSerial();
bool bDone = false;
do
{
// wait indefinitely for a button press
delay(200);
if ( ReefAngel.Joystick.IsButtonPressed() )
{
bDone = true;
}
} while ( ! bDone );
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry5()
{
//Temperature detail screen with sump and room temp, 24 hr. max/min, time stamps, and graph
ReefAngel.ClearScreen(DefaultBGColor);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,13,"TANK:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T1_PROBE], COLOR_BLACK, 36, 13, 10);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,23,"HI:");
ReefAngel.LCD.DrawSingleMonitor(maxTemp, 0, 23, 23, 10);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,48,23,"at");
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,33,"LO:");
ReefAngel.LCD.DrawSingleMonitor(minTemp, 0, 23, 33, 10);
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,48,33,"at");
ReefAngel.LCD.DrawText(T2TempColor,DefaultBGColor, 5 ,43,"R00M:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T2_PROBE], COLOR_BLACK, 36, 43, 10);
ReefAngel.LCD.DrawText(T3TempColor,DefaultBGColor, 5, 53,"SUMP:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T3_PROBE], COLOR_BLACK, 36, 53, 10);
DrawTime(60,23,0, COLOR_WHITE,tsmax);
DrawTime(60,33,0,COLOR_WHITE, tsmin);
ReefAngel.LCD.Clear(DefaultBGColor,0,75,131,125);
ReefAngel.LCD.Clear(DefaultFGColor,1,75,1,125);
for (byte i=6; i<=131; i+=3)
{
ReefAngel.LCD.PutPixel(GraphDotLineColor, i, 100);
}
ReefAngel.LCD.DrawSingleGraph(T1TempColor,1,75,InternalMemory.T1Pointer_read());
ReefAngel.LCD.DrawSingleGraph(T2TempColor,1,75,InternalMemory.T1Pointer_read()+120);
ReefAngel.LCD.DrawSingleGraph(T3TempColor,1,75,InternalMemory.T1Pointer_read()+240);
pingSerial();
bool bDone = false;
do
{
// wait indefinitely for a button press
delay(200);
if ( ReefAngel.Joystick.IsButtonPressed() )
{
bDone = true;
}
} while ( ! bDone );
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry6()
{
ReefAngel.SetupDateTime();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry7()
{
//Flow detail screen with 24 hr. max/min, & time stamps
ReefAngel.ClearScreen(DefaultBGColor);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 5, 13,"FLOW0:");
ReefAngel.LCD.DrawSingleMonitor(Flow1, 0,46,13, 1);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 66, 13,"gal/hr");
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor,5, 23,"HI:");
ReefAngel.LCD.DrawSingleMonitor(maxflow, 0, 23, 23, 1);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 48, 23,"at");
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 5, 33,"LO:");
ReefAngel.LCD.DrawSingleMonitor(minflow, 0, 23, 33, 1);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 48, 33,"at");
DrawTime(60,23,0, COLOR_WHITE,flowmax);
DrawTime(60,33,0,COLOR_WHITE, flowmin);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 5, 43,"FLOW1:");
ReefAngel.LCD.DrawSingleMonitor(Flow2, 0,46,43, 1);
pingSerial();
bool bDone = false;
do
{
// wait indefinitely for a button press
delay(200);
if ( ReefAngel.Joystick.IsButtonPressed() )
{
bDone = true;
}
} while ( ! bDone );
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry8()
{
ReefAngel.DisplayVersion();
DrawBitmap(5,60);
}
void MenuEntry9()
{
Sound++;
if ( Sound > 9 ) Sound = 1;
// Sound=random(0,8);
Soundsend(Sound,1);
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 5, 13,"Playing Sound #");
ReefAngel.LCD.DrawSingleMonitor(Sound, 0,90,13, 1);
ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor, 5, 23,"just keep swimming");
ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor, 5, 33,"Under the sea");
ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor, 5, 43,"anemone");
ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor, 5, 53,"H20 intolerant");
ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor, 5, 63,"fronds like these");
ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor, 5, 73,"Sharkbait");
ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor, 5, 83,"Seabirds");
ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor, 5, 93,"fish are friends");
ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor, 5, 103,"Aquascum");
if (Sound==0) ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor, 5, 23,"just keep swimming");
else if (Sound==1) ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor, 5, 33,"Under the sea");
else if (Sound==2) ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor, 5, 43,"anemone");
else if (Sound==3) ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor, 5, 53,"H20 intolerant");
else if (Sound==4) ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor, 5, 63,"fronds like these");
else if (Sound==5) ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor, 5, 73,"Sharkbait");
else if (Sound==6) ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor, 5, 83,"Seabirds");
else if (Sound==7) ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor, 5, 93,"fish are friends");
else if (Sound==8) ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor, 5, 103,"Aquascum");
}
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);
}
//function to backage int into bytes for parameters temp, pH, timers, actinic%)
void paramsend(int a)
{
param[0]=(byte)(a>>8);
param[1]=(byte)(a);
Wire.write(param,2);
}
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 DrawCustomGraph()
{
}
void DrawCustomMain()
{
// update the min and max temps
if (now()%86400==0)
{
minTemp=ReefAngel.Params.Temp[T1_PROBE];
maxTemp=ReefAngel.Params.Temp[T1_PROBE];
}
if (ReefAngel.Params.Temp[T1_PROBE]<minTemp)
{
minTemp=ReefAngel.Params.Temp[T1_PROBE];
tsmin=now();
}
if (ReefAngel.Params.Temp[T1_PROBE]>maxTemp)
{
maxTemp=ReefAngel.Params.Temp[T1_PROBE];
tsmax=now();
}
// update the min and max pH
if (now()%86400==0)
{
minPH=ReefAngel.Params.PH;
maxPH=ReefAngel.Params.PH;
}
if (ReefAngel.Params.PH<minPH)
{
minPH=ReefAngel.Params.PH;
PHmin=now();
}
if (ReefAngel.Params.PH>maxPH)
{
maxPH=ReefAngel.Params.PH;
PHmax=now();
}
if (now()%86400==0)
{
minflow=flow;
maxflow=flow;
}
if (flow<minflow)
{
minflow=flow;
flowmin=now();
}
if (flow>maxflow)
{
maxflow=flow;
flowmax=now();
}
// the graph is drawn/updated when we exit the main menu &
// when the parameters are saved
ReefAngel.LCD.DrawDate(6, 2);
ReefAngel.LCD.Clear(0, 1, 11, 132, 11);
pingSerial();
GetFlow();
// Display the Tank temperature with color sensors
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,13,"TK:");
if (ReefAngel.Params.Temp[T1_PROBE]>830) ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T1_PROBE], COLOR_RED, 23, 13, 10);
else if (ReefAngel.Params.Temp[T1_PROBE]>810) ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T1_PROBE], COLOR_ORANGE, 23, 13, 10);
else ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T1_PROBE], COLOR_BLACK, 23, 13, 10);
// Display the PH with color sensors
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 64, 13,"PH:");
if (ReefAngel.Params.PH>840 || ReefAngel.Params.PH<790) ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.PH, COLOR_RED, 82, 13, 100);
else if (ReefAngel.Params.PH>830 || ReefAngel.Params.PH<800) ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.PH, COLOR_ORANGE, 82, 13, 100);
else ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.PH, 0, 82, 13, 100);
// Display status of ato's
if (Reservoir == 0)
{
FillCircle(15,26,5,COLOR_RED);
ReefAngel.LCD.DrawText(COLOR_WHITE,COLOR_RED,14,22,"R");
}
else if (Reservoir == 1)
{
FillCircle(15,26,5,COLOR_GREEN);
ReefAngel.LCD.DrawText(COLOR_WHITE,COLOR_GREEN,14,22,"R");
}
if (Overflow == 0)
{
FillCircle(26,26,5,COLOR_GREEN);
ReefAngel.LCD.DrawText(COLOR_WHITE,COLOR_GREEN,23,22,"O");
}
else if (Overflow == 1)
{
FillCircle(26,26,5,COLOR_RED);
ReefAngel.LCD.DrawText(COLOR_WHITE,COLOR_RED,23,22,"O");
}
if (ReefAngel.HighATO.IsActive())
{
HATO = 1;
FillCircle(36,26,5,COLOR_GREEN);
ReefAngel.LCD.DrawText(COLOR_WHITE,COLOR_GREEN,34,22,"H");
}
else
{
HATO = 0;
FillCircle(36,26,5,COLOR_RED);
ReefAngel.LCD.DrawText(COLOR_WHITE,COLOR_RED,34,22,"H");
}
if (ReefAngel.LowATO.IsActive())
{
LATO = 1;
FillCircle(46,26,5,COLOR_RED);
ReefAngel.LCD.DrawText(COLOR_WHITE,COLOR_RED,44,22,"L");
}
else
{
LATO = 0;
FillCircle(46,26,5,COLOR_GREEN);
ReefAngel.LCD.DrawText(COLOR_WHITE,COLOR_GREEN,44,22,"L");
}
// Display the % Moonlight
ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 64, 23,"MN:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.PWM.GetActinicValue(), COLOR_BLACK, 82, 23, 1);
ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 100, 23,"%");
// Display the Flow 1
ReefAngel.LCD.DrawText(T3TempColor,DefaultBGColor,5,33,"FL0:");
ReefAngel.LCD.DrawSingleMonitor(Flow1, COLOR_BLACK, 33, 33, 1);
// Display the Flow 0
ReefAngel.LCD.DrawText(T3TempColor,DefaultBGColor,64,33,"FL1:");
ReefAngel.LCD.DrawSingleMonitor(Flow2, COLOR_BLACK, 92, 33, 1);
// 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.DrawText(DPColor,DefaultBGColor, 5, 43,"New");
else if (AG < 5.53) ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 5, 43,"Waxing Crescent");
else if (AG < 9.92) ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 5, 43,"First Quarter");
else if (AG < 12.91) ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 5, 43,"Waxing Gibbous");
else if (AG < 16.61) ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 5, 43,"Full");
else if (AG < 20.30) ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 5, 43,"Waning gibbous");
else if (AG < 23.99) ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 5, 43,"Last Quarter");
else if (AG < 27.68) ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 5, 43,"Waning Crescent");
else ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 5, 43,"New") ;
//temperature room
ReefAngel.LCD.DrawText(T2TempColor,DefaultBGColor,5,53,"RM:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T2_PROBE], COLOR_BLACK, 23, 53, 10);
//temperature sump
ReefAngel.LCD.DrawText(T2TempColor,DefaultBGColor,64,53,"SP:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T3_PROBE], COLOR_BLACK, 82, 53, 10);
// Display arrows for Wavemaker
ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 5, 63,"WV:");
if (bitRead(ReefAngel.Relay.RelayData,Port5-1)==1) ReefAngel.LCD.DrawText(APColor,DefaultBGColor, 23, 63,"-->"); //port 5 on
else if (bitRead(ReefAngel.Relay.RelayData,Port6-1)==1) ReefAngel.LCD.DrawText(APColor,DefaultBGColor, 23, 63,"<--"); //port 6 on
else ReefAngel.LCD.DrawText(APColor,DefaultBGColor, 43, 63," O "); //port5 and port 6 off, wavemaker delay
//Timer and trigger to keep wavemaker timing correct after setting date/time
int t=ReefAngel.Timer[1].Trigger-now();
if (t>=0)
{
ReefAngel.LCD.Clear(255,23,73,53,83);
ReefAngel.LCD.DrawText(0, DefaultBGColor,23,73,t);
}
if (t>300) ReefAngel.Timer[1].ForceTrigger();
//wavemakers extra
ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 64, 63,"WV:");
if (bitRead(ReefAngel.Relay.RelayDataE[0],Port5-1)==1) ReefAngel.LCD.DrawText(APColor,DefaultBGColor, 82, 63,"v "); //port 5 on
else if (bitRead(ReefAngel.Relay.RelayDataE[0],Port6-1)==1) ReefAngel.LCD.DrawText(APColor,DefaultBGColor, 82, 63," v"); //port 6 on
else ReefAngel.LCD.DrawText(APColor,DefaultBGColor, 82, 63," O "); //port5 and port 6 off, wavemaker delay
//Timer and trigger to keep wavemaker timing correct after setting date/time
int u=ReefAngel.Timer[2].Trigger-now();
if (u>=0)
{
ReefAngel.LCD.Clear(255,82,73,112,83);
if (bitRead(ReefAngel.Relay.RelayDataE[0],Box1_Port5-1)==1 || bitRead(ReefAngel.Relay.RelayDataE[0],Box1_Port6-1)==1)
{
ReefAngel.LCD.DrawText(0, DefaultBGColor,82,73,u);
}
}
if (u>300) ReefAngel.Timer[2].ForceTrigger();
// power status on LCD
if (powerOut)
{
ReefAngel.LCD.Clear(255,1,92,102,102);
ReefAngel.LCD.DrawText(COLOR_RED, DefaultBGColor,1,92,"BACKUP Power ON");
}
else
{
ReefAngel.LCD.Clear(255,1,92,102,102);
ReefAngel.LCD.DrawText(COLOR_GREEN, DefaultBGColor,1,92,"Main Power ON");
}
pingSerial();
byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 110, TempRelay);
// draw 1st expansion relay
TempRelay = ReefAngel.Relay.RelayDataE[0];
TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
ReefAngel.LCD.DrawOutletBox(12, 120, TempRelay);
}
void Soundsend(byte x, long y) //function to play sound and delay before it plays again.
{
interval = y*100;
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval)
{
// save the last time you played a sound
previousMillis = currentMillis;
// if longer than 100 sec than play a sound
Wire.beginTransmission(9); // transmit to device #9
Wire.write('$'); // send the $$$
Wire.write('$');
Wire.write('$');
Wire.write(x); // send the command
Wire.endTransmission(); // stop transmitting
}
}
void setup()
{
ReefAngel.Init(); //Initialize controller and start web banner timer
ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));
ReefAngel.PHMin=546;
ReefAngel.PHMax=868;
// Set the ports that get toggled on & off during the following modes
// To enable a port to be toggled, place a 1 in the appropriate position
// Uncomment and update as needed
// Port 87654321
ReefAngel.FeedingModePorts = B00110000;
ReefAngel.FeedingModePortsE[1] = B00110100;
ReefAngel.WaterChangePorts = B10110000;
ReefAngel.WaterChangePortsE[1] = B11111111;
// Ports that are always on
ReefAngel.Relay.On(Port7); //main pump
ReefAngel.Relay.On(Box1_Port1); //chiller
ReefAngel.Relay.On(Box1_Port2); //chiller pump
ReefAngel.Relay.On(Box1_Port4); //phosban pumpo
// Top smaller pumps once an hour for 5 minutes
ReefAngel.Relay.On(Box1_Port5);
ReefAngel.Timer[2].SetInterval(30);
ReefAngel.Timer[2].Start();
//Side to side Wavemaker Pumps
ReefAngel.Relay.On(Port5);
ReefAngel.Timer[1].SetInterval(200);
ReefAngel.Timer[1].Start();
}
void loop()
{
// Specific functions
//1st Heater at 78.8, 2nd Heater at 77.0, MH on at 10AM off at 8PM, Actinics on at 9AM off at 9PM, Fan kicks on at 82.0
ReefAngel.StandardHeater(Port1,788,792);
ReefAngel.StandardHeater(Port2,770,792);
ReefAngel.MHLights(Port3,10,0,20,0,5);
ReefAngel.StandardLights(Port4,9,0,21,0);
ReefAngel.StandardFan(Port8,792,820);
ReefAngel.DosingPumpRepeat(Box1_Port7,0,60,4); // Dose for 4 seconds every 60 minutes with 0 minutes offset
ReefAngel.DosingPumpRepeat(Box1_Port8,5,60,4); // Dose for 4 seconds every 60 minutes with 5 minutes offset
ReefAngel.CustomVar[1]=Flow0;
ReefAngel.CustomVar[2]=Flow1;
ReefAngel.CustomVar[3]=Flow2;
ReefAngel.CustomVar[6]=buzz;
//Sump refill, check reservoir level first, then standard ATO
if (Reservoir == 1)
{
ReefAngel.StandardATO(Box1_Port3,60); //Setup relay unit Port3 as Auto Top-Off function with 60s timeout
}
//Alarm state
if (ReefAngel.Params.Temp[T1_PROBE]>830)
{
buzz = 1;
}
else
{
buzz = 0;
}
GetFlow();
// Wavemaker Code with night option
if (ReefAngel.Timer[1].IsTriggered() )
{
if ((hour() >= 21) || (hour() <= 8)) //from 9p-Midnight
{ //PWMSlope(byte startHour, byte startMinute, byte endHour, byte endMinute, byte startPWM,
// byte endPWM, byte Duration, byte oldValue)
wmpulse=PWMSlope(21,0,8,0,5,30,179,30);
if (wmdelay)
{
ReefAngel.Timer[1].SetInterval(wmpulse); // WM delay function from 30-170 sec.
ReefAngel.Timer[1].Start();
ReefAngel.Relay.Off(Port5);
ReefAngel.Relay.Off(Port6);
if (wmport==Port5) wmport=Port6; else wmport=Port5;
wmdelay=false;
}
else
{
ReefAngel.Timer[1].SetInterval(200-wmpulse); // WM bursts timing from 170-30 sec.
ReefAngel.Timer[1].Start();
ReefAngel.Relay.On(wmport);
wmdelay=true;
}
}
else
{
//8a-10p normal wave settings
ReefAngel.Timer[1].SetInterval(200);
ReefAngel.Timer[1].Start();
ReefAngel.Relay.Toggle(Port5);
ReefAngel.Relay.Set(Port6,!ReefAngel.Relay.Status(Port5));
}
}
//extra small powerheads to increase circulation once an hour
//for 5 min during the day
if (hour()>=8 && hour()<=21)
{
if (minute()<5)
{
if (ReefAngel.Timer[2].IsTriggered())
{
ReefAngel.Timer[2].SetInterval(30);
ReefAngel.Timer[2].Start();
ReefAngel.Relay.Toggle(Box1_Port5);
ReefAngel.Relay.Set(Box1_Port6,!ReefAngel.Relay.Status(Box1_Port5));
}
}
else
{
ReefAngel.Relay.Off(Box1_Port5);
ReefAngel.Relay.Off(Box1_Port6);
}
}
else
{
ReefAngel.Relay.Off(Box1_Port5);
ReefAngel.Relay.Off(Box1_Port6);
}
//Moonlight
MoonPWMValue=MoonPhase();
if (hour()==21 || hour()==8)
MoonPWMValue=PWMSlope(21,00,9,00,0,MoonPhase(),60,0);
if (ReefAngel.Relay.Status(Port4)) MoonPWMValue=0;
ReefAngel.PWM.SetActinic(MoonPWMValue);
ReefAngel.PWM.SetDaylight(MoonPWMValue);
//I/O module communication
Wire.beginTransmission(7); // transmit to device #7
Wire.write('$'); // send the $$$
Wire.write('$');
Wire.write('$');
Wire.write(buzz);
Wire.endTransmission(); // stop transmitting
//Overflow blocked alarm & main pump shut-off, Reservoir alarm
// Overflow blocked, Reservoir Full
if (Overflow == 1 && Reservoir == 0)
{
ReefAngel.Relay.Off(Port7);
ReefAngel.CustomVar[4]=1; // overflow: 0 good, 1 bad
ReefAngel.CustomVar[5]=0; // reservoir: 0 good, 1 bad
level = 0;
}
// Overflow open, Reservoir Full
else if (Overflow == 0 && Reservoir == 0)
{
ReefAngel.Relay.On(Port7);
ReefAngel.CustomVar[4]=0;
ReefAngel.CustomVar[5]=0;
level = 1;
}
// Overflow blocked, Reservoir Empty
else if (Overflow == 1 && Reservoir == 1)
{
ReefAngel.Relay.Off(Port7);
ReefAngel.CustomVar[4]=1;
ReefAngel.CustomVar[5]=1;
level = 2;
}
// Overflow open, Reservoir Empty
else if (Overflow == 0 && Reservoir == 1)
{
ReefAngel.Relay.On(Port7);
ReefAngel.CustomVar[4]=0;
ReefAngel.CustomVar[5]=1;
level = 3;
}
//ATO status
if (HATO == 1 && LATO == 1)
{
atos = 0;
}
else if (HATO == 1 && LATO == 0)
{
atos = 1;
}
else if (HATO == 0 && LATO == 1)
{
atos = 2;
}
else if (HATO == 0 && LATO == 0)
{
atos = 3;
}
// power sensor with scanner
powerOut = !ReefAngel.Relay.IsRelayPresent(0);
// turn off power hogs if the power is out
if (powerOut)
{
ReefAngel.Relay.Off(Port1);
ReefAngel.Relay.Off(Port2);
ReefAngel.Relay.Off(Port3);
ReefAngel.Relay.Off(Port4);
ReefAngel.Relay.On(Port5);
ReefAngel.Relay.Off(Port6);
ReefAngel.Relay.Off(Port7);
ReefAngel.Relay.Off(Port8);
ReefAngel.CustomVar[7]=1;
}
else
{
ReefAngel.CustomVar[7]=0;
}
//send sound requests
if (ReefAngel.DisplayedMenu==FEEDING_MODE) Soundsend(7,100); //feeding time
if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE) Soundsend(8,100); //feeding time
//send data parameter package to the auxillary monitor
Wire.beginTransmission(10); // transmit to device #10
Wire.write('$'); // send the $$$
Wire.write('$');
Wire.write('$');
paramsend(ReefAngel.Params.Temp[T1_PROBE]);
paramsend(ReefAngel.Params.Temp[T2_PROBE]);
paramsend(ReefAngel.Params.Temp[T3_PROBE]);
paramsend(ReefAngel.Params.PH);
paramsend(ReefAngel.Timer[1].Trigger-now());
paramsend(ReefAngel.PWM.GetActinicValue());
Wire.write(level);
Wire.write(atos);
Wire.write(ReefAngel.Relay.RelayData);
Wire.write(ReefAngel.Relay.RelayDataE[0]);
paramsend(Flow0);
paramsend(Flow1);
paramsend(Flow2);
Wire.write(hour());
Wire.write(minute());
Wire.write(second());
Wire.write(day());
Wire.write(month());
paramsend(year());
Wire.endTransmission(); // stop transmitting
ReefAngel.Portal("jsclownfish");
ReefAngel.ShowInterface();
}
void GetFlow()
{
Wire.requestFrom(7,9);
if(Wire.available())
{
for (int a=0;a<10;a++)
IOIn[a]=Wire.read();
}
Flow0=(IOIn[1]<<8)+IOIn[2];
Flow1=(IOIn[3]<<8)+IOIn[4];
Flow2=(IOIn[5]<<8)+IOIn[6];
Overflow=IOIn[7];
Reservoir=IOIn[8];
}
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
}