Page 1 of 1

Help with old PDE converted to INO

Posted: Wed Jun 04, 2014 1:50 pm
by StuGotz
It's been quite a while since I've attempted to play with my controller, probably over 2 years. I've updated to Arduino 1.0.1, which I assume updated all my libraries. I opened my old sketch and got some errors right off the bat when trying to verify.

BioCube_14_Sketch.cpp: In function 'void DrawCustomMain()':
BioCube_14_Sketch:130: error: 'struct ParamsStruct' has no member named 'Temp1'
BioCube_14_Sketch:160: error: 'struct ParamsStruct' has no member named 'Temp2'
BioCube_14_Sketch:166: error: 'struct ParamsStruct' has no member named 'Temp3'

Here's a copy of my INO, any and all help with these errors and any depreciated code is greatly appreciated!

Code: Select all

// Autogenerated file by RAGen (v1.0.4.92), (10/15/2011 12:40)
// RA_101511_1240.pde
//
// This version designed for v0.8.5 Beta 12 or later

// *********************************************************
// MANY THANKS TO BOTH ROBERTO AND CURT FOR ALL THEIR HELP!*
// *********************************************************

/* The following features are enabled for this PDE File: 
#define DisplayLEDPWM
#define wifi
#define VersionMenu
#define CUSTOM_MAIN
#define NUMBERS_8x16
#define COLORS_PDE
#define CUSTOM_MENU
#define CUSTOM_MENU_ENTRIES 6
#define RFEXPANSION
*/

#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 <RA_Colors.h>
#include <RA_CustomColors.h>
#include <avr/pgmspace.h>
#include <RF.h>

#define Sump                1
#define DosingPump2         2
#define Refugium            3
#define Daylight            4
#define Actinic             5
#define Skimmer             6
#define Heater              7
#define DosingPump1         8

//Cloud & Lightning effect Global Variables
byte ActinicPWMValue=0;
byte DaylightPWMValue=0;
boolean ForceCloud=false;

// Echosmart Global Variable
byte vtechmode;

// Moon Global Variables - Thanks Deckoz2302!
byte DayAge;
byte ThisPhase;
int JulianDate(int,int,int);
double MoonAge(int,int,int);
byte MoonState();

// Create the menu entries
prog_char menu1_label[] PROGMEM = "Feeding";
prog_char menu2_label[] PROGMEM = "Water Change";
prog_char menu3_label[] PROGMEM = "Force Cloud";
prog_char menu4_label[] PROGMEM = "Reboot";
prog_char menu5_label[] PROGMEM = "Overheat Clear";
prog_char menu6_label[] PROGMEM = "PH Calibration";
prog_char menu7_label[] PROGMEM = "Version";

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

// Menu Item actions
void MenuEntry1()
{
ReefAngel.FeedingModeStart();
}
void MenuEntry2()
{
ReefAngel.WaterChangeModeStart();
}
void MenuEntry3()
{
ForceCloud=true;
ReefAngel.DisplayedMenu=RETURN_MAIN_MODE;
}
void MenuEntry4()
{
delay(1000);
}
void MenuEntry5()
{
ReefAngel.OverheatClear();
ReefAngel.DisplayMenuEntry("Clear Overheat");
}
void MenuEntry6()
{
ReefAngel.SetupCalibratePH();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry7()
{
ReefAngel.DisplayVersion();
}

// Custom Main Screen

void DrawCustomMain()
{
  ReefAngel.LCD.DrawText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 0, "                       "); //Top Banner
  ReefAngel.LCD.DrawText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 2, " BioCube 14 Nano Reef  "); //Top Banner
  ReefAngel.LCD.DrawDate(6, 123);
  pingSerial();
  
  // Display Temp Text
  ReefAngel.LCD.DrawText(0,255,12,12,"Temp");
  
  // Display the T1 temp value 10,22
  char text[7];
  ConvertNumToString(text, ReefAngel.Params.Temp1, 10);
  ReefAngel.LCD.Clear(255, 0, 20, 50, 36);
  ReefAngel.LCD.DrawLargeText(COLOR_CORNFLOWERBLUE, 255, 10, 20, text, Num8x16);
  pingSerial();
  
  // Display pH Text
  ReefAngel.LCD.DrawText(0,255,100,12,"pH");
  
  // Display pH Value
  ConvertNumToString(text, ReefAngel.Params.PH, 100);
  ReefAngel.LCD.Clear(255, 90, 20, 98, 36);
  ReefAngel.LCD.DrawLargeText(COLOR_CORNFLOWERBLUE, 255, 90, 20, text, Num8x16);
  pingSerial();
   
  // Display Actinic Percentage Text
  ReefAngel.LCD.DrawText(0,255,8,35,"Actinic %");
  
  // Display the Actinic PWM channel value at 90,40
  ReefAngel.LCD.DrawSingleMonitor(ReefAngel.PWM.GetActinicValue(),COLOR_CORNFLOWERBLUE, 90, 35, 1);
  
  // Display Daylight Percentage Text
  ReefAngel.LCD.DrawText(0,255,8,45,"Daylight %");
    
  // Display the Daylight PWM channel value at 90,50
  ReefAngel.LCD.DrawSingleMonitor(ReefAngel.PWM.GetDaylightValue(),COLOR_CORNFLOWERBLUE, 90, 45, 1);
  
  // Display T2 Temp Text
  ReefAngel.LCD.DrawText(0,255,8,55,"Canopy Temp");
  
  // Display the T2 temperature value at 90,60
  ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp2, COLOR_CORNFLOWERBLUE, 90, 55, 10);
  
  // Display T3 Temp Text
  ReefAngel.LCD.DrawText(0,255,8,65,"Ambient Temp");
  
  // Display the T3 temperature at 90,70
  ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp3, COLOR_CORNFLOWERBLUE, 90, 65, 10);
  
  // Display Seperat0r
  ReefAngel.LCD.DrawText(0,255,5,73,"--------------------------");
  
  ReefAngel.LCD.DrawText(0,255,8,80,"EcoSmart");
  
  // Display EcoSmart Mode Value - Thanks Deckoz2302!
  //ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,90,80,"Storm");
  ReefAngel.LCD.Clear(255, 58, 80, 128, 90);
  if (vtechmode == 0) ReefAngel.LCD.DrawText(COLOR_LIMEGREEN,255,58,80,"Constant");
  else if(vtechmode == 1) ReefAngel.LCD.DrawText(COLOR_GOLD,255,58,80,"Lagoon");
  else if (vtechmode == 2) ReefAngel.LCD.DrawText(COLOR_GOLD,255,58,80,"Reef Crest");
  else if (vtechmode == 3) ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,58,80,"Short Pulse");
  else if (vtechmode == 4) ReefAngel.LCD.DrawText(COLOR_PINK,255,58,80,"Long Pulse");
  else if (vtechmode == 5) ReefAngel.LCD.DrawText(COLOR_MAGENTA,255,58,80,"Nut. Trans");
  else if (vtechmode == 6) ReefAngel.LCD.DrawText(COLOR_MAGENTA,255,58,80,"Tidal Swell");
  else if (vtechmode == 9) ReefAngel.LCD.DrawText(COLOR_WHITE,0,58,80," Night ");
  pingSerial();
  
  // Display Moon Phase & State Text
  ReefAngel.LCD.DrawText(0,255,8,90,"Moon");
  
  // Display Moon Phase & State at 35,90
  DayAge = MoonAge(day(), month(), year());
  MoonState(DayAge);
  char* ThisPhaseLabel[]={
    "New","Waxing Crescent","First Quarter","Waxing Gibbous","Full","Waning Gibbous","Last Quarter","Waning Crescent"                        };
  ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,35,90,ThisPhaseLabel[ThisPhase]);
  
  // Display Outlet Box 
  pingSerial();
  byte TempRelay = ReefAngel.Relay.RelayData;
  TempRelay &= ReefAngel.Relay.RelayMaskOff;
  TempRelay |= ReefAngel.Relay.RelayMaskOn;
  ReefAngel.LCD.DrawOutletBox(13, 99, TempRelay);
}
void DrawCustomGraph()
{
 // ReefAngel.LCD.DrawGraph(5,7);
}

