C library for Sun/Moon effects

Do you have a question on how to do something.
Ask in here.
rufessor
Posts: 293
Joined: Tue Oct 25, 2011 7:39 am

Re: C library for Sun/Moon effects

Post by rufessor »

Ok... disregard email with .INO containing debugging...

If your on the other hand willing to help... just run it and copy and paste to an email the serial debugging output.

Hopefully this can be worked out, I am confused to say the least but the new serial debugging code contains EVERY single variable required in the calculation so perhaps I can see whats getting goofed up. I am betting on alien interference at this point.

If this next set is not informative, well... Roberto... you will be getting a PM :)
User avatar
JNieuwenhuizen
Posts: 96
Joined: Thu Feb 16, 2012 12:39 am
Location: South Africa

Re: C library for Sun/Moon effects

Post by JNieuwenhuizen »

LMAO!!! Alien interferance :lol:
rufessor
Posts: 293
Joined: Tue Oct 25, 2011 7:39 am

Re: C library for Sun/Moon effects

Post by rufessor »

Small update.

I have to admit to having little insight into how we are getting the correct day lengths for any location on the globe- regardless of which set up is computing it... but somehow the conversion to real time rise and set is simply wrong. Its seems that no matter what I feed it, real GMT time, Local time, or any combination of processor clock and corrections to GMT... its getting correct day lengths but the rise and set times are simply not meshing with the input, they are often a little bit behind the input time, they are in fact mostly correct because if I push it and feed the function times that are behind or ahead of the current day the rise and set times change by 84600 or very close to that- which is exactly a day... so its advancing them correctly. I need to sit down and start looking at what the offset is and if its a fixed number or ratio or something to see if I can code in a "fix" I wish I could say I have a handle on this... but its really odd- It may be some time before I can offer help but I am looking at it.
chort55
Posts: 50
Joined: Sun Mar 18, 2012 8:22 pm

Re: C library for Sun/Moon effects

Post by chort55 »

I have been following for quite a while now, and often confused (coding isn't an area I have any knowledge in really, bought the controller from another guy who lied about setting it up for me and screwed me over royally....) :(

Just wondering though, are you setting LED's to follow like a sun path (I'm 99.99% sure you are, but want to make sure I have been following correctly lol)? As in, rise at say 6:00 am, and go down at 9:30pm like they are roughly here..... thats a LOOONG time to be running high powered LED's and would more then likely cook even the most light craving SPS, granted they would only be at 100% for a few hours I'd assume, but still seems like it may be a bit much. If I am misunderstanding this I am sorry.

Also, if they are "a little bit behind" could this possibly be just a timing issue with the internal clock on the module/ controller... or the timing is set from the day the code was created/ 1st uploaded so it sets it behind slightly compared to the current testing day since you made changes it "resets" the date/ time possibly??

I wish you all luck in figuring it out so I can give it a try. I'd love to help "get it right" but I would probably just screw things up more unfortunately.
rufessor
Posts: 293
Joined: Tue Oct 25, 2011 7:39 am

Re: C library for Sun/Moon effects

Post by rufessor »

Hi and thanks for following-

Yes, I am programming the LED to follow a "sun like path" in that they start (you can modify this) at sunset and finish at sunrise. However, I am also calculating what the intensity of solar radiation would be every 3 seconds between sunrise and sunset with the MAX solar irradiation intensity being defined as being midway between sunrise and sunset- the LED are then programmed to run between 0-100% of their intensity set point (you set what you want their "noon" max intensity to be) throughout the day, this function is a cosine so it starts at basically zero at sunrise and then follows the cosine to 100% intensity at noon and then back to zero at sunrise.... so although it seems like a long time to run your LEDs, they are only on at full intensity for a few hours around noon. The cosine function modulates their output throughout the day, as close to the actual variation in sun intensity as I could get it.... thus its not really all that intense overall. For instance, I have a 3 ft long 2ft deep tank 18 inches wide, with 56 LEDs (48 Cree XP-G and XP-E and 8 True VIolet) and I have them very near to 100% output (but I am constraining them to about 80% max current on the drivers) and my corals actually colored up MORE when I started this program (its been about a month now) because there is actually LESS light than the standard 10-12 hour cycle of steady intensity. I was bleaching things before and was going to lower my intensity- then I started this program... and its all good.
rufessor
Posts: 293
Joined: Tue Oct 25, 2011 7:39 am

