Dimmable LED Acclimation for corals

Do you have a question on how to do something.
Ask in here.
User avatar
lnevo
Posts: 5422
Joined: Fri Jul 20, 2012 9:42 am

Re: Dimmable LED Acclimation for corals

Post by lnevo »

Thats the whole range of internal memory variables used by RA. Look for the pwm ones in the middle somewhere...
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

So these are all memory locations 258-275 correct?


#define Mem_B_PWMSlopeStart0 VarsStart+58
#define Mem_B_PWMSlopeEnd0 VarsStart+59
#define Mem_B_PWMSlopeDuration0 VarsStart+60
#define Mem_B_PWMSlopeStart1 VarsStart+61
#define Mem_B_PWMSlopeEnd1 VarsStart+62
#define Mem_B_PWMSlopeDuration1 VarsStart+63
#define Mem_B_PWMSlopeStart2 VarsStart+64
#define Mem_B_PWMSlopeEnd2 VarsStart+65
#define Mem_B_PWMSlopeDuration2 VarsStart+66
#define Mem_B_PWMSlopeStart3 VarsStart+67
#define Mem_B_PWMSlopeEnd3 VarsStart+68
#define Mem_B_PWMSlopeDuration3 VarsStart+69
#define Mem_B_PWMSlopeStart4 VarsStart+70
#define Mem_B_PWMSlopeEnd4 VarsStart+71
#define Mem_B_PWMSlopeDuration4 VarsStart+72
#define Mem_B_PWMSlopeStart5 VarsStart+73
#define Mem_B_PWMSlopeEnd5 VarsStart+74
#define Mem_B_PWMSlopeDuration5 VarsStart+75
Image
User avatar
lnevo
Posts: 5422
Joined: Fri Jul 20, 2012 9:42 am

Re: Dimmable LED Acclimation for corals

Post by lnevo »

Exactly.

So the PWMSlopeStart and PWMSlopeEnd are the ones you want. Now if you wanted you could loop through each channel and modify each. Thats one reason why when I had a % of the End % rather than have a min and max dimming hard coded.

If you said 66% instead of 75-25 then regardless of the settings you could change all your dimming independently and still get a consistent acclimation.
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

True, I guess I just prefer to tell it exactly what I want the beginning Acclimation End% to be. many ways to skin a cat I guess... You have helped me so much already with understanding the code structure that I figured I would just run with my thought process as long as it was ending with the same results and I was doing it right... That way you wouldn't have to do every single step.

Could always create additional bytes for End% for the different channels or your Blue/White/Offwhite etc Channels and have them pull from their respective Expansion channel memory locations with separate formulas.
Image
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

So I've split the formulas up.
1 for Blue Drivers
1 for White Drivers

More could be added to differentiate between Cool White/Off White - Royal Blue/Cool Blue drivers or UV/Green/Red etc...

Code: Select all

//Defining different formulas for different channels

// This part would go in your global declarations.
#define Mem_B_AcclDay                 100 // 30
#define Mem_B_AcclDuration            101 // 30
#define Mem_B_AcclStartingEndPercent  102 // 25

// The rest of this goes inside your loop() or custom function

// Let's make some variables to work with
byte acclDay = InternalMemory.read(Mem_B_AcclDay); // Let's get what's in memory 
byte acclDuration = InternalMemory.read(Mem_B_AcclDuration); //Acclimation Duration
byte acclStartingEndPercent = InternalMemory.read(Mem_B_AcclStartingEndPercent); // Starting End% for Acclimation
byte startPercent = InternalMemory.read(Mem_B_PWMSlopeStart0); // Normal start% 13 //Using Mem_B_PWMSlopeStart0 for all 3 channels
byte endPercentBlue = InternalMemory.read(Mem_B_PWMSlopeEnd1); // Normal Blue end% 65 //Using Mem_B_PWMSlopeEnd1 for both Blue Channels 1,2
byte endPercentWhite = InternalMemory.read(Mem_B_PWMSlopeEnd0); // Normal White end% 75


