Sun position example

The example given in Arduino for the suns position doesn't work. Before I was aware of this example I made my own sketch for the suns position. My guide was an article on the web called 'the suns position_pv education'. This sketch gives the correct elevation and azimuth. The online free app I use is called 'the suns position in Kalgoorlie now'. The sketch gives the same E and A as in the app.
I want to use the sketch with the RTC DS3231. In the serial monitor you have to enter only the local time and the number of days elapsed since Jan 1. You would need more coding to give days lapsed from the date returned on the RTC.
Then you want the MCU and RTC to be completely automatic without having to put in manually the local time and days elapsed. Most of the coding could be included in a library preferably because it is complicated. It certainly was a very smart guy that worked out all this for the celestial movement of the sun.

float b;  //b =360/365(d-81) d is number of days since start of year 6-7 decimal points
float lt;//local time
float tc;//time correction factor
float lst;  //local standard time
int d;    //days since the start of the year
float eot;  //equation of time
float hra;
float r;   //this is radians for arduino

float s;
float s1;
float l;    // longitude
float u;    // latitude
float a;    // elevation angle in radians
float a1;   // elevation angle in degrees
float az;    // azimuth in radians

float az1;   // azimuth in degrees 
float r1;    //hour angle in radians
float r2;
float r3;
float u1;    
void setup() {
Serial.begin(9600);
u=(-30.74889);     //latitude
u1=(u*PI/180);     // convert latitude to radians
l=(121.465836);    // longitude   
}
void loop() {
Serial.print("input value for variable d: ");
while (Serial.available() == 0) {
  }
d = Serial.parseInt();
Serial.print("d=");
Serial.println(d);
Serial.print("input value for variable lt: ");//this is the local time
while (Serial.available() == 0) {
  }
lt = Serial.parseFloat();
Serial.print("lt=");
Serial.println(lt);

b=(360.0/365.0*(d-81));
r=(b*PI/180);           //b is degrees convert to radians
eot=9.87*sin(2*r)-7.53*cos(r)-1.5*sin(r);//eot is equation of time
tc=4*(l-120)+eot;//tc is time correction factor 121. is longitude 120 is lstm
lst=(lt+(tc/60));// lst is local standard time
hra=15*(lst-12);  //  hra is the hour angle
r1=(hra*PI/180);     // convert to radians
r2=(360.0/365.0*(d-81));//this is degrees
r3=(r2*PI/180);         //convert to radians

s=23.45*sin(r3);    //declination angle in degrees
s1=(s*PI/180);      // angle in radians

a=asin(sin (s1)*sin (u1)+cos (s1)*cos (u1)*cos (r1));// elevation of sun in radians
a1=(a*180/PI);  //convert radians to degrees  
az=acos((sin(s1)*cos(u1)-cos(s1)*sin(u1)*cos(r1))/cos(a));   // azimuth or magnetic compass of sun radians
az1=(az*180/PI);  //convert radians to degrees
Serial.print("a1=");
Serial.println(a1);
Serial.print("az1=");
Serial.println(az1);
}

Yes, and the sextant.

North of equator: "south" east
South of equator: "north" east
I use this daily (I am the stick).

I have a question about the variable d: For January 1, does d equal 0, or does d equal 1 ?

What is lt ? You say it is local time. If, for example, it is 5:15 A.M., what value do you use for lt ? What do you do about Daylight Saving Time?

Is your RTC working? Is it set correctly? Let's find out if it is.
What date and time does this sketch show in your Serial monitor?

#include <Wire.h>

byte ss=0, mi=0, hh=0, wd=6, dd=1, mo=1, yy=0;
 
void setup()
{
  Wire.begin();
  Serial.begin(9600);
 
  // clear /EOSC bit
  // Sometimes necessary to ensure that the clock
  // keeps running on just battery power. Once set,
  // it shouldn't need to be reset but it's a good
  // idea to make sure.
//  Wire.beginTransmission(0x68); // address DS3231
//  Wire.write(0x0E); // select register
//  Wire.write(0b00011100); // write register bitmap, bit 7 is /EOSC
//  Wire.endTransmission();
}
 
