Tutorial- Weather Simulation for PWM expansion module
Posted: Mon Jun 25, 2012 9:32 am
So... you want to try to implement the Weather Simulation. Thanks for trying it and I hope you enjoy it.
To do so... I assume you have Arduino open with the .INO loaded and saved as whatever you want to call it (file name is irrelevant). Let me start by trying to explain what the program does then I am going to simply copy and paste EVERY line of code from the .INO that you will NEED to edit- followed by a line by line explanation of what it is your editing and how to do it. ALL you need to do is change some numbers- thats IT. But first a description so you can see if this what you want to run.
As it exists today, the code runs as a stand alone software for the PWM OR ANALOG dimming expansion module. Although I use PWM, Roberto tells me that there is no difference between them aside from the output signal type so the code will work identically on either. By stand alone I mean that it completely takes over your PMW expansion module- it runs independently of the Main controller- it doesn't even acknowledge the fact that the main controller exists. This will evolve as we work to enable some comm etc but its not working now. It simply runs your lights, thats it- period. Sounds like its not doing much? Read on...
So, what does it do?
1) It uses your latitude and longitude position (or the position you select for you tank) to calculate the daily sunrise and sunset times. It turns on your lights (you can modify this... keep reading) at exactly sunrise, and turns them off at exactly sunset. If you use the latitude and longitude of your house the tank will turn on as the sun first appears on the horizon and turn off as the sun dips below the horizon- every day- all year- EXACTLY. If you live somewhere with 5 hours of light in the winter and 18 hour days in the summer... you might want to use your Longitude coordinates but pick a Latitude closer to the equator so your tank sees a bit more of a normal reef light cycle.
2) Once the lights "turn on" how bright are they... do I have to worry about 14 hour days and bleaching my coral... in short... its your tank so watch things if you don't like it change it! BUT... within reason, day length is not a huge concern because the program models the normal variation of solar intensity using a Cosine function. You need to tell it what the LOWEST PWM output setting is that produces flicker free light for each of your channels- and then what the HIGHEST PWM output setting is for each channel (be careful here... read this part of the code tutorial carefully to set this up correctly). Then, when the sun rises- the lights start at their flicker point and progress to their MAX intensity setting at Mid day (exactly half way between sunrise and sunset). As you transition into the second half of the day the lights go from their MAX setting to their flicker point at sunset and then shut off.... but a lot can happen to the lights while they are on... keep reading.
3) You can modify when any given string of lights will rise and set by inputting a Channel Offset value that will cause them to come on XXXX seconds prior to or after sunrise or sunset. For instance, if you have a few blue only channels you could configure it such that they stay on later than the true sunset time (when the white lights would be off... if you configured it this way). This would achieve a nice night time viewing of fluorescence etc... If your lights are set up with channels across the tank left to right, you can configure it so that the left (or right or whatever) lights come on first and set first while the other side comes on late and sets late ... so the sun rises on one side and sets to the other and channels will come on across the tank. Since light intensity changes during the day... and if you use offsets and have lights on prior to or after sunset... each channel theoretically experiences its own independent day length... and if you simply calculate the mid day point (i.e. half way through total lights on time) for each channel independently you would get odd color blends. For instance, my blue strings run 2 hours (7200 sec) longer than the whites in the evening, thus their midday point is an hour later than the whites. To avoid color blends changing through the day as whites peak, and then blues peak- while the white channels are declining, the program corrects for this and actually splits the day into two parts, morning and afternoon (for EVERY channel independently). Each channel then has an independently calculated "slope" so that EVERY channel regardless of offset values peaks at EXACTLY midday (as defined by 1/2 between rise and set without regard to offsets). In this way, your color should be pretty much constant throughout the day (as good as you can get without setting every channel to the exact same length) but you can use your channels any way you want.
4) It randomly calculates (every day a new value is chosen) if the day will be cloudy, what percentage of the day will be overcast, and the number of clouds that will be generated that day, their start and end times. You can set a parameter that controls the percent chance that any given day will be cloudy. The code I distributed will produce clouds every day (chance=100% but this can be changed), their number, their length and their time of appearance is random. Although you can set the min and max number, since they are randomly timed and the effect is nice... I have left it random. Any given cloudy day will experience between 2-10 clouds. The percentage of the day that is overcast is linked to the number of clouds in a given day- in this way days with low # of clouds do not end up with exceedingly long (if few) clouds. Thus, the length of a given cloud is random and may be as little as a few minutes or as much as perhaps 30 minutes but does not get out of hand. It can even be cloudy "after the sun has set" if you have channels that extend light significantly past the calculated sunset (for instance, my blue channels).
5) The Cloud effect is what drives this program... that and storms. A "cloud" is a period of time during which the intensity of all the channels over the tank enters a random walk- and further may be set up such that the lights "chase" each other across the tank. For instance, consider a tank with 4 channels of lights two on the left and two on the right each side has one blue and one white channel. You define a DimOrder array in which you would group the left and right channels independently (details follow with code). Then, as the cloud starts all the channels will dim to 50% of their CURRENT max intensity (this Max intensity of course will changes as the day progresses given the insolation model). Once all the lights have dimmed to 50% (in 20 seconds or so) the random walk starts. The channels you grouped together using 0's in the DimOrder array get their first random walk point and the intensity will go up or down (its random...) from their current 50% set point to whatever the walk value is (+/- 0-20% from current % intensity set point). This occurs over 400 msec as a smooth transition with lights being changed in intensity every 100 msec. Then, a new value is calculated for the walk and the old value is passed to the other side of the tank (with DimOrder values of 1) which begins its intensity change while the new value replaces the prior for the DimOrder array channels with values of 0. So... the tank basically randomly brightens and dims with one side leading by 400 msec the other, its not SUPER obvious that the lights are chasing but I think its sometimes notable and looks very pleasing to the eye. A cloud ends by ramping all channels up to their CURRENT MAX setting over a short period.
5a) As clouds begin they are randomly assigned a potential to form a storm, any given cloud may generate 0, 1, or 2 storms. Any given storm may become severe, although the potential to do so increases if the cloud occurs in the afternoon. The evolution of a cloud to a storm is somewhat complex but it usually takes at least 5-10 minutes of a cloud to actually build up the correct statistics (that are tracked internally) to trigger storm formation (if it is possible for this cloud). Two types of storms are possible, and this will also depend on your tank set up. Basically, you define in the set up which channels are "White" channels... a "storm" sets the white channels to a max intensity of 25% of their current intensity value while the blues ramp from 0-100% (0 is always the flicker point, NO LIGHTS should ever go OFF during a storm). Then a lightning strike sequence is generated when some internally tracked stats accumulate to trigger it. Lightning strike sequences produce 2-11 strikes with random durations between them of up to about 1-2 seconds, each strike is randomly intense (i.e. the intensity output of the channel settings during the strikes), and their durations are modeled based upon the duration of a real strike (although I allow ours to be a bit longer). The random walk during a storm is accelerated, every 300 msec a new value is seeded so the tank lighting moves notably faster during a storm... which is kinda cool
You can configure which channels will be utilized during a lightning strike, I use them ALL to make it intense... but you can pick and choose.
5b) Severe Storms are those storms in which lightning is much more frequent and the "White" channels are turned OFF. Thus, if you set up your WChannel array with any values of 1 (denoting a white channel) these channels will turn off during a storm, the others will ramp and strikes occur. The channels that are used to generate the lightning striked during storms (either type) are specified in your StrikeChannel array (that I briefly alluded to just prior to this). If you only have white channels, you of course would not want to enter a 1 in all positions of the WChannel Array- the tank would go dark during a severe storm but for the lightning strikes. I guess this array is misleadingly labeled... think of the WChannel array as the place to set which channels will go dark to further darken the tank during a severe storm. Of course, if you have independent blue and white channels... Try it will ALL the white channels set to 1 in the array... it looks great.
6) You have the option of configuring MoonPhase lighting for any channel. I just re-wrote this section, its now super easy to configure moon lighting... read on. For reference the code I uploaded uses channel 4 for MoonPhase lighting on my system.
To do so... I assume you have Arduino open with the .INO loaded and saved as whatever you want to call it (file name is irrelevant). Let me start by trying to explain what the program does then I am going to simply copy and paste EVERY line of code from the .INO that you will NEED to edit- followed by a line by line explanation of what it is your editing and how to do it. ALL you need to do is change some numbers- thats IT. But first a description so you can see if this what you want to run.
As it exists today, the code runs as a stand alone software for the PWM OR ANALOG dimming expansion module. Although I use PWM, Roberto tells me that there is no difference between them aside from the output signal type so the code will work identically on either. By stand alone I mean that it completely takes over your PMW expansion module- it runs independently of the Main controller- it doesn't even acknowledge the fact that the main controller exists. This will evolve as we work to enable some comm etc but its not working now. It simply runs your lights, thats it- period. Sounds like its not doing much? Read on...
So, what does it do?
1) It uses your latitude and longitude position (or the position you select for you tank) to calculate the daily sunrise and sunset times. It turns on your lights (you can modify this... keep reading) at exactly sunrise, and turns them off at exactly sunset. If you use the latitude and longitude of your house the tank will turn on as the sun first appears on the horizon and turn off as the sun dips below the horizon- every day- all year- EXACTLY. If you live somewhere with 5 hours of light in the winter and 18 hour days in the summer... you might want to use your Longitude coordinates but pick a Latitude closer to the equator so your tank sees a bit more of a normal reef light cycle.
2) Once the lights "turn on" how bright are they... do I have to worry about 14 hour days and bleaching my coral... in short... its your tank so watch things if you don't like it change it! BUT... within reason, day length is not a huge concern because the program models the normal variation of solar intensity using a Cosine function. You need to tell it what the LOWEST PWM output setting is that produces flicker free light for each of your channels- and then what the HIGHEST PWM output setting is for each channel (be careful here... read this part of the code tutorial carefully to set this up correctly). Then, when the sun rises- the lights start at their flicker point and progress to their MAX intensity setting at Mid day (exactly half way between sunrise and sunset). As you transition into the second half of the day the lights go from their MAX setting to their flicker point at sunset and then shut off.... but a lot can happen to the lights while they are on... keep reading.
3) You can modify when any given string of lights will rise and set by inputting a Channel Offset value that will cause them to come on XXXX seconds prior to or after sunrise or sunset. For instance, if you have a few blue only channels you could configure it such that they stay on later than the true sunset time (when the white lights would be off... if you configured it this way). This would achieve a nice night time viewing of fluorescence etc... If your lights are set up with channels across the tank left to right, you can configure it so that the left (or right or whatever) lights come on first and set first while the other side comes on late and sets late ... so the sun rises on one side and sets to the other and channels will come on across the tank. Since light intensity changes during the day... and if you use offsets and have lights on prior to or after sunset... each channel theoretically experiences its own independent day length... and if you simply calculate the mid day point (i.e. half way through total lights on time) for each channel independently you would get odd color blends. For instance, my blue strings run 2 hours (7200 sec) longer than the whites in the evening, thus their midday point is an hour later than the whites. To avoid color blends changing through the day as whites peak, and then blues peak- while the white channels are declining, the program corrects for this and actually splits the day into two parts, morning and afternoon (for EVERY channel independently). Each channel then has an independently calculated "slope" so that EVERY channel regardless of offset values peaks at EXACTLY midday (as defined by 1/2 between rise and set without regard to offsets). In this way, your color should be pretty much constant throughout the day (as good as you can get without setting every channel to the exact same length) but you can use your channels any way you want.
4) It randomly calculates (every day a new value is chosen) if the day will be cloudy, what percentage of the day will be overcast, and the number of clouds that will be generated that day, their start and end times. You can set a parameter that controls the percent chance that any given day will be cloudy. The code I distributed will produce clouds every day (chance=100% but this can be changed), their number, their length and their time of appearance is random. Although you can set the min and max number, since they are randomly timed and the effect is nice... I have left it random. Any given cloudy day will experience between 2-10 clouds. The percentage of the day that is overcast is linked to the number of clouds in a given day- in this way days with low # of clouds do not end up with exceedingly long (if few) clouds. Thus, the length of a given cloud is random and may be as little as a few minutes or as much as perhaps 30 minutes but does not get out of hand. It can even be cloudy "after the sun has set" if you have channels that extend light significantly past the calculated sunset (for instance, my blue channels).
5) The Cloud effect is what drives this program... that and storms. A "cloud" is a period of time during which the intensity of all the channels over the tank enters a random walk- and further may be set up such that the lights "chase" each other across the tank. For instance, consider a tank with 4 channels of lights two on the left and two on the right each side has one blue and one white channel. You define a DimOrder array in which you would group the left and right channels independently (details follow with code). Then, as the cloud starts all the channels will dim to 50% of their CURRENT max intensity (this Max intensity of course will changes as the day progresses given the insolation model). Once all the lights have dimmed to 50% (in 20 seconds or so) the random walk starts. The channels you grouped together using 0's in the DimOrder array get their first random walk point and the intensity will go up or down (its random...) from their current 50% set point to whatever the walk value is (+/- 0-20% from current % intensity set point). This occurs over 400 msec as a smooth transition with lights being changed in intensity every 100 msec. Then, a new value is calculated for the walk and the old value is passed to the other side of the tank (with DimOrder values of 1) which begins its intensity change while the new value replaces the prior for the DimOrder array channels with values of 0. So... the tank basically randomly brightens and dims with one side leading by 400 msec the other, its not SUPER obvious that the lights are chasing but I think its sometimes notable and looks very pleasing to the eye. A cloud ends by ramping all channels up to their CURRENT MAX setting over a short period.
5a) As clouds begin they are randomly assigned a potential to form a storm, any given cloud may generate 0, 1, or 2 storms. Any given storm may become severe, although the potential to do so increases if the cloud occurs in the afternoon. The evolution of a cloud to a storm is somewhat complex but it usually takes at least 5-10 minutes of a cloud to actually build up the correct statistics (that are tracked internally) to trigger storm formation (if it is possible for this cloud). Two types of storms are possible, and this will also depend on your tank set up. Basically, you define in the set up which channels are "White" channels... a "storm" sets the white channels to a max intensity of 25% of their current intensity value while the blues ramp from 0-100% (0 is always the flicker point, NO LIGHTS should ever go OFF during a storm). Then a lightning strike sequence is generated when some internally tracked stats accumulate to trigger it. Lightning strike sequences produce 2-11 strikes with random durations between them of up to about 1-2 seconds, each strike is randomly intense (i.e. the intensity output of the channel settings during the strikes), and their durations are modeled based upon the duration of a real strike (although I allow ours to be a bit longer). The random walk during a storm is accelerated, every 300 msec a new value is seeded so the tank lighting moves notably faster during a storm... which is kinda cool
You can configure which channels will be utilized during a lightning strike, I use them ALL to make it intense... but you can pick and choose.
5b) Severe Storms are those storms in which lightning is much more frequent and the "White" channels are turned OFF. Thus, if you set up your WChannel array with any values of 1 (denoting a white channel) these channels will turn off during a storm, the others will ramp and strikes occur. The channels that are used to generate the lightning striked during storms (either type) are specified in your StrikeChannel array (that I briefly alluded to just prior to this). If you only have white channels, you of course would not want to enter a 1 in all positions of the WChannel Array- the tank would go dark during a severe storm but for the lightning strikes. I guess this array is misleadingly labeled... think of the WChannel array as the place to set which channels will go dark to further darken the tank during a severe storm. Of course, if you have independent blue and white channels... Try it will ALL the white channels set to 1 in the array... it looks great.
6) You have the option of configuring MoonPhase lighting for any channel. I just re-wrote this section, its now super easy to configure moon lighting... read on. For reference the code I uploaded uses channel 4 for MoonPhase lighting on my system.