Generating PDE w/ RAGen & using Reef Angel Client via USB

Community contributed apps
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Generating PDE w/ RAGen & using Reef Angel Client via US

Post by rimai »

Duh... sometimes I have some moments where I can't see what is in front of me.
My wife tells me on those moments that if it were a snake, I'd have been bitten... lol
I know that the problem is.
When you use the DosingPumpRepeat1, it will affect the timer that you are using for your wavemaker.
So, let just comment those out for now.

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

/* The following features are enabled for this PDE File: 
#define DosingPumpIntervalSetup
#define VersionMenu
#define MetalHalideSetup
#define DirectTempSensor
#define DisplayLEDPWM
#define wifi
#define StandardLightSetup
*/


#include <ReefAngel_Features.h>
#include <ReefAngel_Globals.h>
#include <ReefAngel_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <ReefAngel_EEPROM.h>
#include <ReefAngel_NokiaLCD.h>
#include <ReefAngel_ATO.h>
#include <ReefAngel_Joystick.h>
#include <ReefAngel_LED.h>
#include <ReefAngel_TempSensor.h>
#include <ReefAngel_Relay.h>
#include <ReefAngel_PWM.h>
#include <ReefAngel_Timer.h>
#include <ReefAngel_Memory.h>
#include <ReefAngel.h>

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

//Cloud & Lightning effects
byte ActinicPWMValue=0;
byte DaylightPWMValue=0;
//

void setup()
{
  ReefAngel.Init();  //Initialize controller
  ReefAngel.FeedingModePorts = B10100000; //Ports 6 & 8 turn off
  ReefAngel.WaterChangePorts = B10100000; //Ports 6 & 8 turn off
  ReefAngel.OverheatShutoffPorts = B00000011; //Ports 1 & 2 turn off
  ReefAngel.LightsOnPorts = B00000011; //Ports 1 & 2 turn on

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

  // Random Interval Wavemaker Port between 15 and 35 seconds 
  randomSeed(analogRead(0));
  ReefAngel.Timer[1].SetInterval(random(15,35));
  ReefAngel.Timer[1].Start(); 
  ReefAngel.Relay.On(Port6);
}

void loop()
{
  ReefAngel.ShowInterface();

  // Specific functions
//  ReefAngel.DosingPumpRepeat1(Port4);
//  ReefAngel.DosingPumpRepeat2(Port5);

  // Random Interval Wavemaker Port between 15 and 35 seconds 
  if ( ReefAngel.Timer[1].IsTriggered() )
  {
    ReefAngel.Timer[1].SetInterval(random(15,35));
    ReefAngel.Timer[1].Start();
    ReefAngel.Relay.Toggle(Port6);
  }

  //Heater    
  ReefAngel.StandardHeater(Heater,775,779);  // Setup Heater to turn on at 77.5F and off at 77.9F

  //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

  // Cloud & Lightning effects - Calculate your regular sunrise/sunset PWM value
  // byte PWMSlope(byte startHour, byte startMinute, byte endHour, byte endMinute, byte startPWM, byte endPWM, byte Duration, byte oldValue)
  ActinicPWMValue=PWMSlope(7,00,22,0,0,50,60,ActinicPWMValue); //Actinic turn on at 7am, off at 7pm, and ramp up 0% to 50% PWM in 60 minutes
  DaylightPWMValue=PWMSlope(9,00,19,0,0,50,60,DaylightPWMValue); //Daylight turn on at 9am, off at 5pm, and ramp up 0% to 50% PWM in 60 minutes
  CheckCloud();
  ReefAngel.PWM.SetActinic(ActinicPWMValue);
  ReefAngel.PWM.SetDaylight(DaylightPWMValue);
}

