Jebao Issue on Daylight/Actinic Channel

Do you have a question on how to do something.
Ask in here.
Post Reply
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Jebao Issue on Daylight/Actinic Channel

Post by rimai »

You need to call any one of these waveforms after the PWMSlope/PWMParabola:
http://forum.reefangel.com/viewtopic.php?f=7&t=2844
Roberto.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Jebao Issue on Daylight/Actinic Channel

Post by rimai »

BTW, 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 );
is the same as this:

Code: Select all

    ReefAngel.StandardHeater( Port1 );
Roberto.
ReEfnWrX
Posts: 234
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Jebao Issue on Daylight/Actinic Channel

Post by ReEfnWrX »

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.
Image
ReEfnWrX
Posts: 234
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Jebao Issue on Daylight/Actinic Channel

Post by ReEfnWrX »

rimai wrote:BTW, 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 );
is the same as this:

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...
Image
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Jebao Issue on Daylight/Actinic Channel

Post by rimai »

ReEfnWrX 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.
Which is totally fine :)
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 :ugeek:
Roberto.
ReEfnWrX
Posts: 234
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Jebao Issue on Daylight/Actinic Channel

Post by ReEfnWrX »

Yes, but I really like the DCPump screen that I now do not get :(

As well as the DCPump screen in the portal
Image
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Jebao Issue on Daylight/Actinic Channel

Post by rimai »

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.
Roberto.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Jebao Issue on Daylight/Actinic Channel

Post by rimai »

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.
ReEfnWrX
Posts: 234
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Jebao Issue on Daylight/Actinic Channel

Post by ReEfnWrX »

I switched the Function order to

Code: Select all

    MediaFilter();
    LEDschedule();
    DCPumpRandMode();
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.
Image
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Jebao Issue on Daylight/Actinic Channel

Post by rimai »

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.
Roberto.
ReEfnWrX
Posts: 234
Joined: Tue Nov 05, 2013 8:40 am
Location: Houston TX

Re: Jebao Issue on Daylight/Actinic Channel

Post by ReEfnWrX »

So I see in the globals.cpp that the wave mode codes have this

Code: Select all

	LightsOverride=false;
Could I just add this into my byte elsemode code? That should end the problem?
Last edited by ReEfnWrX on Sat Jan 25, 2014 12:09 pm, edited 1 time in total.
Image
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Jebao Issue on Daylight/Actinic Channel

Post by rimai »

That would work too, I think.
Roberto.
Post Reply