jeudi 15 septembre 2016

Orientation d'un panneau photovoltaïque (PV)

Suite à l'article sur le PV résidentiel, cet article concerne l'orientation des panneaux et le calcul de la position du soleil par rapport au point d'observation / d'installation du PV.

Le soleil parcourt durant 24 h un cercle par rapport au sol. L'inclinaison de ce cercle par rapport à l'horizon dépend de la latitude du lieu. Le centre de ce cercle se décale verticalement en dessous et au dessus du point d'observation en fonction du jour de l'année.

Je vous invite à vous faire une idée précise et visuelle du parcours du soleil en installant sur votre smartphone l'application Sun Surveyor Lite.
En changeant le jour à l'aide du slider du bas, en mode année, on voit bien que le cercle du soleil passe devant et derrière l'utilisateur.

Les journées en été sont plus longues et le soleil se lève au Nord Est pour se coucher au Nord Ouest



Les journées en hiver sont plus courtes et le soleil se lève au Sud Est pour se coucher au Sud Ouest


A l'équinoxe d'automne, le jour et la nuit sont égaux en durée. le soleil se lève à l'Est pour se coucher à l'Ouest

L'extraction de puissance est maximale quand le PV est perpendiculaire aux rayons du soleil. L'idéal est donc d'avoir un système de tracking qui permet de suivre la course du soleil le long de la journée et de l'année.

J'ai depuis longtemps développé des algorithmes de calcul de la position du soleil et on peut coupler cela à une RTC (real time clock) + Arduino ou dspic afin d'avoir la position exacte du soleil.
Techniquement, c'est tout à fait faisable avec une motorisation sur 2 axes et une régulation de position.

Cependant, d'un point de vue énergétique, ce n'est pas du tout intéressant. En effet, le système de suivi consommerait toute la puissance produite par le PV pour le tracking, surtout qu'il doit tenir la position, particulièrement en cas de vent.

Des compromis doivent donc être trouvés.
On peut par exemple choisir de n'orienter le PV qu'en 3 positions horizontalement (azimut, donc par rapport à un axe de rotation vertical). La tenue en couple se ferait par un système de verrouillage mécanique.
Quand à l'orientation verticale (hauteur), elle serait soit fixe, soit manuellement modifiable tous les 1 à 3 mois de manière à tenir compte du parcours du soleil tout au long de l'année.
On peut aussi choisir de maintenir l'azimut fixe, on choisit alors d'orienter le PV plein sud.
Si la hauteur est également fixe, on favorisera plutôt un angle inférieur à la latitude du lieu de manière à mieux capter le soleil en hiver.

Une étude rigoureuse doit être menée mais les aspects technico-économiques et de rendement global doivent y être présents.

Voici mes programmes Matlab qui permettent d'afficher la hauteur et l'azimut du soleil tout au long de l'année.
Bonne continuation pour leur exploitation dans vos propres études, vous pouvez citer (BibTex) mes 2 blogs comme :