float acclPercentPerDayBlue = (endPercentBlue-acclStartingEndPercent)/(acclDuration*100); // (65 - 25) / (30 * 100) = 0.013333 = 1.33% increase/day
float acclPercentPerDayWhite = (endPercentWhite-acclStartingEndPercent)/(acclDuration*100); // (75 - 25) / (30 * 100) = 0.016667 = 1.66% incrase/day
// This is how much we're going to alter the dimming
// This number could also be used to adjust the duration
// of the slope... the startPercent, the photoperiod..whatever you want
float acclFactorBlue=acclDay*acclPercentPerDayBlue; // 30 * 0.013333 = .4
float acclFactorWhite=acclDay*acclPercentPerDayWhite; // 30 * 0.016667 = .5
  
// Adjust the endPercent based on the acclFactor
endPercentBlue=endPercentBlue-(acclFactorBlue*100); 
//Here are some samples
// Day 30 = 65 - (0.4 * 100) = 25%
// Day 15 = 65 - (0.199995 * 100) = 45%
// Day 5  = 65 -  (0.066665 * 100)= 58%
endPercentWhite=endPercentWhite-(acclFactorWhite*100);
// Here's what some samples look like
// Day 30 = 75 - (0.5 * 100) = 25%
// Day 15 = 75 - (0.25 * 100) = 50%
// Day 5  = 75 - (0.083 * 100) = 67*

  
ReefAngel.PWM.SetChannel( 0, PWMSlope(13,0,20,30,startPercent,endPercentWhite,40,20) ); 
ReefAngel.PWM.SetChannel( 1, PWMSlope(12,0,21,30,startPercent,endPercentBlue,40,20) ); 
ReefAngel.PWM.SetChannel( 2, PWMSlope(12,0,21,30,startPercent,endPercentBlue,40,20) ); 
  
// At the end of the day, we need to decrement the acclimation counter.
static boolean acclCounterReady=false; // We need a boolean so we only do this once per day
if (now()%SECS_PER_DAY!=0) acclCounterReady=true; // If it's not midnight we'll get the boolean ready
if (now()%SECS_PER_DAY==0 && acclCounterReady && acclDay>0) { // It's midnight, our bool is true and acclDay is more than 0
  acclDay--; // Reduce the counter
  acclCounterReady=false; // Reset the boolean flag
  InternalMemory.write(Mem_B_AcclDay,acclDay); // Update memory
}
Image
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

So out of curiosity I started looking at the values in the memory bank that I am going to pull from out of the globals.h.

Code: Select all

Mem_B_PWMSlopeStart0
Mem_B_PWMSlopeEnd0
Mem_B_PWMSlopeEnd1
By default they are 100... So are these variables that were placed in the memory bank but do not get used unless we call for them?

I was kind of expecting to see my current PWM Channel values there... But then again, I guess that is the difference between using the code and memory option
Image
User avatar
lnevo
Posts: 5422
Joined: Fri Jul 20, 2012 9:42 am

Re: Dimmable LED Acclimation for corals

Post by lnevo »

Default values. The difference between hard coded and memory :)
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

So I uploaded the code, and it seems to be still running the standard LED cycle.

Do we need to Create an IF and else if statement?
Image
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

In my void loop()
I added this

Code: Select all

if ( InternalMemory.read(Mem_B_AcclDay)<=0 );
{
    ReefAngel.PWM.SetChannel( 0, PWMSlope(13,0,20,30,13,55,40,20) ); // Minimum % for Dimming is 11%
    ReefAngel.PWM.SetChannel( 1, PWMSlope(12,0,21,30,13,55,40,20) ); 
    ReefAngel.PWM.SetChannel( 2, PWMSlope(12,0,21,30,13,55,40,20) ); // Start Hour, Start Minute, End Hour, End Minute, Start Percentage, End Percentage, Duration, Default Percentage used for lights on mode
}
and then in the acclimation code I added