Re: C library for Sun/Moon effects

Post by rufessor »

its 100% fixed. The error was very deep in my understanding of just exactly WHAT the system clock was referencing as time. I simply did not understand the relationship between the clock on our hand and the clock in the arduino processor. They both show the same time but the one in the processor actually thinks its on GMT time, i.e. it thinks that its in Greenwhich England (if you want to think of it that way) and that the prime meridian comes directly though your house... so There is absolutely NO NEED to correct for your actual GMT offset, the processor is in GMT its just that every processor from different parts of the world thinks that GMT midnight=local time midnight. So... this makes all my work to fix this, completely barking up the wrong tree. It also makes making it work very simple indeed.

New code will be posted by tomorrow. GMTOffset is now removed, you no longer have to care about time period, at all... all you need to do is plug in your Lat and Lon coords and it will work. I am 100% certain this is fixed, everything that was not working now makes 100% perfect sense as to why it was not working and will never work. In the end, this was a great error to have, I learned a lot- and Roberto was trying to tell me how this worked from the beginning, but I just could not conceptualize it as I was so hung up on time zones, DST, lat on, and GMToffsets I never really totally 100% checked and confirmed i knew what the system clock was doing..... as they say.. I ASSuMEd... and it made an Ass out of ME! Thats for sure! :mrgreen: :roll: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops:
rufessor
Posts: 293
Joined: Tue Oct 25, 2011 7:39 am

Re: C library for Sun/Moon effects

Post by rufessor »

Lets give this a try.....

You will want to change the latitude and longitude lines to your region (REMEMBER TO USE THE CORRECT SIGN...).

This is the entire top part of the code up to this line in the CalSun function.. you will need to copy and paste in your settings. There IS NO GMToffset... it was not required and an error on my part to even include it in trying to fix this... Just copy over the set up section. The top part with all the ChMax etc etc and then the latitude and longitude which a grouped with ChOffset in the CalSun function... so anything you need to deal with is grouped into two segments. Remember if you copy and paste you old stuff... DELETE GMToffset its no longer in the code and you will get a compile error if you leave that line in.


these last lines are in the copy and paste below, but should be the same in your copy so copy up to them or whatever just dont go past it or duplicate them....

so you end here but look at the code segment... it contains these lines as a marker for you to see the end as continuous with your code. Copy everything from this to the top, delete and insert code below- then edit as appropriate and noted above. DELETE GMToffset from anything you copy from old code with that in it. Good luck

//Calculate rise and set times for all channels in equivlants to elapsed seconds from midnight today
//populate array for chRise and Set as well as chSlope for 0.5pi/ half day lenght for each channel from midday (asymmetric days are allowed)
float deltaY=1.570796327;//1/2 * pi as integer by scaling* 10^9 to fill UL
midDay=(((set-rise)/2)+rise);
long HalfDayLength=((set-rise)/2);
//Serial.print("MidDay");
//Serial.println(midDay);[/code]

Code: Select all

//By Matthew Hockin 2012.  
//SWFLTEK library functions, #includes, and #define were copied directly from the Epherma library
//Epherma (SWFLTEK.com) was written by Michael Rice- thanks Michael it works great. 
//If you copy from this (its all open source) please 
//acknowledge Michael for SWFLTEK library code (obviously labeled) or Matthew Hockin (for the rest).

#include <Time.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <avr/wdt.h>
//includes for SWFLTEK functions
#include <stdlib.h>
#include <math.h>


