Programming Question / Help

I was hoping someone could help me out. I striped out the (moon code) from my complete code thinking it had a conflict with the sunrise / sunset calculations. But it does the same thing.

The problem is... It sort of re-sets every hour. For example, intensity will ramp up to 58% @ 10:59 {then} 40% @ 11:00. Then it will start ramp up again. Same thing after midnight. Example, ramp down to 25% @ 12:59 {then} 45% @ 1:00. Then it starts ramp down again.

Now in the code you will see 2 different calculations. It"s the only way I could get it to ramp up to midnight - then ramp down to my set off time.

Any help getting it to stop resetting every hour would greatly be appreciated.

Ok, Hope I did it right. Sort of new to forum postings.

#include <Wire.h> 
#include "RTClib.h"

RTC_DS1307 RTC;
 
// Moon Pins //
int Moon = 9;          // PWM pin for moon leds
int MoonLow = 3;      // Starting value for moon intensity
int MI;                //Maximum Illumination of Moon (User Defined/Set in Prog. -- Default = 0)


/*||||||||||||||||||||||||||||||||||  D E F I N E  :  L U N A R P H A S E ||||||||||||||||||||||||||||||*/ 
float LC = 29.53059;         //1 Lunar Cycle = 29.53059 days
String LP;                   //Lunar Phase - variable used to print out Moon Phase
int moonled_out;
int moonled_out2;

float moonPhase(int moonYear, int moonMonth, int moonDay)
{ 
  float phase;
  double AG, IP; 
  long YY, MM, K1, K2, K3, JulianDay; 
  YY = moonYear - floor((12 - moonMonth) / 10); 
  MM = moonMonth + 9;
  if (MM >= 12)
    { MM = MM - 12; }
  K1 = floor(365.25 * (YY + 4712));
  K2 = floor(30.6 * MM + 0.5);
  K3 = floor(floor((YY / 100) + 49) * 0.75) - 38;
  JulianDay = K1 + K2 + moonDay + 59;
  if (JulianDay > 2299160)
    { JulianDay = JulianDay - K3; }
  IP = MyNormalize((JulianDay - 2451550.1) / LC);
  AG = IP * LC;
  phase = 0; 

  Serial.println("");
  Serial.print("Julian Day: ");
  Serial.println(JulianDay);
  Serial.println(AG);
  //Determine the Moon Illumination %
  if ((AG >= 0) && (AG <= LC/2))            //FROM New Moon 0% TO Full Moon 100%
    { phase = (2*AG)/LC; }
  if ((AG > LC/2) && (AG <= LC))            //FROM Full Moon 100% TO New Moon 0%
    { phase = 2*(LC-AG)/LC; }

  //Determine the Lunar Phase
  if ((AG >= 0) && (AG <= 1.85))             //New Moon; ~0-12.5% illuminated
    { LP = "New Moon"; }
  if ((AG > 1.85) && (AG <= 5.54))           //Waxing Crescent; ~12.5-37.5% illuminated
    { LP = "Waxing Crescent"; }
  if ((AG > 5.54) && (AG <= 13.15))           //First Quarter; ~37.5-62.5% illuminated
    { LP = "First Quarter"; }
  if ((AG > 13.15) && (AG <= 12.92))          //Waxing Gibbous; ~62.5-87.5% illuminated
    { LP = "Waxing Gibbous"; }
  if ((AG > 12.92) && (AG <= 16.15))         //Full Moon; ~87.5-100-87.5% illuminated
    { LP = "Full Moon"; }    
  if ((AG > 16.15) && (AG <= 22.15))         //Waning Gibbous; ~87.5-62.5% illuminated
    { LP = "Waning Gibbous"; }
  if ((AG > 22.15) && (AG <= 23.15))         //Last Quarter; ~62.5-37.5% illuminated
    { LP = "Last Quarter"; }
  if ((AG > 23.15) && (AG <= 29.15))         //Waning Crescent; ~37.5-12.5% illuminated
    { LP = "Waning Crescent"; }
  if ((AG >= 29.15) && (AG <= LC))           //New Moon; ~12.5-0% illuminated
    { LP = "New Moon"; }
    
  return phase; 
}