Code: Select all

if (acclDay>0)
{
ReefAngel.PWM.SetChannel( 0, PWMSlope(13,0,20,30,startPercent,endPercentWhite,60,20) ); 
ReefAngel.PWM.SetChannel( 1, PWMSlope(12,0,21,30,startPercent,endPercentBlue,90,20) ); 
ReefAngel.PWM.SetChannel( 2, PWMSlope(12,0,21,30,startPercent,endPercentBlue,90,20) ); 
}
Will this work? or should I move the regular code down into the acclimation code and do an If and else if?
Image
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

Either have the code split between void loop and the custom code.

or

have them all together in the custom code like this

Code: Select all

if (acclDay=0)
{
    ReefAngel.PWM.SetChannel( 0, PWMSlope(13,0,20,30,13,55,40,20) ); // Minimum % for Dimming is 11%
    ReefAngel.PWM.SetChannel( 1, PWMSlope(12,0,21,30,13,55,40,20) ); 
    ReefAngel.PWM.SetChannel( 2, PWMSlope(12,0,21,30,13,55,40,20) ); // Start Hour, Start Minute, End Hour, End Minute, Start Percentage, End Percentage, Duration, Default Percentage used for lights on mode
}

else if (acclDay>0)
{
ReefAngel.PWM.SetChannel( 0, PWMSlope(13,0,20,30,startPercent,endPercentWhite,60,20) ); 
ReefAngel.PWM.SetChannel( 1, PWMSlope(12,0,21,30,startPercent,endPercentBlue,90,20) ); 
ReefAngel.PWM.SetChannel( 2, PWMSlope(12,0,21,30,startPercent,endPercentBlue,90,20) ); 
}
My guess would be it is better to keep them all together. What do you think?
Image
User avatar
lnevo
Posts: 5422
Joined: Fri Jul 20, 2012 9:42 am

Re: Dimmable LED Acclimation for corals

Post by lnevo »

No the code works with or without the if because if acclDay is 0 then it should subtract 0 from your normal %.

Either mem is set wrong or you've introduced an error or your old setting is still there. Please post your full code and take out the if.
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

this is my original code where it went to the normal schedule

Code: Select all

#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 <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <Humidity.h>
#include <DCPump.h>
#include <ReefAngel.h>

////// Place global variable code below here

// This part would go in your global declarations.
#define Mem_B_AcclDay  100 // 30
#define Mem_B_AcclDuration  101 // 30
#define Mem_B_AcclStartingEndPercent  102 // 25

////// Place global variable code above here


void setup()
{
    // This must be the first line
    ReefAngel.Init();  //Initialize controller
    ReefAngel.AddStandardMenu();  // Add Standard Menu

    ReefAngel.Use2014Screen();  // Let's use 2014 Screen 
/////    ReefAngel.AddPHExpansion();  // pH Expansion Module
    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = Port3Bit | Port5Bit | Port7Bit;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = Port2Bit | Port3Bit | Port4Bit | Port5Bit | Port8Bit;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = Port2Bit | Port4Bit | Port8Bit;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = Port1Bit;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;
    // Set the Overheat temperature setting
    InternalMemory.OverheatTemp_write( 820 );


    // Ports that are always on
    ReefAngel.Relay.On( Port3 );
    ReefAngel.Relay.On( Port7 );

    ////// Place additional initialization code below here

//Custom Port Labels
ReefAngel.CustomLabels[0]="Heater";  
ReefAngel.CustomLabels[1]="BlueLED";  
ReefAngel.CustomLabels[2]="ReturnPump";  
ReefAngel.CustomLabels[3]="WhiteLED";  
ReefAngel.CustomLabels[4]="KalkATO";  
ReefAngel.CustomLabels[5]="Moonlight";  
ReefAngel.CustomLabels[6]="WP40";  
ReefAngel.CustomLabels[7]="Refugium";  

    ////// Place additional initialization code above here
}

