Tracker solaire

Bonjour,

Depuis quelques mois déjà (8 mois pour être plus précis) j'ai entamé un projet qui consistait à concevoir un système de tracking solaire afin d'optimiser dans un premier temps le rendement des panneaux solaires. Oui je sais, 8 mois c'est un peu trop mais entre les commandes passées et l'attente de la réception, il y a eu du temps qui est passé. Mais peu importe, je l'ai maintenant terminé en tenant compte d'un certains nombres de paramètres qui rendent le système quand même "performant" (enfin si je puis le dire ainsi).

J'ai donc voulu réaliser quelque chose de simple et performant (je sais qu'il y a mieux côté performance mais ma part me satisfait pour le moment). L'électronique du système repose donc sur une carte Arduino, vient ensuite des photorésistances, un fin de course et des moteurs.

Comment ça marche

Tout d'abord j'aimerais préciser que j'ai fait deux mode de fonctionnement pour le système : un mode automatique (le système se gère seul) et un mode manuel (où l'utilisateur peut lui même positionner son panneau comme bon lui semble).

En mode automatique l'organigramme est assez simple :

  • je calcul l'heure du lever et du coucher du soleil à l'aide d'une librairie qui m'a été fourni par @Heloderma-kris (que je remerci au passage) puis ensuite récupère l'heure courante à partir d'une horloge ds1307.
  • il s'en suis ensuite des tests conditionnels
  • je fais ensuite une comparaison entre l'heure courante et les heures calculées.
  • si l'heure courante est comprise entre l'heure du lever et l'heure du coucher alors le système devra se mettre à la recherche du maximum d'éclairement afin de positionner le panneau dans dans la bonne direction.
  • si l'heure courante est supérieur à l'heure du lever et à l'heure du coucher alors le système devra arrêter la poursuite et ramené le panneau dans la position correspondant au lever du soleil du jour suivant.
  • si l'heure courante est inférieur à l'heure du lever et à l'heure du coucher alors il en est de même que précédemment.
  • après avoir fais ces tests, le programme repars calculé et récupéré l'heure puis le tout recommence.

Un fin de course arrête le panneau lorsque celui-ci arrive en fin de course (heure du lever). Avant de placer le fin de course j'ai calculé les heures du lever du soleil pour l'année 2014 puis j'ai ensuite prit l'heure minimal du lever que j'ai fait correspondre à un angle donné. C'est ce qui m'a permit de placer le fin de course.

En mode manuel le principe est aussi simple. J'ai quatre boutons (LR1, LR2, UD1, UD2) au total dont je vérifie l'état afin de pouvoir agir en fonction. Lorsque le système est en mode manuel, il y a deux doubles afficheurs (LR et UD) qui affiche la différence de valeur entre les photorésistances de même axes.

  • au départ je récupère les valeurs renvoyées par les photorésistances de chaque axe (je ne l'ai pas rééchelonné) puis je fait une différence
  • ensuite je vérifie l'état de chaque bouton afin de pouvoir agir en fonction de l'action sur un des boutons.

Supposons que j'ai une différence de 25 entre les photorésistance de l'axe horizontal alors l'afficheur va m'afficher 02 et à ce instant l'utilisateur saura qu'il faut bouger la panneau dans un sens permettant d'avoir 00 comme différence et ce zéro correspond à une différence comprise entre 0 et 10. Je considère que sur une plage de 0 à 10 l'erreur de positionnement est assez négligeable.

Problème 1 En mode manuel il existe un problème majeur que j'ai remarqué :

Si il advenait que le système ne soit plus alimenter (accidentellement) et que cela arrivait vers 9h par exemple alors celui-ci serait bloqué dans la position correspondant cette heure.
Maintenant supposons que l'utilisateur l'ai remarqué mais au alentour de 15h alors il remet sous-tension (en mode automatique). Puisque le positionnement du système n'est pas basé sur le calcul de la position du soleil mais plutôt sur des photorésistances alors celui-ci va se mettre en marche et positionner le panneau dans la position correspondant à l'éclairement lié à son orientation c'est-à-dire 9h. Dans ce cas il y un problème de perte d'énergie.

Solution 1

Pour y remédier, l'utilisateur après avoir remit sous-tension, devra basculer en mode manuel afin de ramener le panneau dans la position correspondant à l'heure courante c'est-à-dire 15h. Dès lors, il pourra "rebasculer" en mode automatique où le système prendra en charge la poursuite afin de positionner le panneau dans la position correspondant à l'éclairement.

Problème 2

Je n'ai pas tenu compte des couvertures nuageuses car comme je le disais, mon système n'est pas basé sur le calcul de la position du soleil dans le ciel. Ce qui fait que s'il y avait un temps couvert de 9h à 15h par exemple, l'on rejoint le problème précédent.

Solution 2

Pour y remédier, j'ai intégré dans la mode automatique un système qui fait que le système ne réagit pas en dessous d'un seuil d'éclairement calculé. Ensuite pour le reste, la solution est la même que précédemment.

Je sais bien évidement que pour avoir un système à 100% performant il faudrait intégrer des calcul qui permettent de trouver la position du soleil dans le ciel. Cela permettrait de résoudre la problème de couverture nuageuse et autres. Il faudrait aussi intégré d'autres composant électronique comme des fourches optoélectroniques etc ... Mais comme je l'ai dit au début, j'ai voulu faire quelque chose de simple, compréhensible et performant ....... enfin performant à 70% :grin:
Le mode manuel a son utilité car l'utilisateur peut lui même vouloir positionner son panneau comme bon lui semble.

Je post ceci :

  • tout d'abord pour partager le résultats de mes travaux,
  • ensuite pour soumettre cela à votre appréciation,
  • et enfin pour permettre à ceux-là qui voudront se lancer dans la réalisation d'un tel système d'avoir déjà une base.

Je travail actuellement sur la réalisation du système en taille réel (grande échelle) mais j'ai écrit ce code en tenant compte, pas d'un système miniature, mais d'un système en taille réel. J'en suis à la réalisation du schéma en tenant en compte de tous les paramètre comme les vents forts et autres. Le travail étant très sérieux, je n'ai pas minimiser le système miniature car si ce n'est pas le poids du panneau qui peut changer la donne, ce dernier est en état d'assurer une poursuite autonome et rentable.

J'aimerais remercier particulièrement @Batto pour le 1er code et @Artouste pour la suite. Je suis ouvert à toutes suggestions d'amélioration.

Première partie du code :

Il est assez lourd mais ce comprend facilement :

#include "Wire.h"
#include <math.h>
#define DS1307_I2C_ADDRESS 0x68
#include <Date_heure.h>
#include <ephemeride.h>

// 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) );
}

