Clouds and Lightining Effects using standard PWM channels

Would you like to help?
Share your walkthrough tutorial with others
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Clouds and Lightining Effects using standard PWM channel

Post by rimai »

Just to draw zeros.
Otherwise, when you go from for example 17:10 to 9:32, if you don't clear or draw zeros, you would see 19:32 instead of 09:32.
Roberto.
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Clouds and Lightining Effects using standard PWM channel

Post by DrewPalmer04 »

ok...so should they overlap???? or be in a different location of them?
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Clouds and Lightining Effects using standard PWM channel

Post by rimai »

Yes, they should overlap, so you actually draw over the 00:00
Roberto.
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Clouds and Lightining Effects using standard PWM channel

Post by DrewPalmer04 »

For both the
if ((cloudstart/60)>=10) x=11; else x=17;
ReefAngel.LCD.DrawText(0,255,48,57,(cloudstart/60));
if ((cloudstart%60)>=10) x=29; else x=35;
ReefAngel.LCD.DrawText(0,255,40,57,(cloudstart%60));

Both should overlap 00:00?
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Clouds and Lightining Effects using standard PWM channel

Post by rimai »

I don't think that will work.
That's what the x is for.
When it is >=10, it's 2 digits and you have to offset the drawing by 6 pixels.
So, I think it should be something like this for the hour:
if ((cloudstart/60)>=10) x=40; else x=46;
And same thing for the minutes.
if ((cloudstart%60)>=10) x=48; else x=54;
Roberto.
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Clouds and Lightining Effects using standard PWM channel

Post by DrewPalmer04 »

got it:

And the last position?
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<----(should be 57?),(cloudstart/60));
if ((cloudstart%60)>=10) x=29; else x=35;
ReefAngel.LCD.DrawText(0,255,x,120<----(should be 57?),(cloudstart%60));
}

For proper placement?
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Clouds and Lightining Effects using standard PWM channel

Post by rimai »

yes
Roberto.
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Clouds and Lightining Effects using standard PWM channel

Post by DrewPalmer04 »

Never knew about the overlap thing...very cool idea. Thanks a ton!
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Clouds and Lightining Effects using standard PWM channel

Post by DrewPalmer04 »

Still a little confused...I removed the 00:00 to see what was going on under it and it looks like this:

Image

If I add the 00:00 back...it is just what you see with the 00:00 over it


If I try to do adjustments for x...they just dissapear.
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Clouds and Lightining Effects using standard PWM channel

Post by DrewPalmer04 »

Flipped them


int x=0;
if ((cloudstart/60)>=10) x=48; else x=54;
ReefAngel.LCD.DrawText(0,255,x,57,(cloudstart/60));
if ((cloudstart%60)>=10) x=40; else x=46;
ReefAngel.LCD.DrawText(0,255,x,57,(cloudstart%60));
}


...now have this


Image
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Clouds and Lightining Effects using standard PWM channel

Post by rimai »

The alignment is off.
You will need to align them perfect just like it was before.
Roberto.
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Clouds and Lightining Effects using standard PWM channel

Post by DrewPalmer04 »

got them to line up i think? What exactly is this determining? The time before the next cloud?

It reads 29:00 right now
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Clouds and Lightining Effects using standard PWM channel

Post by DrewPalmer04 »

If I'm reading this right...it states, "14:29" thus my next cloud is at 2:29pm? Or am I way off?
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Clouds and Lightining Effects using standard PWM channel

Post by rimai »

yeah. whatch and see if it is correct
Roberto.
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Clouds and Lightining Effects using standard PWM channel

Post by DrewPalmer04 »

It works...going to post a video soon
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Clouds and Lightining Effects using standard PWM channel

Post by DrewPalmer04 »

Ramp from cloud and back...showed 12 min duration (perfect) and next cloud due at 1553

AWESOME!

Image

Of course the phone's camera has no white balance nor does it show shimmer very well from the LEDs

And new main showing next cloud and next duration (in minutes)....

Image
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
NMTX
Posts: 10
Joined: Thu Sep 20, 2012 12:36 pm

Re: Clouds and Lightining Effects using standard PWM channel

Post by NMTX »

I'm unsure entirely if this has been covered, but is there a way to define how much the daylights dim during cloud cover? In other words, instead of dimming all the way down to 0V, dim down to 1V (or 10%, however you look at it)? If so, how?

It would be kind of cool if the dimming amount was random, but hey, it's cool as-is. :)
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Clouds and Lightining Effects using standard PWM channel

Post by rimai »

Change this line:

Code: Select all

DaylightPWMValue=ReversePWMSlope(cloudstart,cloudstart+cloudduration,DaylightPWMValue,0,180);
To this:

Code: Select all

DaylightPWMValue=ReversePWMSlope(cloudstart,cloudstart+cloudduration,DaylightPWMValue,10,180);
Roberto.
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Clouds and Lightining Effects using standard PWM channel

