Menu:

PPTEA - Inseguitore Solare


Mediante Coordinate Geografiche ed Orario


Inseguire il sole con i sistemi a fotoresistenza o fotodiodo possono funzionare, ma hanno dei problemini specialmente quando passano le nuvole...
A cosa può servire l'orologio nel PPTEA (REAL TIME CLOCK)? Visto che conosciamo l'ora e pure dove ci troviamo, nel caso possiamo ricavare le coordinate geografiche dal nostro navigatore o da quello di un amico, possiamo scrivere un algoritmo che ci indica tilt ed azimuth del sole.
Questo è un algoritmo di Tracking molto accurato e vi riporto il codice.
Avete capito dove voglio arrivare, basta tradurre questo codice in eabasic ed il gioco è fatto.

Questa è la discussione originale.

Questo è il file ".eab" dell' Inseguitore Solare.
Scarica il file (ZIP)

(26/12/2012 - Corretto bug sul codice alle righe 400-410)

CODICE:

// This file is available in electronic form at http://www.psa.es/sdg/sunpos.htm

#ifndef __SUNPOS_H
#define __SUNPOS_H

// Declaration of some constants
#define pi 3.14159265358979323846
#define twopi (2*pi)
#define rad (pi/180)
#define dEarthMeanRadius 6371.01 // In km
#define dAstronomicalUnit 149597890 // In km
struct cTime
{
int iYear;
int iMonth;
int iDay;
double dHours;
double dMinutes;
double dSeconds;
};

struct cLocation
{
double dLongitude;
double dLatitude;
};

struct cSunCoordinates
{
double dZenithAngle;
double dAzimuth;
};

void sunpos(cTime udtTime, cLocation udtLocation, cSunCoordinates *udtSunCoordinates);

#endif

CODICE:

// This file is available in electronic form at http://www.psa.es/sdg/sunpos.htm

#include "sunpos.h"
#include <math.h>

void sunpos(cTime udtTime,cLocation udtLocation, cSunCoordinates *udtSunCoordinates)
{
// Main variables
double dElapsedJulianDays;
double dDecimalHours;
double dEclipticLongitude;
double dEclipticObliquity;
double dRightAscension;
double dDeclination;

// Auxiliary variables
double dY;
double dX;

// Calculate difference in days between the current Julian Day
// and JD 2451545.0, which is noon 1 January 2000 Universal Time
{
double dJulianDate;
long int liAux1;
long int liAux2;
// Calculate time of the day in UT decimal hours
dDecimalHours = udtTime.dHours + (udtTime.dMinutes
+ udtTime.dSeconds / 60.0 ) / 60.0;
// Calculate current Julian Day
liAux1 =(udtTime.iMonth-14)/12;
liAux2=(1461*(udtTime.iYear + 4800 + liAux1))/4 + (367*(udtTime.iMonth
- 2-12*liAux1))/12- (3*((udtTime.iYear + 4900
+ liAux1)/100))/4+udtTime.iDay-32075;
dJulianDate=(double)(liAux2)-0.5+dDecimalHours/24.0;
// Calculate difference between current Julian Day and JD 2451545.0
dElapsedJulianDays = dJulianDate-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)
{
double dMeanLongitude;
double dMeanAnomaly;
double dOmega;
dOmega=2.1429-0.0010394594*dElapsedJulianDays;
dMeanLongitude = 4.8950630+ 0.017202791698*dElapsedJulianDays; // Radians
dMeanAnomaly = 6.2400600+ 0.0172019699*dElapsedJulianDays;
dEclipticLongitude = dMeanLongitude + 0.03341607*sin( dMeanAnomaly )
+ 0.00034894*sin( 2*dMeanAnomaly )-0.0001134
-0.0000203*sin(dOmega);
dEclipticObliquity = 0.4090928 - 6.2140e-9*dElapsedJulianDays
+0.0000396*cos(dOmega);
}

// 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)
{
double dSin_EclipticLongitude;
dSin_EclipticLongitude= sin( dEclipticLongitude );
dY = cos( dEclipticObliquity ) * dSin_EclipticLongitude;
dX = cos( dEclipticLongitude );
dRightAscension = atan2( dY,dX );
if( dRightAscension < 0.0 ) dRightAscension = dRightAscension + twopi;
dDeclination = asin( sin( dEclipticObliquity )*dSin_EclipticLongitude );
}

// Calculate local coordinates ( azimuth and zenith angle ) in degrees
{
double dGreenwichMeanSiderealTime;
double dLocalMeanSiderealTime;
double dLatitudeInRadians;
double dHourAngle;
double dCos_Latitude;
double dSin_Latitude;
double dCos_HourAngle;
double dParallax;
dGreenwichMeanSiderealTime = 6.6974243242 +
0.0657098283*dElapsedJulianDays
+ dDecimalHours;
dLocalMeanSiderealTime = (dGreenwichMeanSiderealTime*15
+ udtLocation.dLongitude)*rad;
dHourAngle = dLocalMeanSiderealTime - dRightAscension;
dLatitudeInRadians = udtLocation.dLatitude*rad;
dCos_Latitude = cos( dLatitudeInRadians );
dSin_Latitude = sin( dLatitudeInRadians );
dCos_HourAngle= cos( dHourAngle );
udtSunCoordinates->dZenithAngle = (acos( dCos_Latitude*dCos_HourAngle‚Ä™
*cos(dDeclination) + sin( dDeclination )*dSin_Latitude));
dY = -sin( dHourAngle );
dX = tan( dDeclination )*dCos_Latitude - dSin_Latitude*dCos_HourAngle;
udtSunCoordinates->dAzimuth = atan2( dY, dX );
if ( udtSunCoordinates->dAzimuth < 0.0 )
udtSunCoordinates->dAzimuth = udtSunCoordinates->dAzimuth + twopi;
udtSunCoordinates->dAzimuth = udtSunCoordinates->dAzimuth/rad;
// Parallax Correction
dParallax=(dEarthMeanRadius/dAstronomicalUnit)
*sin(udtSunCoordinates->dZenithAngle);
udtSunCoordinates->dZenithAngle=(udtSunCoordinates->dZenithAngle
+ dParallax)/rad;
}
}