// Latitude et Longitude
#define _latD 6
#define _latM 7
#define _lonD 1
#define _lonM 13
#define _J 24
#define _M 5
#define _A 2014
#define _fuso 0

// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
          byte *minute,
          byte *hour,
          byte *dayOfWeek,
          byte *dayOfMonth,
          byte *month,
          byte *year)
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f);  // Need to change this if 12 hour am/pm
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}

// Variables pour la commutation des transistors
byte digit0 = 24; // Afficheur LR
byte digit1 = 25;
byte digit2 = 26;
byte digit3 = 27; // Afficheur UD
byte digit4 = 28;
byte digit5 = 29; 

byte sevenSegmentPins_LR[] = {30,31,32,33,34,35,36}; // Broches à utiliser par les afficheurs LR
byte sevenSegmentPins_UD[] = {40,41,42,43,44,45,46}; // Broches à utiliser par les afficheurs UD

// Tableau d'affichage
byte sevenSegment[10][7] =
{
  //a b c d e f g
  { 0,0,0,0,0,0,1 },  // = 0
  { 1,0,0,1,1,1,1 },  // = 1
  { 0,0,1,0,0,1,0 },  // = 2
  { 0,0,0,0,1,1,0 },  // = 3
  { 1,0,0,1,1,0,0 },  // = 4
  { 0,1,0,0,1,0,0 },  // = 5
  { 0,1,0,0,0,0,0 },  // = 6
  { 0,0,0,1,1,1,1 },  // = 7
  { 0,0,0,0,0,0,0 },  // = 8
  { 0,0,0,1,1,0,0 },  // = 9
};

// Définition des broches du moteur 1 : Axe hoizontal
int motor1_pin1 = 4;
int motor1_pin2 = 5;
int motor1_pin3 = 6;
int motor1_pin4 = 7;

// Définition des broches du moteur 2 : Axe vertical
int motor2_pin1 = 8;
int motor2_pin2 = 9;
int motor2_pin3 = 10;
int motor2_pin4 = 11;

// Définition des broches des photorésistances
int LDR_Left = A0; // Gauche
int LDR_Right = A1; // Droite
int LDR_Up = A2; // Haut
int LDR_Down = A3; // bas

// Déclaration des variables devant recevoir les valeurs des LDRs
int Val_LDR_Left = 0; 
int Val_LDR_Right = 0; 
int Val_LDR_Up = 0; 
int Val_LDR_Down = 0; 

// Variables pour stocker le résultat de la différence entre L et R // U et D
int dif_LR = 0;
int dif_UD = 0;

// Déclaration des variables pour afficheurs
long temps;
int A, B, C, D, E, F, G, H, I, J; 
int Ent_LR, Ent_UD, Mod_LR, Mod_UD;

// Déclaration des variables d'étape
int Etape_H = 0;
int Etape_V = 0;

// Bouton mode de fonctionnement (auto/manuel)
const int boutonPin = 2;

// Fin de course du panneau
const int boutonFC = 3;

// Déclaration des pins pour les leds signalant le mode
const int ledPinAuto =  22;
const int ledPinManu =  23;

// Variable de stockage d'état des boutons
int buttonState = 0;
int boutonStateFC = 0;
int buttonState_LR1 = 0;
int buttonState_LR2 = 0;
int buttonState_UD1 = 0;
int buttonState_UD2 = 0;