void setup()
{
  ReefAngel.Init();  //Initialize controller
  ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items)); //For Custom Menu
  ReefAngel.FeedingModePorts = B00100001; // Feeding mode: Ports 6 & 1 turn off
  ReefAngel.WaterChangePorts = B00100001; // Water Change mode: Ports 6 & 1 turn off
  ReefAngel.OverheatShutoffPorts = B00011000; // Overheat mode: Ports 4 & 5 turn off
  ReefAngel.LightsOnPorts = B00011000; // Lights On mode: ports 4 & 5 turn on
  ReefAngel.Relay.On(Port1); // Port 1 always on
}

void loop()
{
  ReefAngel.ShowInterface();
  
  // Delay Skimmer port 5 minutes whenever turned on
  // From Curt - THANKS CURT!
  ReefAngel.Relay.DelayedOn(Port6, 5);
  
  //Heater    
  ReefAngel.StandardHeater(Heater,775,780);  // Setup Heater to turn on at 77.5F and off at 78.0F
 
  //Lighting schedule
  ReefAngel.MHLights(Daylight,9,0,17,0,0);  //Daylight schedule 9:00am - 5:00pm with 0min cool down
  ReefAngel.StandardLights(Actinic,7,0,19,0);  //Actinic schedule 7:00am - 7:00pm
  ReefAngel.StandardLights(Refugium,19,0,7,0);  //Refugium schedule 7:00pm - 7:00am
  
  // Dosing pumps (OLD DOSING METHOD OF PUMP ONE ON THE HOUR, THEN PUMP2 5 MIN LATER - to use when tank is more mature
  //From Roberto - THANKS ROBERTO!
   /* if (ReefAngel.DisplayedMenu==255 && minute()==0 && second()<1)  //Alk Doser - Only works if Main screen is showing
      ReefAngel.Relay.On(DosingPump1);  //Turn Alk Doser on
    else
      ReefAngel.Relay.Off(DosingPump1);  //Turn Alk Doser off
    if (ReefAngel.DisplayedMenu==255 && minute()==5 && second()<1)  //CA Doser - Only works if Main screen is showing
      ReefAngel.Relay.On(DosingPump2);  //Turn CA Doser on
    else
      ReefAngel.Relay.Off(DosingPump2);  //Turn CA Doser off 
   */
 
  // Dosing pumps
  // From Roberto - THANKS ROBERTO!
  
  if (ReefAngel.DisplayedMenu==255 && hour()%2==0 && minute()==0 && second()<1) // 1 sec dosing on even hours
    ReefAngel.Relay.On(DosingPump1);  //Turn DosingPump1 Doser on
  else
    ReefAngel.Relay.Off(DosingPump1);  //Turn DosingPump1 Doser off
  if (ReefAngel.DisplayedMenu==255 && hour()%2==1 && minute()==0 && second()<1) // 1 sec dosing on odd hours
    ReefAngel.Relay.On(DosingPump2);  //Turn DosingPump2 Doser on
  else
    ReefAngel.Relay.Off(DosingPump2);  //Turn DosingPump2 Doser off

  // Cloud & Lightning effects - Calculate your regular sunrise/sunset PWM value
  // From Roberto - THANKS ROBERTO!
  // byte PWMSlope(byte startHour, byte startMinute, byte endHour, byte endMinute, byte startPWM, byte endPWM, byte Duration, byte oldValue)
  if (hour()>=19 || hour()<7)
    {
      ReefAngel.PWM.SetActinic(MoonPhase());  //Moon phase schedule between 7:00pm - 7:00am
      ReefAngel.RF.UseMemory=false;
      ReefAngel.RF.SetMode(Night,15,0);
      vtechmode = 9;
    }
  else
    {
      ActinicPWMValue=PWMSlope(7,00,19,0,0,35,60,ActinicPWMValue); //Actinic turn on at 7am, off at 10am, and ramp up 0% to 50% PWM in 60 minutes
      //ActinicPWMValue=PWMSlope(16,00,19,0,0,50,60,ActinicPWMValue); //Actinic turn on at 4pm, off at 7pm, and ramp up 0% to 50% PWM in 60 minutes
      ReefAngel.PWM.SetActinic(ActinicPWMValue);
      ReefAngel.RF.SetMode(Feeding_Stop,0,0); //Temp fix for coming out of Night mode
      ReefAngel.RF.UseMemory=true;
      vtechmode = InternalMemory.RFMode_read();
    }
  DaylightPWMValue=PWMSlope(9,00,17,0,0,75,60,DaylightPWMValue); //Daylight turn on at 9am, off at 5pm, and ramp up 0% to 50% PWM in 60 minutes
  CheckCloud(); 
  ReefAngel.PWM.SetDaylight(DaylightPWMValue);
}

//*********************************************************************************************************************************
// Random Cloud/Thunderstorm effects function
// From Roberto - THANKS ROBERTO!
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 6

  // 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 4:30pm
