IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Projet tracker Solaire un seul axe Zénith, contrôler avec fichier de données csv


Sujet :

Arduino

  1. #41
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    Bravo JP ! superbe boulot poussé jusqu'au bout !!



    une petite modification/précision: de mémoire je crois que le fichier utilisé est en UTC+1 et donc la manip avec recompilation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    	/*-------------------------------------------------------------------------
    		Pour remettre à l'heure la RTC changer le if en
    		if (!rtc.lostPower())
    		Recompiler et télécharger, controler si la date est exacte ensuite
    		le plus rapidement possible faire l'operation inverse
    	'*-------------------------------------------------------------------------
    	*/
    	if (rtc.lostPower())                                             // Si RTC a perdu l'heure
    	{
    		Serial.println(F("\n* * * RTC remise a l'heure * * *"));
    		rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));              // Mettre a l'heure du compilateur
    		//rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));                // Mettre a l'heure manuellement
    	}
    risque de ne pas fonctionner lorsqu'on est en heure d'été (en ce moment donc) => Il faut passer par la mise à l'heure manuelle comme si on était tout le temps en heure d'hiver (UTC+1) sinon il y aura un décalage d'une heure sur les élévations à La Chevallerais, Loire-Atlantique.


    Sinon pour l'élévation:
    - la valeur de l'Elevation minimum peut être négative, c'est quand le soleil est sous l'horizon pour nous, on ne le voit pas encore.
    - la valeur max théorique par définition c'est 90° (le soleil au Zénith) mais ça n'arrive pas en France, il faut aller dans la zone de part et d'autre de l'équateur (entre les tropiques du Cancer et du Capricorne). Là bas le Soleil passe au zénith à midi au solstice d'été et la lumière "tombe alors verticalement".

    PS: Si ça présente un intérêt pour vous ou pour @Forexgum, je vais tâcher de retrouver un vieux bout de code que j'ai dans un coin et qui fait les calculs Astronomique de la position du soleil en fonction de sa position sur terre et de l'heure => ça permettrait de se passer de la carte SD et des mises à jour annuelle du ficher et ce ne serait qu'une petite modification de votre code (juste la partie qui fait l'extraction dans le fichier).

  2. #42
    Futur Membre du Club
    Homme Profil pro
    Agriculteur
    Inscrit en
    Juillet 2020
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Agriculteur

    Informations forums :
    Inscription : Juillet 2020
    Messages : 23
    Points : 6
    Points
    6
    Par défaut
    Bonjour,

    Wha wha wha ! Super ! excellent !

    Très beau travail, je dit Bravo jpbbricole.

    Pendant ce temps je n'ai même pas réussi à trouver le calcule pour la correspondance pourcentage Elévation = nombre de tour , comme celui-ci n'ai pas linéaire.

    Vraiment respect

    Pour ce qui est du matériel la commande pour un interrupteur à butée viens de partir, pour ma configuration il vas falloir que j'inverse l'interrupteur,

    le mettre sur le bout de la tige plutôt qu'au niveau du moteur.

    Bien sur Jay M, que la possibilité de supprimer la carte SD reste très intéressante ,

    Dans tout les cas merci à vous pour votre aide si précieuse sur les réseaux

  3. #43
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonjour Forexgum

    Bonjour

    Juste pour le fun!

    Une version avec terminal Bluetooth. Le hardware est le même, j'ai ajouté un module HC-05.
    Le programme du terrminal a été réalisé avec Bluetooth Electronics (Android)
    du site Keuwl. Cer n'est pas le plus évolué, mais il permet de faire des trucs sympas en 30' et il est très peu "invasif" dans votre programme.
    Ainsi, pour afficher l'élévation, il suffit d'envoyer *E12.7*, le E étant défini dans l'objet affichant l'élévation.
    L'envoi de commandes éventuelles vers l'Arduino, suit la même "mécanique".



    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  4. #44
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    Citation Envoyé par Forexgum Voir le message
    Pendant ce temps je n'ai même pas réussi à trouver le calcule pour la correspondance pourcentage Elévation = nombre de tour , comme celui-ci n'ai pas linéaire.
    Pouvez vous décrire votre montage physique (présence de charnière sur le support du moteur ou montage dans une nacelle avec un degrés de liberté ? et côté miroir ? à moins que vous ne preniez un vérin ?)

    Pour la partie maths: Si vous avez un montage comme celui de votre photo ou de @JP avec une tige couplée sur Le rotor du moteur, votre tige fileté dispose d’un certain pas de vis. Un tour de moteur fait se déplacer linéairement l’écrou de la distance de ce pas de vis. L’angle d’inclinaison du miroir dépend ensuite du montage, par exemple si vous avec couplé l’écrou qui se déplace au sommet du panneau vous modifiez la longueur d’une sorte d’hypoténuse ( si le moteur est sur charnière) et le déplacement sur un plan horizontal du sommet du miroir est donc lié par Pythagore à cette hypoténuse et la dimension du miroir. Y’a de la racine carré et du cosinus dans l’air


    Bien sur Jay M, que la possibilité de supprimer la carte SD reste très intéressante:
    Ok je vais fouiller dans mes vieux codes et extraire les formules

  5. #45
    Futur Membre du Club
    Homme Profil pro
    Agriculteur
    Inscrit en
    Juillet 2020
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Agriculteur

    Informations forums :
    Inscription : Juillet 2020
    Messages : 23
    Points : 6
    Points
    6
    Par défaut
    Bonjour,

    Pouvez vous décrire votre montage physique (présence de charnière sur le support du moteur ou montage dans une nacelle avec un degrés de liberté ? et côté miroir ? à moins que vous ne preniez un vérin ?)
    Le projet est monté avec des charnières au niveau du moteur, ainsi que sur le haut et le bas du panneau, comme sur la photo suivante :

    Nom : cadre_3.jpg
Affichages : 1657
Taille : 126,3 Ko

    Le moteur est relié avec le haut du panneau par une tige fileté de 8 mm de Diamètre, de 1 mètres de Longueur, un écrou est soudé sur la charnière du haut du panneau.

    J'avais fait ce tableau l'autre jour, pour montrer le nombre de tour que je devais faire avec la tige fileté, mis en comparaison avec l'Elévation au même moment de la journée.

    Nom : Screenshot_2020-07-31 Projet tracker Solaire un seul axe Zénith, contrôler avec fichier de donné.png
Affichages : 1636
Taille : 10,2 Ko

    Je vais refaire des prises de mesure manuellement avec la tige fileté et le soleil la semaine prochaine, si besoin.

    Encore un grand Merci

    Cdt.

    Forexgum.

  6. #46
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    OK, j'ai retrouvé mes vieilles notes, je vais essayer de les appliquer à votre cas

    -----------------------------------------

    Vous avez ancré le moteur sur un support pivotant
    Vous avez ancré le miroir sur un support pivotant

    voilà quelques éléments mathématiques pour vous aider à réfléchir :

    définitions:
    Vous avez un miroir de Largeur L
    Vous avez une tige de longueur d
    La distance entre l'ancrage du moteur et du miroir est fixe et vaut D
    en fonction de la rotation du moteur, vous pouvez emmener l'écrou à une distance d1 du moteur

    La première grande question c'est:

    quelle est la relation entre un angle 𝞪 du miroir et la position de l'écrou sur la tige fileté ?


    ça ressemble schématiquement à cela:
    Nom : montage.png
