Seasonal Temperatures

Do you have a question on how to do something.
Ask in here.
User avatar
Posts: 2745
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
PostPosted: Sat Oct 14, 2017 11:13 am
Reefology wrote:I have one set of lights. I use pwm channels for the same lights because they dim down low but won't shut down completely unless they are plugged into the relay box. I would like to use those ports for something else, is there a way to shut them down with the pwm alone?

Often times if you set the PWM value to 0, it will shut the lights off. My old set of LED's would only dim down to like 20% and then I had to set them to 0 to get them to shut off.

I would suggest testing out setting the pwm value to 0 for the channels to see if that shuts the light off completely. If it does, then your problem is solved and we can just set the value to 0 to shut off the lights completely and you will be able to plug the power supplies into a regular outlet and not one of the RA outlets. If it does not shut off the lights completely, then you will need to toggle the port to shut off the lights like you are currently doing.

Posts: 173
Joined: Fri Dec 26, 2014 6:38 pm
PostPosted: Sat Oct 14, 2017 11:23 am
binder wrote:
I would suggest testing out setting the pwm value to 0 for the channels


I think I've been doing that all along, the portal indicates 0%, but the lights stay very low when plugged into regular outlet.
Image

Posts: 173
Joined: Fri Dec 26, 2014 6:38 pm
PostPosted: Sat Oct 14, 2017 11:25 am
btw, thanks for helping me with this Curt, really appreciate it!
Image
User avatar
Posts: 2745
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
PostPosted: Sat Oct 14, 2017 11:54 am
Ok. With that being said, you will probably need to continue doing the relay toggling. Here's some code for you to test out. I have it toggling the relay port and put a comment in about removing the line if you didn't need to toggle the port. Also, I have the outlets turn on at the specified times in the arrays and the lights start to slope up/down appropriately. The slope values / percentages are based off of the internal memory values BUT could be changed and handled in the code if you wanted to (it would be pretty simple actually).

Just so you know, I just copied the code for the PWM slope function and tweaked it so it could be controlled manually outside of the libraries.

Anyways, here's the code. I know it compiles against the libraries version 1.1.3. I just tested the compile but I have not uploaded it to a controller to test out everything fully. The only thing that I changed was the code for the lights. So, you will want to verify that the times used for the lights are what you want.

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 <PAR.h>
#include <ReefAngel.h>

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

void SeasonalDaylight ()
{
  static int daylightArray[][4] = {
    {13,0,22,0},  // default in case of error in month=0 (May)
    {15,0,22,0},  //January (winter)
    {14,30,22,0}, //February (winter)
    {14,0,22,0},  //March (early spring)
    {13,30,22,0}, //April (spring)
    {13,0,22,0},  //May (spring)
    {12,30,22,0}, //June (early summer)
    {12,0,22,0},  //July (summer)
    {12,30,22,0}, //August (summer)
    {13,0,22,0},  //September (early fall)
    {13,30,22,0}, //October (fall)
    {14,0,22,0},  //November (fall)
    {14,30,22,0}  //December (early winter)
  };

  // Port 2 is power supply for Day lights
  ReefAngel.PWM.SetDaylightRaw(PWMSlopeHighRes(
    daylightArray[month()][0],
    daylightArray[month()][1],
    daylightArray[month()][2],
    daylightArray[month()][3],
    InternalMemory.PWMSlopeStartD_read(),
    InternalMemory.PWMSlopeEndD_read(),
    InternalMemory.PWMSlopeDurationD_read(),
    ReefAngel.PWM.GetDaylightValueRaw()
  ));
  /*
  TODO comment out the next line if the power supply for the lights is not needed
       and the lights are plugged into a power strip. Otherwise, if the lights
       are plugged into the relay, you will need to toggle the port to turn
       the lights off
  */
  ReefAngel.StandardLights(Port2, daylightArray[month()][0], daylightArray[month()][1],
                                  daylightArray[month()][2], daylightArray[month()][3]);
}//end SeasonalDaylight