//***********************************ARRAYS YOU MUST MODIFY TO MAKE YOUR TANK SET UP WORK*****************************
//YOU MUST READ EVERY WORD IN THIS SECTION IN ORDER TO APPROPRIATELY CONFIGURE THIS PROGERAM- READ EVERY LINE BELOW///
byte ChMax[]={200,220,200,220,225,0,0,0};//Incremental value (Max-flicker) above flicker you want as max intensity (!!!!!!! Light Set Point is ChMax PLUS Flicker !!!!!!) 
byte flicker[]={31,30,31,30,28,0,0,0};//need to input actual values here for flicker point on all channels in PWM expansion box
boolean Wchannel[]={1,0,1,0,0,0,0,0}; //use 1 to designate white channel (i.e. off during storm and used for lightning).  Array corresponds to PWM channel 0-5 in order
//Array to give direction to dimming.  e.g. DimOrder[]={0,0,1,1,0,0} (cloud chase effects, just group channels you want to dim together during a cloud or storm 
//as either a 0 or a 1, i.e. all left side channels are 0 all right are 1 or all front are 0 all back are 1 or whatever
//(which is zero or 1 will change who dims first).  set them all to 0 if your tank has no left/right or front/back lights.
byte DimOrder[]={0,0,1,1,1,0,0,0};
//set all channel positions that you would like to use for the lightning strike effect to 1 (0-5 are PWM channels 6,7 are Main PWM outs)- and channels with a 0 are not used in strike
byte StrikeChannel[]={1,1,1,1,0,0,0,0};
//**********************************DONE CHANGING THINGS HERE BUT YOU MUST CHANGE ChOffset array IN CalcSUN function******


//defines for SWFLTEK functions
// arc-seconds per radian
#define _sec_rad 206264.806247096370813

// axial tilt of earth at epoch, in radians
#define _tilt 0.409092804222329

// tropical year in seconds... rounding error accumulates to 26 seconds by the year 2136
#define _tropical_year 31556925

// 'zenith' of rising (setting) sun in radians (360 - 2 * 90.833 degrees)
#define _zenith 3.11250383272322

//*******************GLOBAL VARIABLE DECLERATIONS FOR MHOCKIN Weather package*************************************
//Unless your planning on editing the program DO NOT CHANGE ANYTHING HERE
long latitude, longitude;
byte TrueIntensity[8];//array used to place hold final write values for PWM intensity setting
long elapsedTime;//used multiple places as elapsed since midnight
long newDay;
unsigned long rise;//time in seconds from the year 2000 (GMT) for sunrise
unsigned long set;//time in seconds from the year 2000 (GMT) for sunrise
long ChRiseSet[16];//times of rise and set for all 8 channels based upon offsets from calc rise and set values
float ChSlope[16];//slopes for 1/2 day calculations based upon time from offset to midday for channel 1-8
long CloudMaster[20];// Set up array to hold start and end times for clouds for the day-
long midDay;// exactly 1/2 way between rise and set, i.e. solar noon for latitudes <60 close enough for us... 
byte PWMports[] ={
    3,5,6,9,10,11};
byte ChannelValue[8];// Array to store output of insolaiton which may be modified and stored in TrueIntensity which is used to write to the PWM channels
unsigned long StrikeStart;//timer to keep track of strike sequence
int StrikeMaster[20];//Array to hold random strike pattern generated by weather array is sized to MAX needed given strike patter generator (8 strikes=16 positions)
byte StrikeNumber;//place to hold total number of strikes this sequence
boolean StrikeNow;//starts lightning strike sequence in loop state change made in weather/storm loop
byte StrikeCount;//Used to properly sequence strike sequence for delay between strikes
byte cmdnum=255;
byte datanum=255;
byte dow=0;//day of week
boolean trigger; //used a few places as a switch to ensure things only run 1x when needed trigger 2 is for daily reset of sunrise sunset
byte strikePattern, strikeTime;//used in Lightning() for timing of particular instance of strike 
boolean Cloud;// are we in a cloud interval on days that have clouds
boolean CloudToday;//set in CalcSun if randomization yields a day with clouds.
boolean IsStorm;// are we in a storm
byte CloudsTotal;// how many clouds today
long lastmillis;// variable to track millis to enable cloud and insolation loop restriction by time
boolean StormAdvance;//storm timer for light effect advance
boolean InsolationAdvance;//when true we recalculate light intensity during clear sky (every 3 seconds seems more than often enough)
byte counter;//used to track millis advance for insolation,cloud trigger
//****************************************
//END HEADER/Global Variable declaration//
//****************************************

