您现在的位置:中国电工网 > 专题 > 新能源
一种太阳能有效接收装置的设计与优化方法
栏目:新能源 编辑:作者:     2019-05-22 10:03
    太阳能有效地接收在光能被越来越重视的今天受到了广泛的关注。由于许多太阳光接收器无法跟随太阳位置的改变而改变,使得太阳能的接收效率低下,因而通过太阳能接收装置的设计与优化来实现对太阳能的有效接收,继而达到提高太阳光能的利用率,从而可以很好的应用于其他与太阳光能有关的设备。
 
    1.设计思路
 
    主要设计思路如下:使太阳能接收装置的接收面能够依照太阳的运动轨迹进行转动,保证时时对着太阳,从而达到太阳光的高效率利用。为有效实现这一目的,主要分为两个方法:检测光强以及太阳轨迹算法。检测光强主要使用光敏电阻来进行,当四周的光敏电阻感受到同样的光强时,即为正对太阳。太阳轨迹算法即根据地球的自转和公转规律,得出太阳的运动轨迹,对于给定的经度、纬度及时间,可以算出太阳的角度。然后,将这算法用C语言的形式写入ArduinoUno开发板中,可以实现接收面按照正对太阳轨迹的方式运动。
 
    ArduinoUNO是ArduinoUSB接口系列的较新版本,作为Arduino平台的参考标准模板。UNO的处理器核心是ATmega328,同时具有14路数字输入/输出口(其中6路可作为PWM输出)、6路模拟输入、一个16MHz晶体振荡器、一个USB口、一个电源插座、一个ICSPheader和一个复位按钮。ArduinoUno开发板非常适合做本设计中微控制器。
 
    通过太阳能探测器和太阳轨道算法,Arduino微控制器能够在工作期间计算太阳位置,并发送控制信号至步进电机,该信号将被步进电机驱动芯片放大,步进电机将执行旋转命令,使太阳能接收装置的接收面能够时时对着太阳。
 
    将检测光强以及太阳轨迹算法两种方法相结合,可以使整个太阳能有效接收装置系统满足要求,高效工作。首先,太阳轨迹算法是所有方法中可以提供较高精度、较低功耗的方法之一,但当使用一个步进电机作为机电设备时,它无法自校准;其次,只使用太阳能检测器,会不可避免地受到无法预料的光源的影响。将两种方法相结合,可以达到电路简单、成本低、功耗低和精度高的理想效果。
 
    2.设计方法
 
    2.1检测光强
 
    使用一系列沿直线布置的光电传感器,并且比较它们所检测到的光强度,从而来确定沿该轴方向的太阳位置。采用两组传感器分别检测太阳方位角和仰角。每组有三个光敏电阻LDR,且两组共享中心位置的LDR,如图1所示。
 
   
 
    图1传感器设置原理图
 
    5个LDR在电路中具有相同的性能,同时,每组分别对称,确保当光源发出光至检测器的中心时,每一组中无光强度偏差。这样,根据其原理图,光强度转换为电压,这是由于依赖于光强度的LDR阻抗造成的。换句话说,太阳位置通过ArduinoUno上的模拟引脚读取的电压值来表示的,这种方法取决于LDR的精度。
 
    本设计中所采用的光敏电阻是对400nm到700nm的光敏感的CdS光敏光电管。其电阻值从10千欧到200千欧变化。这些LDR的灵敏度通常情况下是0.85,对本设计足够高了。
 
    根据原理图所示,应仔细选择电阻,因为电阻直接影响检测器的准确度。LDR的阻值会随入射光强度的改变而变化,合适的电阻决定了测得的电压值的范围。本设计目标应实现较广泛的输出电压范围。假设的LDR的电阻呈线性变化,检测到的电压范围可表示为:
 
   
 
    2.2驱动电路
 
    设计中所采用的步进电机是两相双极步进电机,作为混合动力同步步进电机的模型,其集成了永磁步进和可变磁阻步进的优势。但是,步进电机的选择带来了两个不可避免的问题,一是Arduino的电流不足,另一种是步进电机本身的分辨率限制。
 
    电流不足是步进电机和Arduino之间的电流不匹配导致的:单一的步进电机所需的驱动电流是0.33A,而Arduino数字引脚的较大输出电流为40mA,基于这种状况,需要使用驱动芯片来解决这个问题。
 
    驱动器芯片的型号根据不同的步进电机而不同,相应的双极步进电机的驱动器是半H驱动器,本设计中使用的是SN754410,它具有高的输出电流能力和宽的电源电压范围。此外,集成在芯片上的驱动器的数目与步进电机的输入口的数目是相同的。这样,一个芯片控制一个步进电机,使得代码和电路简单。该驱动器电路如图2所示。
 
 
 
    图2驱动器电路图
 
    从原理图可以看出,不需要额外的电源供给,Arduino具有给两个步进电机和半H驱动器提供足够电流的能力。这是采用这种特定型号的驱动器芯片的另一个优点,不需要外部支持装置或设备,可确保安装的高适应性和低难度。
 
    完整的电路原理图如图3所示。
 
   
 
    图3完整的电路原理图
 
    3.代码的连接与测试
 
    较终代码的流程图如图4所示,用于校准由LDR和其他组件组成的太阳能检测器。给太阳轨道算法提供一个起点,如果太阳能接收器已经正对太阳的话,太阳轨道算法能够计算出步进电机旋转的方位角和仰角,但它无法确定接收器的当前角度。其结果是,需要太阳能检测器给微控制器一个基准。
 
    执行校准的时间和持续的时间间隔是至关重要的。这两个参数直接决定了校准是否成功。首先,如果时间点太早,太阳能光不够强,校准后会出现偏差,如果时间点太晚,会浪费大量的太阳能;其次,如果时间周期太短,受到意外光源干扰的可能性将被放大,如果时间周期太长,也会浪费太阳能。
 
   
 
    图4较终代码的流程图
 
    经过测试和调整,实现准确、高效校准的较好方式如下:计算太阳的仰角,一旦角度超过15度,开始设置传感器在特定的时间内,当太阳在天空中移动1度时来追踪太阳。校准完成后,太阳能接收器应该正确地面对太阳,然后不断计算太阳位置,并进入正常运行循环。
 
    4.小结
 
    较终成品需要在两种特殊情况下进行实验测试。一是在室内用可快速移动的光源进行测试,以验证产品的基本工作情况。可以逐渐改变入射角,但速度比太阳更快(避免长时间的测试时间);二是在室外自然光条件下长时间放置,以验证产品的性能和品质。并基于实验的情况,进行调试和优化,同时,必须加入工作时段和天气因素影响的考虑。
 
    本太阳能有效接收装置具有电路简单、价格低廉、安装便易、适应性强等特点,可很好的应用于其他与太阳光能有关的设备。
 
    附录:完整代码
 
    #include
 
    #include
 
    #include
 
    #include//Steppermotorlibrar
 
    #defineEarthMeanRadius6371.01//Inkm
 
    #defineAstronomicalUnit149597890//Inkm
 
    #definepi3.14159265358979323846
 
    #definetwopi(2*pi)
 
    #definerad(pi/180)
 
    #defineSTEP2180//Azimuth
 
    #defineSTEP190//Horizon
 
    intright=0;//RightLDR
 
    intleft=0;//LeftLDR
 
    intcenter=0;//CenterLDR
 
    intup=0;//TopLDR
 
    intdown=0;//BottomLDR
 
    intldr1=0;//ArrangeLDR'stopins
 
    intldr2=1;
 
    intldr3=2;
 
    intldr4=3;
 
    intldr5=4;
 
    StepperStepper2(STEP2,9,10,11,12);//Azimuth
 
    StepperStepper1(STEP1,5,6,7,8);//Horizon
 
    DS1302rtc(2,3,4);
 
    Timet;
 
    booleannightTime;
 
    floatAzimuth;
 
    floatElevationAngle;
 
    floatElapsedJulianDays;
 
    floatRightAscension;
 
    floatDeclination;
 
    floatParallax;
 
    floatHoursinDecimal;
 
    floatEclipticLongitude;
 
    floatEclipticObliquity;
 
    floatZenithAngle;
 
    floatHourAngle;
 
    intStep2=0;//Azimuth
 
    intStep1=0;//Horizon
 
    intAzimuthPrevious=0;
 
    intElevationPrevious=0;
 
    intAzimuthOneDegree=1;//Enternumberofstepstomove1degreeinAzimuth.
 
    intElevationOneDegree=1;//Enternumberofstepstomove1degreeinElevation.
 
    floatLongitude=-83.23319435119629;//Enterlongitudehere
 
    floatLatitude=42.32005756174596;//Enterlatitudehere
 
    voidsetup()
 
    {
 
    rtc.halt(false);
 
    rtc.writeProtect(false);
 
    Serial.begin(9600);
 
    rtc.setTime(9,0,0);//Setthetimeto12:00:00(24hrformat)
 
    rtc.setDate(16,4,2012);//SetthedatetoApril16th,2012
 
    //setSyncInterval(200);//Re-synctimewiththeRTCevery()miliseconds.
 
    Stepper1.setSpeed(30);//horizon
 
    Stepper2.setSpeed(30);//azimuth
 
    pinMode(ldr1,INPUT);//DeclareLDRsasinput
 
    pinMode(ldr2,INPUT);
 
    pinMode(ldr3,INPUT);
 
    pinMode(ldr4,INPUT);
 
    pinMode(ldr5,INPUT);
 
    Stepper1.setSpeed(30);//Definestepperspeed
 
    Stepper2.setSpeed(30);
 
    }
 
    voidsunPos()
 
    {
 
    floatdY;
 
    floatdX;
 
    floatJulian_Day;
 
    longintliAux1;
 
    longintliAux2;
 
    floatOmega;
 
    floatMeanLongitude;
 
    floatMeanAnomaly;
 
    floatSin_EclipticLongitude;
 
    floatGreenwichMeanSiderealTime;//Primemeridian
 
    floatLocalMeanSiderealTime;
 
    floatLatitudeInRadians;
 
    floatHourAngle;
 
    floatCos_Latitude;
 
    floatSin_Latitude;
 
    floatCos_HourAngle;
 
    t.hour=t.hour+4;
 
    HoursinDecimal=(t.hour+t.min/60.0);
 
    liAux1=(t.mon-14)/12;
 
    liAux2=(1461*(t.year+4800+liAux1))/4+(367*(t.mon-2-12*liAux1))/12-(3*((t.year+4900+liAux1)/100))/4+t.date-32075;
 
    Julian_Day=(float)(liAux2)-0.5+HoursinDecimal/24.0;//CalculatecurrentJulianDay
 
    ElapsedJulianDays=Julian_Day-2451545.0;//CalculatedifferencebetweencurrentJulianDayandJanuary1stnoon2000UniversalTime—JD2451545.0
 
    Omega=2.1429-0.0010394594*ElapsedJulianDays;
 
    MeanLongitude=4.8950630+0.017202791698*ElapsedJulianDays;//Inradians
 
    MeanAnomaly=6.2400600+0.0172019699*ElapsedJulianDays;//Inradians
 
    EclipticLongitude=MeanLongitude+0.03341607*sin(MeanAnomaly)+0.00034894*sin(2*MeanAnomaly)-0.0001134-0.0000203*sin(Omega);//Calculate//eclipticlongitude
 
    EclipticObliquity=0.4090928-6.2140e-9*ElapsedJulianDays+0.0000396*cos(Omega);//Calculateeclipticobliquity
 
    Sin_EclipticLongitude=sin(EclipticLongitude);
 
    dY=cos(EclipticObliquity)*Sin_EclipticLongitude;
 
    dX=cos(EclipticLongitude);
 
    RightAscension=atan2(dY,dX);//Calculatecelestialcoordinates,rightascensioninradians
 
    if(RightAscension<0.0)
 
    {
 
    RightAscension=RightAscension+twopi;
 
    }
 
    Declination=asin(sin(EclipticObliquity)*Sin_EclipticLongitude);
 
    //Calculatecelestialcoordinates,declinationinradians
 
    //Calculatelocalcoordinates(azimuthandzenithangle)indegrees
 
    GreenwichMeanSiderealTime=6.6974243242+0.0657098283*ElapsedJulianDays+HoursinDecimal;
 
    LocalMeanSiderealTime=(GreenwichMeanSiderealTime*15+Longitude)*rad;
 
    HourAngle=LocalMeanSiderealTime-RightAscension;
 
    LatitudeInRadians=Latitude*rad;
 
    Cos_Latitude=cos(LatitudeInRadians);
 
    Sin_Latitude=sin(LatitudeInRadians);
 
    Cos_HourAngle=cos(HourAngle);
 
    dY=-sin(HourAngle);
 
    dX=tan(Declination)*Cos_Latitude-Sin_Latitude*Cos_HourAngle;
 
    Azimuth=atan2(dY,dX);//Calculatelocalcoordinates,azimuthindegrees
 
    if(Azimuth<0.0)
 
    {
 
    Azimuth=Azimuth+twopi;
 
    }
 
    Azimuth=Azimuth/rad;
 
    ZenithAngle=(acos(Cos_Latitude*Cos_HourAngle*cos(Declination)+sin(Declination)*Sin_Latitude));
 
    //Calculatelocalcoordinates,zenithangle//indegrees
 
    //ParallaxCorrection
 
    Parallax=(EarthMeanRadius/AstronomicalUnit)*sin(ZenithAngle);
 
    ZenithAngle=(ZenithAngle+Parallax)/rad;//Zenithangleisfromthetopofthevisiblesky
 
    ElevationAngle=(90-ZenithAngle);//RetrieveusefulelevationanglefromZenithangle
 
    }
 
    voidloop()
 
    {
 
    t=rtc.getTime();
 
    sunPos();//Runsunpositioncalculations
 
    //if(t.sec>15)//Fordebug
 
    //{
 
    //Stepper1.step(50);
 
    //Stepper1.step(-50);//vertical
 
    //}
 
    Serial.print(ZenithAngle);
 
    Step1=(ElevationAngle*ElevationOneDegree);//Step1vertical
 
    Step2=((Azimuth/2)*AzimuthOneDegree);//DevideAzimuthby2forarangeof180degrees,step2horizon
 
    if(ElevationAngle<0)
 
    {
 
    nightTime=true;
 
    Stepper1.step(((90-ElevationAngle)*ElevationOneDegree));//Parkthepanelflatatnight.
 
    Stepper2.step(((Azimuth/4)*AzimuthOneDegree));//Decreasetheeffectofwinds.
 
    while(nightTime)
 
    {
 
    ElevationPrevious=0;//Clear"previous"values
 
    AzimuthPrevious=0;
 
    if(ElevationAngle>0)
 
    {
 
    nightTime=false;
 
    }
 
    sunPos();
 
    }//RunsunpositioncalculationstoseewhenElevationisabovezero.
 
    delay(1000);
 
    }
 
    if(ElevationAngle>0)
 
    {
 
    if(ElevationAngle>10&&ElevationAngle<20)//LDRcollaboration
 
    {
 
    intcenter=analogRead(ldr1);//RecordreadingfromeachLDRs
 
    intright=analogRead(ldr2);
 
    intleft=analogRead(ldr3);
 
    intdown=analogRead(ldr4);
 
    intup=analogRead(ldr5);
 
    //Iftheweatherisnotsogood,parkthepanel
 
    if(center<3&&right<3&&left<3&&down<3&&up<3)
 
    {
 
    Stepper1.step(((90-ElevationAngle)*ElevationOneDegree));
 
    //Parkthepanelflatatnight.
 
    Stepper2.step(((Azimuth/4)*AzimuthOneDegree));//Decreasetheeffectofwinds.
 
    delay(60000);//Detectsolarlightintensityagainafter1min
 
    }//Controlhorizontalposition
 
    elseif(right>center&&left<center)//IfrightLDRhasmorelightthancentreLDR,andcentreLDRhasmorelightthanleft(meanslightistowardsright)
 
    {
 
    Stepper1.step(1);//Increasepositionofservo1by1(0isleft,90iscentre,180isright)
 
    delay(10);//Thisdelayisneededtopreventservofromgoing0-180withoutstopping
 
    }
 
    if(left>center&&right<center)//Iflightistowardscentre
 
    {
 
    Stepper1.step(-1);//Decreasepositionofservo1by1(0isleft,90iscentre,180isright)
 
    delay(10);
 
    }
 
    else
 
    {
 
    Stepper1.step(0);
 
    delay(10);
 
    }
 
    //Controlverticalposition
 
    if(up>center&&down<center)
 
    {
 
    Stepper2.step(1);
 
    delay(10);
 
    }
 
    elseif(down>center&&up<center)
 
    {
 
    Stepper2.step(-1);
 
    delay(10);
 
    }
 
    else
 
    {
 
    Stepper2.step(0);
 
    delay(10);
 
    }
 
    }
 
    elseif(ElevationAngle>=20)
 
    {
 
    if((Step1-ElevationPrevious)<0)//Afterthesolarnoon,Elevationwilldecline
 
    {
 
    Stepper1.step(((Step1-ElevationPrevious)*-1));//StepperrunBACKWARD.
 
    }
 
    Stepper1.step((Step1-ElevationPrevious));
 
    Stepper2.step((Step2-AzimuthPrevious));
 
    ElevationPrevious=Step1;
 
    AzimuthPrevious=Step2;
 
    delay(500);
 
    }
 
    }
 
    }
Tag:太阳能
来源:互联网
0

微信号:chinaetnet

扫一扫,电网信息随手掌控

微信号:dianwangzj

扫一扫,最新信息随手掌控

相关新闻

免责声明

本文系转载中国电工网合作媒体或互联网其它网站,中国电工网登载此文出于传递信息之目的,本文仅代表作者个人观点,与中国电工网无关。
更多产品

推荐产品


博聚网