// Les boutons de déplacement
int boutonPin_LR1 = 50;
int boutonPin_LR2 = 51;
int boutonPin_UD1 = 52;
int boutonPin_UD2 = 53;

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

  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();

  // Configuration en entrée des broches destinées aux ldrs 
  pinMode(LDR_Left, INPUT);
  pinMode(LDR_Right, INPUT);
  pinMode(LDR_Up, INPUT);
  pinMode(LDR_Down, INPUT);

  // Configuration en sortie des pins moteur H
  pinMode(motor1_pin1, OUTPUT);
  pinMode(motor1_pin2, OUTPUT);
  pinMode(motor1_pin3, OUTPUT);
  pinMode(motor1_pin4, OUTPUT);

  // Configuration en sortie des pins moteur V
  pinMode(motor2_pin1, OUTPUT);
  pinMode(motor2_pin2, OUTPUT);
  pinMode(motor2_pin3, OUTPUT);
  pinMode(motor2_pin4, OUTPUT);

  // Mise à l'état haut des variables de stockage d'état
  buttonState = HIGH; // Bouton relaché
  boutonStateFC = HIGH;
  buttonState_LR1 = HIGH;
  buttonState_LR2 = HIGH;
  buttonState_UD1 = HIGH;
  buttonState_UD2 = HIGH;

  //Configuration des leds en sortie
  pinMode(ledPinAuto, OUTPUT);      
  pinMode(ledPinManu, OUTPUT);      

  /* Configuration en entrée des boutons "mode de fonctionnement" et de déplacement */
  pinMode(boutonPin, INPUT);
  pinMode(boutonFC, INPUT);
  pinMode(boutonPin_LR1, INPUT);
  pinMode(boutonPin_LR2, INPUT);
  pinMode(boutonPin_UD1, INPUT);
  pinMode(boutonPin_UD2, INPUT);

  // Configuration en sortie des broches destinées aux afficheurs
  for(int i=0; i<7; i++)
  {
    pinMode(sevenSegmentPins_LR[i], OUTPUT);
    pinMode(sevenSegmentPins_UD[i], OUTPUT);
  }

  // Configuration en sortie des broches destinées aux transistors 
  pinMode(digit0, OUTPUT); //pin 24
  pinMode(digit1, OUTPUT); //pin 25
  pinMode(digit2, OUTPUT); //pin 26
  pinMode(digit3, OUTPUT); //pin 27
  pinMode(digit4, OUTPUT); //pin 28
  pinMode(digit5, OUTPUT); //pin 29

}  

// Fonction d'affichage LR
void segmentWrite_LR(byte digit)
{
  byte pin = 30;
  for (byte i=0; i<7; ++i)
  {
    digitalWrite(pin, sevenSegment[digit][i]);
    ++pin;
  }
}

// Fonction d'affichage UD
void segmentWrite_UD(byte digit)
{
  byte pin = 40;
  for (byte i=0; i<7; ++i)
  {
    digitalWrite(pin, sevenSegment[digit][i]);
    ++pin;
  }
}

void loop()
{
  buttonState = digitalRead(boutonPin); // On lit l'état du bouton et on la stock dans une variable

  if (buttonState == HIGH) {     
    // Mode auto    
    digitalWrite(ledPinManu, HIGH);
    digitalWrite(ledPinAuto, LOW);
    modeAuto();
  } 
  if (buttonState == LOW)
  {
    // Mode manuel
    digitalWrite(ledPinAuto, HIGH);
    digitalWrite(ledPinManu, LOW); 
    modeManuel();
  }
}


void modeAuto()
{
  // Calcul de l'heure du lever et du coucher du soleil  
  int  n =rangJour(_J,_M,_A); 
  float HO=angleHoraireSoeil(n,(_latD+(_latM/60))); //lat D=latitude degree //latM Minute
  float ET=equationDuTemps(n);
  //heure de lever
  int hOnh=int(12-(HO/15)+((_lonD+(_lonM/60))/15)+(ET/60)+_fuso);
  int hOnm=int(((12-(HO/15)+((_lonD+(_lonM/60))/15)+(ET/60)+_fuso)-(hOnh))*60);
  //heure du coucher
  int hOffh=int(12+(HO/15)+((_lonD+(_lonM/60))/15)+(ET/60)+_fuso);
  int hOffm=int(((12+(HO/15)+((_lonD+(_lonM/60))/15)+(ET/60)+_fuso)-(hOffh))*60);
  
  // Récupération de l'heure du RTC
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  
  if (((hour >= hOnh) && (minute >= hOnm)) && ((hour <= hOffh) && (minute <= hOffm)))
  {
    Val_LDR_Left = analogRead(LDR_Left);
    Val_LDR_Right = analogRead(LDR_Right);
    Val_LDR_Up = analogRead(LDR_Up);
    Val_LDR_Down = analogRead(LDR_Down);

    dif_LR = (Val_LDR_Left - Val_LDR_Right);
    dif_UD = (Val_LDR_Up -  Val_LDR_Down);

    if(dif_UD > 20) Bouge_H(1);
    if(dif_UD < -20) Bouge_H(-1);

    if(dif_LR > 100)  Bouge_V(1);
    if (dif_LR < -100) Bouge_V(-1);
  }
  
  if (((hour >= hOnh) && (minute >= hOnm)) && ((hour >= hOffh) && (minute >= hOffm)))
  {
    boutonStateFC = digitalRead(boutonFC);
    while(boutonStateFC == HIGH)
    {
      Bouge_H(-1);
      boutonStateFC = digitalRead(boutonFC);
    }
  }
  
    if (((hour <= hOnh) && (minute <= hOnm)) && ((hour <= hOffh) && (minute <= hOffm)))
  {
    boutonStateFC = digitalRead(boutonFC);
    while(boutonStateFC == HIGH)
    {
      Bouge_H(-1);
      boutonStateFC = digitalRead(boutonFC);
    }
  }
}

