Arduino solar tracker

I want to try that solar tracker. Can you give me some information about that? http://www.sunpowerport.com

See previous discussion...

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1263859285/5

Hello world !

You can see my develop of Sun Tracking system

In the next post I give you the address.

Thanks,

Fernando

You can see my sun tracking develop at:

http://www.suntracking.es

Thank you

Hi Guys,
I'm new to this forum, and new to solar tracking, but plan to build something myself. I've looked at various approaches online, and many use sensors. I have an idea of how to do it, but cannot see any reference to this approach on any websites, so maybe it would not work. Anyway, I wanted to put it out there and ask for feedback. So the idea is to just adjust the position of the panel to maximize the current going to the battery. The current can be measured across an inexpensive shunt resistor. The Arduino would turn the control motor in the direction that causes the current to increase, and stop once the current starts to go down. It sounds pretty simple. Am I missing something?
Feedback most welcome.
Regards,
Gerry.

The remark about wear and tear on the LDRs out in the sun's damaging rays, and all weathers set me thinking...

a) In ANYTHING you design that will be outdoors, design it for easy replacement of damaged parts. They WILL need replacing... sooner than you hope!

b) Are LDRs the way to go? Probably... but I wondered if maybe temperature sensors embedded in small blocks of black epoxy might do just as well, and be more robust?

c) Of course, while I would be the first to applaud anyone wanting to have fun creating a solar tracker... how cool! (I've wanted to build one for years).... if I just wanted my solar panels oriented correctly, I would put my faith in Mr Newton. The geometries of the earth's relationship to the sun are entirely predictable, and a program can be written to point the panels in the right direction without any light sensors. Sorry to be a bore. Do remember on BIG advantage of the track-by-light-sensor approach, though: It doesn't need an accurately set RTC (time of day clock) to work.

d) A KISS point: You really only need the expense, complexity, etc, etc needed to "tip" the panels left and right around one axis of rotation day by day.... to track the sun across the sky. You may want to mount everything on a second axis of rotation to compensate for the sun's height above the horizon at noon, to compensate for the seasonal variation in that axis... but this adjustment can be done manually with whatever you want to use during your routine servicing of the panels. The rate of change in this axis is slow.

I too have been thinking of how to track the sun to gather that extra 30% of energy, but the cost of most commercial solutions has exceeded the cost of installing 30% more solar modules...

I'm very new to the world of Arduino, and from the few forum threads on the subject, the popular method seems to track light levels to determine the position of "Ol' Sol" visually.
The downside I see with this methodology is that it is difficult to allow for all the variations and possible scenarios that the solar array may face, and have to algorithmically respond to.
For example, will the tracker (in the examples given) properly handle if a thunderstorm blows in mid-day ? In other words, all of a sudden there is no bright spot in the sky; what will it do ? I suppose it will stay put, because the two or three light sensors will "see" the same light level, am I right ?
Next, what happens at sundown ? How does it know whan to go back towards the east and wait for sunrise ? Without a sense of time (ie, with an RTC) I'm not convinced it will find the sun in the morning, mostly because the sun will literally be behind the light sensors.

With respect to razorbud's and tkbyd's comments about using lat/long information to determine azimuth and elevation of the sun in real time, I think this is a great idea. It solves a lot of problems in terms of where the sun is, regardless of time or weather. It's not the simplest (no KISS here) but

The big question is: has anyone done this, to calculate the sun's azimuth ?

I've read and looked at ve9qrp's qrptracker project, and how he uses keplerian elements and Plan13 formulas. I'm hoping someone has some information to share on how to do this, to save from re-inventing any wheels.

Thanks to all in advance for any assistance...

Dann.

I think the best simplest solution is to utilize a simple RTC/Calendar to drive a stepper motor gear drive at a constant sidereal rate for a single axis right ascension movement.

If you research telescope clock drives using polar mounts you will see that it's pretty simple, accurate and reliable. You may need to manual adjust the azimuth angle manually every month or so to optimize performance. The RTC/Calendar could also handle the skewing command to reposition to each sunrise from look up table in your program.

Mowcius has the answer!

http://www.mowcius.co.uk/suntrackercode.html

Sun tracker code for you :slight_smile:
Attach to a RTC and tell it your co-ordinates and it'll throw out sun position :wink:

Mowcius

Great thread guys! Mowcius -- I read the info on your personal web site for the sun position tracking and was salivating, but only to find the links to the .pde's are broken! Are you still providing this sample code?

Yeah, annoying aint it.

Hopefully moving my website soon and sorting it out.

Anyway, here's some static code

//Sun Position Calculation
//Provides sun position (relative) from static variables

#include <math.h>
#define pi    3.14159265358979323846
#define twopi (2*pi)
#define rad   (pi/180)
#define EarthMeanRadius     6371.01      // In km
#define AstronomicalUnit    149597890      // In km