void SeasonalActiniclight ()
{
  static int actinicArray[][4] = {
    {12,30,22,30},  // default in case of error in month=0 (May)
    {14,30,22,30},  //January (winter)
    {14,0,22,30},   //February (winter)
    {13,30,22,30},  //March (early spring)
    {13,0,22,30},   //April (spring)
    {12,30,22,30},  //May (spring)
    {12,0,22,30},   //June (early summer)
    {11,30,22,30},  //July (summer)
    {12,0,22,30},   //August (summer)
    {12,30,22,30},  //September (early fall)
    {13,0,22,30},   //October (fall)
    {13,30,22,30},  //November (fall)
    {14,0,22,30}    //December (early winter)
  };

  // Port 1 is power supply for Actinic Lights
  ReefAngel.PWM.SetActinicRaw(PWMSlopeHighRes(
    actinicArray[month()][0],
    actinicArray[month()][1],
    actinicArray[month()][2],
    actinicArray[month()][3],
    InternalMemory.PWMSlopeStartA_read(),
    InternalMemory.PWMSlopeEndA_read(),
    InternalMemory.PWMSlopeDurationA_read(),
    ReefAngel.PWM.GetActinicValueRaw()
  ));
  /*
  TODO comment out the next line if the power supply for the lights is not needed
       and the lights are plugged into a power strip. Otherwise, if the lights
       are plugged into the relay, you will need to toggle the port to turn
       the lights off
  */
  ReefAngel.StandardLights(Port1, actinicArray[month()][0], actinicArray[month()][1],
                                  actinicArray[month()][2], actinicArray[month()][3]);
}//end SeasonalActinics

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


