Author Topic: Solar Tracker algorithm  (Read 3449 times)

0 Members and 1 Guest are viewing this topic.

scottfromscott

• Beginner
• Posts: 6
`#include <stdio.h>#include <math.h>void get_sun_pos(float lat, float lon, char dt_type, float mo, float da, float hour, float minute, float *alt, float *az){   /*      calculate the Sun's altitude and azimuth inputs: 'lat'itude, 'lon'gitude, dt_type('u'|'l'), 'mo'nth, 'da'y, hour, minute dt_type contains 'u'tc date/time, or 'l'ocal date/time flag indicating whether mo, da, hour and minute are utc or local    outputs: 'alt'itude, 'az'imuth code based upon Prof. Richard B. Goldstein's sun position calculator at http://www.providence.edu/mcs/rbg/java/sungraph.htm Appears to give fairly accurate results for the next 10 years or so */ float ti, local_hour; if (dt_type == 'l') local_hour = hour; else /* dt_type == 'u' */ { /* calculate local date/time from utc date/time */ float time_offset = round(lon / 15); //longitude -> hours local_hour = hour + time_offset; //adjust hour, day, month as needed (ignore years and seconds)...  if (local_hour < 0){ local_hour += 24; da--; if (da < 1){ mo--; if (mo < 1) mo = 12; da = (mo==4||mo==6||mo==9||mo==11)?30:(mo==1||mo==3||mo==5||mo==7||mo==10)?31:28; } } else if (local_hour > 23){ local_hour -= 24; da++; if (da > (mo==4||mo==6||mo==9||mo==11)?30:(mo==1||mo==3||mo==5||mo==7||mo==10)?31:28){ mo++; if (mo > 12) mo = 1; da = 1; } } } //total hours and minutes and adjust for +/- offset from noon...   ti = (local_hour + minute / 60) - 12;       float pi180=M_PI/180;    float adjtime;    float za[] = {-0.5,30.5,58.5,89.5,119.5,150.5,180.5,211.5,242.5,272.5,303.5,333.5}; // days from jan at noon    float zi;    float zzi;    float cth; // cosine of latitude    float sth; // sine of latitude    float cph;     float sph;    float cti;    float sti;    float x;    float y;    float loc;    float phi;    float sin_tau, cos_tau;    loc = round(lon / 15) * 15; //     adjtime = (lon - loc) / 40; // offset     zi = za[(int)mo - 1];       //     zzi = 360 * (zi + 0.5 + da - 82) / 365; //     cos_tau = cos(zzi * pi180);    sin_tau = sin(zzi * pi180);    phi = acos(cos_tau * cos_tau + sin_tau * sin_tau * cos(23.45 * pi180)); // formula for sun declination (varies +/- 23.45 deg. over a year)    phi = round(1000 * phi / pi180) / 1000; //    if (sin_tau < 0){phi = -phi;}// sign +/- depends on the time of year       ti = ti * 15; // hours +/- offset from noon to degrees from Prime Meridian    cth = cos(lat * pi180);    sth = sin(lat * pi180);    cph = cos(phi * pi180);    sph = sin(phi * pi180);    cti = cos(ti * pi180);    //altitude = sin-1(sin theta * sin phi + cos theta * cos phi * cos tau)    *alt = sth * sph + cth * cph * cti;    *alt = asin(*alt) / pi180;    *alt = round(1000 * *alt) / 1000;    //azimuth = tan-1(-x'/y')=tan-1(cos phi sin tau/(cos theta sin phi - sin theta cos phi cos tau))    sti = sin(ti * pi180);    x = -cph * sti;    y = cth * sph - sth * cph * cti;    *az = 90 - atan2(y, x) / pi180;    if(*az < 0) *az = *az + 360;    *az = round(1000 * *az) / 1000;}int main(){float alt, az;//           lat,lon,dt_type,mo, da,hour,minute, alt, azget_sun_pos(-30, -90,  'u',   8, 14,  15,    30, &alt, &az);printf("alt: %f  az:%f\n",alt,az);}`