void loop()
{
  // ask RTC for the time
  // send request to receive data starting at register 0
  Wire.beginTransmission(0x68); // 0x68 is DS3231 device address
  Wire.write((byte)0); // start at register 0
  Wire.endTransmission();
  Wire.requestFrom(0x68, 7); // request seven bytes (ss, mi, hh, wd, dd, mo, yy)
  // check for a reply from the RTC, and use it if we can
  if (Wire.available() >= 7) {
    // if we're here, we got a reply and it is long enough
    // so now we read the time
    ss = bcd2bin(Wire.read()); // get seconds
    mi = bcd2bin(Wire.read()); // get minutes
    hh = bcd2bin(Wire.read()); // get hours
    wd = bcd2bin(Wire.read());
    dd = bcd2bin(Wire.read());
    mo = bcd2bin(Wire.read());
    yy = bcd2bin(Wire.read());
    // show that we successfully got the time
    Serial.print("Got the time: ");
    printTime();
  }
  else {
    // if we're here, that means we were unable to read the time
    Serial.println("Unable to read time from RTC");
  }
  delay(500);
}

byte bcd2bin(byte x) {
  // converts from binary-coded decimal to a "regular" binary number
  return ((((x >> 4) & 0xF) * 10) + (x & 0xF)) ;
}

void printTime() {
  // just like it says on the tin
  Serial.print ("\'");
  if (yy<10) Serial.print("0"); Serial.print(yy,DEC); Serial.print("-");
  if (mo<10) Serial.print("0"); Serial.print(mo,DEC); Serial.print("-");
  if (dd<10) Serial.print("0"); Serial.print(dd,DEC); Serial.print(" ");
  if (hh<10) Serial.print("0"); Serial.print(hh,DEC); Serial.print(":");
  if (mi<10) Serial.print("0"); Serial.print(mi,DEC); Serial.print(":");
  if (ss<10) Serial.print("0"); Serial.print(ss,DEC); Serial.println("");
}

When you use the stick, you begin with it casting no shadow.
When you stand there, straight up, that's only possible in the tropics around noon on certain days of the year at all.

But in other places, every day in daylit hours you start with the stick making no shadow.. it is tilted wrt the ground. Give that a try, in 20 minutes the stick will be pointing 5 deg away from the sun which will have moved west and higher or lower depending on AM or PM. How much N or S the shadow moves depends on time of day, the angle of the arc of the sun's path.. the rise or fall for the E-W run (rise/run aka tangent).

The sun doesn't move, we turn on a tilted plane wrt the sun. Correct the tilt, sun path is on that plane and if you measure angle on that plane you don't have to adjust elevation. It's only relative to your Lat on any day that elevation change enough to matter occurs.

How the tracking movement is made can simplify tracking greatly. If the axis of azimuth is tilted, a windup 24H clock motor can track the sun. My design course teacher showed me that.

: )

If you have a clock (or know the time), just point the hour needle of the clock to the sun. The bisectrice between the needle and the 12:00h mark in the clock will point to the south (or the north in the south hemisphere).
It should be the solar time.

If you don't know the time, make a solar clock with the 12:00h pointing to... oh, wait :grin:

Tell you what, everything's relative and there's no such thing as absolute motion. I refer to Earth-Sun and you refer to Sun-Galaxy?

Because in Special and General Relativity, every where is the Center of the Universe, goo-goo-ca-choob!

I never learned the Solar Time thing. The shadowless shadow stick is in my 1968 Scouting for Boys I got when I joined the BSA. Still got it, heard they're rare. Might sell it and a cigar box full of patches some day, all embroidered and one 1972 Philmont Arrowhead patch.