/******* Normalization Function *******/
double MyNormalize(double v) 
{ 
v = v - floor(v);
 if (v < 0)
 v = v + 1;
 return v;
} 

void setup() 
{ 
    Serial.begin(57600); 
    Wire.begin(); 
    RTC.begin();

    // Set the led pinmode //
    pinMode(Moon, OUTPUT); 
   
    }
 
void loop() 
{ 
    static char *buf = (char*)calloc(20, sizeof(char*));
    
    DateTime now = RTC.now();
    
    { 
        
        // Use standard date/time format MM/DD/YYYY HH24:MI:SS.
        sprintf(buf, "%02d/%02d/%04d %02d:%02d:%02d", now.month(), now.day(), now.year(), now.hour(), now.minute(), now.second());
 
        Serial.println(buf);
 
                     
    /*|||||||||||||||||||||||||||||||||||||||||||||||  L U N A R (LED) |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*/ 
    }
    //--------MOON LED SETUP----------//
    float lunarCycle = moonPhase(now.year(), now.month(), now.day()); //get a value for the lunar cycle
    float moon_out = 0.0;
  
        moonled_out = MoonLow *(2.2 - lunarCycle) +            
                   MI * lunarCycle + .5;       
        moonled_out2 = MoonLow *(3.5 - lunarCycle) +            
                   MI * lunarCycle + .5;       
        
    if ( ((now.hour() == 2) && (now.minute() < 30)) || (now.hour() < 2))   // Off at 3:45 am.
    {
        moon_out = moonled_out2 - ((((float)now.hour() - 24) + ((float)now.minute() / 4)) / 2);
    }
    else if (now.hour() > 14) 
    {    
        moon_out = moonled_out * ((((float)now.hour() - 15) + ((float)now.minute() / 38)) / 2);
    }
   
    analogWrite(Moon, moon_out); 
        
  //Print the Lunar Cycle
  Serial.print("LunarCycle: ");  
  Serial.println(lunarCycle);
  Serial.print("Phase: ");  
  Serial.println(LP);
  Serial.print(moon_out);  
  Serial.println("% of FULL");
  Serial.println(" ");

  delay(2000);

}

Just_My_Moon.ino (4.3 KB)

Please edit your original post and paste your code text, rather than downloads. It makes it much easier for people to help you.

When you paste the text, make sure you put it inside ... tags so it looks like this:

code here...

weasel440:
Any help getting it to stop resetting every hour would greatly be appreciated.

It would speed things up a lot if you can provide an explanation of what each part of your code is supposed to do.

...R

It seems complicated, but i'm not having any problems with the rest of the code. It reads the correct phase and so on. I just thought people would ask to see the whole code.

I'm no expert, but i think it has to do with the way this is written why it keeps re-setting intensity every hour. I've read a lot about the language reference. But i still could not get it to work right. Either it didn't ramp OR when i got it to ramp up / down correctly without re-setting every hour it wouldn't turn off. Or if i got it to turn off at specific time it wouldn't turn back on.

Like i mentioned, i have it so it ramps till midnight (moonled_out) - then at midnight it ramps down (moonled_out2) to specific off time.

if ( ((now.hour() == 2) && (now.minute() < 30)) || (now.hour() < 2))   // Off at 3:45 am.
    {
        moon_out = moonled_out2 - ((((float)now.hour() - 24) + ((float)now.minute() / 4)) / 2);
    }
    else if (now.hour() > 14) 
    {    
        moon_out = moonled_out * ((((float)now.hour() - 15) + ((float)now.minute() / 38)) / 2);
    }
   
    analogWrite(Moon, moon_out);

This minus doesn't look right by itself to me:

moon_out = moonled_out2 - ((((float)now.hour() - 24) + ((float)now.minute() / 4)) / 2);

surely that should be

moon_out = moonled_out2 * ... some maths missing here.... ((((float)now.hour() - 24) + ((float)now.minute() / 4)) / 2);

if ( ((now.hour() == 2) && (now.minute() < 30)) || (now.hour() < 2)) // Off at 3:45 am.

When the useless comment doesn't agree with the code, what purpose does it serve?

arduinodlb:
This minus doesn't look right by itself to me:

moon_out = moonled_out2 - ((((float)now.hour() - 24) + ((float)now.minute() / 4)) / 2);

surely that should be

