Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Solar Tracker Algorithm

Not open for further replies.

Val Gretchev

Forum Supporter
I noticed there was a lot of interest in this forum regarding solar tracking. Most of the threads discussing this subject have proposed some sort of photocell control of motors to position a solar array perpendicular to the sun's rays.

Here is a method of predicting where the sun is located for any co-ordinate, date, and time. Photocells are not required. The program outputs the Azimuth Angle (degrees from North) and Elevation Angle (degrees from horizontal) which can be used to move the array to the right spot.

For now, this is strictly a mathematical exercise. I am hoping to build a complete tracker for a small solar array to work out the drive electronics and find a suitable 2-axis positioning mechanism and motors.

I was looking for any articles on the Internet regarding this subject matter and came across this article from Rockwell Automation:


I noticed that their software included an algorithm provided by NREL (National Renewable Energy Laboratory) located near Golden, Colorado. This led me to the NREL web site where I was able to download the NREL/TP-560-34302 Revised January 2008 manual.

**broken link removed**

By registering, I was able to download the spa.c, spa.h, and spa_tester.c source code modules.

I used the same microcontroller board I described in my Grid Tie Inverter Prototype post and loaded the attached project code. It worked very well. I am sure that you PIC users can find a processor with floating point support and port the code to your favorite compiler.

I noticed in the example code that NREL used co-ordinates 39.742476,-105.1786 and if you plug this into Google Earth search box, it will take you to the NREL facility. They have a large solar farm and if you look carefully, there is a moveable array enclosed by a fence casting a large shadow on the ground.


  • Tracker.zip
    515.1 KB · Views: 998


New Member
Hello Val.
Man, we have a lot to talk about.
It´s almost two years by now, since I have decided to develop my own solar tracking system.
In the process, I have invented my own solar tracker mechanism, on which I´m just finishing the last mechanical details, and it´s
working very well, with several advantages over other mechanisms currently available.
My ultimate goal was to create something, that can be cheap but at the same time, precise, with good mechanical resistance, and as
much simple as possible.
And I think that I have achieved all of these goals on an elegant way.
Now, I´m almost ready to start the second phase of my project, which is the development of the electronic controller system.
For more than a year that I'm planning to use NREL's SPA C code to calculate the sun's position, together with my own mathematical algorithm
to control my mechanism, in order to keep it sunlocked.
I am a big fan of Microchip PIC Microcontrollers, and I intend to buy a development board and a C compiler from Mikroe (www.mikroe.com)
for this project.
And right now, my problem is that haven't yet decided what kind of PIC microcontroller will be the best for this task.
I'm torn between PIC 24/DSPic or PIC 32.
Since you're already dealing with this kind of problem, on which I'm just about to start, your experience might be a great help for me.
So, in your opinion, which of these PIC series will be best to run SPA, or, on the other hand, is this something simple enough to be handled
with a PIC 18???
Your ideas and opinions will be of great value to me.

Thanks a lot for your attention


Val Gretchev

Forum Supporter
Solar Tracker

Hi Francisco

I am happy to hear you are making progress on your solar tracker mechanism. Perhaps you can post some pictures of it.

I looked into slewing drives a while ago and found them to be too expensive for experimenters. The same is true for linear actuators. I am certainly interested in knowing whether you found some inexpensive mechanical solutions.

I am not familiar with the PIC microcontroller products. I use Freescale micros in all of my projects. Perhaps someone else reading this forum might be better qualified to give you advice. However, I can venture to say that a 32 bit micro will probably do a better job than a 16-bit micro. The important thing is to make sure the compiler has floating point support.

I looked at the web site you posted (www.mikroe.com) and found their products interesting. I may invest in their mikroC PRO for ARM and buy their mikromedia for ARM module. This, of course would be for an entirely different project.

Good luck on your solar tracker project and I would be happy to answer any specific questions on the work I have already published.



New Member
Here's a good reference to those who are interested in knowing more about SPA **broken link removed**.

I've seen a few algo over the web but haven't tried which one really works.