If I know the date and my latitude, sun elevation might give me time. I'd need a sextant and practice though. If I wait for the stars to come out, I'd know it's night-time!

Solar time is not completely exact, but's it's ok as an approximation.
In some areas there is 1 or 2 hours (or more) shift from solar time, e.g summer and winter time, etc.
In some places, like China, they have all the same hour along the country, so the deviation is bigger.

That was also in my boy scouts manual by the way. Also finding the polar star, etc. But we always managed to get lost... :sweat_smile:

I think I get it. My watch tells TV time, not real time.

As a last option I hit my head with a tree, and when the stars appear I try to calculate the north deviation quickly, with the sextant :slight_smile:

This indicates nothing is in motion.

Even Special Relativity is not so simple but that is one of the rules that came out of Einstein's interpretation of the Michelson-Morely Experiment, the biggest failure of Classical Physics attempt to find the absolute speed of the solar system in the ether, that there is no ether! Light moves the same speed in every direction all the time. It took almost 10 years of retries before the results could not be denied.

It does not mean that nothing moves. It means that space is not 3 dimensional but rather 4 dimensional with implications that defy common sense even before getting down to the curved parts.

I was able to do the special case maths before 2000 to follow the meaning where words fail but since the trauma I can't do what I did so I'm stuggling with the general case meanings. All I can say is good luck if you think it's that simple since it's rather obvious that planets and the sun do move yet observe light the same, as if they don't! You have to be able to let go of what you think you know to think of what works out to be real so far just to catch up to what was new in 1905 and not unproven since!

Proof requires disproof or it is not.

Evidence has to be falsifiable.
Theory can't be proven but can stand until disproven.
No one has shown SR or GR to be wrong.. yet.

Jan 1 counts as day 1. For instance if it is Feb 13 then the number of days since Jan 1=44days. 31 days for Jan +13 for Feb. That is what you input to the serial monitor if it happens to be Feb 13.
If you have daylight saving you have to correct for that for the actual real local time.
Please refer to the on line article 'the sun position_ PV education.'
A RTC is not used in the code. All you need is your latitude and longitude, the days expired since Jan 1 and the local time. Then you get the elevation and azimuth of the sun where you are.
The article referred to explains it all better than I can. Everything is taken into account such as the tilt of the Earth. Local time is actually referenced to a standard universal time base which I think is Greenwich mean time.
I have a separate sketch for the DS3231 RTC and it works perfectly. I need now to combine that sketch with the sun position sketch so that the number of days since Jan 1 can be entered automatically.
Here is my sketch for the ds3231 RTC. It has a peculiar problem because of the resetting of the time everytime the serial monitor is closed and opened again. You have to do this. First enter the date and time, upload. Then go back to the sketch and delete the date and time that was set in set up. Then upload again. Now you can safely use the serial monitor to get the date and time without it resetting to the original setting.

#include <DS323x.h>

DS323x rtc;

void setup()
{
    Serial.begin(115200);
    Wire.begin();
    delay(2000);

    rtc.attach(Wire);
    //enter year,month, day,hour(24),minute,second
}

void loop()
{
    DateTime now = rtc.now();
    Serial.println(now.timestamp());
    delay(1000);
}

Your descriptions are too vague to be much use. What does "works perfectly" mean? What does it actually output? Can you show us the output from this sketch?

What does that mean?
Is your RTC set to Daylight Saving Time when it shouldn't be? Could that be fouling up the output of your calculations?
And you still have not answered my question about lt.

Here is how I would go about doing this.
I would read the date and time from the RTC and store each of the components (year, month, day of month, hour, minute, second) in a separate variable. From those variables, I would then compute the correct values for d and lt. Then I would proceed with the calculation as in the code you are now using.

Note: If the RTC is set to Daylight Saving Time, but the calculations require that Daylight Saving Time not be used, then I would manually set the RTC off of (not on) Daylight Saving Time. Do you know how to do this?