Deuxième partie du code :

void modeManuel()
{
  Val_LDR_Left = analogRead(LDR_Left);
  Val_LDR_Right = analogRead(LDR_Right);
  Val_LDR_Up = analogRead(LDR_Up);
  Val_LDR_Down = analogRead(LDR_Down);

  if(Val_LDR_Left>Val_LDR_Right)
  {
    digitalWrite(digit0, LOW);
    dif_LR = Val_LDR_Left - Val_LDR_Down;
    AffichageLR(dif_LR);
  }
  else if(Val_LDR_Left<Val_LDR_Right)
  {
    digitalWrite(digit0, HIGH);
    dif_LR = Val_LDR_Right - Val_LDR_Left;
    AffichageLR(dif_LR);
  }

  if(Val_LDR_Up>Val_LDR_Down)
  {
    digitalWrite(digit3, LOW);
    dif_UD = (Val_LDR_Up -  Val_LDR_Down); 
    AffichageUD(dif_UD);
  }
  else if(Val_LDR_Up<Val_LDR_Down)
  {
    digitalWrite(digit3, HIGH);
    dif_UD = (Val_LDR_Down - Val_LDR_Up);
    AffichageUD(dif_UD);
  }

  buttonState_LR1 = digitalRead(boutonPin_LR1);
  buttonState_LR2 = digitalRead(boutonPin_LR2);
  buttonState_UD1 = digitalRead(boutonPin_UD1);
  buttonState_UD2 = digitalRead(boutonPin_UD2);

  while(buttonState_UD1 == LOW) // tant que le bouton UD1 est appuyé ...
  {    
    Val_LDR_Left = analogRead(LDR_Left);  // lit la valeur des ldrs
    Val_LDR_Right = analogRead(LDR_Right);
    Val_LDR_Up = analogRead(LDR_Up);
    Val_LDR_Down = analogRead(LDR_Down);

    if(Val_LDR_Left>Val_LDR_Right)
    {
      digitalWrite(digit0, LOW);
      dif_LR = Val_LDR_Left - Val_LDR_Down;
      AffichageLR(dif_LR);
    }
    else if(Val_LDR_Left<Val_LDR_Right)
    {
      digitalWrite(digit0, HIGH);
      dif_LR = Val_LDR_Right - Val_LDR_Left;
      AffichageLR(dif_LR);
    }

    if(Val_LDR_Up>Val_LDR_Down)
    {
      digitalWrite(digit3, LOW);
      dif_UD = (Val_LDR_Up -  Val_LDR_Down); 
      AffichageUD(dif_UD);
    }
    else if(Val_LDR_Up<Val_LDR_Down)
    {
      digitalWrite(digit3, HIGH);
      dif_UD = (Val_LDR_Down - Val_LDR_Up);
      AffichageUD(dif_UD);
    }

    Bouge_H(1);

    buttonState_UD1 = digitalRead(boutonPin_UD1); // Vérifie l'état du bouton UD1
  }


  while(buttonState_UD2 == LOW) // tant que le bouton UD2 est appuyé ...
  {    
    Val_LDR_Left = analogRead(LDR_Left);  // lit la valeur des ldrs
    Val_LDR_Right = analogRead(LDR_Right);
    Val_LDR_Up = analogRead(LDR_Up);
    Val_LDR_Down = analogRead(LDR_Down);

    if(Val_LDR_Left>Val_LDR_Right)
    {
      digitalWrite(digit0, LOW);
      dif_LR = Val_LDR_Left - Val_LDR_Down;
      AffichageLR(dif_LR);
    }
    else if(Val_LDR_Left<Val_LDR_Right)
    {
      digitalWrite(digit0, HIGH);
      dif_LR = Val_LDR_Right - Val_LDR_Left;
      AffichageLR(dif_LR);
    }

    if(Val_LDR_Up>Val_LDR_Down)
    {
      digitalWrite(digit3, LOW);
      dif_UD = (Val_LDR_Up -  Val_LDR_Down); 
      AffichageUD(dif_UD);
    }
    else if(Val_LDR_Up<Val_LDR_Down)
    {
      digitalWrite(digit3, HIGH);
      dif_UD = (Val_LDR_Down - Val_LDR_Up);
      AffichageUD(dif_UD);
    }

    Bouge_H(-1);

    buttonState_UD2 = digitalRead(boutonPin_UD2); // Vérifie l'état du bouton UD2
  }

  while(buttonState_LR1 == LOW) // tant que le bouton LR1 est appuyé ...
  {    
    Val_LDR_Left = analogRead(LDR_Left);  // lit la valeur des ldrs
    Val_LDR_Right = analogRead(LDR_Right);
    Val_LDR_Up = analogRead(LDR_Up);
    Val_LDR_Down = analogRead(LDR_Down);

    if(Val_LDR_Left>Val_LDR_Right)
    {
      digitalWrite(digit0, LOW);
      dif_LR = Val_LDR_Left - Val_LDR_Down;
      AffichageLR(dif_LR);
    }
    else if(Val_LDR_Left<Val_LDR_Right)
    {
      digitalWrite(digit0, HIGH);
      dif_LR = Val_LDR_Right - Val_LDR_Left;
      AffichageLR(dif_LR);
    }

    if(Val_LDR_Up>Val_LDR_Down)
    {
      digitalWrite(digit3, LOW);
      dif_UD = (Val_LDR_Up -  Val_LDR_Down); 
      AffichageUD(dif_UD);
    }
    else if(Val_LDR_Up<Val_LDR_Down)
    {
      digitalWrite(digit3, HIGH);
      dif_UD = (Val_LDR_Down - Val_LDR_Up);
      AffichageUD(dif_UD);
    }

    Bouge_V(1);

    buttonState_LR1 = digitalRead(boutonPin_LR1); // Vérifie l'état du bouton UD1
  }

  while(buttonState_LR2 == LOW) // tant que le bouton LR2 est appuyé ...
  {    
    Val_LDR_Left = analogRead(LDR_Left);  // lit la valeur des ldrs
    Val_LDR_Right = analogRead(LDR_Right);
    Val_LDR_Up = analogRead(LDR_Up);
    Val_LDR_Down = analogRead(LDR_Down);

    if(Val_LDR_Left>Val_LDR_Right)
    {
      digitalWrite(digit0, LOW);
      dif_LR = Val_LDR_Left - Val_LDR_Down;
      AffichageLR(dif_LR);
    }
    else if(Val_LDR_Left<Val_LDR_Right)
    {
      digitalWrite(digit0, HIGH);
      dif_LR = Val_LDR_Right - Val_LDR_Left;
      AffichageLR(dif_LR);
    }

    if(Val_LDR_Up>Val_LDR_Down)
    {
      digitalWrite(digit3, LOW);
      dif_UD = (Val_LDR_Up -  Val_LDR_Down); 
      AffichageUD(dif_UD);
    }
    else if(Val_LDR_Up<Val_LDR_Down)
    {
      digitalWrite(digit3, HIGH);
      dif_UD = (Val_LDR_Down - Val_LDR_Up);
      AffichageUD(dif_UD);
    }

    Bouge_V(-1);

    buttonState_LR2 = digitalRead(boutonPin_LR2); // Vérifie l'état du bouton UD1
  }

}


