Things to add to a custom menu

Do you have a question on how to do something.
Ask in here.
Post Reply
dpitalo
Posts: 39
Joined: Mon Dec 12, 2011 6:45 pm

Things to add to a custom menu

Post by dpitalo »

I'd like to add two items to my menu.

1. Force Cloud
2. Force Thunderstorm

but have no idea where to begin.

I attempted to follow the instructions in the PWM Module User guide with no luck.

My LED's are configured like this

3 Banks of 12 Royal Blues
2 Banks of XP-E Cool Whites
2 Banks of XP-G Cool Whites

If possible, I'd like to do a rolling cloud effect. Maybe having all the blues dim slightly and the whites on one side dim followed by the other side. The other thing that would be neat would be to just have the XP-E's for lightining and everything else just get a little dimmer.

Here's my PDE...

Code: Select all

#define SIMPLE_MENU
#define DisplayLEDPWM

#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>

#define AutoTopOff        1
#define Actinic           2
#define Chiller           3
#define Heater            4
#define Skimmer           5
#define MetalHalide       6
#define SeaSwirl          7
#define Return            8

#define PWMRB1            0
#define PWMRB2            1
#define PWMRB3            2
#define PWMWT1            3
#define PWMWT2            4
#define PWMHN             5


byte PWMChannel[]={
  0,0,0,0,0,0};


#include <avr/pgmspace.h>
//Create the menu entries
prog_char menu1_label[] PROGMEM= "Chow Time";
prog_char menu2_label[] PROGMEM= "h2o Change";
prog_char menu3_label[] PROGMEM= "Clear ATO Warning";
prog_char menu4_label[] PROGMEM= "ph Calibration";
prog_char menu5_label[] PROGMEM= "Set Date Time";


//Group menu entries together
PROGMEM const char *menu_items[] = {
menu1_label, menu2_label, menu3_label, menu4_label, menu5_label
};

void MenuEntry1()
{
ReefAngel.FeedingModeStart();
}
void MenuEntry2()
{
ReefAngel.WaterChangeModeStart();
}
void MenuEntry3()
{
ReefAngel.ATOClear();
ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
}
void MenuEntry4()
{
ReefAngel.SetupCalibratePH();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry5()
{
ReefAngel.SetupDateTime();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}

void DrawCustomMain()
{
byte x = 6;
byte y = 2;
byte t;
ReefAngel.LCD.DrawLargeText(COLOR_BLACK, COLOR_WHITE, 6, 3, "Dave's 40g Reef");
ReefAngel.LCD.DrawDate(6, 120);
ReefAngel.LCD.Clear(COLOR_BLACK, 1, 14, 131, 14);
//pingSerial();
x = 12;
y += MENU_START_ROW+1;
ReefAngel.LCD.DrawText(COLOR_BLUE, COLOR_WHITE, x, y+6, "Temp:        pH:");
char text[7];
ConvertNumToString(text, ReefAngel.Params.PH, 100);
ReefAngel.LCD.Clear(DefaultBGColor, x+16, y+65, x+65, y+16);
ReefAngel.LCD.DrawLargeText(PHColor, DefaultBGColor, x+75, y+18, text);
//pingSerial();

ConvertNumToString(text, ReefAngel.Params.Temp1, 10);
y += MENU_START_ROW*2;
x = 10;
ReefAngel.LCD.Clear(DefaultBGColor,x,y,x+(16*4),y+16);
//pingSerial();
ReefAngel.LCD.DrawHugeNumbers(T1TempColor, DefaultBGColor, x, y, text);
//pingSerial(); 

//Start Moon Phase Display
x += (16*4) + 8;
y += MENU_START_ROW+3;
ReefAngel.LCD.DrawText(COLOR_BLACK, COLOR_WHITE, 12, 55, "Moon Phase:");
if (ReefAngel.PWM.GetActinicValue() ==0) ReefAngel.LCD.DrawText(20,255,81,55,"Off");
else if(ReefAngel.PWM.GetActinicValue() >=1 && ReefAngel.PWM.GetActinicValue() < 20) ReefAngel.LCD.DrawText(20,255,81,55,"New");
else if(ReefAngel.PWM.GetActinicValue() >=20 && ReefAngel.PWM.GetActinicValue() < 35) ReefAngel.LCD.DrawText(20,255,81,55,"Cresent");
else if(ReefAngel.PWM.GetActinicValue() >=35 && ReefAngel.PWM.GetActinicValue() < 45) ReefAngel.LCD.DrawText(20,255,81,55,"Half");
else if(ReefAngel.PWM.GetActinicValue() >=45 && ReefAngel.PWM.GetActinicValue() < 60) ReefAngel.LCD.DrawText(20,255,81,55,"Gibbous");
else if(ReefAngel.PWM.GetActinicValue() >=60 && ReefAngel.PWM.GetActinicValue() < 80) ReefAngel.LCD.DrawText(20,255,81,55,"Full");
//End Display Moon Phase Display


byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 102, TempRelay);
}

