This is so cool! I hadn't really envisioned this aspect of having an auxillary monitor that doesn't bear the weight of the other controller functions. I was messing around with it today and put this group of screens together. It easily moves from one to the next and keeps the data updating. (since I don't have all the sensors hooked up on these there are some of the 0's or Errors on the display)
Check it out....
Now I'm looking forward to really thinking about what each screen should look like and how to display the data. That should keep me busy for awhile.
For anyone interested, here is the pde as well...
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
}