Clouds and Lightining Effects using standard PWM channels
Re: Clouds and Lightining Effects using standard PWM channel
The alignment is off.
You will need to align them perfect just like it was before.
You will need to align them perfect just like it was before.
Roberto.
- DrewPalmer04
- Posts: 818
- Joined: Tue May 29, 2012 2:12 pm
- Location: Christopher, IL
Re: Clouds and Lightining Effects using standard PWM channel
got them to line up i think? What exactly is this determining? The time before the next cloud?
It reads 29:00 right now
It reads 29:00 right now
- DrewPalmer04
- Posts: 818
- Joined: Tue May 29, 2012 2:12 pm
- Location: Christopher, IL
Re: Clouds and Lightining Effects using standard PWM channel
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
yeah. whatch and see if it is correct
Roberto.
- DrewPalmer04
- Posts: 818
- Joined: Tue May 29, 2012 2:12 pm
- Location: Christopher, IL
Re: Clouds and Lightining Effects using standard PWM channel
It works...going to post a video soon
- DrewPalmer04
- Posts: 818
- Joined: Tue May 29, 2012 2:12 pm
- Location: Christopher, IL
Re: Clouds and Lightining Effects using standard PWM channel
Re: Clouds and Lightining Effects using standard PWM channel
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.
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
Change this line:
To this:
Code: Select all
DaylightPWMValue=ReversePWMSlope(cloudstart,cloudstart+cloudduration,DaylightPWMValue,0,180);
Code: Select all
DaylightPWMValue=ReversePWMSlope(cloudstart,cloudstart+cloudduration,DaylightPWMValue,10,180);
Roberto.
- DrewPalmer04
- Posts: 818
- Joined: Tue May 29, 2012 2:12 pm
- Location: Christopher, IL
Re: Clouds and Lightining Effects using standard PWM channel
Good thought! I'll be changing this on mine
Re: Clouds and Lightining Effects using standard PWM channel
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.
I really do enjoy this controller.
Re: Clouds and Lightining Effects using standard PWM channel
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.
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
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.
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.
Re: Clouds and Lightining Effects using standard PWM channel
Hi, I try to use this code
but I get this error
'PWMSlope' was not declared in this scope
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;
}
'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
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
Sorry.... Yes, it was code related.
Try this:
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.
Re: Clouds and Lightining Effects using standard PWM channel
Thanks Roberto, works perfect.
Can I change this
for this?
to use actinic channel 1% as moonlight
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);
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);
Re: Clouds and Lightining Effects using standard PWM channel
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
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
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
Yeah, totally doable
Let me try to find some time to put this together.
Let me try to find some time to put this together.
Roberto.
Re: Clouds and Lightining Effects using standard PWM channel
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
Can you open a new thread for this?
Roberto.
Re: Clouds and Lightining Effects using standard PWM channel
Did we open a new thread for this?
Re: Clouds and Lightining Effects using standard PWM channel
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;
}