void DrawCustomGraph()
{
}

void setup()
{
  ReefAngel.Init();   //Initialize controller
  ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));
  ReefAngel.Relay.On(Return);  //Turn Return on at startup
  ReefAngel.Relay.On(Skimmer); //Turn Skimmer on at startup
  ReefAngel.Relay.On(SeaSwirl); //Turn SeaSwirl on at startup
}

void loop()

{

  ReefAngel.StandardATO(AutoTopOff,30);             //Setup AutoTopOff as Auto Top-Off function with 30s timeout
  ReefAngel.MHLights(MetalHalide,14,30,21,00,15);   //Daylight schedule 1:00pm - 9:30pm with 15min cool down
  ReefAngel.StandardLights(Actinic,13,00,21,30);    //Actinic schedule 1:00pm - 9:30pm
  ReefAngel.StandardHeater(Heater,788,792);         // Setup Heater to turn on at 78.8F and off at 79.2F
  ReefAngel.StandardFan(Chiller,797,80);             // Setup Chiller to turn on at 81.1F and off at 79.7F 
  
    if (hour()>=21 || hour()<10)
  {
    ReefAngel.PWM.SetActinic(MoonPhase());
  }
  else
  {
    ReefAngel.PWM.SetActinic(0);
  }
    //************************************************************ Start of PWM Expansion Code for Slope
  PWMChannel[PWMRB2]=PWMSlope(9,30,21,30,0,90,60,PWMChannel[PWMRB2]);                          //Royal Blue - Right Bank
  PWMChannel[PWMRB3]=PWMSlope(9,45,21,45,0,90,60,PWMChannel[PWMRB3]);                          //Royal Blue - Middle Bank
  PWMChannel[PWMRB1]=PWMSlope(10,00,22,00,0,90,60,PWMChannel[PWMRB1]);                         //Royal Blue - Left Bank

  PWMChannel[PWMWT2]=PWMSlope(11,00,21,00,0,90,90,PWMChannel[PWMWT2]);                          //XP-E Cool Whites - Left Side  
  PWMChannel[PWMWT1]=PWMSlope(11,30,21,30,0,90,90,PWMChannel[PWMWT1]);                          //XP-E Cool Whites - Right Side
 
  PWMChannel[PWMHN]=PWMSlope(12,00,20,00,0,90,120,PWMChannel[PWMHN]);                           //XP-G Cool Whites - Left Side
 
      if (hour()>=21 || hour()<12)
  {
    ReefAngel.PWM.SetDaylight(0);
  }
  else
  {
    ReefAngel.PWM.SetDaylight(PWMSlope(12,30,20,30,0,90,120,ReefAngel.PWM.GetDaylightValue()));   //XP-G Cool Whites - Right Side
  }
  
  
  for (int a=0;a<6;a++)
  {
    ReefAngel.PWM.Expansion(a,int(2.55*PWMChannel[a])); 
  }
  //************************************************************* End of PWM Expansion Code for Slope

  ReefAngel.ShowInterface(); //Draw the Standard Interface
}
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Things to add to a custom menu