#define End_Cloud_Before NumMins(16,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 25

  // 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 result 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;
      }
    }
  
  //When custom menu Force cloud is selected
  if (ForceCloud)
  {
    ForceCloud=false;
    cloudchance=1;
    cloudduration=10;
    lightningchance=1;
    cloudstart=NumMins(hour(),minute())+1;
  }
  
  // Now that we have all the parameters for the cloud, let's create the effect
  if (cloudchance)
  {
    //is it time for cloud yet?
    if (NumMins(hour(),minute())>=cloudstart && NumMins(hour(),minute())<(cloudstart+cloudduration))
    {
      DaylightPWMValue=ReversePWMSlope(cloudstart,cloudstart+cloudduration,DaylightPWMValue,0,180);
      if (lightningchance && (NumMins(hour(),minute())==(cloudstart+(cloudduration/2))) && second()<5) 
      {
        if (random(100)<20) lightningstatus=1; 
        else lightningstatus=0;
        if (lightningstatus)
        {
          DaylightPWMValue=100; 
          ActinicPWMValue=100;
        }
        else 
        {
          DaylightPWMValue=0;
          ActinicPWMValue=0;
        }
        delay(1);
      }
    }
    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,113,132,121);
    ReefAngel.LCD.DrawText(0,255,12,113,"C");
    ReefAngel.LCD.DrawText(0,255,18,113,"00:00");
    ReefAngel.LCD.DrawText(0,255,52,113,"L");
    ReefAngel.LCD.DrawText(0,255,58,113,"00:00");
    ReefAngel.LCD.DrawText(0,255,93,113,"DUR");
    if (cloudchance && (NumMins(hour(),minute())<cloudstart))
    {
      int x=0;
      if ((cloudstart/60)>=10) x=18; 
      else x=24;
      ReefAngel.LCD.DrawText(0,255,x,113,(cloudstart/60));
      if ((cloudstart%60)>=10) x=36; 
      else x=42;
      ReefAngel.LCD.DrawText(0,255,x,113,(cloudstart%60));
    }
    ReefAngel.LCD.DrawText(0,255,114,113,cloudduration);
    if (lightningchance) 
    {
      int x=0;
      if (((cloudstart+(cloudduration/2))/60)>=10) x=88; 
      else x=94;
      ReefAngel.LCD.DrawText(0,255,x,113,((cloudstart+(cloudduration/2))/60));
      if (((cloudstart+(cloudduration/2))%60)>=10) x=109; 
      else x=112;
      ReefAngel.LCD.DrawText(0,255,x,113,((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;
  //End Cloud & Lighting 
}

// Moon Calculators - Thanks Deckoz2302!
int JulianDate(int d, int m, int y)
{ 
  int mm, yy;
  int k1, k2, k3;
  int j;

  yy = y - (int)((12 - m) / 10);
  mm = m + 9;
  if (mm >= 12)
  {
    mm = mm - 12;
  }
  k1 = (int)(365.25 * (yy + 4712));
  k2 = (int)(30.6001 * mm + 0.5);
  k3 = (int)((int)((yy / 100) + 49) * 0.75) - 38;
  // 'j' for dates in Julian calendar:
  j = k1 + k2 + d + 59;
  if (j > 2299160)
  {
    // For Gregorian calendar:
    j = j - k3; // 'j' is the Julian date at 12h UT (Universal Time)
  }
  return j;
}

double MoonAge(int d, int m, int y)
{ 
  int j = JulianDate(d, m, y);
  //Calculate the approximate phase of the moon
  int ip = (j + 4.867) / 29.53059;
  ip = ip - abs(ip); 
  //After several trials I've seen to add the following lines, 
  //which gave the result was not bad 
  if(ip < 0.5)
    int ag = ip * 29.53059 + 29.53059 / 2;
  else
    int ag = ip * 29.53059 - 29.53059 / 2;
  // Moon's age in days
  byte ag = abs(ag) + 1;
  return ag;
}

byte MoonState(byte D)
{
  switch(D){
  case 1: 
    0, 29;
    ThisPhase = 0;
  case 2: 
    1, 2, 3, 4, 5, 6;
    ThisPhase = 1;
  case 3: 
    7;
    ThisPhase = 2;
  case 4: 
    8, 9, 10, 11, 12, 13;
    ThisPhase = 3;
  case 5: 
    14;
    ThisPhase = 4;
  case 6: 
    15, 16, 17, 18, 19, 20, 21;
    ThisPhase = 5;
  case 7: 
    22;
    ThisPhase = 6;
  case 8: 
    23, 24, 25, 26, 27, 28;
    ThisPhase = 7;
  default: 
    return 0;
  }
}

Re: Help with old PDE converted to INO

Posted: Wed Jun 04, 2014 2:39 pm
by binder
it has been converted to an array.
ReefAngel.Params.Temp[T1_PROBE];


Sent from my iPad mini

Re: Help with old PDE converted to INO

Posted: Wed Jun 04, 2014 3:17 pm
by StuGotz
Thanks Binder! It verifies fine now using the array syntax.

Re: Help with old PDE converted to INO

Posted: Wed Jun 04, 2014 3:24 pm
by StuGotz
So I remember why I stopped playing around with my controller when arduino v1.x came out. I think I maxed out on memory with the new libraries. After my verify completed successfully it said "Binary sketch size: 40,672 bytes (of a 258,048 byte maximum)" If I remember correctly though, the first gen controllers only had a 32,256 byte maximum. Are there any new libraries I can use to get rid of some of the custom stuff in my INO that are maybe a bit leaner?

Re: Help with old PDE converted to INO

Posted: Wed Jun 04, 2014 3:29 pm
by lnevo
First off make sure your board is set properly under Tools-->Board this way it will tell you of 32,256 instead of 258,048. Your code has a lot of functions for Moon calculation it seems. Thats all in the libraries now. You also dont need the ReversePWMSlope as thats built into the generic PWMSlope function now. You might want to start out with the wizard and generate a new base line code to start with but i see you have quite a bit of custom code written.

You may also want to think of upgrading the board to plus which would give you a spare controller board and plenty of memory to work with.

Re: Help with old PDE converted to INO

Posted: Wed Jun 04, 2014 3:37 pm
by StuGotz
Thanks lnevo! I changed my board type and did another verify/compile and now it says: Binary sketch size: 29,436 bytes (of a 32,256 byte maximum). I'll upload and go from there.

Re: Help with old PDE converted to INO

Posted: Wed Jun 04, 2014 4:13 pm
by StuGotz
Well I'm bummed. It uploaded just fine but now my LCD display says "No Internal Memory Found"

Re: Help with old PDE converted to INO

Posted: Wed Jun 04, 2014 4:17 pm
by StuGotz
Tried adding "InternalMemory.IMCheck_write(0xCF06A31E);" I found in another thread to setup() but didn't work.

Re: Help with old PDE converted to INO

Posted: Wed Jun 04, 2014 4:38 pm
by rimai
Yes, that should work. Try rebooting it.
If it doesn't work, make sure it is before ReefAngel.Init();

Re: Help with old PDE converted to INO

Posted: Wed Jun 04, 2014 4:52 pm
by StuGotz
rimai wrote:Yes, that should work. Try rebooting it.
If it doesn't work, make sure it is before ReefAngel.Init();
ahh, I had it immediately after. I put it before and now it's working again!

Now to play around with all the updated libraries :)

Re: Help with old PDE converted to INO

Posted: Thu Jun 05, 2014 7:42 am
by StuGotz
OK, started with commenting out the old moonphase code. Is there a variable set for the current phase that I can use to populate my custom menu?

I changed my lighting, but now my actinic turns on for a sec, then stays off. Here's where I'm at, any help would be greatly appreciated.

Is there a new cloud/storm library?

Sorry for the mess of comments in the code:(

Code: Select all

// Autogenerated file by RAGen (v1.0.4.92), (10/15/2011 12:40)
// RA_101511_1240.pde
//
// This version designed for v0.8.5 Beta 12 or later

// *********************************************************
// MANY THANKS TO BOTH ROBERTO AND CURT FOR ALL THEIR HELP!*
// *********************************************************

/* The following features are enabled for this PDE File: 
#define DisplayLEDPWM
#define wifi
#define VersionMenu
#define CUSTOM_MAIN
#define NUMBERS_8x16
#define COLORS_PDE
#define CUSTOM_MENU
#define CUSTOM_MENU_ENTRIES 6
#define RFEXPANSION
*/

#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 <RA_Colors.h>
#include <RA_CustomColors.h>
#include <avr/pgmspace.h>
#include <RF.h>


#define Sump                1
#define DosingPump2         2
#define Refugium            3
#define Daylight            4
#define Actinic             5
#define Skimmer             6
#define Heater              7
#define DosingPump1         8

//Cloud & Lightning effect Global Variables
byte ActinicPWMValue=0;
byte DaylightPWMValue=0;
boolean ForceCloud=false;

// Echosmart Global Variable
byte vtechmode;

/*
// Moon Global Variables - Thanks Deckoz2302!
byte DayAge;
byte ThisPhase;
int JulianDate(int,int,int);
double MoonAge(int,int,int);
byte MoonState();
*/

// Create the menu entries
prog_char menu1_label[] PROGMEM = "Feeding";
prog_char menu2_label[] PROGMEM = "Water Change";
prog_char menu3_label[] PROGMEM = "Force Cloud";
prog_char menu4_label[] PROGMEM = "Reboot";
prog_char menu5_label[] PROGMEM = "Overheat Clear";
prog_char menu6_label[] PROGMEM = "PH Calibration";
prog_char menu7_label[] PROGMEM = "Version";

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

// Menu Item actions
void MenuEntry1()
{
ReefAngel.FeedingModeStart();
}
void MenuEntry2()
{
ReefAngel.WaterChangeModeStart();
}
void MenuEntry3()
{
ForceCloud=true;
ReefAngel.DisplayedMenu=RETURN_MAIN_MODE;
}
void MenuEntry4()
{
delay(1000);
}
void MenuEntry5()
{
ReefAngel.OverheatClear();
ReefAngel.DisplayMenuEntry("Clear Overheat");
}
void MenuEntry6()
{
ReefAngel.SetupCalibratePH();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry7()
{
ReefAngel.DisplayVersion();
}

// Custom Main Screen

void DrawCustomMain()
{
  ReefAngel.LCD.DrawText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 0, "                       "); //Top Banner
  ReefAngel.LCD.DrawText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 2, " BioCube 14 Nano Reef  "); //Top Banner
  ReefAngel.LCD.DrawDate(6, 123);
  pingSerial();
  
  // Display Temp Text
  ReefAngel.LCD.DrawText(0,255,12,12,"Temp");
  
  // Display the T1 temp value 10,22
  char text[7];
  ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
  ReefAngel.LCD.Clear(255, 0, 20, 50, 36);
  ReefAngel.LCD.DrawLargeText(COLOR_CORNFLOWERBLUE, 255, 10, 20, text, Num8x16);
  pingSerial();
  
  // Display pH Text
  ReefAngel.LCD.DrawText(0,255,100,12,"pH");
  
  // Display pH Value
  ConvertNumToString(text, ReefAngel.Params.PH, 100);
  ReefAngel.LCD.Clear(255, 90, 20, 98, 36);
  ReefAngel.LCD.DrawLargeText(COLOR_CORNFLOWERBLUE, 255, 90, 20, text, Num8x16);
  pingSerial();
   
  // Display Actinic Percentage Text
  ReefAngel.LCD.DrawText(0,255,8,35,"Actinic %");
  
  // Display the Actinic PWM channel value at 90,40
  ReefAngel.LCD.DrawSingleMonitor(ReefAngel.PWM.GetActinicValue(),COLOR_CORNFLOWERBLUE, 90, 35, 1);
  
  // Display Daylight Percentage Text
  ReefAngel.LCD.DrawText(0,255,8,45,"Daylight %");
    
  // Display the Daylight PWM channel value at 90,50
  ReefAngel.LCD.DrawSingleMonitor(ReefAngel.PWM.GetDaylightValue(),COLOR_CORNFLOWERBLUE, 90, 45, 1);
  
  // Display T2 Temp Text
  ReefAngel.LCD.DrawText(0,255,8,55,"Canopy Temp");
  
  // Display the T2 temperature value at 90,60
  ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T2_PROBE], COLOR_CORNFLOWERBLUE, 90, 55, 10);
  
  // Display T3 Temp Text
  ReefAngel.LCD.DrawText(0,255,8,65,"Ambient Temp");
  
  // Display the T3 temperature at 90,70
  ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T3_PROBE], COLOR_CORNFLOWERBLUE, 90, 65, 10);
  
  // Display Seperat0r
  ReefAngel.LCD.DrawText(0,255,5,73,"--------------------------");
  
  ReefAngel.LCD.DrawText(0,255,8,80,"EcoSmart");
  
  // Display EcoSmart Mode Value - Thanks Deckoz2302!
  //ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,90,80,"Storm");
  ReefAngel.LCD.Clear(255, 58, 80, 128, 90);
  if (vtechmode == 0) ReefAngel.LCD.DrawText(COLOR_LIMEGREEN,255,58,80,"Constant");
  else if(vtechmode == 1) ReefAngel.LCD.DrawText(COLOR_GOLD,255,58,80,"Lagoon");
  else if (vtechmode == 2) ReefAngel.LCD.DrawText(COLOR_GOLD,255,58,80,"Reef Crest");
  else if (vtechmode == 3) ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,58,80,"Short Pulse");
  else if (vtechmode == 4) ReefAngel.LCD.DrawText(COLOR_PINK,255,58,80,"Long Pulse");
  else if (vtechmode == 5) ReefAngel.LCD.DrawText(COLOR_MAGENTA,255,58,80,"Nut. Trans");
  else if (vtechmode == 6) ReefAngel.LCD.DrawText(COLOR_MAGENTA,255,58,80,"Tidal Swell");
  else if (vtechmode == 9) ReefAngel.LCD.DrawText(COLOR_WHITE,0,58,80," Night ");
  pingSerial();
  
  // Display Moon Phase & State Text
  ReefAngel.LCD.DrawText(0,255,8,90,"Moon");
  
  // Display Moon Phase & State at 35,90
 /* DayAge = MoonAge(day(), month(), year());
  MoonState(DayAge);
  char* ThisPhaseLabel[]={
    "New","Waxing Crescent","First Quarter","Waxing Gibbous","Full","Waning Gibbous","Last Quarter","Waning Crescent"                        };*/
  ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,35,90,"Moon phase here");
  
  // Display Outlet Box 
  pingSerial();
  byte TempRelay = ReefAngel.Relay.RelayData;
  TempRelay &= ReefAngel.Relay.RelayMaskOff;
  TempRelay |= ReefAngel.Relay.RelayMaskOn;
  ReefAngel.LCD.DrawOutletBox(13, 99, TempRelay);
}
void DrawCustomGraph()
{
 // ReefAngel.LCD.DrawGraph(5,7);
}