Affichages : 1821
Taille : 204,6 Ko

    En supposant ce montage 'parfait' et avec une tige suffisamment longue, on peut emmener le miroir à la verticale (appelons cela le max -> 𝞪 = 90°) ou le coucher (appelons cela le min -> 𝞪 = 180°).

    Ceci emmène des contraintes sur la distance d1 qui sépare l'écrou (le sommet du miroir) et le moteur.

    Nom : contraintes.png
Affichages : 1603
Taille : 252,3 Ko

    Lorsqu'on est à 90° on a un triangle rectangle et on peut appliquer Pythagore et si l'écrou est ramené au plus près du moteur, comme il est physiquement attaché au sommet du miroir, lorsqu'on est à 180° la distance minimum c'est la distance qui sépare les 2 points d'ancrage moins la largeur du miroir. (d'où dMIN = D - L)

    Lorsque vous êtes en fonction, l'écrou se trouve donc à une certaine distance d1 du moteur et on peut décrire certaines distances ainsi

    Nom : enFonction.png
Affichages : 1627
Taille : 128,0 Ko

    en utilisant Pythagore et la définition du cosinus (en valeur absolue d'où le carré) on peut écrire les relations suivantes qui en regroupant et simplifiant nous emmène aux formules suivantes:
    Nom : maths.png
Affichages : 1585
Taille : 359,3 Ko


    en rentrant ces 2 formules dans un tableur on voit que ça a l'air de bien correspondre intuitivement:
    Nom : tableur.png
Affichages : 1582
Taille : 59,0 Ko
    si on fixe la distance entre nos distances max et min pour la position de l'écrou on voit l'angle qui varie entre 90° et 179° (à l'arrondi près)
    si on fait varier l'angle entre 90° et 180° on retrouve bien nos distances max et min.


    --------------------------------------------------

    La seconde grande question c'est:

    étant donné une élévation du soleil (qui donne donc des rayons incidents sur le miroir), à quel angle 𝞪 faut il orienter le miroir pour que le rayon réfléchi parte à l'horizontal.



    Tout se fonde sur les Lois de Snell-Descartes: Ces lois sont au nombre de quatre, deux pour la réflexion et deux pour la réfraction. On s'intéresse simplement à la réflexion et le principe qui dit que "les faisceaux incidents et réfléchis forment avec la normale le même angle".

    Nom : loi.png
Affichages : 1651
Taille : 162,5 Ko

    ici les maths ne sont pas très compliqués, il suffit de se souvenir que la somme des angles pour faire un angle plat fait 180° et on obtient la formule magique

    Angle de renvoi = 2 𝞪 + 180 - élévation

    par exemple si l'élévation du soleil est de 45° et que le miroir est mis à -30°, les rayons repartent à 75°
    Nom : exemple.png
Affichages : 1631
Taille : 119,1 Ko


    et donc si vous voulez que le miroir renvoie les rayons du soleil qui est à une élévation connue à l'horizontal ça veut dire que l'on veut un angle de renvoi nul et donc on cherche alpha (l'angle du miroir) pour que:
    2 𝞪 + 180 - élévation = 0
    ce n'est pas très difficile à résoudre et on obtient donc
    𝞪 = (élévation - 180) / 2


    sur le même exemple on voit bien que le rayon vert repart à l'horizontal maintenant qu'on a mis le miroir à -67,5°

    Nom : solution.png
Affichages : 1600
Taille : 176,0 Ko


    --------------------------------------------------

    Voilà, quand on a fait cela on a fait une bonne partie du chemin. ensuite il suffit de se souvenir que un tour de moteur fait bouger l'écrou d'une distance ∆d qui équivaut au pas de la tige filetée. Si vous savez où vous êtes sur la tige et que vous voulez allez vers un autre angle, les formules ci dessus vous donnent ce qu'il faut pour calculer la distance à parcourir et donc le nombre de tours / pas à faire sur le moteur.



    j'espère que ça vous aidera.

  7. #47
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    Voici des formules magiques

    Les calculs sont basés sur les équations et algorithmes astronomiques, par Jean Meeus tels que repris dans les outils du NOAA (l'Agence américaine d'observation océanique et atmosphérique)

    La hauteur du Soleil est l’angle que fait la direction du Soleil avec le plan horizontal. Elle se compte de 0° à partir de l’horizon à 90°vers la voûte céleste.
    L’azimut du Soleil est l’angle créé entre le plan vertical passant à la fois par le Soleil et par l'observateur, et le plan vertical N-S. Cet angle vaut 0° au Nord et est positif (90°) à l’est , 180° au sud, 270° à l'ouest

    Les approximations (développements à 1,2 ou 3 termes) utilisées dans ces programmes sont bonnes pour les années comprises entre 1800 et 2100. En raison des variations de la composition atmosphérique, de la température, de la pression et des conditions, les valeurs observées peuvent différer des calcul.

    Sur un Arduino UNO/MEGA qui n'a pas de double précision, les calculs ne seront pas super précis à cause des arrondis et limitations dans les calculs mathématiques et propagation de ces approximations dans les formules suivantes. Si l'on s'en tient au final à l'arrondi au degrès le plus proche (suffisant dans bien des usages car les systèmes des bidouilleurs du dimanche comme moi ont bien d'autres imprécisions mécaniques de toutes façons )

    Vous pouvez utiliser cet outil web pour générer des calculs similaires (pas tout à fait identiques) ce qui permet de voir que l'algo codé ici est suffisamment proche de la réalité (au degrés près grosso modo).

    Attention à la définition des heures dans les différents outils que l'on trouve. Généralement il ne tiennent pas compte de l'heure locale avec été/hiver mais de l'heure vraie. Le calcul ci dessous se fait idealement en calant la rtc sur l'heure UTC et en mettant deltaTimeZone à 0 (comme cela il n'y a pas à changer le programme aux changements d'heure). Mais si votre RTC est à l'heure locale française métropolitaine, définissez ici la différence d'heure dans la variable deltaTimeZone (+1 pendant l'heure d'hiver et +2 à l'heure d'été).


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    /* ****************************************************************************************************
    
      AUTHOR: JAY, for the arduino forum on developpez.net
    
      Les calculs sont basés sur les équations et algorithmes astronomiques, par Jean Meeus.  https://www.willbell.com/math/mc1.htm
    
      En raison des variations de la composition atmosphérique, de la température, de la pression et des conditions,
      les valeurs observées peuvent différer des calculs
    
      Les approximations utilisées dans ces programmes sont bonnes pour les années comprises entre 1800 et 2100.
    
      La hauteur du Soleil est l’angle que fait la direction du Soleil avec le plan horizontal.
      Elle se compte de 0° à partir de l’horizon à 90°vers la voûte céleste.
    
      L’azimut du Soleil est l’angle créé entre le plan vertical passant à la fois par le Soleil et par l'observateur,
      et le plan vertical N-S. Cet angle vaut 0° au Nord et est  positif (90°) à l’est , 180° au sud, 270° à l'ouest
    
      Sur un Arduino UNO/MEGA qui n'a pas de double précision, les calculs ne seront pas super précis à cause des arrondis
      et limitations dans les calculs mathématiques et propagation de ces approximations dans les formules suivantes.
      Si l'on s'en tient au final à l'arrondi au degrès le plus proche (suffisant dans bien des usages car les systèmes de bidouilleurs du
      dimanche comme moi ont bien d'autres imprécisions mécaniques de toutes façon)
    
      Vous pouvez utiliser cet outil web
      https://www.suncalc.org/#/47.4908,-1.6653,15.776666666666666/2020.07.29/09:59/1/3
      pour générer des calculs similaires (pas tout à fait identiques) ce qui permet de voir que l'algo codé ici
      est suffisament proche de la réalité.
    
    */
    
    //**********************************************************
    // VARIABLES GLOBALES: EN QUEL POINT DU GLOBE ETES VOUS ?
    //double latitude = 48.85717; // PARIS
    //double longitude = 2.34140; // PARIS
    double latitude = 47.4907682;   // La Chevallerais, Loire-Atlantique
    double longitude = -1.6653535;  
    //**********************************************************
    
    
    // ***********************************************************************
    // IDEALEMENT CALER LA RTC SUR L'HEURE UTC ET METTRE deltaTimeZone à 0
    // comme cela il n'y a pas à changer le programme aux changements d'heure
    // Si votre RTC est à l'heure locale, définissez ici la différence d'heure.
    
    int8_t deltaTimeZone = +2;  //  UTC+1 pendant l'heure d'hiver et UTC+2 à l'heure d'été
    // ***********************************************************************
    
    
    
    #include <RTClib.h>
    
    RTC_DS3231 rtc;
    const char* nomDesJours[] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
    
    void erreurFatale(const __FlashStringHelper *message)
    {
      Serial.print(F("ERREUR: ")); Serial.println(message);
      while (true); // on meurt là
    }
    
    void afficherSurDeuxChiffres(uint16_t nombre)
    {
      if (nombre < 10) Serial.write('0');
      Serial.print(nombre);
    }
    
    inline double RADIANS(double a)
    {
      return a * (M_PI / 180.0);
    }
    
    inline double DEGRES(double a)
    {
      return a * (180.0 / M_PI);
    }
    
    void calculAstro(double latitude,         /* Latitude  (positive vers le Nord) */
                     double longitude,        /* Longitude (positive vers l'Est */
                     int8_t deltaTimeZone,    /* Time Zone (positive vers l'Est) */
                     uint32_t nombreDeJours,  /* nombre de jours depuis le 1er Janvier 1900 */
                     uint32_t nbSec           /* nombre de secondes écoulées depuis minuit */)
    {
      double heureLocale = ((double) nbSec) / (24.0 * 3600.0); // fraction de jour
      double jourJulien = 2415018.5 + (double) nombreDeJours + (double) heureLocale - ((double) deltaTimeZone) / 24.0;
      double siecleJulien = (jourJulien - 2451545L) / 36525L;
      double geomMeanLong = fmod(280.46646 + siecleJulien * (36000.76983 + siecleJulien * 0.0003032), 360);
      double geomMeanAnom = 357.52911 + siecleJulien * (35999.05029 - 0.0001537 * siecleJulien);
      double eccentEarthOrbit = 0.016708634 - siecleJulien * (0.000042037 + 0.0000001267 * siecleJulien);
      double sunEquationOfCtr = sin(RADIANS(geomMeanAnom)) * (1.914602 - siecleJulien * (0.004817 + 0.000014 * siecleJulien)) + sin(RADIANS(2 * geomMeanAnom)) * (0.019993 - 0.000101 * siecleJulien) + sin(RADIANS(3 * geomMeanAnom)) * 0.000289;
      double sunTrueLong = geomMeanLong + sunEquationOfCtr;
      double sunAppLong = sunTrueLong - 0.00569 - 0.00478 * sin(RADIANS(125.04 - 1934.136 * siecleJulien));
      double meanObliqEcliptic = 23 + (26 + ((21.448 - siecleJulien * (46.815 + siecleJulien * (0.00059 - siecleJulien * 0.001813)))) / 60) / 60;
      double obliqCorrection = meanObliqEcliptic + 0.00256 * cos(RADIANS(125.04 - 1934.136 * siecleJulien));
      double sunDeclin = DEGRES(asin(sin(RADIANS(obliqCorrection)) * sin(RADIANS(sunAppLong))));
      double varY = tan(RADIANS(obliqCorrection / 2)) * tan(RADIANS(obliqCorrection / 2));
      double equationOfTime = 4 * DEGRES(varY * sin(2 * RADIANS(geomMeanLong)) - 2 * eccentEarthOrbit * sin(RADIANS(geomMeanAnom)) + 4 * eccentEarthOrbit * varY * sin(RADIANS(geomMeanAnom)) * cos(2 * RADIANS(geomMeanLong)) - 0.5 * varY * varY * sin(4 * RADIANS(geomMeanLong)) - 1.25 * eccentEarthOrbit * eccentEarthOrbit * sin(2 * RADIANS(geomMeanAnom)));
      double trueSolarTime = fmod(heureLocale * 1440 + equationOfTime + 4 * longitude - 60 * deltaTimeZone, 1440);
      double hourAngle = (trueSolarTime / 4 < 0) ? (trueSolarTime / 4 + 180) : (trueSolarTime / 4 - 180);
      double solarZenithAngle = DEGRES(acos(sin(RADIANS(latitude)) * sin(RADIANS(sunDeclin)) + cos(RADIANS(latitude)) * cos(RADIANS(sunDeclin)) * cos(RADIANS(hourAngle))));
      double solarElevationAngle = 90 - solarZenithAngle;
    
      double approxAtmosphericRefractionAngle ;
      if (solarElevationAngle > 85) approxAtmosphericRefractionAngle = 0;
      else if (solarElevationAngle > 5)
        approxAtmosphericRefractionAngle = 58.1 / tan(RADIANS(solarElevationAngle)) - 0.07 / pow(tan(RADIANS(solarElevationAngle)), 3) + 0.000086 / pow(tan(RADIANS(solarElevationAngle)), 5);
      else if (solarElevationAngle > -0.575) approxAtmosphericRefractionAngle = 1735 + solarElevationAngle * (-518.2 + solarElevationAngle * (103.4 + solarElevationAngle * (-12.79 + solarElevationAngle * 0.711)));
      else approxAtmosphericRefractionAngle = -20.772 / tan(RADIANS(solarElevationAngle));
      approxAtmosphericRefractionAngle /= 3600.0;
    
      double finalSolarElevation = solarElevationAngle + approxAtmosphericRefractionAngle;
      double finalAzimutAngle = (hourAngle > 0) ?
                                fmod(DEGRES(acos(((sin(RADIANS(latitude)) * cos(RADIANS(solarZenithAngle))) - sin(RADIANS(sunDeclin))) / (cos(RADIANS(latitude)) * sin(RADIANS(solarZenithAngle))))) + 180, 360) :
                                fmod(540 - DEGRES(acos(((sin(RADIANS(latitude)) * cos(RADIANS(solarZenithAngle))) - sin(RADIANS(sunDeclin))) / (cos(RADIANS(latitude)) * sin(RADIANS(solarZenithAngle))))), 360);
    
      Serial.print(nbSec / 3600UL);
      Serial.write(':');
      afficherSurDeuxChiffres((nbSec % 3600UL) / 60);
      Serial.write('\t');
      Serial.print(finalAzimutAngle, 1);
      Serial.print("°\t");
      Serial.print(finalSolarElevation, 1);
    
      Serial.print("°\n");
    }
    
    void setup() {
      uint32_t nombreDeJours;        // nombre de jours depuis le 1er Janvier 1900
      Serial.begin(115200);
    
      if (! rtc.begin()) erreurFatale(F("Horloge RTC introuvable"));
      // IDEALEMENT UTILISER L'HEURE UTC ET PAS L'HEURE LOCALE
      rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // à faire UNE FOIS si votre RTC n'est pas à jour pour la mettre à l'heure sinon commenter.
      // rtc.adjust(DateTime(2020, 1, 2, 10, 30, 0)); // ou pour essayer une date précise, ici le 2 janvier à 10h30
    
      DateTime maintenant = rtc.now(); // l'heure actuelle
      DateTime premierJanvier2020(2020, 1, 1, 0, 0, 0); // point de référence 1er Janvier 2020 à 0h00 UTC
      TimeSpan depuisLePremierJanvier2020 = maintenant - premierJanvier2020 ; // la différence de temps entre maintenant et le 1/1/1900
      nombreDeJours = 43829UL + depuisLePremierJanvier2020.days() ; // + 43829 jours pour compter à partir de 1/1/1900
    
      Serial.print(nomDesJours[maintenant.dayOfTheWeek()]);
      Serial.write(' ');
      Serial.print(maintenant.day());
      Serial.write('/');
      Serial.print(maintenant.month());
      Serial.write('/');
      Serial.print(maintenant.year());
      Serial.write('\t');
      Serial.print(maintenant.hour());
      Serial.write(':');
      afficherSurDeuxChiffres(maintenant.minute());
      Serial.write(':');
      afficherSurDeuxChiffres(maintenant.second());
      Serial.print(F("\nJour N° ")); Serial.println(nombreDeJours);
    
      Serial.println("\nHeure\tAzimut\tElevation");
    
      for (uint32_t moment = 22500; moment <= 79200UL; moment += 900UL) { // de 6h15 à 22h00
        calculAstro(latitude, longitude, deltaTimeZone, nombreDeJours, moment); // toutes les 15 minutes
      }
    
    }
    
    void loop() {}
    si vous faites tourner ce programme sur un UNO vous aurez dans le moniteur série (à 115200 bauds) l'affichage suivant qui correspond à l'azimut et élévation pour la latitude = 47.4907682 et longitude = -1.6653535 (en Loire-Atlantique) pour aujourd'hui entre 6h15 et 22h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    Jour N° 44041
     
    Heure	Azimut	Elevation
    6:15	55.8°	-4.5°
    6:30	58.7°	-2.3°
    6:45	61.5°	0.2°
    7:00	64.2°	2.3°
    7:15	66.9°	4.5°
    7:30	69.6°	6.8°
    7:45	72.2°	9.1°
    8:00	74.9°	11.5°
    8:15	77.5°	14.0°
    8:30	80.1°	16.5°
    8:45	82.8°	19.0°
    9:00	85.5°	21.4°
    9:15	88.2°	24.0°
    9:30	91.0°	26.5°
    9:45	93.8°	29.0°
    10:00	96.7°	31.5°
    10:15	99.7°	34.0°
    10:30	102.8°	36.5°
    10:45	106.0°	39.0°
    11:00	109.4°	41.4°
    11:15	113.1°	43.8°
    11:30	116.9°	46.0°
    11:45	121.0°	48.3°
    12:00	125.3°	50.4°
    12:15	130.1°	52.4°
    12:30	135.1°	54.3°
    12:45	140.6°	56.0°
    13:00	146.4°	57.5°
    13:15	152.7°	58.7°
    13:30	159.4°	59.8°
    13:45	166.4°	60.5°
    14:00	173.6°	61.0°
    14:15	180.9°	61.1°
    14:30	188.2°	60.9°
    14:45	195.4°	60.4°
    15:00	202.3°	59.5°
    15:15	208.8°	58.4°
    15:30	215.0°	57.0°
    15:45	220.8°	55.5°
    16:00	226.1°	53.8°
    16:15	231.1°	51.9°
    16:30	235.7°	49.8°
    16:45	240.0°	47.7°
    17:00	244.0°	45.4°
    17:15	247.8°	43.1°
    17:30	251.4°	40.8°
    17:45	254.7°	38.3°
    18:00	258.0°	35.9°
    18:15	261.0°	33.4°
    18:30	264.0°	30.9°
    18:45	266.9°	28.3°
    19:00	269.7°	25.8°
    19:15	272.4°	23.3°
    19:30	275.1°	20.8°
    19:45	277.8°	18.3°
    20:00	280.4°	15.8°
    20:15	283.1°	13.3°
    20:30	285.7°	10.9°
    20:45	288.3°	8.5°
    21:00	291.0°	6.1°
    21:15	293.6°	3.8°
    21:30	296.4°	1.6°
    21:45	299.1°	-0.6°
    22:00	301.9°	-3.0°

    voilà - avec cela plus besoin de fichier et carte SD jusqu'en 2100 au moins

    Vous avez tout ce qu'il faut pour avancer !!!

    En combinant l'angle obtenu dans le code ci dessus avec les formules mathématiques de mon autre post et en modifiant le code de @JP bricole qui utilisait en première approximation une fonction linéaire pour le calcul du déplacement (et qui n’est pas trop loin de la vérité en interpolant entre les 2 bonnes valeurs) --> la ligne à modifier serait là
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long sunTraSteps = (newPosition * 100.0)/sunTra.sunTraSteps;
    amusez vous bien !

  8. #48
    Futur Membre du Club
    Homme Profil pro
    Agriculteur
    Inscrit en
    Juillet 2020
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Agriculteur

    Informations forums :
    Inscription : Juillet 2020
    Messages : 23
    Points : 6
    Points
    6
    Par défaut
    Bonjour,

    Super intéressent ce cour de math Jay M

    mais du coup je me demande si je ne pourrais pas me servir d'un capteur d'angle branché sur l'Arduino,

    positionner sur le coté du miroir afin de comparer le résultat avec la formule : (( Elévation - 180 ) / 2 ) -180.

    Avec les formules magiques placé dans le code, après la suppression de la SD,

    cela pourrais me permettre l'installation d'une carte d’extension CNC avec quatre A4988 qui ferait tous la même chose.

    Avec tous ça le code que Jpbbricole à écrit risque d'être chamboulé

    Mais je crois que la suite du projet va être encore très intéressent

    Encore un super boulot merci beaucoup.

    Cdt.

    Forexgum.

  9. #49
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    Citation Envoyé par Forexgum Voir le message
    mais du coup je me demande si je ne pourrais pas me servir d'un capteur d'angle branché sur l'Arduino, positionné sur le coté du miroir afin de comparer le résultat avec la formule : (( Elévation - 180 ) / 2 ) -180.
    Salut
    oui si vous pouviez avoir un retour direct, ça simplifierait.
    vous avez l'élévation, vous en déduisez l'angle du miroir pour le renvoi horizontal et vous pilotez le moteur dans le bon sens jusqu'à atteindre cet angle.

  10. #50
    Futur Membre du Club
    Homme Profil pro
    Agriculteur
    Inscrit en
    Juillet 2020
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Agriculteur

    Informations forums :
    Inscription : Juillet 2020
    Messages : 23
    Points : 6
    Points
    6
    Par défaut
    Bonjour,

    Un p'tit conseil pour choisir un capteur d'angle ,

    soit un simple potentiomètre où un inclinomètre du style ADXL335 où ... ?

    Bonne journée.

    Cdt.

    Forexgum.

  11. #51
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    Il faudrait un bon potentiomètre avec moins de 1% d’erreur sinon un inclinomètre bien calibré sera plus précis sans doute car liaison numérique.

  12. #52
    Membre habitué Avatar de two3d
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2012
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Novembre 2012
    Messages : 126
    Points : 168
    Points
    168
    Par défaut
    Salut, je cherche à faire un programme similaire mais plus simple, sans fichier a rentrer et en ayant conscience que le soleil monte en été.

    Mon idée, simple et de placer le panneau solaire sur un axe, voir piece jointe:
    Nom : trackersolaire.png
Affichages : 1551
Taille : 11,1 Ko)

    et d'enclencher un moteur qui fait pivoter le panneau toutes les 10min en début de journée puis 1h au milieu de la journée car le soleil bouge pas beaucoup puis de nouveau 10min (les timing sont données à titre d'exemple, voir dans la journée les timing qui correspondrait le mieux et le programmer dans l'arduino)

    EN fin de journée, faire revenir le moteur au début via la programmation en imaginant une horloge dans l'arduino, je suis totalement novice avec arduino et ne sait pas si il a une fonction horloge intégré...

    Qu'est ce que vous en pensez ? vous voulez peut être avoir le meilleur degré possible, dans ce cas je comprendrais...

  13. #53
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    Citation Envoyé par two3d Voir le message
    , je suis totalement novice avec arduino et ne sait pas si il a une fonction horloge intégré...

    Qu'est ce que vous en pensez ? vous voulez peut être avoir le meilleur degré possible, dans ce cas je comprendrais...
    non pas d’horloge intégrée, il faut un composant à côté. Le plus simple c’est une RTC ou alors un accès internet ou un gps ou décodage signal radio

    Ce que j’en pense ? Est-ce pour un panneau solaire ? Si oui le coût des moteurs, du montage tracker, de la maintenance de parties mobiles, etc dépasse souvent le coût de rajouter un panneau ou en prendre un 30% (le gain Max attendu en traquant) plus puissant et le faire pointer vers le sud à une élévation moyenne fixe

    Je ne comprends pas ce que vous voulez dire par
    vous voulez peut être avoir le meilleur degré possible, dans ce cas je comprendrais
    vous pouvez clarifier ?

  14. #54
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    Citation Envoyé par Jay M Voir le message
    Voici des formules magiques
    ...
    Notez un bug dans le code posté ci dessous. Il y a un décalage de deux jours...

    Il faut changer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     nombreDeJours = 43829UL + depuisLePremierJanvier2020.days() ; // + 43829 jours pour compter à partir de 1/1/1900
    en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     nombreDeJours = 43831UL + depuisLePremierJanvier2020.days() ; // + 43829 jours pour compter à partir de 1/1/1900 plus 2
    car sinon on ne compte pas à partir de 1 pour le 1/1/1900 ni le jour en cours, donc faut rajouter 2.

  15. #55
    Membre habitué Avatar de two3d
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2012
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Novembre 2012
    Messages : 126
    Points : 168
    Points
    168
    Par défaut
    Citation Envoyé par Jay M Voir le message
    Je ne comprends pas ce que vous voulez dire par "vous voulez peut être avoir le meilleur degré possible, dans ce cas je comprendrais " vous pouvez clarifier ?
    Ya pas vraiment besoin d'être au degré prés (pour moi du moins) juste une inclinaison "correcte" fera très bien l'affaire, c'est pourquoi je ne vois pas l'utilité de rentrer des données d'inclinaison (azimuth, etc..).

    Ya pas d'horloge, d'accord mais ya til un système qui comprend le temps ? par exemple on lui dit "maintenant c'est 12h" et à partir de ce temps il sait faire +1sec, +1sec, +1sec... ?

    Dans tous les cas, un panneau solaire nécessite un entretient (enlèvement de la neige, nettoyage de celui-ci pour mieux réceptionner le soleil,...) donc ma conclusion est qu'on peut très bien venir tous les mois pour incliner le panneau (l'inclinaison du bas sur mon schéma) par rapport au soleil et aussi pour enregistrer le temps d'intervalle entre chaque activation du moteur au fil de la journée pour l'incliner correctement de l'axe du haut (sur mon schéma) (ce sont des données que le propriétaire devra rentrer chaque mois, pendant une année, les années suivantes, ça ne bougera pas).

  16. #56
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 711
    Points : 5 390
    Points
    5 390
    Par défaut
    Citation Envoyé par two3d Voir le message
    Ya pas vraiment besoin d'être au degré prés (pour moi du moins) juste une inclinaison "correcte" fera très bien l'affaire, c'est pourquoi je ne vois pas l'utilité de rentrer des données d'inclinaison (azimuth, etc..).
    les formules ci dessous donnent l'azimut et l'élévation. prenez juste l'élévation si vous ne voulez pas changer l'azimut et toujours pointer juste plein sud.

    L'azimut idéal change quand même pas mal dans une journée, le soleil voyageant d'est en ouest (en ce moment à 64° par rapport au Nord au lever, au sud (180°) vers 14h et se couchant à l'ouest vers 296°). Si vous n'êtes pas à ça près, pourquoi le seriez vous pour le changement d'élévation plus particulièrement ? et comme dit précédemment, si vous prenez un panneau légèrement (15% puisque vous n'adaptez pas au mieux en azimut) plus puissant et vous n'aurez aucune manipulation à effectuer et le support sera plus simple et moins couteux à bâtir.

    Ya pas d'horloge, d'accord mais ya til un système qui comprend le temps ? par exemple on lui dit "maintenant c'est 12h" et à partir de ce temps il sait faire +1sec, +1sec, +1sec... ?
    Un peu (cf Arduino Time library et https://github.com/PaulStoffregen/Time), mais l'horloge de votre Arduino qui est supposée tourner à 16Mhz n'est pas précise du tout (l'oscillateur présent à l'origine sur la carte n'est pas un quartz mais un résonateur) et donc vous allez dériver assez vite. Une carte DS3231 fonctionne des années avec une petite pile bouton intégrée souvent et coûte un peu plus d' 1€ (en Asie). Donc faut pas s'en priver.

    ce sont des données que le propriétaire devra rentrer chaque mois, pendant une année, les années suivantes, ça ne bougera pas
    pourquoi ne pas les rentrer d'un coup ou les calculer ?

  17. #57
    Membre habitué Avatar de two3d
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2012
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Novembre 2012
    Messages : 126
    Points : 168
    Points
    168
    Par défaut
    Citation Envoyé par Jay M Voir le message
    pourquoi ne pas les rentrer d'un coup ou les calculer ?
    là je vous rejoins totalement, je ny avait pas pensé

  18. #58
    Futur Membre du Club
    Homme Profil pro
    Agriculteur
    Inscrit en
    Juillet 2020
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Agriculteur

    Informations forums :
    Inscription : Juillet 2020
    Messages : 23
    Points : 6
    Points
    6
    Par défaut
    Bonjour à tous

    Alors me revoilà et pas avec de bonne nouvelle

    Le projet avance mais je suis bloqué sur la partie coordination de l'ensemble,

    Quelque changement au niveau matériel, toujours à la base un Arduino Uno, avec une RTC DS3231, un drivers A4988, un moteur nema 17, et un accéléromètre ADXL335.

    J'ai essayer de jongler entre le code de jpbbricole , et les formules magique de Jay M encore Merci, en y rajoutant un petit bout de code,

    pour transformer l'accéléromètre en capteur d'angle, jusque là tout va bien il me sort bien les infos dans le moniteur,

    mais je suis complètement perdu pour récupérer l'élévation obtenu avec les formules magiques pour ensuite faire l'opération : (( Elévation - 180 ) / 2 ) -180,

    et comparer le résultat avec le capteur d'angle pour que le moteur rectifie la différence entre les angles obtenu.

    Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
     
     /******************************************************************************
        Name:       ARDDEV_SunTrackerSD.ino
        Created:    28.07.2020 16 :00 :00
        Author:     jpbbricole
            
    '******************************************************************************
    */
     
    /* ****************************************************************************************************
     
      AUTHOR: JAY, for the arduino forum on developpez.net
     
    *******************************************************************************
    */
     
    //**********************************************************
    // VARIABLES GLOBALES: EN QUEL POINT DU GLOBE ETES VOUS ?
    //double latitude = 48.85717; // PARIS
    //double longitude = 2.34140; // PARIS
    double latitude = 47.4907682;   // La Chevallerais, Loire-Atlantique
    double longitude = -1.6653535;  
    //**********************************************************
     
     
    // ***********************************************************************
    // IDEALEMENT CALER LA RTC SUR L'HEURE UTC ET METTRE deltaTimeZone à 0
    // comme cela il n'y a pas à changer le programme aux changements d'heure
    // Si votre RTC est à l'heure locale, définissez ici la différence d'heure.
     
    int8_t deltaTimeZone = +2;  //  UTC+1 pendant l'heure d'hiver et UTC+2 à l'heure d'été
    // ***********************************************************************
     
     
     
    #include <RTClib.h>                                                   // https://github.com/adafruit/RTClib
    #include <LiquidCrystal.h> 
     
    LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
    float pot1 = A0;
    float pot2 = A1; 
     
    //===================================== Parametres
    //------------------------------------- Sun tracker (sunTra)
    String sunTraFileName= "SunData.csv";                                // Nom du fichier de donnees (Max. 8 caracteres + extension)
    const float sunTraElevationMin = 0.0;                                // Elevation minimum
    const float sunTraElevationMax = 180.0;                              // Elevation maximum
     
    //------------------------------------- Moteur pas a pas (MPAP)
    #define mpapRpm 180                                                  // MPAP tours/Minute
    const unsigned long mpapStepsTour = 200;                             // MPAP pas/tour
    const boolean mpapReverse = true;                                    // MPAP inverser le sens de rotation
     
    const unsigned long mpapVisLongMm = 100;                             // MPAP longueure vis en MM
    #define mpapVisPasMm100 80                                           // MPAP pas de vis en MM100
     
    #define mpapEnaPinStatus LOW                                         // Etat de la pin pour mettre le A4988 ENAble
    const unsigned long mpapEnaTimout = 4000;                            // Temps avant mise en Disable le A4988 ENA = !mpapEnaPinStatus
    unsigned long mpapEnaTimoutChrono = 0;                               // Pour chronometrer le timout
     
     
    //------------------------------------- Demo
    const unsigned long demoTempo = 1000;                                // Toutes les secondes
     
    //===================================== Parametres FIN
     
    //------------------------------------- Sun tracker (sunTra)
    struct sunTrackerDef                                                 // Objet motaur pas à pas
    {String date; int heure; float posElevation[24]; int elevationMin; int elevationMax; float sunTraSteps;};
    sunTrackerDef sunTra;
     
    #define sunTraLedActivityPin 3                                       // LED temoin d'activite
    unsigned long sunTraLedActivityChrono = millis();
     
    //------------------------------------- Stepper (mpap)
    #define mpapMicroSteps 1                                             // MPAP 1 = pas de micro pas
    #define mpapDirPin 7                                                 // Driver A4988 DIR
    #define mpapStepPin 8                                                // Driver A4988 STEP
    #define mpapEnaPin 9                                                 // Driver A4988 ENA
    #include "A4988.h"                                                   // https://www.arduinolibraries.info/libraries/stepper-driver
    A4988 mpap(mpapStepsTour, mpapDirPin, mpapStepPin);
     
    struct mpapParamDef                                                  // Objet motaur pas à pas
    {long posSteps; unsigned long pasTotal; boolean reverse;};
    mpapParamDef mpapPar;
     
     
    //------------------------------------- RTC
    RTC_DS3231 rtc;
     const char* nomDesJours[] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
     
    void erreurFatale(const __FlashStringHelper *message)
    {
      Serial.print(F("ERREUR: ")); Serial.println(message);
      while (true); // on meurt là
    }
     
    void afficherSurDeuxChiffres(uint16_t nombre)
    {
      if (nombre < 10) Serial.write('0');
      Serial.print(nombre);
    }
     
    inline double RADIANS(double a)
    {
      return a * (M_PI / 180.0);
    }
     
    inline double DEGRES(double a)
    {
      return a * (180.0 / M_PI);
    }
     
    void calculAstro(double latitude,         /* Latitude  (positive vers le Nord) */
                     double longitude,        /* Longitude (positive vers l'Est */
                     int8_t deltaTimeZone,    /* Time Zone (positive vers l'Est) */
                     uint32_t nombreDeJours,  /* nombre de jours depuis le 1er Janvier 1900 */
                     uint32_t nbSec           /* nombre de secondes écoulées depuis minuit */)
    {
      double heureLocale = ((double) nbSec) / (24.0 * 3600.0); // fraction de jour
      double jourJulien = 2415018.5 + (double) nombreDeJours + (double) heureLocale - ((double) deltaTimeZone) / 24.0;
      double siecleJulien = (jourJulien - 2451545L) / 36525L;
      double geomMeanLong = fmod(280.46646 + siecleJulien * (36000.76983 + siecleJulien * 0.0003032), 360);
      double geomMeanAnom = 357.52911 + siecleJulien * (35999.05029 - 0.0001537 * siecleJulien);
      double eccentEarthOrbit = 0.016708634 - siecleJulien * (0.000042037 + 0.0000001267 * siecleJulien);
      double sunEquationOfCtr = sin(RADIANS(geomMeanAnom)) * (1.914602 - siecleJulien * (0.004817 + 0.000014 * siecleJulien)) + sin(RADIANS(2 * geomMeanAnom)) * (0.019993 - 0.000101 * siecleJulien) + sin(RADIANS(3 * geomMeanAnom)) * 0.000289;
      double sunTrueLong = geomMeanLong + sunEquationOfCtr;
      double sunAppLong = sunTrueLong - 0.00569 - 0.00478 * sin(RADIANS(125.04 - 1934.136 * siecleJulien));
      double meanObliqEcliptic = 23 + (26 + ((21.448 - siecleJulien * (46.815 + siecleJulien * (0.00059 - siecleJulien * 0.001813)))) / 60) / 60;
      double obliqCorrection = meanObliqEcliptic + 0.00256 * cos(RADIANS(125.04 - 1934.136 * siecleJulien));
      double sunDeclin = DEGRES(asin(sin(RADIANS(obliqCorrection)) * sin(RADIANS(sunAppLong))));
      double varY = tan(RADIANS(obliqCorrection / 2)) * tan(RADIANS(obliqCorrection / 2));
      double equationOfTime = 4 * DEGRES(varY * sin(2 * RADIANS(geomMeanLong)) - 2 * eccentEarthOrbit * sin(RADIANS(geomMeanAnom)) + 4 * eccentEarthOrbit * varY * sin(RADIANS(geomMeanAnom)) * cos(2 * RADIANS(geomMeanLong)) - 0.5 * varY * varY * sin(4 * RADIANS(geomMeanLong)) - 1.25 * eccentEarthOrbit * eccentEarthOrbit * sin(2 * RADIANS(geomMeanAnom)));
      double trueSolarTime = fmod(heureLocale * 1440 + equationOfTime + 4 * longitude - 60 * deltaTimeZone, 1440);
      double hourAngle = (trueSolarTime / 4 < 0) ? (trueSolarTime / 4 + 180) : (trueSolarTime / 4 - 180);
      double solarZenithAngle = DEGRES(acos(sin(RADIANS(latitude)) * sin(RADIANS(sunDeclin)) + cos(RADIANS(latitude)) * cos(RADIANS(sunDeclin)) * cos(RADIANS(hourAngle))));
      double solarElevationAngle = 90 - solarZenithAngle;
     
      double approxAtmosphericRefractionAngle ;
      if (solarElevationAngle > 85) approxAtmosphericRefractionAngle = 0;
      else if (solarElevationAngle > 5)
        approxAtmosphericRefractionAngle = 58.1 / tan(RADIANS(solarElevationAngle)) - 0.07 / pow(tan(RADIANS(solarElevationAngle)), 3) + 0.000086 / pow(tan(RADIANS(solarElevationAngle)), 5);
      else if (solarElevationAngle > -0.575) approxAtmosphericRefractionAngle = 1735 + solarElevationAngle * (-518.2 + solarElevationAngle * (103.4 + solarElevationAngle * (-12.79 + solarElevationAngle * 0.711)));
      else approxAtmosphericRefractionAngle = -20.772 / tan(RADIANS(solarElevationAngle));
      approxAtmosphericRefractionAngle /= 3600.0;
     
      double finalSolarElevation = solarElevationAngle + approxAtmosphericRefractionAngle;
      double finalAzimutAngle = (hourAngle > 0) ?
                                fmod(DEGRES(acos(((sin(RADIANS(latitude)) * cos(RADIANS(solarZenithAngle))) - sin(RADIANS(sunDeclin))) / (cos(RADIANS(latitude)) * sin(RADIANS(solarZenithAngle))))) + 180, 360) :
                                fmod(540 - DEGRES(acos(((sin(RADIANS(latitude)) * cos(RADIANS(solarZenithAngle))) - sin(RADIANS(sunDeclin))) / (cos(RADIANS(latitude)) * sin(RADIANS(solarZenithAngle))))), 360);
     
      Serial.print(nbSec / 3600UL);
      Serial.write(':');
      afficherSurDeuxChiffres((nbSec % 3600UL) / 60);
      Serial.write('\t');
      Serial.print(finalAzimutAngle, 1);
      Serial.print(\t");
      Serial.print(finalSolarElevation, 1);
     
      Serial.print(\n");
    }
    //------------------------------------- Demo
    #define demoStrapPin 5                                              // Pont pour mode demo
     
    struct demoTimeDef                                                  
    {int year; int month; int day; int hour;};
    demoTimeDef demoTime;
     
    boolean demoMode = false;
    unsigned long demoTempoStart = millis();
    int demoHeure = 0;
     
    void setup(){
     
    {
    pinMode(pot1, INPUT);
    pinMode(pot2, INPUT);
    lcd.begin(16, 2);
    }
     
      Serial.begin(115200);
      delay(500);
     
    { 
    uint32_t nombreDeJours;        // nombre de jours depuis le 1er Janvier 1900
      Serial.begin(115200);
     
      if (! rtc.begin()) erreurFatale(F("Horloge RTC introuvable"));
      // IDEALEMENT UTILISER L'HEURE UTC ET PAS L'HEURE LOCALE
      // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // à faire UNE FOIS si votre RTC n'est pas à jour pour la mettre à l'heure sinon commenter.
      // rtc.adjust(DateTime(2020, 1, 2, 10, 30, 0)); // ou pour essayer une date précise, ici le 2 janvier à 10h30
     
      DateTime maintenant = rtc.now(); // l'heure actuelle
      DateTime premierJanvier2020(2020, 1, 1, 0, 0, 0); // point de référence 1er Janvier 2020 à 0h00 UTC
      TimeSpan depuisLePremierJanvier2020 = maintenant - premierJanvier2020 ; // la différence de temps entre maintenant et le 1/1/1900
      nombreDeJours = 43831UL + depuisLePremierJanvier2020.days() ; // + 43831 jours pour compter à partir de 1/1/1900
     
      Serial.print(nomDesJours[maintenant.dayOfTheWeek()]);
      Serial.write(' ');
      Serial.print(maintenant.day());
      Serial.write('/');
      Serial.print(maintenant.month());
      Serial.write('/');
      Serial.print(maintenant.year());
      Serial.write('\t');
      Serial.print(maintenant.hour());
      Serial.write(':');
      afficherSurDeuxChiffres(maintenant.minute());
      Serial.write(':');
      afficherSurDeuxChiffres(maintenant.second());
      Serial.print(F("\nJour N° ")); Serial.println(nombreDeJours);
     
      Serial.println("\nHeure\tAzimut\tElevation");
     
      for (uint32_t moment = 22500; moment <= 79200UL; moment += 900UL) { // de 6h15 à 22h00
        calculAstro(latitude, longitude, deltaTimeZone, nombreDeJours, moment); // toutes les 15 minutes
      }
     
    }
     
     
      progInitialisation();
     
      sunTra.date = "";
    }
     
    void loop(){
     
    {
    delay(60000);
    float Ax = analogRead(pot1);
    float Ay = analogRead(pot2);
     
     
    /*
    Nous utilisons -1000 et 1000 au lieu de -1 et 1 car la fonction map() ne travail qu'avec des nombres entiers.
    268 et 404 sont les valeur de tension de sortie minimale et maximale de l'accéléromètre en x. (de même pour 271 et 406 en y)
    */
     
    float AX = map(Ax, 268, 404, -1000, 1000);
    float AY = map(Ay, 271, 406, -1000, 1000);
    //*180/PI pour convertir les radians en degré
    float I = atan(AX/AY)*180/PI;
     
    //Affiche la valeur de l'angle en degré
    Serial.print("I: ");
    Serial.println(I);
    } 
     
      {
     
        if (sunTra.date != rtcGetDate())                                 // Si la date est changee
     
        sunTra.date = rtcGetDate();                                  // On recupere la date de la RTC auformat sunTra
    //    sdSunFileGetDateData(sunTra.date);                           // Recherche dxes donnees du jour et mise en tableau des donnees ???????????????????? 
                                                                     // elevation (posElevation[24]) du jour sunTra.date
        Serial.print(F("\n--- ")); Serial.print(sunTra.date); Serial.println(F(" ---"));
      }
     
      if (sunTra.heure != rtcGetHour())                                 // Si l'heure a change
      {
        sunTra.heure = rtcGetHour();
        sunTraDayGotoPositionHeure(sunTra.heure);
      }
      //--------------------------------- Desactivation du MPAP quand pas utilise
      if (mpapEnaTimoutChrono != 0 && (millis()- mpapEnaTimoutChrono >= mpapEnaTimout))    // Si plus d'activite du MPAP
      {
        digitalWrite(mpapEnaPin, !mpapEnaPinStatus);
      }
     
      //--------------------------------- LED activite
      if (millis() - sunTraLedActivityChrono >= 10000)                                     // Toutes les 10 secondes
      {
        digitalWrite(sunTraLedActivityPin, HIGH);
        delay(10);
        digitalWrite(sunTraLedActivityPin, LOW);
        sunTraLedActivityChrono = millis();
      }
     
      //--------------------------------- Demo
      if (demoMode)
      {
        if (millis() - demoTempoStart >= demoTempo)                      // Toutes les secondes, 1 heure
        {
    //      demoIncrementHour(1);
          demoTempoStart = millis();
        }
      }
    }
     
    //===================================== Initialisation
    void progInitialisation()
    {
      //--------------------------------- MPAP
      mpap.begin(mpapRpm, mpapMicroSteps);
      mpapPar.pasTotal = ((mpapVisLongMm * 100) / mpapVisPasMm100) * mpapStepsTour;        
      mpapPar.posSteps = 0;
      mpapPar.reverse = mpapReverse;
      pinMode(mpapEnaPin, OUTPUT);
      digitalWrite(mpapEnaPin, !mpapEnaPinStatus);
     
     
     
      //--------------------------------- sunTra
      sunTra.elevationMin = sunTraElevationMin;
      sunTra.elevationMax = sunTraElevationMax;
      long moveTotalMM100 = (sunTra.elevationMax * 100) - (sunTra.elevationMin * 100);
      sunTra.sunTraSteps = (float)moveTotalMM100 / (float)mpapPar.pasTotal;
      sunTra.heure = 0;
     
      pinMode(sunTraLedActivityPin, OUTPUT);
      digitalWrite(sunTraLedActivityPin, LOW);
    }
     
    //===================================== Sun trace
     
    void sunTraDayGotoPositionHeure(int heurePosition)
    {
      Serial.print(F("Heure\t")); Serial.print(heurePosition); //+ 
      Serial.print(F("\tElevation\t")); Serial.print(sunTra.posElevation[heurePosition]);
     
      mpapGotoPos(sunTra.posElevation[heurePosition]);
     
      if (demoMode && sunTra.posElevation[heurePosition] != 0.00)
      {
        delay(4000);                                                 // Pour le demo
      }
    }
     
    //===================================== MPAP
    void mpapGotoPos(float newPosition)
    {
      boolean moveStepsIfNegatif = false;
     
      long sunTraSteps = (newPosition * 100.0)/sunTra.sunTraSteps;
      long moveSteps = sunTraSteps - mpapPar.posSteps;
      if (moveSteps < 0)
      {
        moveStepsIfNegatif = true;
      }
      Serial.print(F("\tMPAP move ")); Serial.println(moveSteps);
     
      if (moveSteps != 0)
      {
        mpapMove(moveSteps);
      }
     
      mpapPar.posSteps = sunTraSteps; 
    }
     
    void mpapMove(long stepsNbr)
    {
      if (mpapPar.reverse)
      {
        stepsNbr = -stepsNbr;
      }
      digitalWrite(mpapEnaPin, mpapEnaPinStatus);
      mpap.move(stepsNbr);
      mpapEnaTimoutChrono = millis();                                  // Redemarrer timout
    }
     
    //===================================== SD
    //------------------------------------- Recherche les donnees pour une date (2020-07-11 par ex.) = "" si pas trouve
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    //===================================== RTC
    String rtcGetDate()
    {
      DateTime nowDate = rtc.now();
     
      if (!demoMode)
      {
        return String(nowDate.year()) + "-" + zeroPadding(nowDate.month(), 2) + "-" + zeroPadding(nowDate.day(), 2);
      } 
      else
      {
        return String(demoTime.year) + "-" + zeroPadding(demoTime.month, 2) + "-" + zeroPadding(demoTime.day, 2);
      }
    }
     
    int rtcGetHour()
    {
      if (!demoMode)
      {
        DateTime nowDate = rtc.now();
        return nowDate.hour();
      }
      else
      {
        return demoTime.hour;
      }
    }
     
    //===================================== Demo
    void demoInitialisation()
    {
      pinMode(demoStrapPin, INPUT_PULLUP);
     
      DateTime nowDate = rtc.now();
      demoTime.year = nowDate.year();
      demoTime.month = nowDate.month();
      demoTime.day = nowDate.day();
     
      if (digitalRead(demoStrapPin) == LOW)
      {demoMode = true;}
      else
      {demoMode = false;}
    }
     
    void demoIncrementHour(int incrHour)
    {
      demoTime.hour += incrHour;
      if (demoTime.hour > 23)
      {
        demoTime.hour = demoTime.hour- 24;
        demoTime.day ++;
      }
     
      if (demoTime.day > 28)
      {
        demoTime.month ++;
        demoTime.day = demoTime.day -28;
      }
      if (demoTime.month > 12)
      {
        demoTime.month = 1;
      }
      DateTime nowDate = rtc.now();
      demoTime.year = nowDate.year();
    }
    //===================================== Outils
     
    String zeroPadding(int padValue, byte padSize)
    {
      String retVal = "000000" + String(padValue);
      retVal = retVal.substring(retVal.length()-padSize);
     
      return retVal;
    }
    Cdt.

    Forexgum.

  19. #59
    Futur Membre du Club
    Homme Profil pro
    Agriculteur
    Inscrit en
    Juillet 2020
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Agriculteur

    Informations forums :
    Inscription : Juillet 2020
    Messages : 23
    Points : 6
    Points
    6
    Par défaut


    Problème avec l'opération : ((Elévation - 180) / 2 ) -180,

    ça ne fonctionne pas !! pour trouver mon angle il faudrais l'opération (( Elévation + 180 ) / 2 ) - 90.

    Voili voilà !

    Cdt.

    Forexgum.

  20. #60
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonsoir Forexgum
    Citation Envoyé par Forexgum Voir le message
    ... J'ai essayer de jongler entre le code de jpbbricole ,...
    Surtout pas!
    Mon code avait pour but unique de répondre à la question "Projet tracker Solaire un seul axe Zénith, contrôler avec fichier de données csv", avec l'orientation que prend ton projet, je te conseille de faire du "Jay M" à 100%, ce sera plus cohérent. Pour le "papy bricoleur" que je suis, ce sujet est devenu trop du "chinois" pour t'aider en quoi que ce soit à adapter mon code.

    A+
    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

Discussions similaires

  1. Changer [FontSize] d'un seul axe
    Par Newenda dans le forum MATLAB
    Réponses: 3
    Dernier message: 11/08/2009, 09h27
  2. Réponses: 1
    Dernier message: 07/07/2009, 11h09
  3. regrouper deux projet JSF en un seul !
    Par King_T dans le forum NetBeans
    Réponses: 0
    Dernier message: 19/06/2009, 19h33
  4. afficher des courbes sur un seul "axes" d'une interface utilisateur
    Par Angel30 dans le forum Interfaces Graphiques
    Réponses: 4
    Dernier message: 06/06/2009, 23h49
  5. Réponses: 2
    Dernier message: 08/06/2008, 20h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo