Jebao Issue on Daylight/Actinic Channel
Jebao Issue on Daylight/Actinic Channel
So my Jebao is hooked up to my Daylight channel. Every time I force my Light Relay Ports on through Android App, the RA automatically pulls the default Value for Daylight/Actinic. This in turn affects my Jebao which I have running random custom modes through out the day/night.
Is there a way for me to get the RA to not change the Daylight/Actinic channel dimming % when I turn on the Relay ports associated with my RA?
I guess the easiest solution would be to rewire my Jebao to my dimming expansion....
Is there a way for me to get the RA to not change the Daylight/Actinic channel dimming % when I turn on the Relay ports associated with my RA?
I guess the easiest solution would be to rewire my Jebao to my dimming expansion....
Re: Jebao Issue on Daylight/Actinic Channel
I actually created a variable to disable dimming overide, but declared it wrong within the libraries
So, you have no way to change it.
I created a bug report:
https://github.com/reefangel/Libraries/issues/137
So, you have no way to change it.
I created a bug report:
https://github.com/reefangel/Libraries/issues/137
Roberto.
Re: Jebao Issue on Daylight/Actinic Channel
Is it something simple to change in the library, so I can manual do it until you push out a new version of libraries?
Re: Jebao Issue on Daylight/Actinic Channel
Actually on a second look and quick test, the variable is referenced as extern inside Globals.h
And the PWM class takes care of assigning values to it, but it bases the assignment on whether you use PWMSlope or PWMParabola in your code. If you do, it just assumes you are using the channels for lights.
What I'm thinking is that you have one channel for light and another for Jebao, correct?
If so, your solution is the easiest indeed.
The libraries will override both channels or none.
And the PWM class takes care of assigning values to it, but it bases the assignment on whether you use PWMSlope or PWMParabola in your code. If you do, it just assumes you are using the channels for lights.
What I'm thinking is that you have one channel for light and another for Jebao, correct?
If so, your solution is the easiest indeed.
The libraries will override both channels or none.
Roberto.
Re: Jebao Issue on Daylight/Actinic Channel
I use Daylight for Jebao, Actinic is not used. I use dimming expansion channels 0,1,2 for my LED's.
I chose to keep my LED drivers plugged into the relay so I could have the option to force my lights on at any time of the day
I chose to keep my LED drivers plugged into the relay so I could have the option to force my lights on at any time of the day
Re: Jebao Issue on Daylight/Actinic Channel
Can you post your code?
Maybe if we change the order of things, we can make this work.
Maybe if we change the order of things, we can make this work.
Roberto.
Re: Jebao Issue on Daylight/Actinic Channel
Excuse my bootleg Random Wave mode code... As I could not get the other Random wave mode code to use Else mode I put something together really quickly.
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
////// Memory Locations used by all formulas
#define Mem_B_AcclDay 100 // Acclimation Day
#define Mem_B_AcclDuration 101 // Days in Accl Cycle
#define Mem_B_SlopeStart 102 // Slopestart for White and Blue channels
/////// Memory Locations used by Blue Formula
#define Mem_B_AcclStartEndBlue 105 // Acclimation starting Slope end%
#define Mem_B_SlopeEndBlue 106 // slope End%
////// Memory Locations used by White Formula
#define Mem_B_AcclStartEndWhite 110 // Acclimation starting Slope end%
#define Mem_B_SlopeEndWhite 111 // Slope End%
////// 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 = Port5Bit;
// 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]="CarbPhos";
ReefAngel.CustomLabels[6]="WP40";
ReefAngel.CustomLabels[7]="Refugium";
////// Place additional initialization code above here
}
void loop()
{
int heaterOn=InternalMemory.read_int(Mem_I_HeaterTempOn);
int heaterOff=InternalMemory.read_int(Mem_I_HeaterTempOff);
ReefAngel.StandardHeater( Port1,heaterOn,heaterOff );
ReefAngel.StandardLights( Port2,12,0,22,0 );
ReefAngel.StandardLights( Port4,13,0,21,0 );
ReefAngel.SingleATO( true,Port5,1200,1 );
ReefAngel.StandardLights( Port8,20,30,13,0 );
////// Place your custom code below here
DCPumpRandMode();
MediaFilter();
LEDschedule();
////// Place your custom code above here
// This should always be the last line
ReefAngel.Portal("ReEfnWrX","******");
ReefAngel.ShowInterface();
}
void DCPumpRandMode() {
static unsigned long feeding;
// Set timer when in feeding mode
if (now()%SECS_PER_DAY<36000 || now()%SECS_PER_DAY>=79200) { // 10pm -> 10am
ReefAngel.PWM.SetDaylight( ElseMode(35,0,true) ); // Night mode (go to 30%)
}
else if (now()%SECS_PER_DAY>=36000 && now()%SECS_PER_DAY<79200) {
static byte randMode=2;
if (now()%SECS_PER_DAY==36001 || now()%SECS_PER_DAY==43200 || now()%SECS_PER_DAY==50400 || now()%SECS_PER_DAY==57600 || now()%SECS_PER_DAY==64800 || now()%SECS_PER_DAY==72000) randMode=random(1,8);
if (randMode==1) ReefAngel.PWM.SetDaylight( SineMode(40,75,85,true) );
if (randMode==2) ReefAngel.PWM.SetDaylight( ElseMode(60,20,true) );
if (randMode==3) ReefAngel.PWM.SetDaylight( SineMode(30,70,180,true) );
if (randMode==4) ReefAngel.PWM.SetDaylight( ElseMode(50,15,true) );
if (randMode==5) ReefAngel.PWM.SetDaylight( ReefCrestMode(55,20,true) );
if (randMode==6) ReefAngel.PWM.SetDaylight( LongPulseMode(25,65,60,true) );
if (randMode==7) ReefAngel.PWM.SetDaylight( LongPulseMode(40,40,900,true) );
}
if (ReefAngel.DisplayedMenu==FEEDING_MODE) {
feeding=now();
ReefAngel.PWM.SetDaylight( LongPulseMode(0,21,60,true) );
}
else if (now()-feeding>0 && now()-feeding<=9000) {
// Continue NTM for the 2.5 hours
ReefAngel.PWM.SetDaylight( NutrientTransportMode(0,70,400,true) );
}
}
void MediaFilter() {
if ( (now()%SECS_PER_DAY>0) && (now()%SECS_PER_DAY<=7200) ) {
ReefAngel.Relay.On( Port6 );
}
else if ( (now()%SECS_PER_DAY>=7201) ) {
ReefAngel.Relay.Off( Port6 );
}
}
void LEDschedule() {
////////// LED Dimming Acclimation Cycle and your standard LED schedule
////////// Variables used for all channels
byte acclDay = InternalMemory.read(Mem_B_AcclDay); // What day in the acclimation cycle it is
byte acclDuration = InternalMemory.read(Mem_B_AcclDuration); // Acclimation Duration in days
byte startPercent = InternalMemory.read(Mem_B_SlopeStart); // Normal start% being used by all 3 channels
////////// Blue Channel Variables
byte acclStartEndBlue = InternalMemory.read(Mem_B_AcclStartEndBlue); // Starting End% for Acclimation cycle
float acclendPercentBlue = InternalMemory.read(Mem_B_SlopeEndBlue); // Your target Blue end% once acclimation is complete
////////// Blue Channel Formula
float acclPercentPerDayBlue = (acclendPercentBlue - acclStartEndBlue) / acclDuration; // How much your Blue end% rises per acclimation day
float acclFactorBlue = acclDay * acclPercentPerDayBlue; // endPercentBlue will be offset by this much. If acclDay = 0 then this value will be 0
byte endPercentBlue = acclendPercentBlue - acclFactorBlue; // Your final Blue end% for the day
////////// White Channel Variables
byte acclStartEndWhite = InternalMemory.read(Mem_B_AcclStartEndWhite); // Starting End% for Acclimation cycle
float acclEndPercentWhite = InternalMemory.read(Mem_B_SlopeEndWhite); // Your target White end% once acclimation is complete
////////// White Channel Formula
float acclPercentPerDayWhite= (acclEndPercentWhite - acclStartEndWhite) / acclDuration; // How much your White end% rises per acclimation day
float acclFactorWhite = acclDay * acclPercentPerDayWhite; // endPercentWhite will be offset by this much. If acclDay = 0 then this value will be 0
byte endPercentWhite = acclEndPercentWhite - acclFactorWhite;
////////// Your standard PWM Dimming code using the variables above to determine start% and end%
ReefAngel.PWM.SetChannel( 0, PWMSlope(13,0,21,0,startPercent,endPercentWhite,60,25) );
ReefAngel.PWM.SetChannel( 1, PWMSlope(12,0,22,0,startPercent,endPercentBlue,120,25) );
ReefAngel.PWM.SetChannel( 2, PWMSlope(12,0,22,0,startPercent,endPercentBlue,120,25) );
////////// 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
}
}
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,10000); // 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;
}
}
Re: Jebao Issue on Daylight/Actinic Channel
Add this to your code below LEDschedule:
The order things happen within the code matters.
Your LEDschedule function is setting the variable LightsOverride to true. We need a way to set it to false.
The functions that do that are all the waveforms we have available, so we just call one of them, just to assign the LightsOverride to false, but we really don't need to do anything with the return value.
Just make sure that the waveform comes always after any call of PWMSlope or PWMParabola.
Code: Select all
int dummy=ShortPulseMode(0,0,0,true);
Your LEDschedule function is setting the variable LightsOverride to true. We need a way to set it to false.
The functions that do that are all the waveforms we have available, so we just call one of them, just to assign the LightsOverride to false, but we really don't need to do anything with the return value.
Just make sure that the waveform comes always after any call of PWMSlope or PWMParabola.
Roberto.
Re: Jebao Issue on Daylight/Actinic Channel
What if I just swapped the order that the functions are called in my loop? Since my randmode function is called first... if I move that function after the LEDschedule function would that provide the same result?
Re: Jebao Issue on Daylight/Actinic Channel
Your randmode is custom and doesn't use any of our waveforms or it would work too...
Roberto.
Re: Jebao Issue on Daylight/Actinic Channel
You need to call any one of these waveforms after the PWMSlope/PWMParabola:
http://forum.reefangel.com/viewtopic.php?f=7&t=2844
http://forum.reefangel.com/viewtopic.php?f=7&t=2844
Roberto.
Re: Jebao Issue on Daylight/Actinic Channel
BTW, this:
is the same as this:
Code: Select all
int heaterOn=InternalMemory.read_int(Mem_I_HeaterTempOn);
int heaterOff=InternalMemory.read_int(Mem_I_HeaterTempOff);
ReefAngel.StandardHeater( Port1,heaterOn,heaterOff );
Code: Select all
ReefAngel.StandardHeater( Port1 );
Roberto.
Re: Jebao Issue on Daylight/Actinic Channel
Yeah, I tried to switch back to using DCPump class and use the other random wave mode in another thread for DCPump wave modes... However, I could never get it to select Else mode, it would only choose DCPump modes...
Reason I want else mode is I like that I am able to adjust the delay range and the offset which I have not been able to figure out with any of the other modes.. It seems that they are all based off the same wave speed and I feel restricted by not being able to really change all of their parameters.
Reason I want else mode is I like that I am able to adjust the delay range and the offset which I have not been able to figure out with any of the other modes.. It seems that they are all based off the same wave speed and I feel restricted by not being able to really change all of their parameters.
Re: Jebao Issue on Daylight/Actinic Channel
rimai wrote:BTW, this:is the same as this:Code: Select all
int heaterOn=InternalMemory.read_int(Mem_I_HeaterTempOn); int heaterOff=InternalMemory.read_int(Mem_I_HeaterTempOff); ReefAngel.StandardHeater( Port1,heaterOn,heaterOff );
Code: Select all
ReefAngel.StandardHeater( Port1 );
Lol.... thank you. I knew there was a simpler way to do it. I was trying to figure it out by looking in the libraries but couldn't. Still trying to learn the depths of your code...
Re: Jebao Issue on Daylight/Actinic Channel
Which is totally fineReEfnWrX wrote:Yeah, I tried to switch back to using DCPump class and use the other random wave mode in another thread for DCPump wave modes... However, I could never get it to select Else mode, it would only choose DCPump modes...
Reason I want else mode is I like that I am able to adjust the delay range and the offset which I have not been able to figure out with any of the other modes.. It seems that they are all based off the same wave speed and I feel restricted by not being able to really change all of their parameters.
That's the beauty of the controller.... You can pick and choose what you want and if you don't like, just change it and come up with a totally different solution
Roberto.
Re: Jebao Issue on Daylight/Actinic Channel
Yes, but I really like the DCPump screen that I now do not get
As well as the DCPump screen in the portal
As well as the DCPump screen in the portal
Re: Jebao Issue on Daylight/Actinic Channel
My bad....
I totally missed the function DCPumpRandMode you mentioned before.
Yeah, if you switch the order, it would work too, just like you said. Disregard my previous comment, because you are indeed using the SineMode inside your function.
If we change the code to put the screen back, you won't be able to achieve the Longpulse during feeding. The waveform for feeding is constant. Other than that, I think it can be changed.
I totally missed the function DCPumpRandMode you mentioned before.
Yeah, if you switch the order, it would work too, just like you said. Disregard my previous comment, because you are indeed using the SineMode inside your function.
If we change the code to put the screen back, you won't be able to achieve the Longpulse during feeding. The waveform for feeding is constant. Other than that, I think it can be changed.
Roberto.
Re: Jebao Issue on Daylight/Actinic Channel
Maybe something like this:
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
////// Memory Locations used by all formulas
#define Mem_B_AcclDay 100 // Acclimation Day
#define Mem_B_AcclDuration 101 // Days in Accl Cycle
#define Mem_B_SlopeStart 102 // Slopestart for White and Blue channels
/////// Memory Locations used by Blue Formula
#define Mem_B_AcclStartEndBlue 105 // Acclimation starting Slope end%
#define Mem_B_SlopeEndBlue 106 // slope End%
////// Memory Locations used by White Formula
#define Mem_B_AcclStartEndWhite 110 // Acclimation starting Slope end%
#define Mem_B_SlopeEndWhite 111 // Slope End%
////// 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 = Port5Bit;
// 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 );
// Feeeding and Water Change mode speed
ReefAngel.DCPump.FeedingSpeed=0;
ReefAngel.DCPump.WaterChangeSpeed=0;
ReefAngel.DCPump.UseMemory = false;
ReefAngel.DCPump.DaylightChannel = Sync;
ReefAngel.DCPump.ActinicChannel = None;
// 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]="CarbPhos";
ReefAngel.CustomLabels[6]="WP40";
ReefAngel.CustomLabels[7]="Refugium";
////// Place additional initialization code above here
}
void loop()
{
int heaterOn=InternalMemory.read_int(Mem_I_HeaterTempOn);
int heaterOff=InternalMemory.read_int(Mem_I_HeaterTempOff);
ReefAngel.StandardHeater( Port1,heaterOn,heaterOff );
ReefAngel.StandardLights( Port2,12,0,22,0 );
ReefAngel.StandardLights( Port4,13,0,21,0 );
ReefAngel.SingleATO( true,Port5,1200,1 );
ReefAngel.StandardLights( Port8,20,30,13,0 );
////// Place your custom code below here
MediaFilter();
LEDschedule();
DCPumpRandMode();
////// Place your custom code above here
// This should always be the last line
ReefAngel.Portal("ReEfnWrX","******");
ReefAngel.ShowInterface();
}
void DCPumpRandMode() {
static unsigned long feeding;
// Set timer when in feeding mode
if (now()%SECS_PER_DAY<36000 || now()%SECS_PER_DAY>=79200) { // 10pm -> 10am
ReefAngel.PWM.SetDaylight( ElseMode(35,0,true) ); // Night mode (go to 30%)
ReefAngel.DCPump.SetMode( Custom,35,0 );
}
else if (now()%SECS_PER_DAY>=36000 && now()%SECS_PER_DAY<79200) {
static byte randMode=2;
if (now()%SECS_PER_DAY==36001 || now()%SECS_PER_DAY==43200 || now()%SECS_PER_DAY==50400 || now()%SECS_PER_DAY==57600 || now()%SECS_PER_DAY==64800 || now()%SECS_PER_DAY==72000) randMode=random(1,8);
if (randMode==1)
{
ReefAngel.PWM.SetDaylight( SineMode(40,75,85,true) );
ReefAngel.DCPump.SetMode( Custom,75,85 );
}
if (randMode==2)
{
ReefAngel.PWM.SetDaylight( ElseMode(60,20,true) );
ReefAngel.DCPump.SetMode( Custom,60,20 );
}
if (randMode==3)
{
ReefAngel.PWM.SetDaylight( SineMode(30,70,180,true) );
ReefAngel.DCPump.SetMode( Custom,70,180 );
}
if (randMode==4)
{
ReefAngel.PWM.SetDaylight( ElseMode(50,15,true) );
ReefAngel.DCPump.SetMode( Custom,50,15 );
}
if (randMode==5)
{
// ReefAngel.PWM.SetDaylight( ReefCrestMode(55,20,true) );
ReefAngel.DCPump.SetMode( ReefCrest,55,20 );
}
if (randMode==6)
{
// ReefAngel.PWM.SetDaylight( LongPulseMode(25,65,60,true) );
ReefAngel.DCPump.SetMode( LongPulse,65,60 );
}
if (randMode==7)
{
// ReefAngel.PWM.SetDaylight( LongPulseMode(40,40,900,true) );
ReefAngel.DCPump.SetMode( LongPulse,40,900 );
}
}
if (ReefAngel.DisplayedMenu==FEEDING_MODE) {
feeding=now();
// ReefAngel.PWM.SetDaylight( LongPulseMode(0,21,60,true) );
}
else if (now()-feeding>0 && now()-feeding<=9000) {
// Continue NTM for the 2.5 hours
// ReefAngel.PWM.SetDaylight( NutrientTransportMode(0,70,400,true) );
ReefAngel.DCPump.SetMode( NutrientTransport,70,400 );
}
}
void MediaFilter() {
if ( (now()%SECS_PER_DAY>0) && (now()%SECS_PER_DAY<=7200) ) {
ReefAngel.Relay.On( Port6 );
}
else if ( (now()%SECS_PER_DAY>=7201) ) {
ReefAngel.Relay.Off( Port6 );
}
}
void LEDschedule() {
////////// LED Dimming Acclimation Cycle and your standard LED schedule
////////// Variables used for all channels
byte acclDay = InternalMemory.read(Mem_B_AcclDay); // What day in the acclimation cycle it is
byte acclDuration = InternalMemory.read(Mem_B_AcclDuration); // Acclimation Duration in days
byte startPercent = InternalMemory.read(Mem_B_SlopeStart); // Normal start% being used by all 3 channels
////////// Blue Channel Variables
byte acclStartEndBlue = InternalMemory.read(Mem_B_AcclStartEndBlue); // Starting End% for Acclimation cycle
float acclendPercentBlue = InternalMemory.read(Mem_B_SlopeEndBlue); // Your target Blue end% once acclimation is complete
////////// Blue Channel Formula
float acclPercentPerDayBlue = (acclendPercentBlue - acclStartEndBlue) / acclDuration; // How much your Blue end% rises per acclimation day
float acclFactorBlue = acclDay * acclPercentPerDayBlue; // endPercentBlue will be offset by this much. If acclDay = 0 then this value will be 0
byte endPercentBlue = acclendPercentBlue - acclFactorBlue; // Your final Blue end% for the day
////////// White Channel Variables
byte acclStartEndWhite = InternalMemory.read(Mem_B_AcclStartEndWhite); // Starting End% for Acclimation cycle
float acclEndPercentWhite = InternalMemory.read(Mem_B_SlopeEndWhite); // Your target White end% once acclimation is complete
////////// White Channel Formula
float acclPercentPerDayWhite= (acclEndPercentWhite - acclStartEndWhite) / acclDuration; // How much your White end% rises per acclimation day
float acclFactorWhite = acclDay * acclPercentPerDayWhite; // endPercentWhite will be offset by this much. If acclDay = 0 then this value will be 0
byte endPercentWhite = acclEndPercentWhite - acclFactorWhite;
////////// Your standard PWM Dimming code using the variables above to determine start% and end%
ReefAngel.PWM.SetChannel( 0, PWMSlope(13,0,21,0,startPercent,endPercentWhite,60,25) );
ReefAngel.PWM.SetChannel( 1, PWMSlope(12,0,22,0,startPercent,endPercentBlue,120,25) );
ReefAngel.PWM.SetChannel( 2, PWMSlope(12,0,22,0,startPercent,endPercentBlue,120,25) );
////////// 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
}
}
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,10000); // 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;
}
}
Roberto.
Re: Jebao Issue on Daylight/Actinic Channel
I switched the Function order to
And when I turn on the Relay port for the LED's it still overrides the Daylight channel to internal memory.
Maybe this is because the random mode selected was Else mode... and not one of the other's that are defined in the libraries.
Code: Select all
MediaFilter();
LEDschedule();
DCPumpRandMode();
Maybe this is because the random mode selected was Else mode... and not one of the other's that are defined in the libraries.
Re: Jebao Issue on Daylight/Actinic Channel
I know why....
When the time is for ElseMode, the LightsOverride variable is set to true because it is not one of the default wave patterns... So, you still need to call the dummy waveform just to ensure we are always calling it.
When the time is for ElseMode, the LightsOverride variable is set to true because it is not one of the default wave patterns... So, you still need to call the dummy waveform just to ensure we are always calling it.
Roberto.
Re: Jebao Issue on Daylight/Actinic Channel
So I see in the globals.cpp that the wave mode codes have this
Could I just add this into my byte elsemode code? That should end the problem?
Code: Select all
LightsOverride=false;
Last edited by ReEfnWrX on Sat Jan 25, 2014 12:09 pm, edited 1 time in total.