void Bouge_H(long Pas){

  if(Pas>0){
    for(int y=0;y<Pas;y++){
      Etape_H++;
      if(Etape_H>4) Etape_H=1;
      FaireUnPasH(); 
    }
  }

  if(Pas<0){
    for(int x=0;x<(-Pas);x++){
      Etape_H--;
      if(Etape_H<1) Etape_H=4; 
      FaireUnPasH();
    }
  }
}

void Bouge_V(long Pas){

  if(Pas>0){
    for(int y=0;y<Pas;y++){
      Etape_V++;
      if(Etape_V>4) Etape_V=1; 
      FaireUnPasV();
    }
  }

  if(Pas<0){
    for(int x=0;x<(-Pas);x++){
      Etape_V--;
      if(Etape_V<1) Etape_V=4; 
      FaireUnPasV();
    }
  }
}


void AffichageLR(int dif_LR)
{
  if(dif_LR < 100)
  {
    A = dif_LR/10;
    Ent_LR = int (A);
    Mod_LR = 0;
  }

   else if(dif_LR>=100)
    {
      B = dif_LR/10;
      C = int(B);
      D = C%10;
      Ent_UD = int(D);
      E = C/10;
      Mod_UD = int(E);
    }

    int t1 = 50;  

    while(t1>0)
    {
      t1 = t1 - 10;
      digitalWrite(digit2, HIGH); 
      segmentWrite_LR(Ent_LR);          
      digitalWrite(digit1, LOW);
      delay(10);
      digitalWrite(digit1, HIGH);
      segmentWrite_LR(Mod_LR);          
      digitalWrite(digit2, LOW);
      delay(10);
    } 
}  // Fin de void AffichageLR

void AffichageUD(int dif_UD)
{
  if(dif_UD <100)
  {
  F = dif_UD/10;
  Ent_UD = int (F);
  Mod_UD = 0;
  }
  
  else if(dif_UD>=100)
  {
    G = dif_UD/10;
    H = int(G);
    I = H%10;
    Ent_UD = int(I);
    J = H/10;
    Mod_UD = int(J);
  }
  
  int t2 = 50;
  
  while(t2>0)
  {
  t2 = t2 - 10;
  digitalWrite(digit5, HIGH); 
  segmentWrite_UD(Ent_UD);          
  digitalWrite(digit4, LOW);
  delay(10);
  digitalWrite(digit4, HIGH);
  segmentWrite_UD(Mod_UD);          
  digitalWrite(digit5, LOW);
  delay(10);
  }
}// Fin de void AffichageUD