Visto che la V.2.8 è stata consegnata vi posto il codice che visualizza la posizione del SOLE.
In questa versione occorre avere il REAL TIME CLOCK, l'espansione di memoria, un display e tutto funziona automaticamente
Se non avete il display potete far uscire l'output su usb.
Occorre solo settare le coordinate (latitudine e longitudine Linea 130 e 140
Questo è il codice, impiega meno di un secondo a fare tutti i calcoli: bravo PPTEA...hehehe ^_^ .
Il codice può essere ottimizzato, ma considerate che rimane più della metà della memoria libera, sufficiente per fare qualsiasi cosa.

Un applicazione carina sarebbe quella di realizzare un orologio, sensore di temperatura, alba, tramonto e fasi lunari.
C'è qualche volontario?


100 MATH_PRECISION=18 ' AUMENTIAMO LA PRECISIONE DEL PPTEA
110 'Calcolo posizione Sole FINO AL BLOCCO CON VERSIONE PPTEA 2.8 O SUPERIORE
120 PRAGMA EXTERNAL_EEPROM
125 'USBOUT="START"
130 CONSTANT dLongitude=13.526507
140 CONSTANT dLatitude=45.813530
150 CONSTANT dEarthMeanRadius=6371.01
160 CONSTANT dAstronomicalUnit=149597890
170 ' ----- Calculate difference in days between the current Julian Day
180 ' and JD 2451545.0, which is noon 1 January 2000 Universal Time -----
190 ' Calculate time of the day in UT decimal hours
200 'GG_MM_AA=DATE '
210 'USBOUT="GIORNO MISURE:" & GG_MM_AA & chr(13) & chr(10)
220 'FDATE=4
230 'dDecimalHours =DATE/3600.0 ' 35608/3600.0 '
240 FDATE=2
250 GG_MM_AA=DATE '
260 LCDPOS=&H11
270 LCDWRITE= " PPTEA BOLLE"
280 LCDPOS=&H21
290 LCDWRITE= " SUN POSITION"
300 waits 2
301 LCDCLEAR
302 LCDPOS=&H24
303 FDATE=1
305 LCDWRITE= DATE
310 LCDPOS=&H11
320 LCDWRITE="DATE: "& GG_MM_AA
330 waits 2
340 LCDPOS=amp;H11
350 LCDWRITE= " Lat. Long. "
360 LCDPOS=&H21
370 LCDWRITE= "45.8135 13.5265"
380 waits 2
381 LCDCLEAR
382 LCDPOS=&H11
383 LCDWRITE="START REAL TIME"
384 LCDPOS=&H21
385 LCDWRITE=" ELABORATION"
386 waits 1
387 FDATE=4
388 dDecimalHours =DATE/3600.0 ' 35608/3600.0 '
389 dDecimalHours-=1.0 'metto l'ora sul fuso giusto
390 iMonth=mid(GG_MM_AA,4,2)
400 liAux1=(iMonth-14)/12
410 iYear =right(GG_MM_AA,2)+2000
420 iDay=left(GG_MM_AA,2)
430 liAux2=((1461*(iYear + 4800 + liAux1))/4)
440 liAux2+=(367*(iMonth- 2-12*liAux1))/12
450 liAux2+= -1*(3*((iYear + 4900+ liAux1)/100))/4+iDay-32075
460 dJulianDate= liAux2 - 0.5 + dDecimalHours/24.0
470 ' Calculate difference between current Julian Day and JD 2451545.0
480 dElapsedJulianDays = dJulianDate-2451545.0
490 ' ----- Calculate ecliptic coordinates -----
500 dOmega=2.1429-0.0010394594*dElapsedJulianDays
510 dMeanLongitude = 4.8950630+ 0.01720279169 * dElapsedJulianDays 'Radians
520 dMeanAnomaly = 6.2400600+ 0.0172019699 * dElapsedJulianDays
530 'NV= dMeanAnomaly
540 'GOSUB :NORMALIZZA_VALORE
550 NV1=SIN(dMeanAnomaly)
560 'NV= dMeanAnomaly*2
570 'GOSUB :NORMALIZZA_VALORE
580 NV2=SIN(dMeanAnomaly*2)
590 'NV= dOmega
600 'GOSUB :NORMALIZZA_VALORE
610 NV3=SIN(dOmega)
620 dEclipticLongitude = dMeanLongitude + 0.03341607*NV1+ 0.00034894*NV2-0.0001134 -0.0000203*NV3
630 'USBOUT= "dEclLon=" & dEclipticLongitude
640 'NV= dOmega
650 'GOSUB :NORMALIZZA_VALORE
660 NV1=COS(dOmega)
670 'USBOUT="COS="& NV1
680 dEclipticObliquity = 0.4090928 - (0.00000006214*dElapsedJulianDays)/10 +0.0000396*NV1
690 'USBOUT= " dEclObl=" & dEclipticObliquity
700 'Calculate celestial coordinates ( right ascension and declination )
710 'in radians but without limiting the angle to be less than 2*Pi
720 'NV=dEclipticLongitude
730 'GOSUB :NORMALIZZA_VALORE
740 dSin_EclipticLongitude= sin( dEclipticLongitude )
750 'NV=dEclipticObliquity
760 'GOSUB :NORMALIZZA_VALORE
770 dY = cos( dEclipticObliquity) * dSin_EclipticLongitude
780 'NV=dEclipticLongitude
790 'GOSUB :NORMALIZZA_VALORE
800 dX = cos(dEclipticLongitude)
810 NV2=DY
820 NV1=DX
830 GOSUB :ATAN2
840 dRightAscension = NV1
850 if dRightAscension >= 0.0 THEN 900
860 dRightAscension = dRightAscension + 2*PI
870 'NV=dEclipticObliquity
880 'GOSUB :NORMALIZZA_VALORE
890 dDeclination=sin(dEclipticObliquity)*dSin_EclipticLongitude
900 dDeclination = asin( dDeclination )
910 'USBOUT= " dSinEcl=" & dSin_EclipticLongitude
920 'USBOUT= " dRigAsc=" & dRightAscension
930 'USBOUT= " dDecl=" & dDeclination
940 'Calculate local coordinates ( azimuth and zenith angle ) in degrees
950 dLocalMeanSiderealTime = 6.6974243242 + 0.0657098283 * dElapsedJulianDays + dDecimalHours
960 dLocalMeanSiderealTime= (dLocalMeanSiderealTime*15 + dLongitude)*PI/180
970 liAux1 = dLocalMeanSiderealTime - dRightAscension 'dHourAngle
980 'NV=liAux1
990 'GOSUB :NORMALIZZA_VALORE
1000 'liAux1=NV
1010 'USBOUT=" dHourAngle="& liAux1
1020 liAux2 = dLatitude * PI/180 'dLatitudeInRadians
1030 'USBOUT=" dLat="& liAux2
1040 NV1=cos( liAux2 ) 'dCos_Latitude
1050 'USBOUT=" dCos="& NV1
1060 NV2=sin( liAux2 ) 'dSin_Latitude
1070 'USBOUT=" dSin="& NV2
1080 NV= cos( liAux1 ) 'dCos_HourAngle
1090 'USBOUT=" dCosH="& NV
1100 iMonth=acos(NV1*NV*cos(dDeclination)+sin(dDeclination)*NV2) 'dZenithAngle
1110 'USBOUT=" dZen="& iMonth
1120 dY = -sin( liAux1 )
1130 'USBOUT=" dY="& dy
1140 dX = tan( dDeclination )*NV1-NV2*NV
1150 'USBOUT=" dx="& dx
1160 NV2=DY
1170 NV1=DX
1180 GOSUB :ATAN2
1190 if NV1 > 0 then 1210
1200 NV1 += 2*PI
1210 NV1=NV1/(PI/180)
1212 LCDPOS=&H11
1213 FDATE=4
1215 if DATE mod 10 then :SALT
1216 LCDWRITE= " Azimuth Elevat"'& DATE
1217 GOTO 1220
1218 :SALT FDATE=1
1219 LCDWRITE= " TIME "& DATE
1220 USBOUT=" dAzim="& NV1
1230 LCDPOS=&H22
1240 LCDWRITE=left(NV1,6) 'LCDWRITE="Azimuth="& left(NV1,6)
1250 dParallax=dEarthMeanRadius/dAstronomicalUnit *sin(iMonth)
1260 'USBOUT=" dPar="& dParallax
1270 iMonth=(iMonth+ dParallax)/(PI/180) 'dZenithAngle
1280 USBOUT=" dZen="& iMonth &" "
1290 'LCDPOS=&H21
1299 iMonth=90.0-iMonth
1300 LCDWRITE=" "& left(iMonth,6) 'LCDWRITE="Zenith ="& left(iMonth,6)
1310 'NV= int((dDecimalHours-int(dDecimalHours))*60)
1320 'NV2= int(dDecimalHours *3600 - int(dDecimalHours) *3600 - NV*60)
1330 'MV3=right("0"&int(dDecimalHours),2) &":" & right("0"&NV,2) &":"&right("0"&NV2,2)
1340 'USBOUT=MV3 & chr(13) & chr(10)
1350 'LCDPOS=&H21
1360 'LCDWRITE=" SUNPOS " & MV3
1370 'dDecimalHours+=0.0166666666
1380 goto 387
1390 ':NORMALIZZA_VALORE
1400 'USBOUT=" NV1="& NV
1410 'NV= NV/ (2*PI)
1420 'USBOUT=" NV2="& NV
1430 'L= NV-INT(NV)
1440 'USBOUT=" L="& L
1450 'NV=L*2*PI+2*PI
1460 'USBOUT=" NV3="& NV
1470 RETURN
1480 :ATAN2
1490 IF NV1 > 0 Then 1540
1500 IF NV1 < 0 Then 1560
1510 IF NV2 = 0 Then 1610
1520 NV1= SGN(NV2) * pi / 2
1530 RETURN
1540 NV1= ATAN(NV2 / NV1)
1550 RETURN
1560 NV = SGN(NV2)
1570 NV3 = ABS(NV2 / NV1)
1580 NV3 = ATAN( NV3)
1590 NV1 = NV * (PI - NV3)
1600 RETURN
1610 NV1 = 0.0
1620 RETURN

Si può notare che la funzione ATAN2 non esiste nel PPTEA e quindi è stata realizzata a livello di codice EAbasic.







Valid XHTML 1.0 Strict



[ Back to top ] [ Home ]