//Input Variables --------------------- TIME HAS TO BE IN UT (UNIVERSAL TIME)! NO TIME ZONES OR SUMMER TIMES --------
//My last modifications were probably at this time on this date!
      int Year = 2010; //year
      int Month = 7; //month
      int Day = 3; //day
      float Hours = 16; //hour
      float Minutes = 38; //minutes

      float Longitude = 1.2967; //enter longitude here
      float Latitude = 1.5465; //enter latitude here
//--------

//Program Variables
      float ZenithAngle;
      float Azimuth;
        float RightAscension;
      float Declination;
        float Parallax;
        float ElevationAngle;

      float ElapsedJulianDays;
      float DecimalHours;
      float EclipticLongitude;
      float EclipticObliquity;
//--------

void setup() {
 Serial.begin(9600);
}

void sunPos(){


      // Auxiliary variables
      float dY;
      float dX;

      // Calculate difference in days between the current Julian Day
      // and JD 2451545.0, which is noon 1 January 2000 Universal Time

            float JulianDate;
            long int liAux1;
            long int liAux2;
            // Calculate time of the day in UT decimal hours
            DecimalHours = Hours + (Minutes / 60.0);
            // Calculate current Julian Day
            liAux1 =(Month-14)/12;
            liAux2=(1461*(Year + 4800 + liAux1))/4 + (367*(Month
                  - 2-12*liAux1))/12- (3*((Year + 4900
            + liAux1)/100))/4+Day-32075;
            JulianDate=(float)(liAux2)-0.5+DecimalHours/24.0;
            // Calculate difference between current Julian Day and JD 2451545.0
            ElapsedJulianDays = JulianDate-2451545.0;

      // Calculate ecliptic coordinates (ecliptic longitude and obliquity of the
      // ecliptic in radians but without limiting the angle to be less than 2*Pi
      // (i.e., the result may be greater than 2*Pi)

            float MeanLongitude;
            float MeanAnomaly;
            float Omega;
            Omega=2.1429-0.0010394594*ElapsedJulianDays;
            MeanLongitude = 4.8950630+ 0.017202791698*ElapsedJulianDays; // Radians
            MeanAnomaly = 6.2400600+ 0.0172019699*ElapsedJulianDays;
            EclipticLongitude = MeanLongitude + 0.03341607*sin( MeanAnomaly )
                  + 0.00034894*sin( 2*MeanAnomaly )-0.0001134
                  -0.0000203*sin(Omega);
            EclipticObliquity = 0.4090928 - 6.2140e-9*ElapsedJulianDays
                  +0.0000396*cos(Omega);

      // Calculate celestial coordinates ( right ascension and declination ) in radians
      // but without limiting the angle to be less than 2*Pi (i.e., the result may be
      // greater than 2*Pi)

            float Sin_EclipticLongitude;
            Sin_EclipticLongitude= sin( EclipticLongitude );
            dY = cos( EclipticObliquity ) * Sin_EclipticLongitude;
            dX = cos( EclipticLongitude );
            RightAscension = atan2( dY,dX );
            if( RightAscension < 0.0 ) RightAscension = RightAscension + twopi;
            Declination = asin( sin( EclipticObliquity )*Sin_EclipticLongitude );

      // Calculate local coordinates ( azimuth and zenith angle ) in degrees

            float GreenwichMeanSiderealTime;
            float LocalMeanSiderealTime;
            float LatitudeInRadians;
            float HourAngle;
            float Cos_Latitude;
            float Sin_Latitude;
            float Cos_HourAngle;
            GreenwichMeanSiderealTime = 6.6974243242 +
                  0.0657098283*ElapsedJulianDays
                  + DecimalHours;
            LocalMeanSiderealTime = (GreenwichMeanSiderealTime*15
                  + Longitude)*rad;
            HourAngle = LocalMeanSiderealTime - RightAscension;
            LatitudeInRadians = Latitude*rad;
            Cos_Latitude = cos( LatitudeInRadians );
            Sin_Latitude = sin( LatitudeInRadians );
            Cos_HourAngle= cos( HourAngle );
            ZenithAngle = (acos( Cos_Latitude*Cos_HourAngle
                  *cos(Declination) + sin( Declination )*Sin_Latitude));
            dY = -sin( HourAngle );
            dX = tan( Declination )*Cos_Latitude - Sin_Latitude*Cos_HourAngle;
            Azimuth = atan2( dY, dX );
            if ( Azimuth < 0.0 )
              Azimuth = Azimuth + twopi;
            Azimuth = Azimuth/rad;
            // Parallax Correction
            Parallax=(EarthMeanRadius/AstronomicalUnit)
                  *sin(ZenithAngle);
            ZenithAngle=(ZenithAngle //Zenith angle is from the top of the visible sky (thanks breaksbassbleeps)
                  + Parallax)/rad;
                ElevationAngle = (90-ZenithAngle); //Retrieve useful elevation angle from Zenith angle
}