Post by rimai »

Try this:

Code: Select all

#define SIMPLE_MENU
#define DisplayLEDPWM

#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>

#define AutoTopOff        1
#define Actinic           2
#define Chiller           3
#define Heater            4
#define Skimmer           5
#define MetalHalide       6
#define SeaSwirl          7
#define Return            8

#define PWMRB1            0
#define PWMRB2            1
#define PWMRB3            2
#define PWMWT1            3
#define PWMWT2            4
#define PWMHN             5


byte PWMChannel[]={
  0,0,0,0,0,0};

boolean ForceCloud=false;
boolean ForceLightning=false;



#include <avr/pgmspace.h>
//Create the menu entries
prog_char menu1_label[] PROGMEM= "Chow Time";
prog_char menu2_label[] PROGMEM= "h2o Change";
prog_char menu3_label[] PROGMEM= "Clear ATO Warning";
prog_char menu4_label[] PROGMEM= "Force Cloud";
prog_char menu5_label[] PROGMEM= "Force Lightning";


//Group menu entries together
PROGMEM const char *menu_items[] = {
menu1_label, menu2_label, menu3_label, menu4_label, menu5_label
};

void MenuEntry1()
{
ReefAngel.FeedingModeStart();
}
void MenuEntry2()
{
ReefAngel.WaterChangeModeStart();
}
void MenuEntry3()
{
ReefAngel.ATOClear();
ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
}
void MenuEntry4()
{
ForceCloud=true;
ReefAngel.DisplayedMenu=RETURN_MAIN_MODE;
}
void MenuEntry5()
{
ForceLightning=true;
ReefAngel.DisplayedMenu=RETURN_MAIN_MODE;
}

void DrawCustomMain()
{
byte x = 6;
byte y = 2;
byte t;
ReefAngel.LCD.DrawLargeText(COLOR_BLACK, COLOR_WHITE, 6, 3, "Dave's 40g Reef");
ReefAngel.LCD.DrawDate(6, 120);
ReefAngel.LCD.Clear(COLOR_BLACK, 1, 14, 131, 14);
//pingSerial();
x = 12;
y += MENU_START_ROW+1;
ReefAngel.LCD.DrawText(COLOR_BLUE, COLOR_WHITE, x, y+6, "Temp:        pH:");
char text[7];
ConvertNumToString(text, ReefAngel.Params.PH, 100);
ReefAngel.LCD.Clear(DefaultBGColor, x+16, y+65, x+65, y+16);
ReefAngel.LCD.DrawLargeText(PHColor, DefaultBGColor, x+75, y+18, text);
//pingSerial();

ConvertNumToString(text, ReefAngel.Params.Temp1, 10);
y += MENU_START_ROW*2;
x = 10;
ReefAngel.LCD.Clear(DefaultBGColor,x,y,x+(16*4),y+16);
//pingSerial();
ReefAngel.LCD.DrawHugeNumbers(T1TempColor, DefaultBGColor, x, y, text);
//pingSerial(); 

//Start Moon Phase Display
x += (16*4) + 8;
y += MENU_START_ROW+3;
ReefAngel.LCD.DrawText(COLOR_BLACK, COLOR_WHITE, 12, 55, "Moon Phase:");
if (ReefAngel.PWM.GetActinicValue() ==0) ReefAngel.LCD.DrawText(20,255,81,55,"Off");
else if(ReefAngel.PWM.GetActinicValue() >=1 && ReefAngel.PWM.GetActinicValue() < 20) ReefAngel.LCD.DrawText(20,255,81,55,"New");
else if(ReefAngel.PWM.GetActinicValue() >=20 && ReefAngel.PWM.GetActinicValue() < 35) ReefAngel.LCD.DrawText(20,255,81,55,"Cresent");
else if(ReefAngel.PWM.GetActinicValue() >=35 && ReefAngel.PWM.GetActinicValue() < 45) ReefAngel.LCD.DrawText(20,255,81,55,"Half");
else if(ReefAngel.PWM.GetActinicValue() >=45 && ReefAngel.PWM.GetActinicValue() < 60) ReefAngel.LCD.DrawText(20,255,81,55,"Gibbous");
else if(ReefAngel.PWM.GetActinicValue() >=60 && ReefAngel.PWM.GetActinicValue() < 80) ReefAngel.LCD.DrawText(20,255,81,55,"Full");
//End Display Moon Phase Display


byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 102, TempRelay);
}