//Setup
void setup(){
    Serial.begin(57600);
    Wire.begin(8);
    //Wire.onReceive(receiveEvent);
    //Wire.onRequest(requestEvent);

    pinMode(3,OUTPUT);
    pinMode(5,OUTPUT);
    pinMode(6,OUTPUT);
    pinMode(9,OUTPUT);
    pinMode(10,OUTPUT);
    pinMode(11,OUTPUT);
    wdt_enable(WDTO_1S);
    unsigned long seed=0, count=32;
    while (--count){
      seed = (seed<<1) | (analogRead(5)&1);
    }
      randomSeed(seed);//start random generator at a different point each time (not perfect but whatever its gonna be pretty damn random)
    setSyncProvider(RTC.get);   // the function to get the time from the RTC
    setSyncInterval(SECS_PER_HOUR);  // Changed to sync every hour.
    
    dow=0;//set Day Of Week (dow) to a 0 value which is impossible (day()=1-7)... so we trigger calcSun on restart 
    StrikeNow=false;//no lightning strike yet
    CloudToday=false;//set to no clouds so CalcSun can set correctly if should be true
    Cloud=false;//set cloud to false
    IsStorm=false;//set storm to false
    lastmillis=millis();//start our millis timer now
    counter=0;//used in weather for triggering a storm, triggering lightning in a storm.
    StrikeCount=0;//Number of lightning strikes in the sequence.. set to zero until initialized in sequence
}
//End Setup
//*********************************************************************************************************************************

//*********************************************************************************************************************************
//Loop
void loop(){ 
    elapsedTime=(now()-newDay);//Elapsed time is seconds from midnight of today- local processor time.
    wdt_reset();
    if (cmdnum!=255){
        ProcessCMD(cmdnum,datanum);    
        cmdnum=255;
        datanum=255;
    }
    
    if (dow!=day()){ //used to see that were in a new day and need to recalculate sunrise and sunset
      trigger=true;//on reset this will also be true as numbering is 1-31 max
      //Serial.println("We set trigger to true");
      dow=day();//now set dow to actual day numbering so that at midnight/new day we again calc sunrise sunset
    }
  
    //Use millis to enable tracking of time interval
    if ((millis()-lastmillis)>=100){
        lastmillis=millis();
        counter+=1;
        StormAdvance=true;
        //now a bunch of stuff that may or may not be true at the same time but that all needs to happen when its true
        if (counter==0){
          InsolationAdvance=true;//so that it runs on start up to provide light immediately 
        }  
        if (counter%30==0){
          InsolationAdvance=true;
          /*long dayleft=set-elapsedTime;
          Serial.print("Day remaining=");
          Serial.println(dayleft);
          Serial.print("elapsed time in seconds from midnight is =");
          Serial.println(elapsedTime);
          Serial.print("cloud=");
          Serial.println(Cloud);
          Serial.print("IsStorm=");
          Serial.println(IsStorm);*/
        }
        if (counter==210) counter=0; 
    }     

   if (trigger==true) CalSun();// calculate rise set, clouds.
   if (InsolationAdvance==true) Insolation();//calculate clear sky solar intensity as the day advances
   Weather();//run the weather overlay (cloud, storm)
   //check to see if were need to have a lightning strike
    if (StrikeNow==true){
       if ((millis()-StrikeStart)>=StrikeMaster[(StrikeCount*2)]){//check if time has passed the delay (position 0,2,4,6,8 etc in StrikeMaster)-StrikeCount is indexed up by 1 after each strike so we see positions 0,2,4,6,etc in sequence
          byte intensity;
          intensity=random(180,256);// this little bit should generate a randomly bright flash variation between the series of flashes in StrikeMaster
              for (byte b=0; b<6; b++){
                  if (StrikeChannel[b]==1) analogWrite(PWMports[b],intensity);// set all strike channels to intensity of strike
              }
          delay(StrikeMaster[((StrikeCount*2)+1)]);//index to +1 position in array from 0,2,4, etc to 1,3,5 etc
          StrikeCount++;//so that the next time we look at elapsed time were looking at the right array position
          if (StrikeCount==(StrikeNumber-1)){
            StrikeNow=false;
            StrikeCount=0;
          }
       }
    }
    for (byte a=0;a<6;a++){//using all prior mods to light intensity (Insolation-->Cloud-->Storm) lets make some light
      analogWrite(PWMports[a],TrueIntensity[a]);//dont change this to 8 to refelct array for channels.. we only have 6 here!
    }
}
//End Loop
//*********************************************************************************************************************************

