Page 2 of 2

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Wed Aug 22, 2012 11:42 am
by rimai
The alignment is off.
You will need to align them perfect just like it was before.

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Wed Aug 22, 2012 11:46 am
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

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Wed Aug 22, 2012 12:04 pm
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?

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Wed Aug 22, 2012 12:27 pm
by rimai
yeah. whatch and see if it is correct

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Wed Aug 22, 2012 12:37 pm
by DrewPalmer04
It works...going to post a video soon

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Wed Aug 22, 2012 12:46 pm
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

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Wed Oct 31, 2012 3:18 pm
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. :)

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Wed Oct 31, 2012 3:40 pm
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);

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Wed Oct 31, 2012 3:58 pm
by DrewPalmer04
Good thought! I'll be changing this on mine

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Thu Nov 01, 2012 12:34 am
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.

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Sat Apr 06, 2013 2:46 pm
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.

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Sat Apr 06, 2013 4:22 pm
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.

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Mon Apr 08, 2013 11:26 am
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'

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Mon Apr 08, 2013 11:32 am
by rimai

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Mon Apr 08, 2013 1:20 pm
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?

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Mon Apr 08, 2013 1:32 pm
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;
}

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Tue Apr 09, 2013 7:02 am
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

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Thu May 30, 2013 10:30 am
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.

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Thu May 30, 2013 10:32 am
by lnevo
I believe its the same commands for pwm and analog. The hardware takes care of the differences.

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Thu May 30, 2013 10:38 am
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?

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Thu May 30, 2013 11:24 am
by rimai
Yeah, totally doable :)
Let me try to find some time to put this together.

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Thu May 30, 2013 11:29 am
by jjdezek
Ok cool thanks. I will get some wire to set my lights up to those ports.

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Thu May 30, 2013 11:38 am
by rimai
Can you open a new thread for this?

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Wed Oct 09, 2013 7:21 am
by Bruz4023
Did we open a new thread for this?

Re: Clouds and Lightining Effects using standard PWM channel

Posted: Wed Mar 12, 2014 6:36 am
by jegillis
IMAG0802.jpg
IMAG0802.jpg (71.13 KiB) Viewed 6742 times
I think I broke something my storm is after the clouds is that right?

Code: Select all

//*********************************************************************************************************************************
// 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(15,00)

  // Always end the cloud effect before this setting
  // In this example, end could before 8:00pm
#define End_Cloud_Before NumMins(22,00)

  // 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,15,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=15;
        }
        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,8,108,"Cloud");
    ReefAngel.LCD.DrawText(0,255,8,118,"00:00");
    ReefAngel.LCD.DrawText(0,255,90,108,"Storm");
    ReefAngel.LCD.DrawText(0,255,48,108,"Length");
    ReefAngel.LCD.DrawText(0,255,90,118,"00:00");
    if (cloudchance && (NumMins(hour(),minute())<cloudstart))
    {
      int x=0;
      if ((cloudstart/60)>=10) x=8; else x=14;
      ReefAngel.LCD.DrawText(37,255,x,118,(cloudstart/60));
      if ((cloudstart%60)>=10) x=58; else x=64;
      ReefAngel.LCD.DrawText(37,255,x,118,(cloudstart%60));
    }
    if (lightningchance) 
    {
      int x=0;
      if (((cloudstart+(cloudduration/2))/60)>=10) x=90; else x=96;
      ReefAngel.LCD.DrawText(37,255,x,118,((cloudstart+(cloudduration/2))/60));
      if (((cloudstart+(cloudduration/2))%60)>=10) x=108; else x=114;
      ReefAngel.LCD.DrawText(37,255,x,118,((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;
}