void DrawCustomGraph()
{
}

void setup()
{
  ReefAngel.Init();   //Initialize controller
  ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items));
  ReefAngel.Relay.On(Return);  //Turn Return on at startup
  ReefAngel.Relay.On(Skimmer); //Turn Skimmer on at startup
  ReefAngel.Relay.On(SeaSwirl); //Turn SeaSwirl on at startup
}

void loop()

{

  ReefAngel.StandardATO(AutoTopOff,30);             //Setup AutoTopOff as Auto Top-Off function with 30s timeout
  ReefAngel.MHLights(MetalHalide,14,30,21,00,15);   //Daylight schedule 1:00pm - 9:30pm with 15min cool down
  ReefAngel.StandardLights(Actinic,13,00,21,30);    //Actinic schedule 1:00pm - 9:30pm
  ReefAngel.StandardHeater(Heater,788,792);         // Setup Heater to turn on at 78.8F and off at 79.2F
  ReefAngel.StandardFan(Chiller,797,80);             // Setup Chiller to turn on at 81.1F and off at 79.7F 
  
    if (hour()>=21 || hour()<10)
  {
    ReefAngel.PWM.SetActinic(MoonPhase());
  }
  else
  {
    ReefAngel.PWM.SetActinic(0);
  }
    //************************************************************ Start of PWM Expansion Code for Slope
  PWMChannel[PWMRB2]=PWMSlope(9,30,21,30,0,90,60,PWMChannel[PWMRB2]);                          //Royal Blue - Right Bank
  PWMChannel[PWMRB3]=PWMSlope(9,45,21,45,0,90,60,PWMChannel[PWMRB3]);                          //Royal Blue - Middle Bank
  PWMChannel[PWMRB1]=PWMSlope(10,00,22,00,0,90,60,PWMChannel[PWMRB1]);                         //Royal Blue - Left Bank

  PWMChannel[PWMWT2]=PWMSlope(11,00,21,00,0,90,90,PWMChannel[PWMWT2]);                          //XP-E Cool Whites - Left Side  
  PWMChannel[PWMWT1]=PWMSlope(11,30,21,30,0,90,90,PWMChannel[PWMWT1]);                          //XP-E Cool Whites - Right Side

  PWMChannel[PWMHN]=PWMSlope(12,00,20,00,0,90,120,PWMChannel[PWMHN]);                           //XP-G Cool Whites - Left Side

      if (hour()>=21 || hour()<12)
  {
    ReefAngel.PWM.SetDaylight(0);
  }
  else
  {
    ReefAngel.PWM.SetDaylight(PWMSlope(12,30,20,30,0,90,120,ReefAngel.PWM.GetDaylightValue()));   //XP-G Cool Whites - Right Side
  }
    CheckCloud();

  
  for (int a=0;a<6;a++)
  {
    ReefAngel.PWM.Expansion(a,int(2.55*PWMChannel[a])); 
  }
  //************************************************************* End of PWM Expansion Code for Slope

  ReefAngel.ShowInterface(); //Draw the Standard Interface
}