void FaireUnPasH(){

  switch(Etape_H) {

  case 1:
    digitalWrite(4,HIGH);
    digitalWrite(5,LOW);
    digitalWrite(6,LOW);   
    digitalWrite(7,LOW);
    break;

  case 2:
    digitalWrite(4,LOW);
    digitalWrite(5,HIGH);
    digitalWrite(6,LOW);   
    digitalWrite(7,LOW);
    break;

  case 3:
    digitalWrite(4,LOW);
    digitalWrite(5,LOW);
    digitalWrite(6,HIGH);   
    digitalWrite(7,LOW);
    break;

  case 4:
    digitalWrite(4,LOW);
    digitalWrite(5,LOW);
    digitalWrite(6,LOW);   
    digitalWrite(7,HIGH);
    break;
  }
}// Fin de void FaireUnPasH

void FaireUnPasV(){

  switch(Etape_V) {

  case 1:
    digitalWrite(8,HIGH);
    digitalWrite(9,LOW);
    digitalWrite(10,LOW);   
    digitalWrite(11,LOW);
    break;

  case 2:
    digitalWrite(8,LOW);
    digitalWrite(9,HIGH);
    digitalWrite(10,LOW);   
    digitalWrite(11,LOW);
    break;

  case 3:
    digitalWrite(8,LOW);
    digitalWrite(9,LOW);
    digitalWrite(10,HIGH);   
    digitalWrite(11,LOW);
    break;

  case 4:
    digitalWrite(8,LOW);
    digitalWrite(9,LOW);
    digitalWrite(10,LOW);   
    digitalWrite(11,HIGH);
    break;
  }
}// Fin de void FaireUnPasV

Uzuma:
Problème 1 En mode manuel il existe un problème majeur que j'ai remarqué :

Si il advenait que le système ne soit plus alimenter (accidentellement) et que cela arrivait vers 9h par exemple alors celui-ci serait bloqué dans la position correspondant cette heure.
Maintenant supposons que l'utilisateur l'ai remarqué mais au alentour de 15h alors il remet sous-tension (en mode automatique). Puisque le positionnement du système n'est pas basé sur le calcul de la position du soleil mais plutôt sur des photorésistances alors celui-ci va se mettre en marche et positionner le panneau dans la position correspondant à l'éclairement lié à son orientation c'est-à-dire 9h. Dans ce cas il y un problème de perte d'énergie.

Solution 1

Pour y remédier, l'utilisateur après avoir remit sous-tension, devra basculer en mode manuel afin de ramener le panneau dans la position correspondant à l'heure courante c'est-à-dire 15h. Dès lors, il pourra "rebasculer" en mode automatique où le système prendra en charge la poursuite afin de positionner le panneau dans la position correspondant à l'éclairement.

Bonsoir
rapidement
Je ne comprend pas bien ta demarche de (re)positionnement suite à "reset" 8)

perso , je passerais en seul tracking "auto max lumiere" systematiquement à chaque reset pendant une durée de X (intellectuellement je mettrais une durée de l'ordre de +/- 15 minutes, mais c'est à creuser ), avant de rendre la main à un tracking "basé ephemerides"
Il n'y a besoin de "personne" apres un reset pour se retrouver ensuite dans la situation "la moins penalisante"

Salut @Artouste,

comme je l'ai expliqué, si le système a été remit sous-tension à une heure ne correspondant pas à l'orientation du panneau, il faudrait faire de tel manière que celui-ci puisse se retrouver dans la position la moins pénalisante.
Alors pour remédier à cela, je me suis dit que comme la remise sous-tension est faites par une intervention humaine, ce dernier peu après cela repositionné le panneau avant de passé la main au mode basé sur les éphémérides.
Ci-joint, une image expliquant la problématique.

Problème.PNG

Uzuma:
Salut @Artouste,

comme je l'ai expliqué, si le système a été remit sous-tension à une heure ne correspondant pas à l'orientation du panneau, il faudrait faire de tel manière que celui-ci puisse se retrouver dans la position la moins pénalisante.
Alors pour remédier à cela, je me suis dit que comme la remise sous-tension est faites par une intervention humaine, ce dernier peu après cela repositionné le panneau avant de passé la main au mode basé sur les éphémérides.
Ci-joint une image expliquant le problématique.

