Weather Simulation for Dimming expansion module

Share you PDE file with our community

Posts: 293
Joined: Tue Oct 25, 2011 7:39 am
PostPosted: Wed Sep 26, 2012 9:23 am
Sooooo..... I figured out why my dimming module suddenly went crap-0-la and stopped working.

Damn fish :twisted:

I recently added a Niger (red-tooth) trigger to my tank. It is doing very well, eats like a pig and also apparently enjoys surfing the stream coming out of one of my power heads up near the back left corner (top) of my tank, which is- you guessed it- right over my dimming module sitting down near the ground. :o

Summary and basic electronics tutorial.

Corals and trigger fish live in salt water.
Salt water is apparently corrosive to PCB circuitry (who'd a thunk :mrgreen: )
Short circuiting PCB circuitry causes massive issues with actually running a program
I need a new dimming module

So- PLEASE... if your like me and were loading a ton of stuff to a dimming module during development, then got it all working and had it running for a few months but were too lazy to screw on the nice plastic case to keep the water off it... well... you might consider doing that ASAP. Its mUCH cheaper.

Posts: 14
Joined: Wed Jul 04, 2012 7:03 pm
PostPosted: Thu Oct 25, 2012 7:08 am
I have a MP40w and a MP60w running on my tank. Would it be that difficult to work them into the code?

I am a complete newb and get frustrated(and scared) faster than I can learn this stuff. lol

Posts: 293
Joined: Tue Oct 25, 2011 7:39 am
PostPosted: Wed Nov 14, 2012 9:16 am
Sorry for the long delay... since my module was fried by the damn fish I have been using the very sophisticated method of plug the lights in in the morning and un-plug them at night... it almost exactly mirrors my awake time :)

But... my new module will be here this week so I can play more. The code running on the dimming module really is isolated from the pump. However, and I keep saying I am going to do this.... it is pretty easy to get the dimming module to talk to the main and tell it its a storm, cloud, sunny etc which then could be used to change pump settings. However, although I may put up something with comm in it, I do not have programmable in tank pumps/power heads so I would not be able to help you. That said, there all ready exist a number of implementations for the pumps you have and it would be trivial to change a few lines to get them to run based upon the storm/cloud/etc output from this program.


Just to reiterate for everyone else looking here... the code for the weather package is working 100% and some of it has been ported to the main by lenovo. The only reason I was worried about bugs was the unknown fact that my fish was slowly killing my dimming module... ;