void setup()
{
  InternalMemory.IMCheck_write(0xCF06A31E); //Fix "No Internal Memory Found" LCD Display Error after upload
  ReefAngel.Init();  //Initialize controller
  ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items)); //For Custom Menu
  ReefAngel.FeedingModePorts = B00100001; // Feeding mode: Ports 6 & 1 turn off
  ReefAngel.WaterChangePorts = B00100001; // Water Change mode: Ports 6 & 1 turn off
  ReefAngel.OverheatShutoffPorts = B00011000; // Overheat mode: Ports 4 & 5 turn off
  ReefAngel.LightsOnPorts = B00011000; // Lights On mode: ports 4 & 5 turn on
  ReefAngel.Relay.On(Port1); // Port 1 always on
}

void loop()
{
  ReefAngel.ShowInterface();
  
  // Delay Skimmer port 5 minutes whenever turned on
  // From Curt - THANKS CURT!
  ReefAngel.Relay.DelayedOn(Port6, 5);
  
  //Heater    
  ReefAngel.StandardHeater(Heater,775,780);  // Setup Heater to turn on at 77.5F and off at 78.0F
 
  //Lighting schedule
  ReefAngel.StandardLights(Daylight,9,0,17,0);  //Daylight schedule 9:00am - 5:00pm with 0min cool down
  ReefAngel.StandardLights(Actinic,7,0,19,0);  //Actinic schedule 7:00am - 7:00pm
  ReefAngel.StandardLights(Refugium,19,0,7,0);  //Refugium schedule 7:00pm - 7:00am
  
  // Dosing pumps (OLD DOSING METHOD OF PUMP ONE ON THE HOUR, THEN PUMP2 5 MIN LATER - to use when tank is more mature
  //From Roberto - THANKS ROBERTO!
   /* if (ReefAngel.DisplayedMenu==255 && minute()==0 && second()<1)  //Alk Doser - Only works if Main screen is showing
      ReefAngel.Relay.On(DosingPump1);  //Turn Alk Doser on
    else
      ReefAngel.Relay.Off(DosingPump1);  //Turn Alk Doser off
    if (ReefAngel.DisplayedMenu==255 && minute()==5 && second()<1)  //CA Doser - Only works if Main screen is showing
      ReefAngel.Relay.On(DosingPump2);  //Turn CA Doser on
    else
      ReefAngel.Relay.Off(DosingPump2);  //Turn CA Doser off 
   */
 
  // Dosing pumps
  // From Roberto - THANKS ROBERTO!
  
  if (ReefAngel.DisplayedMenu==255 && hour()%2==0 && minute()==0 && second()<1) // 1 sec dosing on even hours
    ReefAngel.Relay.On(DosingPump1);  //Turn DosingPump1 Doser on
  else
    ReefAngel.Relay.Off(DosingPump1);  //Turn DosingPump1 Doser off
  if (ReefAngel.DisplayedMenu==255 && hour()%2==1 && minute()==0 && second()<1) // 1 sec dosing on odd hours
    ReefAngel.Relay.On(DosingPump2);  //Turn DosingPump2 Doser on
  else
    ReefAngel.Relay.Off(DosingPump2);  //Turn DosingPump2 Doser off

  // Cloud & Lightning effects - Calculate your regular sunrise/sunset PWM value
  // From Roberto - THANKS ROBERTO!
  // byte PWMSlope(byte startHour, byte startMinute, byte endHour, byte endMinute, byte startPWM, byte endPWM, byte Duration, byte oldValue)
  if (hour()>=19 || hour()<7)
    {
      ReefAngel.PWM.SetActinic(MoonPhase());  //Moon phase schedule between 7:00pm - 7:00am
      ReefAngel.RF.UseMemory=false;
      ReefAngel.RF.SetMode(Night,15,0);
      vtechmode = 9;
    }
  else
    {
      ReefAngel.PWM.SetActinic( PWMParabola(7,0,19,0,15,50,0) ); //Actinic turn on at 7am, off at 7pm, and parabola 15% to 50% PWM 
      //ActinicPWMValue=PWMSlope(16,00,19,0,0,50,60,ActinicPWMValue); //Actinic turn on at 4pm, off at 7pm, and ramp up 0% to 50% PWM in 60 minutes
      ReefAngel.PWM.SetActinic(ActinicPWMValue);
      ReefAngel.RF.SetMode(Feeding_Stop,0,0); //Temp fix for coming out of Night mode
      ReefAngel.RF.UseMemory=true;
      vtechmode = InternalMemory.RFMode_read();
    }
  ReefAngel.PWM.SetDaylight( PWMParabola(9,0,17,0,15,50,0) ); //Daylight turn on at 9am, off at 5pm, and parabola 15% to 50% PWM
  CheckCloud(); 
  ReefAngel.PWM.SetDaylight(DaylightPWMValue);
}