//*********************************************************************************************************************************
// Random Cloud/Thunderstorm effects function
void CheckCloud()
{

  // ------------------------------------------------------------
  // Change the values below to customize your cloud/storm effect

  // Frequency in days based on the day of the month - number 2 means every 2 days, for example (day 2,4,6 etc)
  // For testing purposes, you can use 1 and cause the cloud to occur everyday
#define Clouds_Every_X_Days 1 

  // Percentage chance of a cloud happening today
  // For testing purposes, you can use 100 and cause the cloud to have 100% chance of happening
#define Cloud_Chance_per_Day 100

  // Minimum number of minutes for cloud duration.  Don't use max duration of less than 6
#define Min_Cloud_Duration 7

  // Maximum number of minutes for the cloud duration. Don't use max duration of more than 255
#define Max_Cloud_Duration 15

  // Minimum number of clouds that can happen per day
#define Min_Clouds_per_Day 3

  // Maximum number of clouds that can happen per day
#define Max_Clouds_per_Day 5

  // Only start the cloud effect after this setting
  // In this example, start could after 11:30am
#define Start_Cloud_After NumMins(11,30)

  // Always end the cloud effect before this setting
  // In this example, end could before 8:00pm
#define End_Cloud_Before NumMins(18,30)

  // Percentage chance of a lightning happen for every cloud
  // For testing purposes, you can use 100 and cause the lightning to have 100% chance of happening
#define Lightning_Change_per_Cloud 100

  // Channels used by the actinic LEDs on the PWM Expansion module
  // These channels will not be dimmed when the cloud effect is triggered
  // Number is a binary form. B001100 means channel 2 and 3 are used for actinics
#define Actinic_Channels B000111

  // Channels used by the daylight LEDs on the PWM Expansion module
  // These channels will be used for the spike when lightning effect is triggered
  // Number is a binary form. B000011 means channel 0 and 1 are used for daylights
#define Daylight_Channels B111000

  // Note: Make sure to choose correct values that will work within your PWMSLope settings.
  // For example, in our case, we could have a max of 5 clouds per day and they could last for 50 minutes.
  // Which could mean 250 minutes of clouds. We need to make sure the PWMSlope can accomodate 250 minutes of effects or unforseen resul could happen.
    // Also, make sure that you can fit double those minutes between Start_Cloud_After and End_Cloud_Before.
  // In our example, we have 510 minutes between Start_Cloud_After and End_Cloud_Before, so double the 250 minutes (or 500 minutes) can fit in that 510 minutes window.
    // It's a tight fit, but it did.

    //#define printdebug // Uncomment this for debug print on Serial Monitor window
  #define forcecloudcalculation // Uncomment this to force the cloud calculation to happen in the boot process. 


    // Change the values above to customize your cloud/storm effect
  // ------------------------------------------------------------
  // Do not change anything below here

  static byte cloudchance=255;
  static byte cloudduration=0;
  static int cloudstart=0;
  static byte numclouds=0;
  static byte lightningchance=0;
  static byte cloudindex=0;
  static byte lightningstatus=0;
  static int LastNumMins=0;
  // Every day at midnight, we check for chance of cloud happening today
  if (hour()==0 && minute()==0 && second()==0) cloudchance=255;

#ifdef forcecloudcalculation
    if (cloudchance==255)
#else
    if (hour()==0 && minute()==0 && second()==1 && cloudchance==255) 
#endif
    {
      //Pick a random number between 0 and 99
      cloudchance=random(100); 
      // if picked number is greater than Cloud_Chance_per_Day, we will not have clouds today
      if (cloudchance>Cloud_Chance_per_Day) cloudchance=0;
      // Check if today is day for clouds. 
      if ((day()%Clouds_Every_X_Days)!=0) cloudchance=0; 
      // If we have cloud today
      if (cloudchance)
      {
        // pick a random number for number of clouds between Min_Clouds_per_Day and Max_Clouds_per_Day
        numclouds=random(Min_Clouds_per_Day,Max_Clouds_per_Day);
        // pick the time that the first cloud will start
        // the range is calculated between Start_Cloud_After and the even distribuition of clouds on this day. 
        cloudstart=random(Start_Cloud_After,Start_Cloud_After+((End_Cloud_Before-Start_Cloud_After)/(numclouds*2)));
        // pick a random number for the cloud duration of first cloud.
        cloudduration=random(Min_Cloud_Duration,Max_Cloud_Duration);
        //Pick a random number between 0 and 99
        lightningchance=random(100);
        // if picked number is greater than Lightning_Change_per_Cloud, we will not have lightning today
        if (lightningchance>Lightning_Change_per_Cloud) lightningchance=0;
      }
    }
  // Now that we have all the parameters for the cloud, let's create the effect
  if (ForceCloud)
  {
  ForceCloud=false;
  cloudchance=1;
  cloudduration=10;
//  lightningchance=1;
  cloudstart=NumMins(hour(),minute())+1;
  }
  if (ForceLightning)
  {
  ForceLightning=false;
  cloudchance=1;
  cloudduration=10;
  lightningchance=1;
  cloudstart=NumMins(hour(),minute())+1;
  }
  if (cloudchance)
  {
    //is it time for cloud yet?
    if (NumMins(hour(),minute())>=cloudstart && NumMins(hour(),minute())<(cloudstart+cloudduration))
    {
      // let's go through all channels to pick which ones will be dimmed
      for (int a=0;a<6;a++)
      {
        if (bitRead(Actinic_Channels,a)==0)
        {
          // this will slope down the channel from the current PWM to 0 within 3minutes.
          // then it will stay at 0 for the duration of the cycle
          // and finally slope up from 0 to PWM value within 3 minutes
          // it is basically an inversed slope
          PWMChannel[a]=ReversePWMSlope(cloudstart,cloudstart+cloudduration,PWMChannel[a],0,180);
        }
      }
      if (lightningchance && (NumMins(hour(),minute())==(cloudstart+(cloudduration/2))) && second()<5) 
      {
        for (int b=0;b<6;b++)
        {
          if (bitRead(Daylight_Channels,b)==1)
          {
            if (random(100)<20) lightningstatus=1; 
            else lightningstatus=0;
            if (lightningstatus) PWMChannel[b]=100; 
            else PWMChannel[b]=0;
            //delay(10);
          }
          else
          {
            PWMChannel[b]=20;
          }
        }
      }
    }
    if (NumMins(hour(),minute())>(cloudstart+cloudduration))
    {
      cloudindex++;
      if (cloudindex < numclouds)
      {
        cloudstart=random(Start_Cloud_After+(((End_Cloud_Before-Start_Cloud_After)/(numclouds*2))*cloudindex*2),(Start_Cloud_After+(((End_Cloud_Before-Start_Cloud_After)/(numclouds*2))*cloudindex*2))+((End_Cloud_Before-Start_Cloud_After)/(numclouds*2)));
        // pick a random number for the cloud duration of first cloud.
        cloudduration=random(Min_Cloud_Duration,Max_Cloud_Duration);
        //Pick a random number between 0 and 99
        lightningchance=random(100);
        // if picked number is greater than Lightning_Change_per_Cloud, we will not have lightning today
        if (lightningchance>Lightning_Change_per_Cloud) lightningchance=0;
      }
    }
  }
  
  if (LastNumMins!=NumMins(hour(),minute()))
  {
    LastNumMins=NumMins(hour(),minute());
    ReefAngel.LCD.Clear(255,0,120,132,132);
    ReefAngel.LCD.DrawText(0,255,5,120,"C");
    ReefAngel.LCD.DrawText(0,255,11,120,"00:00");
    ReefAngel.LCD.DrawText(0,255,45,120,"L");
    ReefAngel.LCD.DrawText(0,255,51,120,"00:00");
    if (cloudchance && (NumMins(hour(),minute())<cloudstart))
    {
      int x=0;
      if ((cloudstart/60)>=10) x=11; else x=17;
      ReefAngel.LCD.DrawText(0,255,x,120,(cloudstart/60));
      if ((cloudstart%60)>=10) x=29; else x=35;
      ReefAngel.LCD.DrawText(0,255,x,120,(cloudstart%60));
    }
    ReefAngel.LCD.DrawText(0,255,90,120,cloudduration);
    if (lightningchance) 
    {
      int x=0;
      if (((cloudstart+(cloudduration/2))/60)>=10) x=51; else x=57;
      ReefAngel.LCD.DrawText(0,255,x,120,((cloudstart+(cloudduration/2))/60));
      if (((cloudstart+(cloudduration/2))%60)>=10) x=69; else x=75;
      ReefAngel.LCD.DrawText(0,255,x,120,((cloudstart+(cloudduration/2))%60));
    }
  }   
}