//*********************************************************************************************************************************
//Standard PWM Functions Receive/Process
void receiveEvent(int howMany) {
    wdt_reset();
    if (howMany==5){
        byte cmd1, cmd2, cmd3, cmd4, cmd5;
        cmd1=Wire.read();
        cmd2=Wire.read();
        cmd3=Wire.read();
        cmd4=Wire.read();
        cmd5=Wire.read();
        if (cmd1=='$' && cmd2=='$' && cmd3=='$'){
            cmdnum=cmd4;
            datanum=cmd5;
            //Serial.println(cmd4,DEC);
            //Serial.println(cmd5,DEC);
        }
    }
    else{
        for (int a=0;a<howMany;a++){
            Wire.read();
        }
    }  
}

void ProcessCMD(byte cmd, byte data){
    wdt_reset(); 
}

//End Standard Functions
//*********************************************************************************************************************************
//Start of sunrise, sunset and cloud calculations- runs on reset and once a day thereafter.
void CalSun(){
   //Serial.println("CalSun Run Now");

        //*********************YOU NEED TO CHANGE THESE VALUES Read instructions in their ENTIRETY and CAREFULLY change to values for your tank and geographical region***************************
        //channels 0-5 are PWM expansion board lights 6,7 are ReefAngel Controller PWM outputs
        //offsets for rise/set all values in seconds offset from calculated rise or set value (-) am offset=longer day****** (-)pm offset=shorter day)
        //array order is ch0 am offset, pm offset, ch1 am offset, pm offset etc..
        //THESE values are the number of seconds that a particular channel will be offset from the rise/set time, i.e. negative to rise earlier/set earlier
        int Choffset[]={
            -600,0,-1800,6000,0,600,-1200,6600,-2200,6600,0,0,0,0,0,0};
        // NOW SET YOUR LATIDTUDE AND LONGITUDE COORDINATES as Degrees, Minutes, Seconds of Lat and Lon
        //If Your NORTH of the equator your LONGITUDE must START with a NEGATIVE number (the rest are positive) e.g. All of North America, Europe, Russia etc are negative
        //If Your EAST of the Prime Meridian your LATITUDE must START with a NEGATIVE number (the rest are positive), e.g. Most of Europe, All of China, India, Austraila, Russia etc are negative
        latitude=dmsToSeconds(-25,87,13); //Set to Witbank - South Africa
        longitude=dmsToSeconds(29,23,32); //Set to Witbank - South Africa
        //latitude=dmsToSeconds(40,44,00);//United States of America- Salt Lake City, local time is -7 hours GMT 
        //longitude=dmsToSeconds(-111,47,00);
        //**********************ok now were done changing things IF YOU CHANGED the Top part of the GLOBAL variable decleration AND this... your FULLY configured and ready to load******************************************** 
        
   trigger=false;//we only run once a day... or on a restart
    long hours, minutes;//store current elapsed local hours as total seconds from midnight
   
    time_t t=now();//store current clock time then parse to hour and minutes of current day using time.h functions
    hours=hour(t);
    minutes=minute(t);
    hours=(hours*3600);//convert to seconds
    minutes=(minutes*60);//convert to seconds
    
    newDay=now()-(hours+minutes);//Convert current local unix epoch time to local unix epoch time of midnight 
    //#define SECS_YR_2000 (946684800) the time at the start of y2k (need to subtract from unix epoch time to bring to Y2K origin
    newDay-=946684800;//convert GMT unix Epoch to seconds elasped since 2000 for GMT midnight of today
    
    rise=newDay;//set value to send to SunRise as midnight GMT in seconds from Y2K
    set=newDay;//
    //Calculate rise time and set time using Epherma Library functions (see end of code) 
    SunRise(&rise);//call to Epherma function
    SunSet(&set);//Call to Epherma functionunsigned long newDay;
    //set rise to elapsed time of day... its currently in seconds since 2000 for today rise time 
  /* Serial.print("rise and set=  ");
   Serial.println(rise);
   Serial.println(set);
   Serial.print("newDay=  ");
   Serial.println(newDay);*/
   
    rise=(rise-newDay);
    set=(set-newDay);
   /*Serial.print("rise and set as elapsed seconds of day=  ");
   Serial.println(rise);
   Serial.println(set);*/
   
    newDay+=946684800;//Convert current local to midnight 
   /*Serial.print("newDAy=  ");
   Serial.print(newDay);
   Serial.print("elapsed is");
   long elapsed=now()-newDay;
   Serial.println(elapsed);*/
   
   
   
   
    
        //Calculate rise and set times for all channels in equivlants to elapsed seconds from midnight today
        //populate array for chRise and Set as well as chSlope for 0.5pi/ half day lenght for each channel from midday (asymmetric days are allowed)
        float deltaY=1.570796327;//1/2 * pi as integer by scaling* 10^9 to fill UL
        midDay=(((set-rise)/2)+rise);
        long HalfDayLength=((set-rise)/2);
        //Serial.print("MidDay");
        //Serial.println(midDay);
rufessor
Posts: 293
Joined: Tue Oct 25, 2011 7:39 am

Re: C library for Sun/Moon effects

Post by rufessor »

Ok-

I have confirmation that the newest code is fixed and we are getting rise and set times for LED PWM lights over a tank in South Africa that correspond exactly with the rise and set times of the sun out the window.

In order to simplify the process of individual users installing this code on their PWM modules and using the lighting effects it offers-

I am starting two new threads. The .INO FILE you NEED to download, modify and install on your PWM module is going to live in a thread titled

"Weather Simulation for PWM expansion module"
http://forum.reefangel.com/viewtopic.php?f=11&t=1450

Please go here if you want to download a working complete version of this code. This thread will stay active as I add new features (COMM is being worked on as of now). So if you want to help test/develop this is where you need to look. If you just want the latest complete working version of the code..... link is above.
JoelIreland
Posts: 58
Joined: Sat Jan 26, 2013 1:27 am

Re: C library for Sun/Moon effects

Post by JoelIreland »

Hey all
I have just got a retro kit from Steve's LEDs for my Red Sea Max 650.
I have installed the kit and now want to add the dimmer expansion module to control sunrise sunset ( in Australia )
I already have the module and have been following this thread. The issue I am having is when i plug the module in to the PC to upload the code, it comes up with either faulty or unknown USB Device.
I run an IT company so this sort of thing is second nature but still having issues with it.

My question is, what is the best way for me to do this? and what code should I be using from GIT to control 4 chanels.

Thanks all
Joel
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: C library for Sun/Moon effects

Post by rimai »

This would only apply to a very early module.
The new generation is not programmable anymore.
The code needs to be ported to run in the head unit for this to work.
Roberto.
JoelIreland
Posts: 58
Joined: Sat Jan 26, 2013 1:27 am

Re: C library for Sun/Moon effects

Post by JoelIreland »

Yeah figured out how to use the sun library. Weird thing is for my lights -100 Turns lights bright where as 100 turns them off. Any ideas
JoelIreland
Posts: 58
Joined: Sat Jan 26, 2013 1:27 am

Re: C library for Sun/Moon effects

Post by JoelIreland »

Just an update. I think I have this working but the time is out as we are in Australia. Does anyone know the best way to adjust to match Brisbane time? Also anyone done any coding with storms using the dimmer expansion? Thanks.
User avatar
Rodasphoto
Posts: 187
Joined: Wed Apr 10, 2013 2:48 pm
Location: Athens, Ga
Contact:

Re: C library for Sun/Moon effects

Post by Rodasphoto »

JoelIreland wrote:Just an update. I think I have this working but the time is out as we are in Australia. Does anyone know the best way to adjust to match Brisbane time? Also anyone done any coding with storms using the dimmer expansion? Thanks.
Their is a way to have storms using dimming expansion but the code is uploaded to the dimming expansion. I would love to see/hear if there is another way.
Image
JoelIreland
Posts: 58
Joined: Sat Jan 26, 2013 1:27 am

Re: C library for Sun/Moon effects

Post by JoelIreland »

Happy to upload to it if anyone can explain how. Have 1.2 version.
Post Reply