So far, this is the one that really got my attention.

#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 https://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;
if (da < 1){
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;
if (da > (mo==4||mo==6||mo==9||mo==11)?30:(mo==1||mo==3||mo==5||mo==7||mo==10)?31:28){
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, az
get_sun_pos(-30, -90, 'u', 8, 14, 15, 30, &alt, &az);
printf("alt: %f az:%f\n",alt,az);

I'll be trying it out and see how it works. :) N.B.
Last edited:


New Member
Here's another approach - and a bit of fun that requires time and dedication. However, it works for one location only. And, unlike the NREL software, it is certainly not valid for 6,000 years. :p

Get the tracking data empirically. No math needed !

Basically you track the sun manually and log its positions over the course of a year. If you save that logged data to files on a PC, you can reverse the process and use that same data to drive servo motors! Take a reading once every one or two hours (or to what ever accuracy you need). And you can do this once a week - say on a saturday or sunday ... but it should be nearly the same day each week. Unless you are very far North or South, a once-a-week data set should be enough for tracking solar panels, etc.... the Sun track doesn't change that much week to week. (and, if you do want math, you can interpolate the missing data ! :) )

Here's the rough explainer:

Rig up some position sensors connected to a flat, square plate of painted wood or thick plastic.
The plate should mounted on a fixed stand in the yard. The plate needs to move on that stand in three dimensions (x,y,z). One of those dimension (z), you will fix to your latitude, so you need only two position sensors, one each for x and y. (to fix the Z, point the plate flatwise towards the North star. ... in other words, draw an imaginary line along the plate's flat surface, extended out to the North Star. ... see equatorial mounted telescope for more info. )

Make a cross-hair:

Drill four holes on the flat side of the plate ... on the 'face' ... each one near the edge of each side, centered on the middle of each side.

It will look (sort of :) )like this ... holes are marked "*":

|*.. X..*| side
Take two pieces of wire, each about three times as long as the plate is wide.
Stick one into the the side holes, making it go across; stick the other wire in the top and bottom holes to make it go up and down.
They will overlap in about the middle, and should stand away from the face about 6 to 10 inches. (Arbitrary).
Point the face at the sun, making the cross hair's shadow point to the middle (give or take)... Mark that spot with an X using a Sharpie. ... or whatever.

To take readings,

Hook your recorder, pc, what ever up to the sensors using your homebrew interface.
Now all you have to do is move the plate until the shadow of the cross hairs hits the X marks the spot. Take an x and y reading.
Wash, rinse, repeat ...

now you have a real record of the Sun at Your Place !

= If you have a push-to telescope, look at the position sensors it has.
= Find the plans online for a sun dial. Look for how to set the latitude of the dial for your location.

- H
Last edited:


New Member

you could take my suggestion, but mount a flat mirror on the flat plat ... then point the sun's reflection at your desired target each time you want to log the sun's position. (I'd not use a parabolic mirror until your data is verified - nothing like having the focal point slew to your asphalt roof ... sure would have a tough time explaining that accident to the Fire Department - LOL )...

say, you are in Toronto - so my idea will be more difficult for you ... you'd need to take hourly readings probably once every other day.

- Howard


I've been looking for Sun tracking source code, now what would it take to make it a Heliostat.

As far as I know you must be aware that the heliostat mirror will need to track half the speed of the real Sun tracking rate. This has been discussed in this Sol forum https://solarchat.solarastronomy.org/index.php/en/this-is-solar-chat/6-this-is-solarchat-

My solar guider is working within limits so far I have found out of 1-2 arcminutes. So I think mounting a solar tracker just next to the heliostat the sensor would receive the collimated Sun rays but when the mirror is not in the correct position eg. the SUn rays will have an angle on the solar guider, the solar guider would adjust the speed of the motors.


New Member
newbie alert :) hi guys i am planning to make this sun tracker using the code you generous people shared above, but what are the schematics( cct diagrams) based on this code ? could someone help me please:confused:
Not open for further replies.

Latest threads

EE World Online Articles