void loop(){
  sunPos(); //Run sun position calculations
  Serial.print("Elevation Angle:  ");
  Serial.println(ElevationAngle, 0); //Print Elevation (Vertical) with no decimal places as accuracy is not really great enough
  Serial.print("Azimuth:  ");
  Serial.println(Azimuth, 0); //Print Azimuth (Horizontal) with no decimal places
  if(ElevationAngle < 0)
  Serial.println("The sun has set. Get some sleep!");
  while(1){} //Stop - Values aren't going to have changed anyway as they are currently static variables!
}

Should work fine.

Mowcius

Thanks Mowcius, this is great!
I have what is probably a really uneducated, lame question: It seems to get this to work in my area, all I need is to swap in my lat/long, is that correct? If so, I tried that, and I must be doing this wrong:

In my area, (Redmond, OR, USA), my decimal lat/long comes up as:
Latitude: 44.2727778
Longitude: -121.1727778

When plugging that in, I see the serial port reads a negative elevation angle, and azimuth 239, and says 'The sun has set...."

Can you point me in the right direction?
I feel guilty asking someone who as written such detailed complex code, for something like this :frowning:

EDIT:: Sorry!! Disregard. I had lat/long switched in the code. I guess I was right that it was a lame question :slight_smile: Thanks again for this fantastic code!

I feel guilty asking someone who as written such detailed complex code, for something like this

EDIT:: Sorry!! Disregard. I had lat/long switched in the code. I guess I was right that it was a lame question Thanks again for this fantastic code!

I feel slightly guilty every time someone writes something like that as I merely took it and modified it slightly for the arduino.

Yeah I think it'd confusing how it is written with the lat and long. People always seem to stick them in the wrong way round :stuck_out_tongue:

Mowcius

Have you done any further work with integrating this with a GPS for the clock and lat/long? (I saw you talking about this in another thread by chance, and figured the two projects were related)

I integrated it with a RTC (DS1307) for the time. I don't have a GPS at the moment so I can't do it with that.

It's easy enough :slight_smile:

I'd love to use a compass and a GPS some time to make an automatic system that will track the sun anywhere without any values being programmed in.

Something I am going to using it for in the next month is for part of a lamp I am doing. Because I know when the sun has set, I can adjust lighting accordingly in the evening. Then there's no chance of sticking something on top of an LDR by accident and making the light turn on in the middle of the day when it's still light :slight_smile:

Mowcius

Hi Mowcius

It seems that a lot of people using your sun tracker code.
Your code is great! Many thanks!!

I am working still on my solar concentrating power system.
The full code for it is done, at the moment I am waiting for some mechanical parts from italy.
With these parts I would be able to finish my project till spring.

I tested your code with a libelium gps module and it works everywhere!

Please visit my website under http://www.andres.li/
The website is written in german...under "Steuerung" you can see how arduino is working with the gps module.

schwizer

I tested your code with a libelium gps module and it works everywhere!

Great!

Cool project, glad it works OK with the GPS. I presume you are converting the output from the GPS to decimal or is it outputting in decimal?

Hey Mowcius,
I ordered a RTC kit, and I'm wondering if you wouldn't mind posting your updated tracker code that includes your RTC?

I also ordered and Ethernet shield, and I'll be working on doing HTTP post to SQL via PHP scripts, so my data is logged properly, so I will make sure and contribute my code once I get to that point.

Last night I welded up a solar panel 2-axis jig, so I can begin a sanity check of the hardware/software once my RTC arrives.

Umm, if I knew where I put it then I would :smiley:

It's simple enough, I presume your RTC will be a DS1307, there are a few libraries around, easiest is probably DS1307.h then add some of this to your sketch:

#include <Wprogram.h>
#include <Wire.h>
#include <DS1307.h>

int rtc[7];

void setup()
{
  RTC.start();
}

void loop()
{
  RTC.get(rtc,true);

  for(int i=0; i<7; i++)
  {
    if (rtc[0] < 10 && i==0){ Serial.print("0");}
    Serial.print(rtc[i]);
    Serial.print(" ");
  }

  Serial.println();

  delay(1000);

}

From the output of that sketch you will be able to work out what rtc[0] to rtc[6] are then you can assign them to variables.

You will also need a sketch to set the time on the RTC, there are a few of them around too.

Call RTC.get(rtc, true) at the start of the sun position calculation, then use rtc as the variables.
I'll see if I can find my code again, if not then I'll whip this back up into a sketch tonight - might add in the time set over serial code too.
Mowcius

I built a simple little light tracker for my controls class, I made a video of it at the request of the professor. Its not nearly as complex as what you guys are planning, but it shows what you can do with a couple of photo-resistors.

It doesn't actually record the lights position, though this could be remedied by attaching a pot. A 2-axis system would just be everything here except duplicated and turned 90 degrees.