Bonjour
J'ai bien compris, mais je ne vois pas l'utilité du mode manuel
qu'il faille une action "humaine" ou pas pour la remise "en route/reset"
quel est l'interet d'utiliser un mode manuel ?
si tu a une rtc (ou une recup d'horodatage)
à la (re)mise en route (quelle que soit l'heure) apres coupure (quelle que soit l'heure) , la solution la moins penalisante est de laisser le tracking luminosité travailler tout seul.
De toutes façons ton tracking en mode ephemeride est en boucle ouverte = tu ne connais pas physiquement la position de ton panneau , elle est simplement deduite

Bonjour,
donc d'après toi, qu'il y ait mode manuel ou pas, après le reset du système, ce dernier est capable de se retrouver de lui même dans la position du maximum d'éclairement ?!
C'est que je n'arrive pas à imaginer, sans calcul de la hauteur et l'azimut et sans fourche, que mon système puisse de lui-même se retrouver dans la meilleure position après reset. C'est pour cela que j'ai pensé à un moyen (manuel) qui permette d'amener le panneau sans attendre dans la meilleure position après un resset.
Si j'ai bien saisit ton point de vue alors après remise sous-tension, mon système va paginer jusqu'à ce qu'il trouve l'équilibre ?!

Uzuma:
Bonjour,
donc d'après toi, qu'il y ait mode manuel ou pas, après le reset du système, ce dernier est capable de se retrouver de lui même dans la position du maximum d'éclairement ?!
C'est que je n'arrive pas à imaginer, sans calcul de la hauteur et l'azimut et sans fourche, que mon système puisse de lui-même se retrouver dans la meilleure position après reset. C'est pour cela que j'ai pensé à un moyen (manuel) qui permette d'amener le panneau sans attendre dans la meilleure position après un resset.
Si j'ai bien saisit ton point de vue alors après remise sous-tension, mon système va paginer jusqu'à ce qu'il trouve l'équilibre ?!

bon , on va se poser tranquillement :grin:
et reposer les bases 8)

de ce que j'ai retenu de ton projet :

  • tu dispose d'un tracking luminosité basé sur des LDR ?

  • tu dispose d'une motorisation baséee sur de l'ephemeride , mais qui n'est pas bouclée = tu bouge ton/tes moteurs en fonction de "l'heure" fournie par ton systeme , mais tu ne connais pas/jamais la reelle position physique de tes moteurs(verins) en fonction de cette "heure" ?

  • tu dispose

Artouste:

  • tu dispose d'un tracking luminosité basé sur des LDR ?
  • tu dispose d'une motorisation baséee sur de l'ephemeride , mais qui n'est pas bouclée = tu bouge ton/tes moteurs en fonction de "l'heure" fournie par ton systeme , mais tu ne connais pas/jamais la reelle position physique de tes moteurs(verins) en fonction de cette "heure" ?

Oui

Uzuma:

Artouste:

  • tu dispose d'un tracking luminosité basé sur des LDR ?
  • tu dispose d'une motorisation baséee sur de l'ephemeride , mais qui n'est pas bouclée = tu bouge ton/tes moteurs en fonction de "l'heure" fournie par ton systeme , mais tu ne connais pas/jamais la reelle position physique de tes moteurs(verins) en fonction de cette "heure" ?

Oui

alors pour resumer à la (re)mise en route , laisse faire le tracking "luminosité"
autre chose : quel est l'interet d'un "positionnement ephemeride" , si il n'est pas bouclé ?
le seul tracking "luminosité" sera de toute façon toujours "meilleur"

Artouste:
autre chose : quel est l'interet d'un "positionnement ephemeride" , si il n'est pas bouclé ?

C'est pour dire par exemple :

  • arrivé au soir, arrête la poursuite et bouge le panneau dans le sens inverse jusqu'à ce que ce dernier bute un fin de course;
  • ne fait rien pendant la nuit même si tu reçois un éclairage parasite;
  • au matin, commence la poursuite.

Un éclairage parasite, tu peux facilement t'en débarrasser - fait juste en sorte que si lors du scan il ne tombe pas sur un certain seuil de luminosité minimum il passe en mode "ok je rembale tout, bonne nuit les gens!" et revérifie toutes les demi-heure à partir d'une certaine heure (5h du mat en été?)- je ne sais pas trop comment ton installation est réalisée mais mettre les photorésistances dans des tubes d'une manière générale rend les mesures plus "précises" et moins facilement parasitables (des gaines thermorétractables non rétractées ça marche aussi) - surtout si tu comptes mettre ton panneau sur un toit par exemple, il se moquera bien de la lumière des phares de ton voisin de retour de chez sa maîtresse.

J'ai beau chercher je ne trouve vraiment pas l'intérêt de calculer un positionnement éphéméride ô_ô (du moins rien qui vaille le coup comparé à un bête traqueur de luminosité de base)

Uzuma:

Artouste:
autre chose : quel est l'interet d'un "positionnement ephemeride" , si il n'est pas bouclé ?

C'est pour dire par exemple :

  • arrivé au soir, arrête la poursuite et bouge le panneau dans le sens inverse jusqu'à ce que ce dernier bute un fin de course;
  • ne fait rien pendant la nuit même si tu reçois un éclairage parasite;
  • au matin, commence la poursuite.

oui , ça aussi j'avais bien compris :grin:
mais je persiste à croire/penser que mettre là de "l'ephemeride" est parfaitement inutile :grin:
et complexifie sans raisons du "simple tracking luminosité" :grin:
Si tu dispose d'une reference de temps , il suffit simplement de rapatrier en "butée EST" ton panneau à 22H30 (loc )
de mettre l'ensemble en sommeil , et de reveiller tout ce beau monde à 05H30 (loc)

  • heures prises à la louche :grin:

Artouste:
oui , ça aussi j'avais bien compris :grin:
mais je persiste à croire/penser que mettre là de "l'ephemeride" est parfaitement inutile :grin:
et complexifie sans raisons du "simple tracking luminosité" :grin:
Si tu dispose d'une reference de temps , il suffit simplement de rapatrier en "butée EST" ton panneau à 22H30 (loc )
de mettre l'ensemble en sommeil , et de reveiller tout ce beau monde à 05H30 (loc)

Faire quelque chose de simple mais qui tienne la route en même temps, voilà ce que j'ai voulu faire en intégrant tout cela. Je crois que j'ai construis mon tracker en me basant sur un système doté d'un programme et de l'électronique permettant de placer le panneau en fonction de la hauteur et l'azimut calculé, je n'ai pas tenu compte des conditions dans lesquelles j'étais.
Deux butés auraient pu faire l'affaire c'est vrai et je n'aurais pas eu besoin de calculer les heures de lever et de coucher de quoi que se soit. Mais j'ai pensé autrement et j'ai fait les choses autrement. XD
Je vais essayer de trouver une utilité "crédible" aux choses que j'ai faites. Je compte approfondir mon travail et s'il y a des suggestions à faire, pour pas qu'à la fin je me retrouve dans la situation actuelle, alors je suis preneur. :grin:

Uzuma:

Artouste:
oui , ça aussi j'avais bien compris :grin:
mais je persiste à croire/penser que mettre là de "l'ephemeride" est parfaitement inutile :grin:
et complexifie sans raisons du "simple tracking luminosité" :grin:
Si tu dispose d'une reference de temps , il suffit simplement de rapatrier en "butée EST" ton panneau à 22H30 (loc )
de mettre l'ensemble en sommeil , et de reveiller tout ce beau monde à 05H30 (loc)

Faire quelque chose de simple mais qui tienne la route en même temps, voilà ce que j'ai voulu faire en intégrant tout cela. Je crois que j'ai construis mon tracker en me basant sur un système doté d'un programme et de l'électronique permettant de placer le panneau en fonction de la hauteur et l'azimut calculé, je n'ai pas tenu compte des conditions dans lesquelles j'étais.
Deux butés auraient pu faire l'affaire c'est vrai et je n'aurais pas eu besoin de calculer les heures de lever et de coucher de quoi que se soit. Mais j'ai pensé autrement et j'ai fait les choses autrement. XD
Je vais essayer de trouver une utilité "crédible" aux choses que j'ai faites. Je compte approfondir mon travail et s'il y a des suggestions à faire, pour pas qu'à la fin je me retrouve dans la situation actuelle, alors je suis preneur. :grin:

Je comprend bien ta demarche, mais elle est "un peu viciée" à la base
si tu regarde le bilan d'erreur possible (et probable) d'un positionnement par "ephemeride" , il est soumis à des grosses contraintes de base de temps et de positionnement
Rien que le positionnement referencé "exact" de ton panneau sera avec sa tolerance propre tres surement moins precis qu'un simple tracking "lum" .
Je pense qu'il faut etre pramatique : "le mieux est souvent l'ennemi du bien"
complexifier un probleme est rarement utile et ou preferable

pour ajouter mes 10 centimes au débat : avec deux moteurs et trois LDR disposées sur les trois faces d'une pyramide isocele tu peux positionner idéalement en azimut et en hauteur à tout moment de la journée, et ce quelles que soient les conditions méteo qui peuvent faire varier l'albedo. Comme le système se déplace toujours pour avoir la pointe de la pyramide orientée vers la zone la plus lumineuse, même si il y a de la neige ou du brouillard tu sera toujours au max, ce que ne permets pas un calcul de position du soleil, car le max n'est pas forcément face au soleil, mais peut-être à une position médiane entre le soleil et le sol si il y a de la neige, ou encore complètement décalée d'un coté ou de l'autre en fonction des nuages.
Le calcul de position du soleil en fonction de l'heure peut par contre servir à diminuer le temps de recherche après un "cold start" en milieu de journée. Mais comme Artouste j'ai tendance à croire que ça conplexifie beaucoup pour pas grand chose :wink:

J'aime beaucoup le principe du capteur avec 3 ldr sur les faces d'un cube ou d'une pyramide...
Avez-vous des liens vers des projets existants?

non, mais c'est ce qui se fait assez couramment sur les produits commerciaux. je suppose que c'est parceque c'est un des trucs les plus fiables. (et les moins couteux)

bricofoy:
...
Le calcul de position du soleil en fonction de l'heure peut par contre servir à diminuer le temps de recherche après un "cold start" en milieu de journée. Mais comme Artouste j'ai tendance à croire que ça conplexifie beaucoup pour pas grand chose :wink:

bonjour bricofoy
J'ai encore tendance à penser que la solution ephemeride ne sert à quasi rien (ou du moins qu'elle n' apporte aucun reel benefice vu de l'autonomie.)

l'interet de ce genre de source d'energie est de chercher le rendement justement sans chercher à savoir "l'heure" qu'il est :grin:

en cas de cold start et dans la mesure où il n'y a pas de capteur de position "absolu" , je continuerais ma course vers l'ouest pour detecter un point d'inflechissement "lum" (hysteresis lourd) avant butée W
si je n'en detecte pas avant butée ouest , parcours vers l'est , et si je n'en detecte pas avant butée E , c'est qu'il fait nuit et j'attend "un beau matin" :grin:

oui ça ça a des chances de fonctionner beaucoup plus "fiablement" qu'un truc dont l'horloge peut se dérégler...