void loop()
{
    ReefAngel.StandardHeater( Port1,784,790 );
    ReefAngel.StandardLights( Port2,12,0,21,30 );
    ReefAngel.StandardLights( Port4,13,0,20,30 );
    ReefAngel.SingleATO( true,Port5,1200,1 );
    ReefAngel.StandardLights( Port8,20,30,13,0 );
/// Using custom code at the bottom   ReefAngel.PWM.SetChannel( 0, PWMSlope(13,0,20,30,13,55,40,20) ); // Minimum % for Dimming is 11%
/// Using custom code at the bottom   ReefAngel.PWM.SetChannel( 1, PWMSlope(12,0,21,30,13,55,40,20) ); 
/// Using custom code at the bottom   ReefAngel.PWM.SetChannel( 2, PWMSlope(12,0,21,30,13,55,40,20) ); // Start Hour, Start Minute, End Hour, End Minute, Start Percentage, End Percentage, Duration, Default Percentage used for lights on mode
    ReefAngel.PWM.SetActinic( ReefCrestMode (0, 0, false));
    ////// Place your custom code below here
    
if ( (hour()>=11) && (now()%SECS_PER_DAY<73800) )                                   // 11am - 8:30pm
{
    ReefAngel.PWM.SetDaylight( ElseMode(60,20,true) );                 // ReefCrest at 55% +/- 20% on sync mode
}
else if ( (now()%SECS_PER_DAY>73800) && (hour()<23) )                             // 8:30pm - 11pm
{
    ReefAngel.PWM.SetDaylight( NutrientTransportMode(0,70,400,true) ); // Nutrient Transport 0%minspeed - 70%maxspeed - 400ms 
}    
else if ( (hour()>=23 || hour()<11) )                                   // 11pm - 11am
{
    ReefAngel.PWM.SetDaylight( ElseMode(30,10, true) );                 // ReefCrest at 35% +/- 15% on sync mode
}


// The rest of this goes inside your loop() or custom function

// Let's make some variables to work with
byte acclDay = InternalMemory.read(Mem_B_AcclDay); // Let's get what's in memory 
byte acclDuration = InternalMemory.read(Mem_B_AcclDuration); //Acclimation Duration 15
byte acclStartingEndPercent = InternalMemory.read(Mem_B_AcclStartingEndPercent); // Starting End% 55 for Acclimation
byte startPercent = InternalMemory.read(Mem_B_PWMSlopeStart0); // Normal start% 15 //Using Mem_B_PWMSlopeStart0 for all 3 channels
byte endPercentBlue = InternalMemory.read(Mem_B_PWMSlopeEnd1); // Normal Blue end% 65 //Using Mem_B_PWMSlopeEnd1 for both Blue Channels 1,2
byte endPercentWhite = InternalMemory.read(Mem_B_PWMSlopeEnd0); // Normal White end% 75


float acclPercentPerDayBlue = (endPercentBlue-acclStartingEndPercent)/(acclDuration*100); // (65 - 25) / (30 * 100) = 0.013333 = 1.33% increase/day
float acclPercentPerDayWhite = (endPercentWhite-acclStartingEndPercent)/(acclDuration*100); // (75 - 25) / (30 * 100) = 0.016667 = 1.66% incrase/day
// This is how much we're going to alter the dimming
// This number could also be used to adjust the duration
// of the slope... the startPercent, the photoperiod..whatever you want
float acclFactorBlue=acclDay*acclPercentPerDayBlue; // 30 * 0.013333 = .4
float acclFactorWhite=acclDay*acclPercentPerDayWhite; // 30 * 0.016667 = .5
  
// Adjust the endPercent based on the acclFactor
endPercentBlue=endPercentBlue-(acclFactorBlue*100); 
//Here are some samples
// Day 30 = 65 - (0.4 * 100) = 25%
// Day 15 = 65 - (0.199995 * 100) = 45%
// Day 5  = 65 -  (0.066665 * 100)= 58%

endPercentWhite=endPercentWhite-(acclFactorWhite*100);
// Here's what some samples look like
// Day 30 = 75 - (0.5 * 100) = 25%
// Day 15 = 75 - (0.25 * 100) = 50%
// Day 5  = 75 - (0.083 * 100) = 67*
  
ReefAngel.PWM.SetChannel( 0, PWMSlope(13,0,20,30,startPercent,endPercentWhite,60,20) ); 
ReefAngel.PWM.SetChannel( 1, PWMSlope(12,0,21,30,startPercent,endPercentBlue,90,20) ); 
ReefAngel.PWM.SetChannel( 2, PWMSlope(12,0,21,30,startPercent,endPercentBlue,90,20) ); 
  
// At the end of the day, we need to decrement the acclimation counter.
static boolean acclCounterReady=false; // We need a boolean so we only do this once per day
if (now()%SECS_PER_DAY!=0) acclCounterReady=true; // If it's not midnight we'll get the boolean ready
if (now()%SECS_PER_DAY==0 && acclCounterReady && acclDay>0) { // It's midnight, our bool is true and acclDay is more than 0
  acclDay--; // Reduce the counter
  acclCounterReady=false; // Reset the boolean flag
  InternalMemory.write(Mem_B_AcclDay,acclDay); // Update memory
}



    ////// Place your custom code above here

    // This should always be the last line
    ReefAngel.Portal("ReEfnWrX","******");
    ReefAngel.ShowInterface();
}