byte ReversePWMSlope(long cstart,long cend,byte PWMStart,byte PWMEnd, byte clength)
{
  long n=elapsedSecsToday(now());
  cstart*=60;
  cend*=60;
  if (n<cstart) return PWMStart;
  if (n>=cstart && n<=(cstart+clength)) return map(n,cstart,cstart+clength,PWMStart,PWMEnd);
  if (n>(cstart+clength) && n<(cend-clength)) return PWMEnd;
  if (n>=(cend-clength) && n<=cend) return map(n,cend-clength,cend,PWMEnd,PWMStart);
  if (n>cend) return PWMStart;
}
With this features file:

Code: Select all

#ifndef __REEFANGEL_FEATURES_H__
#define __REEFANGEL_FEATURES_H__


#define DateTimeSetup
#define VersionMenu
#define DisplayLEDPWM
#define wifi
#define WDT
#define CUSTOM_MENU
#define CUSTOM_MENU_ENTRIES 5
#define PWMEXPANSION
#define CUSTOM_MAIN
#define FONT_8x8
#define NUMBERS_16x16


#endif  // __REEFANGEL_FEATURES_H__
Roberto.
dpitalo
Posts: 39
Joined: Mon Dec 12, 2011 6:45 pm

Re: Things to add to a custom menu

