trouble with pwmslope

Do you have a question on how to do something.
Ask in here.
Post Reply
duck
Posts: 28
Joined: Tue Jan 24, 2012 4:12 pm

trouble with pwmslope

Post by duck »

Im using the cloud effects from the sticky thread, and cut and pasted. I dont know what values to edit to give it more time.. My lights go from 14 to 100 % in about 2 minutes. Heres the code. Any ideas?

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

    byte ActinicPWMValue=0;
    byte DaylightPWMValue=0;
    
    //Return              1
    //Blue LED and Fans   2
    //White LED           3
    //Alk                 4
    //Powerhead           5
    //Heater              6
    #define ATO           7
    //Skimmer             8
    #define wifi

    void setup()
    {
    ReefAngel.Init();  //Initialize controller
    ReefAngel.PHMin=200;
    ReefAngel.PHMax=807;
    ReefAngel.AddStandardMenu();  // Add Standard Menu

    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = Port1Bit | Port5Bit | Port7Bit;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = Port1Bit | Port5Bit | Port7Bit;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = Port2Bit | Port3Bit;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = Port2Bit | Port3Bit | Port5Bit | Port6Bit | Port7Bit;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;
    // Set the Overheat temperature setting
    InternalMemory.OverheatTemp_write( 830 );


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

    void loop()
    {
      ReefAngel.StandardLights( Port2,9,0,21,0 );
      ReefAngel.StandardLights( Port3,9,0,21,0 );
      ReefAngel.StandardHeater( Port6,760,770 );
      ReefAngel.ShowInterface();
      // Calculate your regular sunrise/sunset PWM value
      ActinicPWMValue=PWMSlope(9,0,21,0,14,100,14,ActinicPWMValue);
      DaylightPWMValue=PWMSlope(9,0,21,0,14,100,14,DaylightPWMValue);
      CheckCloud();
      ReefAngel.PWM.SetActinic(ActinicPWMValue);
      ReefAngel.PWM.SetDaylight(DaylightPWMValue);
      //Alk Dosing Pump 1 Minute Every 45 Minutes
      if (now()%2700<60) ReefAngel.Relay.On(Port4); else ReefAngel.Relay.Off(Port4);
      //Powerhead On Every 4 Hours With 30 Min Pause
      if (now()%1800<12600) ReefAngel.Relay.On(Port5); else ReefAngel.Relay.Off(Port5);
      //Heater Control on at 77F and off at 78F
      ReefAngel.StandardHeater(Port6,770,780);
      ReefAngel.SingleATO(true,ATO,300,0);

    }

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

      // 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 8:00pm
    #define End_Cloud_Before NumMins(18,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 50

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


    // This should always be the last line
    ReefAngel.ShowInterface();
}
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: trouble with pwmslope

Post by rimai »

Looks ok, except for:

Code: Select all

ReefAngel.ShowInterface();
It needs to be the last line inside the loop() section, right below the SingleATO.
Roberto.
ufgators2k
Posts: 57
Joined: Sun May 12, 2013 2:21 pm

Re: trouble with pwmslope

Post by ufgators2k »

Is there library that includes the cloud functions or is it best to leave it in the main code?
Image
User avatar
lnevo
Posts: 5422
Joined: Fri Jul 20, 2012 9:42 am

Re: trouble with pwmslope

Post by lnevo »

Not yet... I know rufessor is working on a weather package, but it's still a bit from release.
Post Reply