@online{baghli_orientation_2016,
title = {Orientation d'un panneau photovoltaïque ({PV})},
url = {http://baghli.blogspot.com/2016/09/orientation-dun-panneau-photovoltaique.html},
titleaddon = {activités baghli},
type = {blog},
author = {Baghli, Lotfi},
urldate = {2016-09-15},
date = {2016-09-15}
}

@online{baghli_photovoltaique_2016,
title = {Le photovoltaïque ({PV}) résidentiel},
url = {http://baghli.blogspot.com/2016/09/le-photovoltaique-pv-residentiel.html},
titleaddon = {activités baghli},
type = {Blog},
author = {Baghli, Lotfi},
urldate = {2016-09-15},
date = {2016-09-15}
}


Voici le programme Matlab et les 2 fonctions qui permettent de faire le calcul de la position du soleil dans le ciel de l'observateur et de calculer l'incidence par rapport au PV.

La fonction calchaz, calcule la hauteur et l'azimut du soleil (par rapport au sud) :
function [hauteur,azcorrige] = calchaz(latitudeinput, longitudeinput, Timezoneinput, DSTinput, heurelocaleinput, jour, mois, annee)
% calchaz(34.88,-1.31, 1, 0, 14, 8,6,2016 )
% 2 Algérie          Tlemcen          34.88       -1.31       1        0   1 
Mn2PI =2*pi;
pin2 =pi/2;
deg2rd = 0.017453292519943295769236907684886;
rd2deg = 57.295779513082320876798154814105;
SolarSiderealCorrection = 1.002738;

latitude = deg2rd*latitudeinput;
longitude = deg2rd*longitudeinput;
% CountryName = CountryNameinput;
% TownName = VilleSelect;

TimeZone = Timezoneinput;
DST = DSTinput;
heurelocale = heurelocaleinput;


Soleil.az = 0;  % coord. horizontal
Soleil.h = 0;
Soleil.delta = 0;  % coord equatorial
Soleil.tau = 0;
Soleil.RA = 0;  % ascension droite
Soleil.L = 0;   %longitude r�ele

% jour/mois/ann�e/heure.xxx
date.j = jour;
date.m = mois;
date.a = annee;
date.h = 0; %sera écrasé

% % milisec, secondes/, minutes, heures
% heure.ms = 0;
% heure.s = 0;
% heure.m = 0;
% heure.h = 0;

%struct TownData { char CountryName[Namelenght], TownName[Namelenght];
%  double longitude, latitude;
%  int TimeZoneTown, Convention, DST;
% };

% datenanNow;
% ActualDate; %format JS
% Njours=new Array(12);
%
% JD, T,  % Jour Julien, Julien Century : T,
% theta0, theta,  % theta0 : temps sideral � Greenwich
% longitude, latitude;
% TimeZone, TimeZoneTown, NTowns, TownSelected, Verbose, Convention;
% DST, DSTApplies;

Mounths=char('Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre');
MounthsAbrev=char('jan', 'févr', 'mars', 'avr', 'mai', 'juin', 'juil','août', 'sept', 'oct', 'nov', 'déc');
Days=char('Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche');


%%--------------------------------------------------------------------------
% Julian day: 86400 s, Julian year: 365.25 d, Julian Century: 36525 d
% Julian Day (valid from 1900/3/1 to 2100/2/28)
%function JulianDay (ndate, nmonth, nyear, nUT)
%{
% if (nmonth<=2) {nmonth=nmonth+12; nyear=nyear-1;}
% return floor(365.25*nyear) + (int)(30.6001*(nmonth+1)) - 15 + 1720996.5 + ndate + nUT/24.0;
%}
%%-------------------------------------------------------------------------
function  [JC] = JulianCentury (ndate, nmonth, nyear, nUT)
% Julian century depuis 01/01/2000 � 12h UT
    if (nmonth<=2) 
    nmonth = nmonth+12;
    nyear = nyear-1;
    end
  JC = (floor(365.25*nyear) + floor(30.6001*(nmonth+1)) - 15 + 1720996.5 + ndate + nUT/24.0 - 2451545.0)/36525.0;
end 
%%-------------------------------------------------------------------------
%Solar Coordinates (according to: Jean Meeus: Astronomical Algorithms), accuracy of 0.01 degree 
function result = SoleilLongitude( nT)   % L
 nM = 357.52910 + 35999.05030*nT - 0.0001559*nT*nT - 0.00000048*nT*nT*nT; % mean anomaly, degree
 nL0 = 280.46645 + 36000.76983*nT + 0.0003032*nT*nT; % mean longitude, degree 
 nDL = (1.914600 - 0.004817*nT - 0.000014*nT*nT)*sin(deg2rd*nM) + (0.019993 - 0.000101*nT)*sin(deg2rd*2*nM) + 0.000290*sin(deg2rd*3*nM); 
 nL=nL0 + nDL; % true longitude, deg sans modulo
 nLm=nL-360*floor(nL/360);
 if (nLm==0)
        nLm = nLm+360;
    end
 result= nLm*deg2rd; % true , rd 
end 
%%-------------------------------------------------------------------------
% convert ecliptic longitude L (rd) to right ascension RA and declination delta
function [RA, delta] = eclipticL2RAndelta( nT, nSol)
% convert ecliptic longitude L (rd) to right ascension RA and declination delta
% old approxim  neps = deg2rd*23.43999; % obliquity of ecliptic
 neps = deg2rd*(23.4393 -0.013*nT); % obliquity of ecliptic
 nX = cos(nSol.L); nY = cos(neps)*sin(nSol.L); nZ = sin(neps)*sin(nSol.L); nR = sqrt(1.0-nZ*nZ); 
 delta = atan2(nZ, nR); % in rd 
 RA = 2*atan2(nY, nX+nR); %  in rd 
end 

%%-------------------------------------------------------------------------
function theta0 = TempsSideral( nT)   % theta0
%compute sidereal time at Greenwich (according to: Jean Meeus: Astronomical Algorithms ) 
% T siecle julien depuis 2000
 ntheta0=280.46061837 + 360.98564736629*nT*36525 + 0.000387933*nT*nT - nT*nT*nT/38710000.0;
 ntheta0m=ntheta0-360*floor(ntheta0/360);
 if (ntheta0m<0)
        ntheta0m = ntheta0m+360;
    end
 theta0 = ntheta0m*deg2rd;    % TempsSideralen rd
end 
%%-------------------------------------------------------------------------
function [h, az] = equatorial2horizontal( nbeta, nSol)
%convert tau, delta to horizon coordinates of the observer (altitude h, azimuth az) , needs latitude : beta
 h=asin( sin(nbeta)*sin(nSol.delta) + cos(nbeta)*cos(nSol.delta)*cos(nSol.tau)); % h en rd
 az =atan2( -sin(nSol.tau), cos(nbeta)*tan(nSol.delta) - sin(nbeta)*cos(nSol.tau))-pi; % az en rd du SUD
 if (az<0)
        az = az+2*pi;
    end
end 
%%-------------------------------------------------------------------------
function Calchaz_in()
 date.h=heurelocale-TimeZone; % heure GMT
 if (date.h<0) 
        date.h = date.h + 24;
        date.j = date.j-1;
    end
 T=JulianCentury (date.j, date.m, date.a, date.h);
 Soleil.L=SoleilLongitude(T);
 [Soleil.RA, Soleil.delta] = eclipticL2RAndelta( T, Soleil);
 theta0=TempsSideral( T);
 theta=theta0+longitude;
 Soleil.tau=theta-Soleil.RA;
 [Soleil.h, Soleil.az] =equatorial2horizontal( latitude, Soleil);
% equatorial2horizontal( latitude, Soleil.tau, Soleil.delta, Soleil.h, Soleil.az);
end
%%-------------------------------------------------------------------------
%function CalculeNjdumois( m, annee)
%{
%Nonbissextile = floor(annee-4*floor(annee/4)+2)/3;  % 1 pour une ann�e commune et  0 pour une bissextile)
% if (m==1 || m==3 || m==5 || m==7
%  || m==8 || m==10 || m==12)  return 31;
%   else {
%      if (m==2) {if (Nonbissextile) return 28;
%               else    return 29;
%           }
%        else  return 30;
%    }
%}

 Calchaz_in();
 azcorrige=Soleil.az;
 if (azcorrige<-pi)
        azcorrige = azcorrige + Mn2PI;
    end
 if (azcorrige> pi)
        azcorrige = azcorrige - Mn2PI;
    end
 hauteur = Soleil.h;
%% en degrés    
    hauteur = hauteur*rd2deg;
    azcorrige = azcorrige*rd2deg;
    %Days(i,:)
end


La fonction incline permet de calculer l'angle que fait le soleil avec la surface du PV :
function inc = incline(azs, inclineMax)
% calcule l'inclinaison pour un angle d'azimut donné 
 inc = asin( sin(inclineMax) *cos(azs)); % h en rd
end


Le programme principal uilise les 2 fonctions précédentes pour afficher la hauteur du soleil et son azimut le long de la journée et de l'année et de calculer l'angle d'incidence sur le PV :
% course du soleil durant l'année à Tlemcen
%[h, az] = calchaz(34.88,-1.31, 1, 0, 14, 8,6,2016 )
close all; clear all;
deg2rd = 0.017453292519943295769236907684886;
rd2deg = 57.295779513082320876798154814105;
inclinaisonPV = 34;
heure = [5:10./60:22];
for mm = 1:12
    for hh = 1:length(heure)
        [h, az] = calchaz(34.88,-1.31, 1, 0, heure(hh), 1,mm,2016 );
        Hauteur(mm,hh)=h;
        Azimut(mm,hh)=az;
        inclinaison(mm,hh)= h + rd2deg*incline(az*deg2rd, inclinaisonPV*deg2rd);
    end
end
cc=hsv(12);
% Hauteur
figure (1);
hold on;
for mm = 1:12
    plot(heure, Hauteur(mm,:),'color',cc(mm,:));
end
% Azimut
figure (2);
hold on;
for mm = 1:12
    plot(heure, Azimut(mm,:),'color',cc(mm,:));
end

% inclinaison absolue
figure (3);
hold on;
for mm = 1:12
    plot(heure, inclinaison(mm,:),'color',cc(mm,:));
end

figure (4);
plot(heure, Hauteur(6,:),'b', heure, inclinaison(6,:),'r' );
legend('hauteur horizon', 'inclinaison soleil - PV juin');


Hauteur (en °) du soleil en fonction de l'heure de la journée
Un angle négatif signifie que le soleil est en dessous de l'horizon


Azimut (en °) du soleil en fonction de l'heure de la journée
Un angle négatif signifie que le soleil se trouve à l'est, nul au sud, positif à l'ouest


Inclinaison (en °) ou incidence du soleil par rapport au PV en fonction de l'heure de la journée, l'inclinaison du PV est de 34°

Comparaison entre la hauteur du soleil et de l'incidence des rayons sur le PV, en fonction de l'heure de la journée, pour le mois de juin
L'inclinaison du PV est de 34°



2 commentaires:

  1. Je pense qu'il faut définir l'inclinaison du PV par rapport à la verticale, et non au soleil

    RépondreSupprimer
    Réponses
    1. Pour la dernière courbe, lL'inclinaison du PV est de 34° (par rapport à l'horizon)
      Cependant, on a besoin de connaître l'angle que fait le soleil à chaque instant avec le plan du PV pour estimerl'efficacité de notre orientation et faire des études comparatives.

      Supprimer