byte ElseMode( byte MidPoint, byte Offset, boolean WaveSync )
{
  // Static's only initialize the first time they are called
  static unsigned long LastChange=millis();        // Set the inital time that the last change occurred
  static int Delay = random(2000,3000);           // Set the initial delay - default 500, 3000
  static int NewSpeed = MidPoint;                  // Set the initial speed
  static int AntiSpeed = MidPoint;                 // Set the initial anti sync speed
  if ((millis()-LastChange) > Delay)               // Check if the delay has elapsed
  {
    Delay=random(2000,15000);                        // If so, come up with a new delay - default - 500, 5000
    int ChangeUp = random(Offset);                 // Amount to go up or down
    if (random(100)<50)                            // 50/50 chance of speed going up or going down
    {
      NewSpeed = MidPoint - ChangeUp;
      AntiSpeed = MidPoint + ChangeUp;
    }
    else
    {
      NewSpeed = MidPoint + ChangeUp;
      AntiSpeed = MidPoint - ChangeUp;
    }
    LastChange=millis();                           // Reset the time of the last change
  }
  if (WaveSync)
  {
    return NewSpeed;
  }
  else
  {
    return AntiSpeed;
  }
  
}
I do not know if I am not seeing something, but the way I read it... There is simply two seperate schedules but nothing to tell the RA which to use... so it's defaulting to the first one?
Last edited by ReEfnWrX on Thu Jan 02, 2014 2:15 pm, edited 3 times in total.
Image
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

Never mind, I get it, I didn't think of taking out the original schedule code lol

I updated my previous post with the current fixed code.
Image
User avatar
Sacohen
Posts: 1833
Joined: Sun Apr 21, 2013 6:25 am
Location: Davie, FL

Re: Dimmable LED Acclimation for corals

Post by Sacohen »

I've been reading along with this, for when I get my LED's.
ReEfnWrX this code, from 2 post up, is the working version?

Code: Select all

#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 <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <Humidity.h>
#include <DCPump.h>
#include <ReefAngel.h>

////// Place global variable code below here

// This part would go in your global declarations.
#define Mem_B_AcclDay  100 // 30
#define Mem_B_AcclDuration  101 // 30
#define Mem_B_AcclStartingEndPercent  102 // 25

////// Place global variable code above here


void setup()
{
    // This must be the first line
    ReefAngel.Init();  //Initialize controller
    ReefAngel.AddStandardMenu();  // Add Standard Menu

    ReefAngel.Use2014Screen();  // Let's use 2014 Screen 
/////    ReefAngel.AddPHExpansion();  // pH Expansion Module
    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = Port3Bit | Port5Bit | Port7Bit;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = Port2Bit | Port3Bit | Port4Bit | Port5Bit | Port8Bit;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = Port2Bit | Port4Bit | Port8Bit;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = Port1Bit;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;
    // Set the Overheat temperature setting
    InternalMemory.OverheatTemp_write( 820 );


    // Ports that are always on
    ReefAngel.Relay.On( Port3 );
    ReefAngel.Relay.On( Port7 );

    ////// Place additional initialization code below here

//Custom Port Labels
ReefAngel.CustomLabels[0]="Heater";  
ReefAngel.CustomLabels[1]="BlueLED";  
ReefAngel.CustomLabels[2]="ReturnPump";  
ReefAngel.CustomLabels[3]="WhiteLED";  
ReefAngel.CustomLabels[4]="KalkATO";  
ReefAngel.CustomLabels[5]="Moonlight";  
ReefAngel.CustomLabels[6]="WP40";  
ReefAngel.CustomLabels[7]="Refugium";  

    ////// Place additional initialization code above here
}

void loop()
{
    ReefAngel.StandardHeater( Port1,784,790 );
    ReefAngel.StandardLights( Port2,12,0,21,30 );
    ReefAngel.StandardLights( Port4,13,0,20,30 );
    ReefAngel.SingleATO( true,Port5,1200,1 );
    ReefAngel.StandardLights( Port8,20,30,13,0 );
/// Using custom code at the bottom   ReefAngel.PWM.SetChannel( 0, PWMSlope(13,0,20,30,13,55,40,20) ); // Minimum % for Dimming is 11%
/// Using custom code at the bottom   ReefAngel.PWM.SetChannel( 1, PWMSlope(12,0,21,30,13,55,40,20) ); 
/// Using custom code at the bottom   ReefAngel.PWM.SetChannel( 2, PWMSlope(12,0,21,30,13,55,40,20) ); // Start Hour, Start Minute, End Hour, End Minute, Start Percentage, End Percentage, Duration, Default Percentage used for lights on mode
    ReefAngel.PWM.SetActinic( ReefCrestMode (0, 0, false));
    ////// Place your custom code below here
    
if ( (hour()>=11) && (now()%SECS_PER_DAY<73800) )                                   // 11am - 8:30pm
{
    ReefAngel.PWM.SetDaylight( ElseMode(60,20,true) );                 // ReefCrest at 55% +/- 20% on sync mode
}
else if ( (now()%SECS_PER_DAY>73800) && (hour()<23) )                             // 8:30pm - 11pm
{
    ReefAngel.PWM.SetDaylight( NutrientTransportMode(0,70,400,true) ); // Nutrient Transport 0%minspeed - 70%maxspeed - 400ms 
}    
else if ( (hour()>=23 || hour()<11) )                                   // 11pm - 11am
{
    ReefAngel.PWM.SetDaylight( ElseMode(30,10, true) );                 // ReefCrest at 35% +/- 15% on sync mode
}


// The rest of this goes inside your loop() or custom function

// Let's make some variables to work with
byte acclDay = InternalMemory.read(Mem_B_AcclDay); // Let's get what's in memory 
byte acclDuration = InternalMemory.read(Mem_B_AcclDuration); //Acclimation Duration 15
byte acclStartingEndPercent = InternalMemory.read(Mem_B_AcclStartingEndPercent); // Starting End% 55 for Acclimation
byte startPercent = InternalMemory.read(Mem_B_PWMSlopeStart0); // Normal start% 15 //Using Mem_B_PWMSlopeStart0 for all 3 channels
byte endPercentBlue = InternalMemory.read(Mem_B_PWMSlopeEnd1); // Normal Blue end% 65 //Using Mem_B_PWMSlopeEnd1 for both Blue Channels 1,2
byte endPercentWhite = InternalMemory.read(Mem_B_PWMSlopeEnd0); // Normal White end% 75


float acclPercentPerDayBlue = (endPercentBlue-acclStartingEndPercent)/(acclDuration*100); // (65 - 25) / (30 * 100) = 0.013333 = 1.33% increase/day
float acclPercentPerDayWhite = (endPercentWhite-acclStartingEndPercent)/(acclDuration*100); // (75 - 25) / (30 * 100) = 0.016667 = 1.66% incrase/day
// This is how much we're going to alter the dimming
// This number could also be used to adjust the duration
// of the slope... the startPercent, the photoperiod..whatever you want
float acclFactorBlue=acclDay*acclPercentPerDayBlue; // 30 * 0.013333 = .4
float acclFactorWhite=acclDay*acclPercentPerDayWhite; // 30 * 0.016667 = .5
  
// Adjust the endPercent based on the acclFactor
endPercentBlue=endPercentBlue-(acclFactorBlue*100); 
//Here are some samples
// Day 30 = 65 - (0.4 * 100) = 25%
// Day 15 = 65 - (0.199995 * 100) = 45%
// Day 5  = 65 -  (0.066665 * 100)= 58%

endPercentWhite=endPercentWhite-(acclFactorWhite*100);
// Here's what some samples look like
// Day 30 = 75 - (0.5 * 100) = 25%
// Day 15 = 75 - (0.25 * 100) = 50%
// Day 5  = 75 - (0.083 * 100) = 67*
  
ReefAngel.PWM.SetChannel( 0, PWMSlope(13,0,20,30,startPercent,endPercentWhite,60,20) ); 
ReefAngel.PWM.SetChannel( 1, PWMSlope(12,0,21,30,startPercent,endPercentBlue,90,20) ); 
ReefAngel.PWM.SetChannel( 2, PWMSlope(12,0,21,30,startPercent,endPercentBlue,90,20) ); 
  
// At the end of the day, we need to decrement the acclimation counter.
static boolean acclCounterReady=false; // We need a boolean so we only do this once per day
if (now()%SECS_PER_DAY!=0) acclCounterReady=true; // If it's not midnight we'll get the boolean ready
if (now()%SECS_PER_DAY==0 && acclCounterReady && acclDay>0) { // It's midnight, our bool is true and acclDay is more than 0
  acclDay--; // Reduce the counter
  acclCounterReady=false; // Reset the boolean flag
  InternalMemory.write(Mem_B_AcclDay,acclDay); // Update memory
}



    ////// Place your custom code above here

    // This should always be the last line
    ReefAngel.Portal("ReEfnWrX","******");
    ReefAngel.ShowInterface();
}