Post by DrewPalmer04 »

Good thought! I'll be changing this on mine
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
NMTX
Posts: 10
Joined: Thu Sep 20, 2012 12:36 pm

Re: Clouds and Lightining Effects using standard PWM channel

Post by NMTX »

Yeah, my LED-based light (named for a Greek god) is great, but below 1V, the LEDs just shut down since the driver can't go lower. As I was watching the cloud-dimming simulation—something that I really do enjoy, thank you Roberto et al—I just thought it would look smoother in my application to stop the whites at 1V rather than going off entirely, and still give the desired effect.

I really do enjoy this controller.
saf1
Posts: 111
Joined: Thu Jun 28, 2012 1:46 pm

Re: Clouds and Lightining Effects using standard PWM channel

Post by saf1 »

Does this feature work in the current libraries or development libs I should say?

Also, would be sort of cool if you could add in a option to turn on, for a short burst, say your ports that control wave makers. So you mix in the cloud and storm effects with a quick burst of current.

Probably be a bad thing if it got stuck on...but would be sort of good to build up all the movement for a short period of time. I'm sort of doing that with the Hydor 425's I'm using or trying to anyway. The Koralia circulation and wave pumps say they work on timers. So I'm randomly turning on the ports on the relay box on and off between 60 and 300 seconds. With 2 in the tank I'm trying to find a way to randomly let them overlap at least once every 24 hours...tie that to the storm module would be really cool.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Clouds and Lightining Effects using standard PWM channel

Post by rimai »

Yeah, it works.
You can also change the code to move water more violently.
Not sure how good it would be with a koralia though. Maybe Jebao, Tunze or Vortech would give you better results.
Roberto.
fran_
Posts: 3
Joined: Sat Mar 09, 2013 2:27 am

Re: Clouds and Lightining Effects using standard PWM channel

Post by fran_ »

Hi, I try to use this code

Code: Select all

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

byte ActinicPWMValue=0;
byte DaylightPWMValue=0;

void setup()
{
  ReefAngel.Init();  //Initialize controller
}

void loop()
{
  ReefAngel.ShowInterface();
  // Calculate your regular sunrise/sunset PWM value
  ActinicPWMValue=PWMSlope(10,00,22,15,0,50,40,ActinicPWMValue);
  DaylightPWMValue=PWMSlope(10,00,22,15,0,50,40,DaylightPWMValue);
  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 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 100

  // 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;
}
but I get this error

'PWMSlope' was not declared in this scope

Code: Select all









The following features were automatically added:
Watchdog Timer
Version Menu

The following features were detected:
Dimming Signal
Simple Menu
In file included from CloudStandard.cpp:18:
/Users/Fran/Documents/Arduino/libraries/ReefAngel/ReefAngel.h:86: error: 'ParamsStruct' does not name a type
/Users/Fran/Documents/Arduino/libraries/ReefAngel/ReefAngel.h:88: error: 'RA_NokiaLCD' does not name a type
/Users/Fran/Documents/Arduino/libraries/ReefAngel/ReefAngel.h:89: error: 'RA_JoystickClass' does not name a type
/Users/Fran/Documents/Arduino/libraries/ReefAngel/ReefAngel.h:90: error: 'LEDClass' does not name a type
/Users/Fran/Documents/Arduino/libraries/ReefAngel/ReefAngel.h:92: error: 'RA_ATOHighClass' does not name a type
/Users/Fran/Documents/Arduino/libraries/ReefAngel/ReefAngel.h:93: error: 'RA_ATOLowClass' does not name a type
/Users/Fran/Documents/Arduino/libraries/ReefAngel/ReefAngel.h:94: error: 'RA_TempSensorClass' does not name a type
/Users/Fran/Documents/Arduino/libraries/ReefAngel/ReefAngel.h:95: error: 'RelayClass' does not name a type
/Users/Fran/Documents/Arduino/libraries/ReefAngel/ReefAngel.h:97: error: 'RA_PWMClass' does not name a type
/Users/Fran/Documents/Arduino/libraries/ReefAngel/ReefAngel.h:133: error: 'TimerClass' does not name a type
/Users/Fran/Documents/Arduino/libraries/ReefAngel/ReefAngel.h:315: error: 'Total_Menus' was not declared in this scope
/Users/Fran/Documents/Arduino/libraries/ReefAngel/ReefAngel.h:316: error: 'Total_Menus' was not declared in this scope
CloudStandard.cpp: In function 'void loop()':
CloudStandard.pde:-1: error: 'PWMSlope' was not declared in this scope
CloudStandard.pde:-1: error: 'class ReefAngelClass' has no member named 'PWM'
CloudStandard.pde:-1: error: 'class ReefAngelClass' has no member named 'PWM'
CloudStandard.cpp: In function 'void CheckCloud()':
CloudStandard.pde:-1: error: 'NumMins' was not declared in this scope
CloudStandard.pde:-1: error: 'NumMins' was not declared in this scope
CloudStandard.pde:-1: error: 'NumMins' was not declared in this scope
CloudStandard.pde:-1: error: 'NumMins' was not declared in this scope
CloudStandard.pde:-1: error: 'class ReefAngelClass' has no member named 'LCD'
CloudStandard.pde:-1: error: 'class ReefAngelClass' has no member named 'LCD'
CloudStandard.pde:-1: error: 'class ReefAngelClass' has no member named 'LCD'
CloudStandard.pde:-1: error: 'class ReefAngelClass' has no member named 'LCD'
CloudStandard.pde:-1: error: 'class ReefAngelClass' has no member named 'LCD'
CloudStandard.pde:-1: error: 'class ReefAngelClass' has no member named 'LCD'
CloudStandard.pde:-1: error: 'class ReefAngelClass' has no member named 'LCD'
CloudStandard.pde:-1: error: 'class ReefAngelClass' has no member named 'LCD'
CloudStandard.pde:-1: error: 'class ReefAngelClass' has no member named 'LCD'
CloudStandard.pde:-1: error: 'class ReefAngelClass' has no member named 'LCD'
fran_
Posts: 3
Joined: Sat Mar 09, 2013 2:27 am

