Documento
Documento
h> #include <Wire.h> #include <LiquidCrystal.h> #include <DS1307RTC.h> #include <enc28j60.h> #include <etherShield.h> #include <ip_arp_udp_tcp.h> #include <ip_config.h> #include <net.h> #include <websrv_help_functions.h> #include <Client.h> #include <SPI.h>
3.14159265358979323846
#define twopi (2*pi) #define rad (pi/180) #define EarthMeanRadius #define AstronomicalUnit 6371.01 // In km 149597890 // In km
int ElevPrevious = 0; int AziOneDegree = 10; // Enter number of steps to physically move your rig 1 degree Azimuth. int ElevOneDegree = 20; // Enter number of steps to physically move your rig 1 degree Elevation.
float Longitude = -121.23486042022705; //enter longitude here float Latitude = 44.224928297647466; //enter latitude here
float ZenithAngle; float Azimuth; float RightAscension; float Declination; float Parallax; float ElevationAngle; float ElapsedJulianDays; float DecimalHours; float EclipticLongitude; float EclipticObliquity;
pinMode (17, OUTPUT); // +5v for DS1307 RTC on analog 4 (digital 17)
pinMode (16, OUTPUT); // Ground for DS1307 on analog 3 (digital 16) pinMode (2, OUTPUT); // Backlight for LCD
digitalWrite (17, HIGH); // tell pin 17 to be +5v digitalWrite (16, LOW); digitalWrite (2, HIGH); // tell pin 16 to be Ground // tell pin 2 to be +5v (for backlight)
setSyncProvider(RTC.get); // Get time from RTC setSyncInterval(86400); ElevStepper.setSpeed(120); AziStepper.setSpeed(120); // re-sync time with the RTC every ( ) seconds.
//------------------------//
void RealTimeClock() {
lcd.print("0"); lcd.print(hour()); lcd.print(":"); if(minute() <10) lcd.print("0"); lcd.print(minute()); lcd.print(":"); if(second() <10) lcd.print("0"); lcd.print(second()); lcd.print(" "); lcd.print(month()); lcd.print("/"); lcd.print(day()); lcd.print("/"); lcd.print(year()); lcd.print(" "); }
void sunPos(){
RealTimeClock();
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 = (hour() + minute() / 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
void loop(){ sunPos(); //Run sun position calculations RealTimeClock(); //Call time function
// Convert Azimuth and ElevationAngle to output to stepper motors // NOTE!!! For the code below, you must manually calculate how many steps it takes // to mechanically move your rig exactly 1 degree of physical motion. This is in variables above, // as ElevOneDegree and AziOneDegree.
ElevStep = (ElevationAngle * ElevOneDegree); //Elevation is 0 - 90 degrees, so this adds up perfect. AziStep = ((Azimuth / 2) * AziOneDegree); //devide Azimuth by 2 to give us 180 degrees of range.
if (ElevationAngle < 0){ nightTime = true; lcd.setCursor(0,3); lcd.print (" Parking All Panels "); ElevStepper.step(((90-ElevationAngle)*ElevOneDegree),BACKWARD, DOUBLE); // Park the panel flat at night. This is the safest position in AziStepper.step(((Azimuth/4)*AziOneDegree),BACKWARD, DOUBLE); // case of high winds. }
while(nightTime){ ElevPrevious = 0; AziPrevious = 0; lcd.setCursor(0,3); lcd.print(" Night Time "); // Clear "previous" values
sunPos(); //Run sun position calculations to see when Elevation is above zero. if (ElevationAngle > 0) nightTime = false;
ElevStepper.step(((ElevStep - ElevPrevious)*-1),BACKWARD, DOUBLE); // to invert the negative number to positive (* -1), and tell else BACKWARD. // the stepper to run // For //
ElevStepper.step((ElevStep - ElevPrevious),FORWARD, DOUBLE); the steppers, we want to only have motion if there has been AziStepper.step((AziStep - AziPrevious),FORWARD, DOUBLE); change. By subtracting the previous values from the current values, unless there is change. // lcd.setCursor(0,3); // lcd.print(ElevStep); // lcd.print(" "); // lcd.print(AziStep); // lcd.print(" "); // lcd.print(ElevStep - ElevPrevious); // lcd.print(" "); // lcd.print(AziStep - AziPrevious); // lcd.print(" ");
while (client.connected() && client.available()) { bool connected; client.print("GET /writeDBTrackingData.php?elevation="); client.print(ElevationAngle); client.print("&azimuth="); client.println(Azimuth); client.stop(); connected = false; } //delay (10000);
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
RTC_DS1307 RTC;
void setup () {
Serial.begin(57600); Wire.begin(); RTC.begin(); lcd.begin(19,3); pinMode (17, OUTPUT); // +5v for DS1307 RTC on analog 4 (digital 17) pinMode (16, OUTPUT); // Ground for DS1307 on analog 3 (digital 16) pinMode (2, OUTPUT); // Backlight for LCD
digitalWrite (17, HIGH); // tell pin 17 to be +5v digitalWrite (16, LOW); digitalWrite (2, HIGH); // tell pin 16 to be Ground // tell pin 2 to be +5v (for backlight)
// following line sets the RTC to the date & time this sketch was compiled RTC.adjust(DateTime(__DATE__, __TIME__)); }
lcd.setCursor(0,0); lcd.print("RTC Clock set to:"); lcd.setCursor(0,1); lcd.print(now.hour(), DEC); lcd.print(':'); if(now.minute() <10)
lcd.print("0"); lcd.print(now.minute(), DEC); lcd.print(':'); if(now.second() <10) lcd.print("0"); lcd.print(now.second(), DEC); lcd.print(" "); lcd.print(now.month(), DEC); lcd.print('/'); lcd.print(now.day(), DEC); lcd.print('/'); lcd.print(now.year(), DEC);
delay(1000);