void setup()
{
    // This must be the first line
    InternalMemory.LCDID_write(0); //this line was added when i got a replacement RA+ board
    ReefAngel.Init();  //Initialize controller
    ReefAngel.Use2014Screen();  // Let's use 2014 Screen
    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = Port5Bit | Port6Bit;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = Port3Bit | Port4Bit | Port5Bit | Port6Bit;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = Port1Bit | Port2Bit;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = Port1Bit | Port2Bit | Port3Bit | Port5Bit | Port6Bit;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;

    // Feeeding and Water Change mode speed
    ReefAngel.DCPump.FeedingSpeed=0;
    ReefAngel.DCPump.WaterChangeSpeed=0;

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

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


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

void loop()
{
    //ReefAngel.ActinicLights( Port1 );
    //ReefAngel.DayLights( Port2 );
    // Light code
    SeasonalDaylight();
    SeasonalActiniclight();

    ReefAngel.StandardHeater( Port3 );
    ReefAngel.Relay.DelayedOn(Port5 );
    ReefAngel.DosingPumpRepeat1( Port7 );
    ReefAngel.DosingPumpRepeat2( Port8 );
    //ReefAngel.PWM.DaylightPWMSlope();
    //ReefAngel.PWM.ActinicPWMSlope();
    ReefAngel.DCPump.LowATOChannel = Sync; // WP40
    ReefAngel.DCPump.HighATOChannel = AntiSync; // SW-8
    ReefAngel.DCPump.AntiSyncOffset = 125;

    ////// Place your custom code below here

    // Wavemaker

    if ( ((hour() >= 2) && (hour() < 8)) || ((hour() >= 15) && (hour() < 19)) ) // off from 2am-8am & 3pm-7pm
      {
        ReefAngel.Relay.Off(Port6);
      }
        else
      {
        ReefAngel.WavemakerRandom( Port6, 30, 150 ); // random between 30 and 150 seconds
      }


    // DC pumps....................................
    static int rmode;
    static boolean changeMode=true;

    // These are the modes we can cycle through. You can add more and even repeat...
    byte modes[] = { ReefCrest, Lagoon, TidalSwell, ShortPulse, Sine, Else, Gyre, NutrientTransport };

    if (now()%1800==0 || changeMode==true)  // Change every 30 mins (1800seconds) or controller reboot
    {
    rmode=random(100)%sizeof(modes); // Change the mode by picking from our array
    changeMode=false;
    }

    // Set timer when in feeding mode
    static unsigned long feeding;
    if (ReefAngel.DisplayedMenu==FEEDING_MODE) feeding=now();

    // Continue NutrientTranspot Mode for 30 minutes after feeding
    if (now()-feeding<1800)
    {
    ReefAngel.DCPump.UseMemory=false;
    ReefAngel.DCPump.Duration=InternalMemory.DCPumpDuration_read();
    ReefAngel.DCPump.Mode=ReefCrest;
    ReefAngel.DCPump.Speed=75;
    }

    // Night/Quiet mode
      else if (hour()>=2 && hour()<8 ) // 2am to 8am
    {
    ReefAngel.DCPump.UseMemory=false;
    ReefAngel.DCPump.SetMode( Gyre,40,10 );
    }
      else if (hour()>=15 && hour()<19) // 3pm and 7pm
    {
    ReefAngel.DCPump.UseMemory=false;
    ReefAngel.DCPump.SetMode( ShortPulse,40,30 );
    }

    //Storm mode
    else if (hour()>=1 && hour()<2) // 1am and 2am
    {
    ReefAngel.DCPump.UseMemory=false;
    ReefAngel.DCPump.SetMode( Else,70,15 );
    }
      else if (hour()>=11 && hour()<12) // 11am and 12pm
    {
    ReefAngel.DCPump.UseMemory=false;
    ReefAngel.DCPump.SetMode( ReefCrest,80,15 );
    }

    // Custom Mode and nothing else going on
    else if (InternalMemory.DCPumpMode_read()==11)
    {
    ReefAngel.DCPump.UseMemory=false;
    ReefAngel.DCPump.Duration=InternalMemory.DCPumpDuration_read();
    ReefAngel.DCPump.Mode=modes[rmode]; // Put the mode to the random mode :)
    ReefAngel.DCPump.Speed=InternalMemory.DCPumpSpeed_read(); // Set speed from portal
    } else {
    ReefAngel.DCPump.UseMemory=true; // Will reset all values from memory
    }
    ////// Place your custom code above here

    // This should always be the last line
    ReefAngel.Portal( "" );
    ReefAngel.DDNS( "" ); // Your DDNS is
    ReefAngel.ShowInterface();
}


Hopefully everything makes sense to you. If you need to alter any of the times, you should be able to figure it out from the code (arrays). This code also allows for both the Actinic and Daylight channels to be controlled independently. We could simplify things if they always used the same schedule OR if they were always 30 minutes (or whatever time offset) apart.
Let me know if you have any further questions or comments.

Posts: 173
Joined: Fri Dec 26, 2014 6:38 pm
PostPosted: Sat Oct 14, 2017 12:54 pm
that looks great Curt, I'll give it a try.

I do have a questions though:

how does the controller use the default month? and why do we need it?

Code: Select all

{774,778},// default in case of error in month=0 (May)


thanks a bunch!
Image
User avatar
Posts: 2745
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
PostPosted: Sat Oct 14, 2017 5:55 pm
that's added in for 2 reasons: 1) on the off chance the controller gets a 0 returned when it calls the month function, which should never happen since there's not a month 0 but you never know (so it's a sanity check) 2) the month function returns a value between 1 and 12 inclusive. arrays in c/c++ always start with an index of zero. since there's not a zero month, in order for the months to match up with the indices, you would either have to subtract 1 from the month function call (which there is lots of them) or you pad the array (like we did). either option would work, however our option would result in less instructions/operations being called and it's a simple index to the array. it can also yield a little easier to read code as well.

so the default values should never be used but are there just in case. hopefully this explanation makes sense.

Sent from my XT1585 using Tapatalk
Previous

Return to How do I code ...

Who is online

Users browsing this forum: No registered users and 3 guests

cron