moon_out = moonled_out2 * ... some maths missing here.... ((((float)now.hour() - 24) + ((float)now.minute() / 4)) / 2);

I did the "minus" to get the correct intensity for after midnight 12:00 am.
But I did try it with the *, and it didn't make a difference with the problem i'm having.

PaulS:
When the useless comment doesn't agree with the code, what purpose does it serve?

Don't understand what you mean useless comment? If i take any of them out. It won't verify / compile.

weasel440:
Don't understand what you mean useless comment? If i take any of them out. It won't verify / compile.

Well, it says 3:45 when the code checks 2:30, so it's wrong. You can always take out comments and code will still compile, so I don't know what you're doing there.

weasel440:
I did the "minus" to get the correct intensity for after midnight 12:00 am.
But I did try it with the *, and it didn't make a difference with the problem i'm having.

Don't just change it to a *, check the maths.

Try this (untested):

    int minutes = (now.hour() * 60) + now.minute();

    if ( minutes < 150) 
    {
        moon_out = moonled_out2 - (moonled_out2 * ((float)minutes / (float)150));
    }
    else if (now.hour() > 14) 
    {    
        minutes = ((now.hour() - 14 ) * 60) + now.minute();
        moon_out = moonled_out * ((float)minutes / (float)((24 - 14) * 60));
    }

arduinodlb:
Well, it says 3:45 when the code checks 3:30, so it's wrong. You can always take out comments and code will still compile, so I don't know what you're doing there.

It's my fault. I didn't change / remove that. // Off at 3:45 am. I see how that would be confusing, when asking for help.
I currently have it set to turn off at 2:30 according to sketch.

Why are you using

static char *buf = (char*)calloc(20, sizeof(char*));

instead of

char buf[20] = {0};

?

Also, can you add some comments to your code so we know what it is supposed to be doing? Its rather cryptic right now

weasel440:
It seems complicated, but i'm not having any problems with the rest of the code. It reads the correct phase and so on. I just thought people would ask to see the whole code.

I did not mean that I did not want to see the whole code.
But, as you say yourself "it seems complicated" and I am lazy so I thought you would be prepared to write a few sentences explaining how the code is intended to work.

I find it a great help to have an overview of the code when trying to see problems rather than start by studying the syntax of individual lines and their comments.

But perhaps I am odd.

...R

Robin2:
I did not mean that I did not want to see the whole code.
But, as you say yourself "it seems complicated" and I am lazy so I thought you would be prepared to write a few sentences explaining how the code is intended to work.

I find it a great help to have an overview of the code when trying to see problems rather than start by studying the syntax of individual lines and their comments.

But perhaps I am odd.

...R

That would make 2 of us being odd. :o

arduinodlb:
Try this (untested):

    int minutes = (now.hour() * 60) + now.minute();

if ( minutes < 150)
    {
        moon_out = moonled_out2 - (moonled_out2 * ((float)minutes / (float)150));
    }
    else if (now.hour() > 14)
    {   
        minutes = ((now.hour() - 14 ) * 60) + now.minute();
        moon_out = moonled_out * ((float)minutes / (float)((24 - 14) * 60));
    }

TY.
I did test it last night. It did ramp down & turn off, but it was already after midnight to test if it turns on, how it ramps, and transitions at 11:59 to 12:00.
I plan on testing later this evening.

weasel440:
TY.
I did test it last night. It did ramp down & turn off, but it was already after midnight to test if it turns on, how it ramps, and transitions at 11:59 to 12:00.
I plan on testing later this evening.

if you want to test at other times of the day, you can replace the direct calls to now.hour() and now.minute() with new variables called hour and minute, then set them yourself. If it were me, I'd run these variables through a for loop to see what happens. You should also check the maths to make sure it should be doing what you want it to do.

I thought about testing earlier, but I figured I would be nice to the fish and not scare them with flickering lights.

Plus my wife makes sure I have enough chores to keep me busy all day.

Ok... seems to be fixed, with a few minor math adjustments for intensity of moon light.

arduinodlb, i would like to say thank you again for the help.

weasel440:
Ok... seems to be fixed, with a few minor math adjustments for intensity of moon light.

arduinodlb, i would like to say thank you again for the help.

No problem. Glad you got it working.