//*********************************************************************************************************************************
// Random Cloud/Thunderstorm effects function
// From Roberto - THANKS ROBERTO!
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 6

  // 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 4:30pm
#define End_Cloud_Before NumMins(16,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 25

  // 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 result 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;
      }
    }
  
  //When custom menu Force cloud is selected
  if (ForceCloud)
  {
    ForceCloud=false;
    cloudchance=1;
    cloudduration=10;
    lightningchance=1;
    cloudstart=NumMins(hour(),minute())+1;
  }
  
  // Now that we have all the parameters for the cloud, let's create the effect
  if (cloudchance)
  {
    //is it time for cloud yet?
    if (NumMins(hour(),minute())>=cloudstart && NumMins(hour(),minute())<(cloudstart+cloudduration))
    {
      DaylightPWMValue=ReversePWMSlope(cloudstart,cloudstart+cloudduration,DaylightPWMValue,0,180);
      if (lightningchance && (NumMins(hour(),minute())==(cloudstart+(cloudduration/2))) && second()<5) 
      {
        if (random(100)<20) lightningstatus=1; 
        else lightningstatus=0;
        if (lightningstatus)
        {
          DaylightPWMValue=100; 
          ActinicPWMValue=100;
        }
        else 
        {
          DaylightPWMValue=0;
          ActinicPWMValue=0;
        }
        delay(1);
      }
    }
    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,113,132,121);
    ReefAngel.LCD.DrawText(0,255,12,113,"C");
    ReefAngel.LCD.DrawText(0,255,18,113,"00:00");
    ReefAngel.LCD.DrawText(0,255,52,113,"L");
    ReefAngel.LCD.DrawText(0,255,58,113,"00:00");
    ReefAngel.LCD.DrawText(0,255,93,113,"DUR");
    if (cloudchance && (NumMins(hour(),minute())<cloudstart))
    {
      int x=0;
      if ((cloudstart/60)>=10) x=18; 
      else x=24;
      ReefAngel.LCD.DrawText(0,255,x,113,(cloudstart/60));
      if ((cloudstart%60)>=10) x=36; 
      else x=42;
      ReefAngel.LCD.DrawText(0,255,x,113,(cloudstart%60));
    }
    ReefAngel.LCD.DrawText(0,255,114,113,cloudduration);
    if (lightningchance) 
    {
      int x=0;
      if (((cloudstart+(cloudduration/2))/60)>=10) x=88; 
      else x=94;
      ReefAngel.LCD.DrawText(0,255,x,113,((cloudstart+(cloudduration/2))/60));
      if (((cloudstart+(cloudduration/2))%60)>=10) x=109; 
      else x=112;
      ReefAngel.LCD.DrawText(0,255,x,113,((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;
  //End Cloud & Lighting 
}
/*
// Moon Calculators - Thanks Deckoz2302!
int JulianDate(int d, int m, int y)
{ 
  int mm, yy;
  int k1, k2, k3;
  int j;

  yy = y - (int)((12 - m) / 10);
  mm = m + 9;
  if (mm >= 12)
  {
    mm = mm - 12;
  }
  k1 = (int)(365.25 * (yy + 4712));
  k2 = (int)(30.6001 * mm + 0.5);
  k3 = (int)((int)((yy / 100) + 49) * 0.75) - 38;
  // 'j' for dates in Julian calendar:
  j = k1 + k2 + d + 59;
  if (j > 2299160)
  {
    // For Gregorian calendar:
    j = j - k3; // 'j' is the Julian date at 12h UT (Universal Time)
  }
  return j;
}

double MoonAge(int d, int m, int y)
{ 
  int j = JulianDate(d, m, y);
  //Calculate the approximate phase of the moon
  int ip = (j + 4.867) / 29.53059;
  ip = ip - abs(ip); 
  //After several trials I've seen to add the following lines, 
  //which gave the result was not bad 
  if(ip < 0.5)
    int ag = ip * 29.53059 + 29.53059 / 2;
  else
    int ag = ip * 29.53059 - 29.53059 / 2;
  // Moon's age in days
  byte ag = abs(ag) + 1;
  return ag;
}

byte MoonState(byte D)
{
  switch(D){
  case 1: 
    0, 29;
    ThisPhase = 0;
  case 2: 
    1, 2, 3, 4, 5, 6;
    ThisPhase = 1;
  case 3: 
    7;
    ThisPhase = 2;
  case 4: 
    8, 9, 10, 11, 12, 13;
    ThisPhase = 3;
  case 5: 
    14;
    ThisPhase = 4;
  case 6: 
    15, 16, 17, 18, 19, 20, 21;
    ThisPhase = 5;
  case 7: 
    22;
    ThisPhase = 6;
  case 8: 
    23, 24, 25, 26, 27, 28;
    ThisPhase = 7;
  default: 
    return 0;
     
  }
}*/

Re: Help with old PDE converted to INO

Posted: Thu Jun 05, 2014 8:07 am
by lnevo
MoonPhase() is the function to get the current phase (in 0-100%) and MoonPhaseLabel() to get the name of the current phase.

The cloud lightning library has not really been updated.

Can you narrow down the code for your lights to make it easier to review? :)

Re: Help with old PDE converted to INO

Posted: Thu Jun 05, 2014 9:36 am
by StuGotz
Thanks!

let's see, I think this covers it.

Code: Select all

  

  //Lighting schedule
  ReefAngel.StandardLights(Daylight,9,0,17,0);  //Daylight schedule 9:00am - 5:00pm with 0min cool down
  ReefAngel.StandardLights(Actinic,7,0,19,0);  //Actinic schedule 7:00am - 7:00pm
  ReefAngel.StandardLights(Refugium,19,0,7,0);  //Refugium schedule 7:00pm - 7:00am


  if (hour()>=19 || hour()<7)
    {
      ReefAngel.PWM.SetActinic(MoonPhase());  //Moon phase schedule between 7:00pm - 7:00am
      ReefAngel.RF.UseMemory=false;
      ReefAngel.RF.SetMode(Night,15,0);
      vtechmode = 9;
    }
  else
    {
      ReefAngel.PWM.SetActinic( PWMParabola(7,0,19,0,15,50,0) ); //Actinic turn on at 7am, off at 7pm, and parabola 15% to 50% PWM 
      ReefAngel.PWM.SetActinic(ActinicPWMValue);
      ReefAngel.RF.SetMode(Feeding_Stop,0,0); //Temp fix for coming out of Night mode
      ReefAngel.RF.UseMemory=true;
      vtechmode = InternalMemory.RFMode_read();
    }
  ReefAngel.PWM.SetDaylight( PWMParabola(9,0,17,0,15,50,0) ); //Daylight turn on at 9am, off at 5pm, and parabola 15% to 50% PWM
  CheckCloud(); 
  ReefAngel.PWM.SetDaylight(DaylightPWMValue);
}

Re: Help with old PDE converted to INO

Posted: Thu Jun 05, 2014 12:06 pm
by StuGotz
I uploaded my previous sketch before I made any changes and my lights come on for a second, then go off still. Could there be some internal memory settings that were wiped somehow affecting it? The last time this happened my canopy temp probe wasn't reporting a temp, but it's working fine right now.

Looks like my RF module for ecotech mp10 isn't doing anything either. I think that was based on an initial memory setting.

Re: Help with old PDE converted to INO

Posted: Thu Jun 05, 2014 1:29 pm
by rimai
If think this:

Code: Select all

  ReefAngel.PWM.SetDaylight( PWMParabola(9,0,17,0,15,50,0) ); //Daylight turn on at 9am, off at 5pm, and parabola 15% to 50% PWM
  CheckCloud(); 
  ReefAngel.PWM.SetDaylight(DaylightPWMValue);
Needs to be changed to this:

Code: Select all

  DaylightPWMValue=PWMParabola(9,0,17,0,15,50,0); //Daylight turn on at 9am, off at 5pm, and parabola 15% to 50% PWM
  CheckCloud(); 
  ReefAngel.PWM.SetDaylight(DaylightPWMValue);

Re: Help with old PDE converted to INO

Posted: Thu Jun 05, 2014 4:32 pm
by StuGotz
Now both actinic and daylight turn on for a second, and then completely off. I pushed the daylight to stay on until 7pm to during testing.

The only other thing that has ever affected my lights was my canopy temp, and that's 78.4F. Like I mentioned ealier, my RF Module isn't working anymore either. Could this have something to do with my memory settings?

Code: Select all

// Autogenerated file by RAGen (v1.0.4.92), (10/15/2011 12:40)
// RA_101511_1240.pde
//
// This version designed for v0.8.5 Beta 12 or later

// *********************************************************
// MANY THANKS TO BOTH ROBERTO AND CURT FOR ALL THEIR HELP!*
// *********************************************************

/* The following features are enabled for this PDE File: 
#define DisplayLEDPWM
#define wifi
#define VersionMenu
#define CUSTOM_MAIN
#define NUMBERS_8x16
#define COLORS_PDE
#define CUSTOM_MENU
#define CUSTOM_MENU_ENTRIES 6
#define RFEXPANSION
*/

#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 <RA_Colors.h>
#include <RA_CustomColors.h>
#include <avr/pgmspace.h>
#include <RF.h>


#define Sump                1
#define DosingPump2         2
#define Refugium            3
#define Daylight            4
#define Actinic             5
#define Skimmer             6
#define Heater              7
#define DosingPump1         8

//Cloud & Lightning effect Global Variables
byte ActinicPWMValue=0;
byte DaylightPWMValue=0;
boolean ForceCloud=false;

// Echosmart Global Variable
byte vtechmode;

// Create the menu entries
prog_char menu1_label[] PROGMEM = "Feeding";
prog_char menu2_label[] PROGMEM = "Water Change";
prog_char menu3_label[] PROGMEM = "Force Cloud";
prog_char menu4_label[] PROGMEM = "Reboot";
prog_char menu5_label[] PROGMEM = "Overheat Clear";
prog_char menu6_label[] PROGMEM = "PH Calibration";
prog_char menu7_label[] PROGMEM = "Version";

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

// Menu Item actions
void MenuEntry1()
{
ReefAngel.FeedingModeStart();
}
void MenuEntry2()
{
ReefAngel.WaterChangeModeStart();
}
void MenuEntry3()
{
ForceCloud=true;
ReefAngel.DisplayedMenu=RETURN_MAIN_MODE;
}
void MenuEntry4()
{
delay(1000);
}
void MenuEntry5()
{
ReefAngel.OverheatClear();
ReefAngel.DisplayMenuEntry("Clear Overheat");
}
void MenuEntry6()
{
ReefAngel.SetupCalibratePH();
ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry7()
{
ReefAngel.DisplayVersion();
}

// Custom Main Screen

void DrawCustomMain()
{
  ReefAngel.LCD.DrawText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 0, "                       "); //Top Banner
  ReefAngel.LCD.DrawText(COLOR_WHITE, COLOR_CORNFLOWERBLUE, 0, 2, " BioCube 14 Nano Reef  "); //Top Banner
  ReefAngel.LCD.DrawDate(6, 123);
  pingSerial();
  
  // Display Temp Text
  ReefAngel.LCD.DrawText(0,255,12,12,"Temp");
  
  // Display the T1 temp value 10,22
  char text[7];
  ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
  ReefAngel.LCD.Clear(255, 0, 20, 50, 36);
  ReefAngel.LCD.DrawLargeText(COLOR_CORNFLOWERBLUE, 255, 10, 20, text, Num8x16);
  pingSerial();
  
  // Display pH Text
  ReefAngel.LCD.DrawText(0,255,100,12,"pH");
  
  // Display pH Value
  ConvertNumToString(text, ReefAngel.Params.PH, 100);
  ReefAngel.LCD.Clear(255, 90, 20, 98, 36);
  ReefAngel.LCD.DrawLargeText(COLOR_CORNFLOWERBLUE, 255, 90, 20, text, Num8x16);
  pingSerial();
   
  // Display Actinic Percentage Text
  ReefAngel.LCD.DrawText(0,255,8,35,"Actinic %");
  
  // Display the Actinic PWM channel value at 90,40
  ReefAngel.LCD.DrawSingleMonitor(ReefAngel.PWM.GetActinicValue(),COLOR_CORNFLOWERBLUE, 90, 35, 1);
  
  // Display Daylight Percentage Text
  ReefAngel.LCD.DrawText(0,255,8,45,"Daylight %");
    
  // Display the Daylight PWM channel value at 90,50
  ReefAngel.LCD.DrawSingleMonitor(ReefAngel.PWM.GetDaylightValue(),COLOR_CORNFLOWERBLUE, 90, 45, 1);
  
  // Display T2 Temp Text
  ReefAngel.LCD.DrawText(0,255,8,55,"Canopy Temp");
  
  // Display the T2 temperature value at 90,60
  ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T2_PROBE], COLOR_CORNFLOWERBLUE, 90, 55, 10);
  
  // Display T3 Temp Text
  ReefAngel.LCD.DrawText(0,255,8,65,"Ambient Temp");
  
  // Display the T3 temperature at 90,70
  ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp[T3_PROBE], COLOR_CORNFLOWERBLUE, 90, 65, 10);
  
  // Display Seperat0r
  ReefAngel.LCD.DrawText(0,255,5,73,"--------------------------");
  
  ReefAngel.LCD.DrawText(0,255,8,80,"EcoSmart");
  
  // Display EcoSmart Mode Value - Thanks Deckoz2302!
  //ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,90,80,"Storm");
  ReefAngel.LCD.Clear(255, 58, 80, 128, 90);
  if (vtechmode == 0) ReefAngel.LCD.DrawText(COLOR_LIMEGREEN,255,58,80,"Constant");
  else if(vtechmode == 1) ReefAngel.LCD.DrawText(COLOR_GOLD,255,58,80,"Lagoon");
  else if (vtechmode == 2) ReefAngel.LCD.DrawText(COLOR_GOLD,255,58,80,"Reef Crest");
  else if (vtechmode == 3) ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,58,80,"Short Pulse");
  else if (vtechmode == 4) ReefAngel.LCD.DrawText(COLOR_PINK,255,58,80,"Long Pulse");
  else if (vtechmode == 5) ReefAngel.LCD.DrawText(COLOR_MAGENTA,255,58,80,"Nut. Trans");
  else if (vtechmode == 6) ReefAngel.LCD.DrawText(COLOR_MAGENTA,255,58,80,"Tidal Swell");
  else if (vtechmode == 9) ReefAngel.LCD.DrawText(COLOR_WHITE,0,58,80," Night ");
  pingSerial();
  
  // Display Moon Phase & State Text
  ReefAngel.LCD.DrawText(0,255,8,90,"Moon");
  
  // Display Moon Phase & State at 35,90
  ReefAngel.LCD.DrawText(COLOR_CORNFLOWERBLUE,255,35,90,MoonPhaseLabel());
  
  // Display Outlet Box 
  pingSerial();
  byte TempRelay = ReefAngel.Relay.RelayData;
  TempRelay &= ReefAngel.Relay.RelayMaskOff;
  TempRelay |= ReefAngel.Relay.RelayMaskOn;
  ReefAngel.LCD.DrawOutletBox(13, 99, TempRelay);
}
void DrawCustomGraph()
{
 // ReefAngel.LCD.DrawGraph(5,7);
}