Posts: 293
Joined: Tue Oct 25, 2011 7:39 am
PostPosted: Tue Nov 20, 2012 9:14 am
So here is a bit of code that might be one solution to the short winter days, and to fixing the bleaching I was getting due to the 17 hour summer days... first bit can be used to symmetrically shift the day to a longer time by just using set=set(5e-1*etc... for each line...

Second bit is not going to work currently due to issues with ChOffset needing to be defined here so its not continually edited downward.... and I am not filling it correctly, I just copy and pasted so ignore that array statement stuff but once I get that fixed the for loop should do what we need... it indexes intensity down as a decimal percentage of the length of the extra daylight (beyond desired light on time) as compared to the desired day... so if your desired day is 100 seconds and your sun rise and set yield 110 your extra day light is 10 seconds, which is 10% of 100 so your lights would be set to 0.9*ChMax values... hope that makes sense...

This is just to gather comment, the first part would probably run now, the second is a SKETCH... with known bugs and issues, it will not even compile.. just thinking this through a bit.

if ((set-rise)<45000){
long dayDelta;
dayDelta=45000-(set-rise);
//change following constants to sum to 1.0 to distribute additional seconds of day accordingly
set=set+(7e-1*dayDelta);
rise=rise-(3e-1*dayDelta);
}
if ((set-rise)>45000){
float dayDelta;
dayDelta=(set-rise)-45000;
dayDelta=1-(dayDelta/45000);//as fractional decrease in intensity max setting for the day (every 10% longer than 12.5 hours reduces ChMax to 0.9*ChMax)

//adjust intensity to compensate for long days
for (byte b=0; b<8; b++){
ChMax[b]=ChMax[b]*dayDelta;
}
}

Posts: 293
Joined: Tue Oct 25, 2011 7:39 am
PostPosted: Tue Dec 11, 2012 1:36 pm
Ok... so I have code compiled that I will be uploading.

What I noticed is that as the seasons changed I got better coloration in my corals, which has now transitioned into some of the Zoas that are partially shaded have begun growing long necks "reaching for the light" so I know that given my latitude and longitude I have too much PAR variation throughout the year, with peak summer causing some loss of coloration even slight bleaching and the depths of winter causing light stress due to too little light.

I decided to take a two pronged approach. Since you cannot go higher than full PWM 100% output which is constrained by the dimmer at whatever max current output you set, the only way to fix the winter light shortage is to enforce a longer day. Since I like to view my tank at night and with sunset before 5 pm where I live, the tank is going dark before I get a chance to fully enjoy it so my solution to adding time to winter days is to basically set a minimal daylight period of 12.5 hours. Then when days are less than that, add back the required time to get to 12.5 hours (45000) seconds and distribute it asymmetrically such that the sunset is delayed more than the rise is accelerated.

Then, if the day is longer than 45000 seconds I decided to use PWM dimming to REDUCE the channel intensity set points by the fractional day length difference

e.g. if the day is 49500 long, which is 4500 longer than 45000 seconds (10%) the individual channel intensities are set back by 10% of their value (in the last part of the code which is from insolation). I am using integer math to do fractions so I am calculating the percent difference and adding 100 to it... if that helps make sense.. this is stripped out in the last bit.


First - you need to globally initialize a variable so add this to the setup

float fracInt;

Then... this code goes into CalSun right below the final calculations to rise and set for elapsed day time.
Code: Select all
//Minimum desired day length is inside if statement 45000=12.5 hrs
 //calculation distributes additional time required to yield 12.5 hour light cycle symetrically to rise and set if you use 5e-1 as constant in if loop below
   if ((set-rise)<45000){
     long dayDelta;
     dayDelta=45000-(set-rise);
     //change following constants to sum to 1.0 to distribute additional seconds of day accordingly
     set=set+(75e-2*dayDelta);//75% of the additional time is used to delay set
     rise=rise-(25e-2*dayDelta);//25% of the additional time is used to set rise to earlier value
     fracInt=100;//set this to make no correction to intensity in insolation for short days
   }
   //Max desired day length at 54000 is 15 hours
   //If calc day length exceeds trim to 54000 and set rise to 0.7 of difference (adding 0.7 of excess) with the rest coming off set
 else if ((set-rise)>45000){
     float dayDelta;
     dayDelta=100*(((set-rise)-45000)/45000);
     //change following constants to sum to 1.0 to distribute additional seconds of day accordingly
     fracInt=dayDelta+100;//fractional math with integers requires scaling to remove decimal
   } 
 else fracInt=100;//set this for days that are exactly equal to 45000


Then, I changed the Insolation routine a little bit so that once the actual fractional intensity required at the given point of the day (modeling solar insolation using a cosine) the actual output light setting is modified by the fracIntensity to downgrade intensity set point on long days to avoid bleaching.

To assist in not having to find the small changes I made throughout this routine, I am just copy pasting the entire function.
Code: Select all
void Insolation()
{
  InsolationAdvance=false;//reset this flag now that we have entered function

        //define Pi as delta Y for slope since cos 0.5-1.5 Pi goes 0-1-0 in 0.5 pI increments slope of 1/2 day (0-1 intensity) delta Y is 1/2 Pi
        float Pi=3.1415926;//scale to 10^8
        float PiHalf=1.5707963;//scale to 10^8
       
        float secSoFar;//variable to account for seconds elapsed for each channel 1/2 day period from rise-->midDay and midDay-->set
       
        /* using -cos(pi/2+elapsedTime/slope) calculate fractional intensity of each channel throughout the day
         use flicker points to adjust minimum intensity to stable light.  Turn off lights after set or before rise etc.
         by splitting into half days centered on midday (1/2 ofset-rise) we center exactly the cos function for every channel so color blends are maintained
         throughout intensity ramp... more or less ... change intensity every 120 seconds throughout the day*/
         if (elapsedTime<=midDay){
           byte c=0;//loop counter
            for (byte b=0;b<16;b=(b+2)){
                if (elapsedTime>=ChRiseSet[b]){
                    secSoFar=(elapsedTime-ChRiseSet[b]);//just account for length of every channel 1/2 day and switch at midDay
                    ChannelValue[c]=ChMax[c]*(-cos(PiHalf+(ChSlope[b]*secSoFar)));
                 }
                 else if (elapsedTime<ChRiseSet[b]){
                   if (MoonCh[c]==1){ 
                      byte MoonToday=MoonPhase()*0.5;//SCALE FACTOR to DIM moon setting for use with HIGH power LED as moon light
                      if (MoonToday==0) ChannelValue[c]=0;
                      else ChannelValue[c]=MoonToday;
                   }
                   else if (MoonCh[c]==0){
                     ChannelValue[c]=0;//its dark and this is not a moon phase channel
                   }
                 }
              c++;//index by one so we count 0-7 as b goes 0-14 by twos
            }
        } 
        else if (elapsedTime>midDay){
            byte c=0;//loop counter
            for (byte b=1;b<16;b=b+2){
              if (elapsedTime<=ChRiseSet[b]){
                    secSoFar=(elapsedTime-midDay);
                    ChannelValue[c]=ChMax[c]*(-cos(Pi+(ChSlope[b]*secSoFar)));         
               }
               else if (elapsedTime>ChRiseSet[b]){
                   if (MoonCh[c]==1){ 
                      byte MoonToday=MoonPhase()*0.5;//SCALE FACTOR to DIM moon setting for use with HIGH power LED as moon light
                      if (MoonToday==0) ChannelValue[c]=0;
                      else ChannelValue[c]=MoonToday;
                   }
                   else if (MoonCh[c]==0){
                     ChannelValue[c]=0;//its dark and this is not a moon phase channel
                   }
                }
              c++;//index to count 0-7 as b counts 1-15 by twos.
            }
        } 
     //The next bit modifies the actual ouput intensity to account for day length variations in attempt to maintain PAR levels
     //throughout the year.
     //You must set ChMax to obtain adequate PAR for a 12.5 hr (45000) light day
     //This modifies that by REDUCING indensity linearly by % day length over 12.5 Hr for any day over 12.5 Hr.
     //Add Flicker setting to all utilized channels (ChannelValue!=0) to avoid flicker
     byte a=0;
     for (a=0;a<8;a++){
       if (ChannelValue[a]!=0){
         ChannelValue[a]=((ChannelValue[a]/fracInt)*100)+flicker[a];
       }
     } 
   }//END function
//WEATHER FUNCTION BEGIN


The rational i use for taking a direct percent of daylength to modify PWM setting is that the PAR value is "set" at 100% of whatever that is with a PMW setting of 255. Using PWM dimming you are NOT altering the intensity of the LED by modifying current, you are simply flashing it at 100% current- very quickly. So, if you simply flash it 10% less you aught to deliver 10% less PAR to the tank... we shall see.. but it will literally take nearly a year to tell if this is a fix as there is no way to assess this in terms of coral coloration and growth other than to watch the tank.

I AM NOT CERTAIN THAT THIS IS A GOOD APPROACH for analog dimming... maybe someone can chime in.

Posts: 293
Joined: Tue Oct 25, 2011 7:39 am
PostPosted: Wed Dec 12, 2012 10:45 am
I have the mods running and all the code for expanding the daylight times if the day is less than 12.5 hours is working correctly. So if you want this, go ahead and use it. As for the code to dim according to % day length exceeding 45000 seconds- I am not planning on really testing this until summer rolls around and then only will have any idea if its working after we get well into summer and I can see if the corals avoid the bleaching I was seeing- although I suspect it will fix the problem its going to be a months long process to determine if its an adequate adjustment... so when we roll though July I will post back how things are working.

Posts: 1
Joined: Sun Mar 10, 2013 10:12 pm
PostPosted: Thu Mar 14, 2013 12:13 am
So I figured out what to change within the sketch to use with a mega.I also added some code to the loop to see each channel intensity in 0-100%.

Code: Select all
for (int i = 0; i < 8; i++) { 
        Serial.print(" ");
      if (ChannelValue[i] < 10)
        Serial.print(" ");
      else if (ChannelValue[i] < 100)
        Serial.print(" ");
        Serial.print(map(ChannelValue[i], 0, 255, 0, 100));
        Serial.print(" ");
      }

Posts: 2
Joined: Fri Mar 22, 2013 12:06 pm
PostPosted: Mon Mar 25, 2013 4:58 pm
So my (first) question is why did you go the route of making this a PWM expansion from the start?It seems like in doing so you automatically limit or make things more difficult to communicate with the Portal and the Controller.

Being somewhat new to RA but well seasoned with Arduino I may be missing the reason but it seems like the code could pretty easier just as well work if flashed to the controller instead.

Just curious as taking apart the PWM to flash changes seems like an extra step without any real benefit other than maybe saving memory space on the controller.

Thanks!
User avatar
Posts: 5416
Joined: Fri Jul 20, 2012 9:42 am
PostPosted: Mon Mar 25, 2013 5:17 pm
I think it was initially a memory decision. This code may even be out pre ra+ the independent sunrise/sunset class can be used on the main unit and this code could probably be easily ported for the main unit as well.

Posts: 293
Joined: Tue Oct 25, 2011 7:39 am
PostPosted: Fri Mar 29, 2013 11:00 am
This was indeed created pre RA+ and was specifically coded on the PMW expansion module as the older (and many are still current use) RA controllers were pretty constrained with respect to memory and thus to enable full use of the controller I wrote it to be run on the PMW board since it of course has a processor equivalent to the original RA. I am actually going through this code and restructuring it into compact subs so that it can be more easily incorporated into the library and would then be available to all users regardless of configuration so long as memory was in fact free.


I should also note that there is an error in the code in two places, my recently posted update to allow for PWM intensity alteration during extended photo periods during the summer months has a simple error in the math which I have now corrected. I also found an error in the cloud period calculation that is invisible to the user but results in some differences in length of cloud period throughout the days from what I had intended. I will be posting the new package with compact subs relatively soon. My coding skills have moved significantly as I have been working very intensively on PERL for my job and thus I anticipate that I will likely make wholesale changes to the code base since this code evolved as I in fact taught my self the version of C that arduino makes use of and as anyone who has spent any significant time coding will tell you.... your first efforts, although functional, begin to look pretty darn ugly as you learn.

The reason I have not pushed to get this into the library is that the code is very difficult to maintain currently as some subs are pages long which is a cardinal sin- thus I am repenting for my sins and re-doing his in my limited spare time.

I have also made some more changes to the clouds allowing for random drift to occur between the different colors available so that during clouds the actual color temperature of the tank changes. I had initially thought this would look stupid but I tried it and find that it in-fact is a subtle but noticeable improvement as it adds additional variety.

If your using this code with the day length mods for summer and winter as I posted above your probably keeping up with this and would not mind making the simple changes to the lines I have corrected so if you PM me I can send you the changes to make. If your thinking about using it... maybe give me a week or two to get it reworked and tested then I will see if Kurt has time and interest to incorporate this into the library so all can use it.

The other reason I have not gone so far as to ask for it to be put into the library, is that making changes then becomes a much different task as they would be needed to be pushed into the current implementation of the library and then become part of an update and until I am happy with it being maintainable, error free, and truly worthy of incorporation I was hesitant to push for it being in the library.

I promise to get this out. I had been thinking that very few people were using it and just playing with it on my own but have been made to believe that perhaps there is a wider audience and thus will do my part to ensure that once its "out of my hands" and put into the library, its as good as I can make it and easier to understand.
PreviousNext

Return to My PDE/INO file

Who is online

Users browsing this forum: No registered users and 3 guests

cron