Re: Clouds and Lightining Effects using standard PWM channel

Post by fran_ »

I have deleted arduino folder and reinstalled RA and the problem persists - 'PWMSlope' was not declared in this scope. Can be a problem in the code?
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Clouds and Lightining Effects using standard PWM channel

Post by rimai »

Sorry.... Yes, it was code related.
Try 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 <AI.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <Salinity.h>
#include <PH.h>
#include <WaterLevel.h>
#include <ReefAngel.h>

byte ActinicPWMValue=0;
byte DaylightPWMValue=0;

void setup()
{
  ReefAngel.Init();  //Initialize controller
}

void loop()
{
  ReefAngel.ShowInterface();
  // Calculate your regular sunrise/sunset PWM value
  ActinicPWMValue=PWMSlope(10,00,22,15,0,50,40,ActinicPWMValue);
  DaylightPWMValue=PWMSlope(10,00,22,15,0,50,40,DaylightPWMValue);
  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 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 100

  // 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;
}
Roberto.
fran_
Posts: 3
Joined: Sat Mar 09, 2013 2:27 am

Re: Clouds and Lightining Effects using standard PWM channel

Post by fran_ »

Thanks Roberto, works perfect.

Can I change this

Code: Select all

ReefAngel.ShowInterface();
  // Calculate your regular sunrise/sunset PWM value
  ActinicPWMValue=PWMSlope(10,00,22,15,0,50,40,ActinicPWMValue);
  DaylightPWMValue=PWMSlope(10,00,22,15,0,50,40,DaylightPWMValue);
  CheckCloud();
  ReefAngel.PWM.SetActinic(ActinicPWMValue);
  ReefAngel.PWM.SetDaylight(DaylightPWMValue);
for this?

Code: Select all

 ReefAngel.ShowInterface();
  // Calculate your regular sunrise/sunset PWM value
  ActinicPWMValue=PWMSlope(10,00,21,00,1,100,120,1);
  DaylightPWMValue=PWMSlope(10,00,21,00,0,100,120,0);
  CheckCloud();
  ReefAngel.PWM.SetActinic(ActinicPWMValue);
  ReefAngel.PWM.SetDaylight(DaylightPWMValue);
to use actinic channel 1% as moonlight
jjdezek
Posts: 329
Joined: Fri May 17, 2013 1:35 pm

Re: Clouds and Lightining Effects using standard PWM channel

Post by jjdezek »

i read through this and noticed it says pwm for everything. does this work for anolog? I have 3 heat sinks over my 210 with the meanwell ELN 60-48D drivers hooked up to the anolog expansion. right now all white are hooked to same port 0 and all blues are hook to same port 1 but i can hook them up to different ports so each heat sink is on its own port and allow for the effect of a cloud passing over my tank if thats possible? the lightening would be neat as well but more interested in the cloud.
Image
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Clouds and Lightining Effects using standard PWM channel

Post by lnevo »

I believe its the same commands for pwm and analog. The hardware takes care of the differences.
jjdezek
Posts: 329
Joined: Fri May 17, 2013 1:35 pm

Re: Clouds and Lightining Effects using standard PWM channel

Post by jjdezek »

cool. well i have no idea now to do coding so if anyone could figure out how to do a cloud slowly passing over my tank from one side to the other that would be cool. say i have left heat sink whites in port 0 blues in port 1, middle heat sink whites in port 2 blues in port 3, right heat sink whites in port 4 and blues in port 5. could it start dimming on left then middle then dim right and brighten left then middle and right with a slow moving cloud effect, or is that too complex?
Image
Post Reply