byte ElseMode( byte MidPoint, byte Offset, boolean WaveSync )
{
  // Static's only initialize the first time they are called
  static unsigned long LastChange=millis();        // Set the inital time that the last change occurred
  static int Delay = random(2000,3000);           // Set the initial delay - default 500, 3000
  static int NewSpeed = MidPoint;                  // Set the initial speed
  static int AntiSpeed = MidPoint;                 // Set the initial anti sync speed
  if ((millis()-LastChange) > Delay)               // Check if the delay has elapsed
  {
    Delay=random(2000,15000);                        // If so, come up with a new delay - default - 500, 5000
    int ChangeUp = random(Offset);                 // Amount to go up or down
    if (random(100)<50)                            // 50/50 chance of speed going up or going down
    {
      NewSpeed = MidPoint - ChangeUp;
      AntiSpeed = MidPoint + ChangeUp;
    }
    else
    {
      NewSpeed = MidPoint + ChangeUp;
      AntiSpeed = MidPoint - ChangeUp;
    }
    LastChange=millis();                           // Reset the time of the last change
  }
  if (WaveSync)
  {
    return NewSpeed;
  }
  else
  {
    return AntiSpeed;
  }
  
}
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

No, we have been putting it together for the past few days, I am now testing it.

Seems that it is setting end% at the target%... Trying to figure it out now