//*********************************************************************************************************************************
// Random Cloud/Thunderstorm effects function
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 5

  // 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 resul
  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;
      }
    }
  // 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,120,132,132);
    ReefAngel.LCD.DrawText(0,255,5,120,"C");
    ReefAngel.LCD.DrawText(0,255,11,120,"00:00");
    ReefAngel.LCD.DrawText(0,255,45,120,"L");
    ReefAngel.LCD.DrawText(0,255,51,120,"00:00");
    if (cloudchance && (NumMins(hour(),minute())<cloudstart))
    {
      int x=0;
      if ((cloudstart/60)>=10) x=11; 
      else x=17;
      ReefAngel.LCD.DrawText(0,255,x,120,(cloudstart/60));
      if ((cloudstart%60)>=10) x=29; 
      else x=35;
      ReefAngel.LCD.DrawText(0,255,x,120,(cloudstart%60));
    }
    ReefAngel.LCD.DrawText(0,255,90,120,cloudduration);
    if (lightningchance) 
    {
      int x=0;
      if (((cloudstart+(cloudduration/2))/60)>=10) x=51; 
      else x=57;
      ReefAngel.LCD.DrawText(0,255,x,120,((cloudstart+(cloudduration/2))/60));
      if (((cloudstart+(cloudduration/2))%60)>=10) x=69; 
      else x=75;
      ReefAngel.LCD.DrawText(0,255,x,120,((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 
}

Roberto.
StuGotz
Posts: 95
Joined: Sat Oct 15, 2011 9:17 am

Re: Generating PDE w/ RAGen & using Reef Angel Client via US

Post by StuGotz »

YES! That did it!! Thank you. I was about to go out and get the 1/4" tubing to hook up the dosing pumps and test those. I guess I have another hurdle to get those going then? I calibrated my pH probe today, and ready to start figuring out my 2 part schedule.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Generating PDE w/ RAGen & using Reef Angel Client via US

Post by rimai »

Cool.
Now that we got wavemaking out of the way, let's work on dosing.
I'll recommend you use the same code I use, due to the fact that it won't interfere with the timer you are already using.
The assumption is that you will have 24 doses throughout the day, one for every hour.

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

/* The following features are enabled for this PDE File: 
#define DosingPumpIntervalSetup
#define VersionMenu
#define MetalHalideSetup
#define DirectTempSensor
#define DisplayLEDPWM
#define wifi
#define StandardLightSetup
*/


#include <ReefAngel_Features.h>
#include <ReefAngel_Globals.h>
#include <ReefAngel_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <ReefAngel_EEPROM.h>
#include <ReefAngel_NokiaLCD.h>
#include <ReefAngel_ATO.h>
#include <ReefAngel_Joystick.h>
#include <ReefAngel_LED.h>
#include <ReefAngel_TempSensor.h>
#include <ReefAngel_Relay.h>
#include <ReefAngel_PWM.h>
#include <ReefAngel_Timer.h>
#include <ReefAngel_Memory.h>
#include <ReefAngel.h>

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

//Cloud & Lightning effects
byte ActinicPWMValue=0;
byte DaylightPWMValue=0;
//

void setup()
{
  ReefAngel.Init();  //Initialize controller
  ReefAngel.FeedingModePorts = B10100000; //Ports 6 & 8 turn off
  ReefAngel.WaterChangePorts = B10100000; //Ports 6 & 8 turn off
  ReefAngel.OverheatShutoffPorts = B00000011; //Ports 1 & 2 turn off
  ReefAngel.LightsOnPorts = B00000011; //Ports 1 & 2 turn on

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

  // Random Interval Wavemaker Port between 15 and 35 seconds 
  randomSeed(analogRead(0));
  ReefAngel.Timer[1].SetInterval(random(15,35));
  ReefAngel.Timer[1].Start(); 
  ReefAngel.Relay.On(Port6);
}

void loop()
{
  ReefAngel.ShowInterface();

  // Specific functions
//  ReefAngel.DosingPumpRepeat1(Port4);
//  ReefAngel.DosingPumpRepeat2(Port5);

  // Random Interval Wavemaker Port between 15 and 35 seconds 
  if ( ReefAngel.Timer[1].IsTriggered() )
  {
    ReefAngel.Timer[1].SetInterval(random(15,35));
    ReefAngel.Timer[1].Start();
    ReefAngel.Relay.Toggle(Port6);
  }

  //Heater    
  ReefAngel.StandardHeater(Heater,775,779);  // Setup Heater to turn on at 77.5F and off at 77.9F

  //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
  
  if (ReefAngel.DisplayedMenu==255 && minute()==0 && second()<4)  //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()<4)  //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
  
  // Cloud & Lightning effects - Calculate your regular sunrise/sunset PWM value
  // byte PWMSlope(byte startHour, byte startMinute, byte endHour, byte endMinute, byte startPWM, byte endPWM, byte Duration, byte oldValue)
  ActinicPWMValue=PWMSlope(7,00,22,0,0,50,60,ActinicPWMValue); //Actinic turn on at 7am, off at 7pm, and ramp up 0% to 50% PWM in 60 minutes
  DaylightPWMValue=PWMSlope(9,00,19,0,0,50,60,DaylightPWMValue); //Daylight turn on at 9am, off at 5pm, and ramp up 0% to 50% PWM in 60 minutes
  CheckCloud();
  ReefAngel.PWM.SetActinic(ActinicPWMValue);
  ReefAngel.PWM.SetDaylight(DaylightPWMValue);
}

//*********************************************************************************************************************************
// Random Cloud/Thunderstorm effects function
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 5

  // 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;
      }
    }
  // 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,120,132,132);
    ReefAngel.LCD.DrawText(0,255,5,120,"C");
    ReefAngel.LCD.DrawText(0,255,11,120,"00:00");
    ReefAngel.LCD.DrawText(0,255,45,120,"L");
    ReefAngel.LCD.DrawText(0,255,51,120,"00:00");
    if (cloudchance && (NumMins(hour(),minute())<cloudstart))
    {
      int x=0;
      if ((cloudstart/60)>=10) x=11; 
      else x=17;
      ReefAngel.LCD.DrawText(0,255,x,120,(cloudstart/60));
      if ((cloudstart%60)>=10) x=29; 
      else x=35;
      ReefAngel.LCD.DrawText(0,255,x,120,(cloudstart%60));
    }
    ReefAngel.LCD.DrawText(0,255,90,120,cloudduration);
    if (lightningchance) 
    {
      int x=0;
      if (((cloudstart+(cloudduration/2))/60)>=10) x=51; 
      else x=57;
      ReefAngel.LCD.DrawText(0,255,x,120,((cloudstart+(cloudduration/2))/60));
      if (((cloudstart+(cloudduration/2))%60)>=10) x=69; 
      else x=75;
      ReefAngel.LCD.DrawText(0,255,x,120,((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 
}
You can change the number of seconds you want to dose and the minutes to spread them more apart if you need to.
Roberto.
StuGotz
Posts: 95
Joined: Sat Oct 15, 2011 9:17 am

Re: Generating PDE w/ RAGen & using Reef Angel Client via US

Post by StuGotz »

Thanks again Roberto, relays switch on the hour and, 5 minutes. Unfortunately I haven't been able to use them yet. The plugs for the dosers won't fit in the relay box. They overlap the plug next to them :( Can I turn the plug clockwise 90 degrees easily if I open up the relay box? I really don't want to get shorty extension cords to plug them in.

I also made my connector to use the actinic PWM channel for both my Actinic LED dimming and moonlights. I did something wrong with the code though, the moonlight value is not being set.

Code: Select all

   if (hour()>19 && hour()<7)
  {
    ReefAngel.PWM.SetActinic(MoonPhase());  //Moon phase schedule between 7:00pm - 7:00am
  }
  else
  {
    ActinicPWMValue=PWMSlope(7,00,19,0,0,50,60,ActinicPWMValue); //Actinic turn on at 7am, off at 7pm, and ramp up 0% to 50% PWM in 60 minutes
    ReefAngel.PWM.SetActinic(ActinicPWMValue);
  }
  DaylightPWMValue=PWMSlope(9,00,17,0,0,50,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);
Any ideas? Thanks!!
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Generating PDE w/ RAGen & using Reef Angel Client via US

Post by rimai »

Code: Select all

if (hour()>19 && hour()<7)
This will never happen. && means and, so you are checking if hour is grater than 19 and less than 7, which will never happen.
Try this:

Code: Select all

if (hour()>19 || hour()<7)
What if you move the daylight and actinic to port4 and 5 and move the Ca and Alk to 1 and 2? This way, they are going to be at the end of the relay box protuding out. Just a suggestion.
Roberto.
StuGotz
Posts: 95
Joined: Sat Oct 15, 2011 9:17 am

Re: Generating PDE w/ RAGen & using Reef Angel Client via US

Post by StuGotz »

Moonlights working :)

Had to move the outlets and my labels on the relay box around a little more, since the dosing pump plug and the refugium light plug can't be next to one another either.

Code: Select all

#define Sump                1
#define DosingPump2         2
#define Refugium            3
#define Daylight            4
#define Actinic             5
#define Wavemaker1          6
#define Heater              7
#define DosingPump1         8
Could I be done? :shock:

Thanks again for all your patience, quick responses and such a great product. Now to figure out why my canopy is running 20 degrees hotter than yesterday and the days before. Could the moonlights run that hot?
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Generating PDE w/ RAGen & using Reef Angel Client via US

Post by rimai »

You can move them around just like you did.
You should be fine on the moonlights. Just make sure you don't get too hot to melt the plastic, tough.
Roberto.
StuGotz
Posts: 95
Joined: Sat Oct 15, 2011 9:17 am

Re: Generating PDE w/ RAGen & using Reef Angel Client via US

Post by StuGotz »

Good morning Roberto!

If I wanted my dosing pumps to run alternately on the even or odd hours, what's the best way to code that?

I'd like pump1 to run on even hours, and pump2 to run on the odd hours.

Thank you!
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Generating PDE w/ RAGen & using Reef Angel Client via US

Post by rimai »

Try this:

Code: Select all

  if (ReefAngel.DisplayedMenu==255 && hour()%2==0 && minute()==0 && second()<3) // 3 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()<3) // 3 sec dosing on odd hours
    ReefAngel.Relay.On(DosingPump2);  //Turn DosingPump2 Doser on
  else
    ReefAngel.Relay.Off(DosingPump2);  //Turn DosingPump2 Doser off
Roberto.
StuGotz
Posts: 95
Joined: Sat Oct 15, 2011 9:17 am

Re: Generating PDE w/ RAGen & using Reef Angel Client via US

Post by StuGotz »

Thanks again!! BTW, I ordered a MP10wES last night, so I'm sure the RF module is in my future :)
StuGotz
Posts: 95
Joined: Sat Oct 15, 2011 9:17 am

Re: Generating PDE w/ RAGen & using Reef Angel Client via US

Post by StuGotz »

I setup my MP10wES last night. Since I removed the old pump on port 6 I'd like to plug my skimmer in it's place, however can I have the port delay start coming out of feeding and water change mode 5 minutes? I need time for the water level to settle.

Thanks!
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: Generating PDE w/ RAGen & using Reef Angel Client via US

Post by binder »

Inside the loop() function you will want to add this line:

Code: Select all

ReefAngel.Relay.DelayedOn(Port6, 5);
That will tell the controller that Port6 is on a 5 minute delay at startup and coming out of the feeding & water change modes.

curt
StuGotz
Posts: 95
Joined: Sat Oct 15, 2011 9:17 am

Re: Generating PDE w/ RAGen & using Reef Angel Client via US

Post by StuGotz »

Great, thanks Curt!
Post Reply