Post by dpitalo »

Roberto,

You, sir, are the man!

I'll be uploading everything as soon as I get home this evening.

Thanks!
dpitalo
Posts: 39
Joined: Mon Dec 12, 2011 6:45 pm

Re: Things to add to a custom menu

Post by dpitalo »

Working great...it's quite cloudy on my reef today. :-)

Only thing I wish could be faster would be the lightning strikes...more of a strobe effect rather than just a couple of flashes.
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Things to add to a custom menu

Post by rimai »

That's a limitation of the driver.
I tried it too... Just doesn't discharge and charge again fast enough in my opinion.
But you can play around with this part:

Code: Select all

        for (int b=0;b<6;b++)
        {
          if (bitRead(Daylight_Channels,b)==1)
          {
            if (random(100)<20) lightningstatus=1; 
            else lightningstatus=0;
            if (lightningstatus) PWMChannel[b]=100; 
            else PWMChannel[b]=0;
            //delay(10);
          }
          else
          {
            PWMChannel[b]=20;
          }
        }
This is where the lightning effect happens.
If you change

Code: Select all

            PWMChannel[b]=20;
To

Code: Select all

            PWMChannel[b]=20;
May improve things...
Or you can come up with a different logic that makes it even faster decisions.
Right now, It has to go through each channel and make a decision on whether to turn it on or off.
If the decision was made for all 6 at the same time, you may get faster response from the controller, but I don't think the driver would follow.
But who knows... I'd love to be wrong :)
Roberto.
Post Reply