When i get it working, I'll post with the separate code sections and where they go in the INO file.
Image
User avatar
Sacohen
Posts: 1833
Joined: Sun Apr 21, 2013 6:25 am
Location: Davie, FL

Re: Dimmable LED Acclimation for corals

Post by Sacohen »

Thanks.

Please post the final code when you get it working.
User avatar
lnevo
Posts: 5422
Joined: Fri Jul 20, 2012 9:42 am

Re: Dimmable LED Acclimation for corals

Post by lnevo »

ReEfnWrX,

It may also help to lean how to use Serial.print(); and Serial.println(); It may interfere with your wifi while doing it, but after you upload the code, you can open Serial Monitor and see what the variables are doing...

Serial.print("My variable % is: ");
Serial.println(endPercent);

Enjoy, that should help you figure out what's going wrong.

Lee
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

Where in the code does it go?
Image
User avatar
lnevo
Posts: 5422
Joined: Fri Jul 20, 2012 9:42 am

Re: Dimmable LED Acclimation for corals

Post by lnevo »

Wherever you want it :) It will print out whatever output through the serial port to help you debug. So you can set a variable and then print it to verify it's getting set to what you expect.
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

Ill have to try to figure out how to do it, I am assuming i would use the serial monitor in the coding tool?
Image
User avatar
lnevo
Posts: 5422
Joined: Fri Jul 20, 2012 9:42 am

Re: Dimmable LED Acclimation for corals

Post by lnevo »

lnevo wrote:It may interfere with your wifi while doing it, but after you upload the code, you can open Serial Monitor and see what the variables are doing...
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

Thanks to the Serial.print I found where the issue was.

Question for you. so I see that acclFactor is being affected by the Controller rounding down formula results that have a decimal... I guess this can be countered by multiplying the decimal by 100 and then dividing that value by 100 in the next formula and +1 so when the formula rounds down we are at the correct full %.

Example
if Percentperday results as a decimal the controller will drop the decimal

2.33*15= 34.95 becomes 2*15 = 30..

and to correct the decimal being dropped

PercentPerday = (75-40)/15)*100=233

acclFactor = (15*(233/100)+1 = 35.95 which the controller will now round down to 35..
Image
User avatar
lnevo
Posts: 5422
Joined: Fri Jul 20, 2012 9:42 am

Re: Dimmable LED Acclimation for corals

Post by lnevo »

Sounds good. You're now an RA professional. Good work :)
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

lol far from it.

What is the difference between a float and a byte?
Image
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

So my previous solution is all fine and dandy if things worked like you thought... lol

apparently

acclPercentPerDay can only be a value between 1-100.....
Image
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Dimmable LED Acclimation for corals

Post by rimai »

Roberto.
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

So if I wanted to use decimals for the formulas to keep them exact, I should assign all the variables as floats and then my final product end% a byte?
Image
ReEfnWrX
Posts: 232
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Dimmable LED Acclimation for corals

Post by ReEfnWrX »

Finally... Code is completed and tested. Everything works. acclDay counter also decays by 1 at midnight.

I will edit my original post for this thread with the final code.
Image
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Dimmable LED Acclimation for corals

Post by rimai »

Awesome!!!
Roberto.
User avatar
lnevo
Posts: 5422
Joined: Fri Jul 20, 2012 9:42 am

Re: Dimmable LED Acclimation for corals

Post by lnevo »

ReEfnWrX wrote:So if I wanted to use decimals for the formulas to keep them exact, I should assign all the variables as floats and then my final product end% a byte?
Usually you dont want to do that because floats take up 4-8 times as much mem as a byte...so if you do try and keep it to the variables that need it...

One thing you can do is use casting if you write (float) in front of an equation then it will keep the result as a float. You can use that as a way to placehold the float in your equation without having to declare another float variable.

I do this in my dosing pump calibration function, but I think i also deal with some rounding. It really doesnt make too much of a difference. :)

Good job though. I'm sure a lot of people will get use out of this. I know I do (although sans dimming..)
Post Reply