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
}