Bonsoir
f6exb
le programme pour l'arduino :
//References
//http://www.sunearthtools.com/dp/tools/pos_sun.php?lang=fr / calcul
//
http://herve.silve.pagesperso-orange.fr/solaire.htm
// Ce code calcul à partir d'une horloge en temps réel la position du soleil.
// Explication:
// Azimuth = 0° au Nord
// elevation= 0° à l'horizon
// Le delai est de 30 secondes entre chaqe calcul
// L'affichage ce fait via le moniteur serie du logitiel Arduino (petite loupe en haut à droite)
// Pour l'arduinio UNO, SLC est connecté au pin A5 et SDA au pin A4 uniquement pour l'horloge DS3132 for PI
// le reste est dans le texte
// Bon amusement
// PSEMEL 15/01/16
//=================================librairies=======================================================
#include <math.h>
#include "Wire.h"
// =========================================== constantes ===============================
#define pi 3.14159265358979323846
#define twopi (2*pi)
#define rad (pi/180)
#define EarthMeanRadius 6371.01 // In km
#define AstronomicalUnit 149597890 // In km
//=================================================Horloge DS 3132 FOR PI============================================================
#define DS3231_I2C_ADDRESS 0x68
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return( (val/16*10) + (val%16) );
}
//====================PARAMETRES --------
float Longitude = -2.5686785; //enter longitude du lieu sous le meme format<=======================
float Latitude = 48.1125059; //enter latitude du lieu sous le meme format<=======================
float ZenithAngle;
float Azimuth;
float RightAscension;
float Declination;
float Parallax;
float ElevationAngle;
float ElapsedJulianDays;
float DecimalHours;
float EclipticLongitude;
float EclipticObliquity;
float Sunrise;
int Jmois;
int N1;
int N2;
float K;
int j;
float C;
float L;
float R;
float EOT;// en minute
float declinaison; // en rad
void setup() {
Wire.begin();
Serial.begin(9600);
// set the initial time here:================remise à l'heure du module horloge ===========================
// DS3231 seconds, minutes, hours, day, date, month, year
// setDS3231time(00,45,19,3,16,06,15);=====> Mise à l'heure du module horloge en enlevant // en debut de ligne<=======================
}
// ====================================BOUCLE PRINCIPALE==============================================================
void loop(){
SunPos(); // calcul de l'heure puis calcul de la position
Serial.print("Elevation Angle: ");
Serial.print(ElevationAngle); //Print Elevation (Vertical) with no decimal places as accuracy is not really great enough
Serial.print("Azimuth: ");
Serial.print(Azimuth); //Print Azimuth (Horizontal) with no decimal places
Serial.println();
}
void SunPos() {// =====================================================sous programme principale======================================================
// recuperation des données de l'horloge
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
// retrieve data from DS3231
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
// affichage sur le moniteur serie
Serial.print(hour, DEC);
// convert the byte variable to a decimal number when displayed
Serial.print(":");
Serial.print(minute);
Serial.print(":");
Serial.print(second);
Serial.print(" ");
Serial.print(dayOfMonth);
Serial.print("/");
Serial.print(month);
Serial.print("/");
Serial.print(year);
Serial.print(" Day of week: ");
switch(dayOfWeek){ // ========================Option
case 1:
Serial.println("Sunday");
break;
case 2:
Serial.println("Monday");
break;
case 3:
Serial.println("Tuesday");
break;
case 4:
Serial.println("Wednesday");
break;
case 5:
Serial.println("Thursday");
break;
case 6:
Serial.println("Friday");
break;
case 7:
Serial.println("Saturday");
break;
}// fin option
delay(3000);//=============> delais entre chaque calcul
// conversion des variables horloge/ calcul de la position// on peut optimiser ces 6 lignes
int Year = year;
int Month = month;
int Day = dayOfMonth;
float Hours = hour-1; // pour UTM -2 heure d'ete -1 heure d'hiver<=====================================
float Minutes = minute;
float Secondes = second;
// =======================================================
// Variable tempoporaire et calcul
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)+(Secondes/3600);//
// 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+Parallax)/rad;
ElevationAngle = (90-ZenithAngle); //Retrieve useful elevation angle from Zenith angle
// affichage sur moniteur serie du logitiel arduino
Serial.print("Azimuth=");
Serial.println(Azimuth);
Serial.print("Elevation=");
Serial.println(ElevationAngle);
}
//===================================================HORLOGE Materiel DS3231 for PI === sous programme de mise à l'heure=====================================
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year)
{
// sets time and date data to DS3231
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set next input to start at the seconds register
Wire.write(decToBcd(second)); // set seconds
Wire.write(decToBcd(minute)); // set minutes
Wire.write(decToBcd(hour)); // set hours
Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
Wire.write(decToBcd(month)); // set month
Wire.write(decToBcd(year)); // set year (0 to 99)
Wire.endTransmission();
}
//========================== sous programme de lecture de heure===================================================
void readDS3231time(byte *second,byte *minute,byte *hour,byte *dayOfWeek,byte *dayOfMonth,byte *month,byte *year)
{
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set DS3231 register pointer to 00h
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
// request seven bytes of data from DS3231 starting from register 00h
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f);
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
Ce programme fonctionne avec une horloge RTC DS 3231 et donne la position du soleil en fonction de la longitude et de la latitude.
Il reste a programmer suivant le materiel que tu as de commander des moteurs, d'avoir des butées etc.