void setup()
{
  InternalMemory.IMCheck_write(0xCF06A31E); //Fix "No Internal Memory Found" LCD Display Error after upload
  ReefAngel.Init();  //Initialize controller
  ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items)); //For Custom Menu
  ReefAngel.FeedingModePorts = B00100001; // Feeding mode: Ports 6 & 1 turn off
  ReefAngel.WaterChangePorts = B00100001; // Water Change mode: Ports 6 & 1 turn off
  ReefAngel.OverheatShutoffPorts = B00011000; // Overheat mode: Ports 4 & 5 turn off
  ReefAngel.LightsOnPorts = B00011000; // Lights On mode: ports 4 & 5 turn on
  ReefAngel.Relay.On(Port1); // Port 1 always on
}

void loop()
{
  ReefAngel.ShowInterface();
  
  // Delay Skimmer port 5 minutes whenever turned on
  // From Curt - THANKS CURT!
  ReefAngel.Relay.DelayedOn(Port6, 5);
  
  //Heater    
  ReefAngel.StandardHeater(Heater,775,780);  // Setup Heater to turn on at 77.5F and off at 78.0F
 
  //Lighting schedule
  ReefAngel.MHLights(Daylight,9,0,19,0,0);  //Daylight schedule 9:00am - 5:00pm with 0min cool down
  ReefAngel.StandardLights(Actinic,7,0,19,0);  //Actinic schedule 7:00am - 7:00pm
  ReefAngel.StandardLights(Refugium,19,0,7,0);  //Refugium schedule 7:00pm - 7:00am
  
  // Dosing pumps (OLD DOSING METHOD OF PUMP ONE ON THE HOUR, THEN PUMP2 5 MIN LATER - to use when tank is more mature
  //From Roberto - THANKS ROBERTO!
   /* if (ReefAngel.DisplayedMenu==255 && minute()==0 && second()<1)  //Alk Doser - Only works if Main screen is showing
      ReefAngel.Relay.On(DosingPump1);  //Turn Alk Doser on
    else
      ReefAngel.Relay.Off(DosingPump1);  //Turn Alk Doser off
    if (ReefAngel.DisplayedMenu==255 && minute()==5 && second()<1)  //CA Doser - Only works if Main screen is showing
      ReefAngel.Relay.On(DosingPump2);  //Turn CA Doser on
    else
      ReefAngel.Relay.Off(DosingPump2);  //Turn CA Doser off 
   */
 
  // Dosing pumps
  // From Roberto - THANKS ROBERTO!
  
  if (ReefAngel.DisplayedMenu==255 && hour()%2==0 && minute()==0 && second()<1) // 1 sec dosing on even hours
    ReefAngel.Relay.On(DosingPump1);  //Turn DosingPump1 Doser on
  else
    ReefAngel.Relay.Off(DosingPump1);  //Turn DosingPump1 Doser off
  if (ReefAngel.DisplayedMenu==255 && hour()%2==1 && minute()==0 && second()<1) // 1 sec dosing on odd hours
    ReefAngel.Relay.On(DosingPump2);  //Turn DosingPump2 Doser on
  else
    ReefAngel.Relay.Off(DosingPump2);  //Turn DosingPump2 Doser off

  // Cloud & Lightning effects - Calculate your regular sunrise/sunset PWM value
  // From Roberto - THANKS ROBERTO!
  // byte PWMSlope(byte startHour, byte startMinute, byte endHour, byte endMinute, byte startPWM, byte endPWM, byte Duration, byte oldValue)
  if (hour()>=19 || hour()<7)
    {
      ReefAngel.PWM.SetActinic(MoonPhase());  //Moon phase schedule between 7:00pm - 7:00am
      ReefAngel.RF.UseMemory=false;
      ReefAngel.RF.SetMode(Night,15,0);
      vtechmode = 9;
    }
  else
    {
      ActinicPWMValue=PWMParabola(9,0,19,0,15,50,0);  //Actinic turn on at 7am, off at 7pm, and parabola 15% to 50% PWM 
      ReefAngel.PWM.SetActinic(ActinicPWMValue);
      ReefAngel.RF.SetMode(Feeding_Stop,0,0); //Temp fix for coming out of Night mode
      ReefAngel.RF.UseMemory=true;
      vtechmode = InternalMemory.RFMode_read();
    }
  DaylightPWMValue=PWMParabola(9,0,19,0,15,50,0); //Daylight turn on at 9am, off at 5pm, and parabola 15% to 50% PWM
  CheckCloud(); 
  ReefAngel.PWM.SetDaylight(DaylightPWMValue);
}

//*********************************************************************************************************************************
// Random Cloud/Thunderstorm effects function
// From Roberto - THANKS ROBERTO!
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 6

  // 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 4:30pm
#define End_Cloud_Before NumMins(16,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 25

  // 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 result 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;
      }
    }
  
  //When custom menu Force cloud is selected
  if (ForceCloud)
  {
    ForceCloud=false;
    cloudchance=1;
    cloudduration=10;
    lightningchance=1;
    cloudstart=NumMins(hour(),minute())+1;
  }
  
  // Now that we have all the parameters for the cloud, let's create the effect
  if (cloudchance)
  {
    //is it time for cloud yet?
    if (NumMins(hour(),minute())>=cloudstart && NumMins(hour(),minute())<(cloudstart+cloudduration))
    {
      DaylightPWMValue=ReversePWMSlope(cloudstart,cloudstart+cloudduration,DaylightPWMValue,0,180);
      if (lightningchance && (NumMins(hour(),minute())==(cloudstart+(cloudduration/2))) && second()<5) 
      {
        if (random(100)<20) lightningstatus=1; 
        else lightningstatus=0;
        if (lightningstatus)
        {
          DaylightPWMValue=100; 
          ActinicPWMValue=100;
        }
        else 
        {
          DaylightPWMValue=0;
          ActinicPWMValue=0;
        }
        delay(1);
      }
    }
    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,113,132,121);
    ReefAngel.LCD.DrawText(0,255,12,113,"C");
    ReefAngel.LCD.DrawText(0,255,18,113,"00:00");
    ReefAngel.LCD.DrawText(0,255,52,113,"L");
    ReefAngel.LCD.DrawText(0,255,58,113,"00:00");
    ReefAngel.LCD.DrawText(0,255,93,113,"DUR");
    if (cloudchance && (NumMins(hour(),minute())<cloudstart))
    {
      int x=0;
      if ((cloudstart/60)>=10) x=18; 
      else x=24;
      ReefAngel.LCD.DrawText(0,255,x,113,(cloudstart/60));
      if ((cloudstart%60)>=10) x=36; 
      else x=42;
      ReefAngel.LCD.DrawText(0,255,x,113,(cloudstart%60));
    }
    ReefAngel.LCD.DrawText(0,255,114,113,cloudduration);
    if (lightningchance) 
    {
      int x=0;
      if (((cloudstart+(cloudduration/2))/60)>=10) x=88; 
      else x=94;
      ReefAngel.LCD.DrawText(0,255,x,113,((cloudstart+(cloudduration/2))/60));
      if (((cloudstart+(cloudduration/2))%60)>=10) x=109; 
      else x=112;
      ReefAngel.LCD.DrawText(0,255,x,113,((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;
  //End Cloud & Lighting 
}



Re: Help with old PDE converted to INO

Posted: Thu Jun 05, 2014 4:52 pm
by StuGotz
I tried running "Overheat Clear" on my menu... it did nothing. So I commented out the following code and the lights stay on now.

Code: Select all

ReefAngel.OverheatShutoffPorts = B00011000; // Overheat mode: Ports 4 & 5 turn off
Any idea why it's tripping an overheat?

Re: Help with old PDE converted to INO

Posted: Thu Jun 05, 2014 4:55 pm
by StuGotz
I uncommented the first line and added the second line and all is well.

Code: Select all

ReefAngel.OverheatShutoffPorts = B00011000; // Overheat mode: Ports 4 & 5 turn off
InternalMemory.OverheatTemp_write( 869 ); // Set the Overheat temperature setting
Any idea why the following selection on my menu didn't clear the overheat?

Code: Select all

void MenuEntry5()
{
ReefAngel.OverheatClear();
ReefAngel.DisplayMenuEntry("Clear Overheat");

Re: Help with old PDE converted to INO

Posted: Thu Jun 05, 2014 6:57 pm
by rimai
You probably had the overheat temp set wrong and the minute you clear it, it goes into overheat again in a split of a second.

Re: Help with old PDE converted to INO

Posted: Fri Jun 06, 2014 6:56 am
by StuGotz
rimai wrote:You probably had the overheat temp set wrong and the minute you clear it, it goes into overheat again in a split of a second.
Thanks. I never changed it from before I updated my libraries, so not sure how that happened.

Is there a way to change the default feeding timeout? I'm sorry for all these questions. I tried to find a manual with all the commands, but can't find one.

Re: Help with old PDE converted to INO

Posted: Fri Jun 06, 2014 7:59 am
by lnevo
The overheat temp write looked ok so it's odd that you had an issue, even odder that uncommenting fixed it because the memory write is persistent.

If you go into Globals/Globals.h you can find all the memory locations. And you can use the InternalMemory.write to update that FeedingTimer location. Forget the actual name. If you look at the InternalMemory.h file you can also find the function that will update the field similar to the InternalMemory.OverheatWriteTemp_write() one.

Good luck

Re: Help with old PDE converted to INO

Posted: Fri Jun 06, 2014 8:13 am
by rimai
Here it is:

Code: Select all

InternalMemory.FeedingTimer_write(1500); 

Re: Help with old PDE converted to INO

Posted: Sun Jun 08, 2014 4:21 am
by StuGotz
rimai wrote:Here it is:

Code: Select all

InternalMemory.FeedingTimer_write(1500); 
Thank you. Adding that to my loop fixed my feeding mode timer.

Re: Help with old PDE converted to INO

Posted: Sun Jun 08, 2014 7:55 am
by rimai
No. Don't place it in the loop.
It needs to be in setup or you will damage the memory.

Re: Help with old PDE converted to INO

Posted: Sun Jun 08, 2014 1:58 pm
by StuGotz
I put it in setup initially and it didn't work. Then i tried loop and it worked fine. I put it back into setup and it works this time. Any idea why all my memory settings were wiped when I switched to the latest libraries?

Re: Help with old PDE converted to INO

Posted: Sun Jun 08, 2014 2:50 pm
by binder
StuGotz wrote:I put it in setup initially and it didn't work. Then i tried loop and it worked fine. I put it back into setup and it works this time. Any idea why all my memory settings were wiped when I switched to the latest libraries?
I forget what point in the libraries (probably with the 0.9.0 update or later), we switched to different memory locations to make way for future improvements. so that's probably what got you. the old locations started at 800 and the new locations start at 200.

Re: Help with old PDE converted to INO

Posted: Mon Jun 09, 2014 5:24 am
by StuGotz
binder wrote:I forget what point in the libraries (probably with the 0.9.0 update or later), we switched to different memory locations to make way for future improvements. so that's probably what got you. the old locations started at 800 and the new locations start at 200.
Ahh, thank you.

Re: Help with old PDE converted to INO

Posted: Fri Jun 20, 2014 8:59 am
by StuGotz
I've noticed my moon lights no longer work since switching to the new libraries. I use the ones sold through the RA online store. They're currently sharing the PWM port with my daylight driver. I saw in a recent thread that it's possible to use an ATO port to dim LEDs with the right code. I'm having a hard time finding a thread with information on it. Is someone familiar with how I can drive my moonlight with an ATO port? I'd like to use the built-in function for the Moon Phase.

Re: Help with old PDE converted to INO

Posted: Fri Jun 20, 2014 3:01 pm
by rimai
The ato port doesn't have enough power.
It will be very dim.

Sent from my SM-G900P using Tapatalk