基于物联网(IoT)的太阳能跟踪器
本文最后更新于:1 年前
基于物联网(IoT)的太阳能跟踪器
1 项目概述
该项目提供了一个简单和低成本的 IoT 解决方案,用于监控和控制智能双轴太阳能跟踪系统,用于性能评估。
项目中的基于 IoT 的太阳能跟踪系统在图 1 中进行了描述。它是一种双轴太阳能跟踪器,可以自动旋转,使用LDR传感器跟踪太阳的位置,或者用户通过物理控制的仪表板手动跟踪太阳的位置。系统从 LDR 传感器检测太阳位置(光的强度)开始,并将数据发送到控制器(Arduino Mega 板)。后者然后处理这些数据以命令保存器 (SM1 和 SM2),这些存储器将光伏面板旋转到太阳。产生的光伏电压值和电流、温度和湿度也通过相关传感器发送到 Arduino。
接下来,安装在 Arduino 并允许其连接到 Internet 的以太网扩展模块将把Arduino正在获取或处理的数据发送到云(Webserver)。最后,通过预制的小部件实时显示太阳跟踪器数据,包括LDR传感器、光伏功率、温度和湿度。物联网监控应用程序是使用我的设备卡宴。一旦用户从计算机或智能手机连接到互联网,他可以在物联网应用程序的仪表板中在其相关小部件中可视化所有太阳能跟踪器数据。因此,用户拥有与光伏面板的环境和性能相关的必要数据。
此外,在手动模式下,伺服运动器将从仪表板中的相关小部件中获取角度方向。因此,用户可以控制自己的系统,以寻求最佳的环境条件,并从光伏面板中提取最大能量。物联网应用程序还被编程为在senor达到预定阈值时发送通知警报(短信或电子邮件)。
2 硬件设计
- 如图2所示,物联网太阳能跟踪系统由光伏电池板、两台伺服电机、四个LDR传感器、电压分频器电路、温度和湿度传感器、Led和Arduino Mega 板组成。
使用的光伏面板尺寸为 115 mm 乘 85mm,输出为 1.6 W,可产生高达 6 V 的电压。两个180度的伺服器用于使太阳能跟踪器电机化,它们由阿尔杜伊诺板通过PWM引脚5和6控制。左右 (L-R) 伺服电机 (MG996R) 在垂直轴上(东/西)旋转太阳跟踪器,而上下 (U-D) 伺服电机 (SG90) 在水平轴 (南/北) 上旋转太阳跟踪器。
四个LDR(Cds GL5528)用于感应太阳的位置,这些位置已固定在面板的四个角落。LDR 传感器通过 A0 到 A3 的模拟引脚连接到阿尔杜伊诺。LDR 是一种电阻器,其值随着表面光强度事件的增加而降低。LDR 传感器设计为电压分流器电路,如图 2 所见。分频器输出电压由 Arduino Mega 的微控制器从模拟值转换为 0 到 1023 之间的数字值。因为微控制器的模拟数字转换器 (ADC) 编码为 10 位。LDR 传感器电路中的系列电阻器值为 330 Ω。
温度和湿度通过 DHT22 传感器测量。DHT22 内嵌有一个热电容器和电容湿度传感器,可测量温度和相对湿度。其温度范围为 -40 至 80 °C,准确度为 < ±0.5°C,湿度范围为 0 至 100%,±2%(最大±5%)准确性。此传感器使用一根信号线将数据传输到 Arduino(数字引脚 2)和两根用于电源的电线。
光伏电压和电流通过电压分隔电路测量,该分频器也作为负载,由两个 10 Ohms 的系列电阻器组成。分频器电路输出与阿尔杜伊诺的模拟引脚 A4 相连。此外,连接到数字引脚 3 的 LED 在系统电路中反映了太阳能跟踪器(手动或自动)的模式状态。
Arduino Mega 与ATmega2560 微控制器用作嵌入式控制器,与阿尔杜伊诺以太网屏蔽以及监控平台交互。安装在 Arduino 板上方的以太网防护罩必须通过图 3 中显示的 RJ45 电缆与 Wi-Fi 路由器 (或 PC) 连接。以太网盾基于 Wiznet W5100 以太网芯片,该芯片为 TCP 和 UDP 协议提供了网络 (IP) 堆栈。
3 软件设计
3.1 Arduino IDE
Arduino 是一个开源电子原型平台,具有易于使用的硬件和软件。Arduino 平台提供集成开发环境 (IDE),其中包括对 C 和C++编程语言的支持。本作品中使用的 Arduino 板由 IDE 编程,该 IDE 充当代码编辑器,程序代码可以通过 USB 电缆上传到微控制器,如图 3 所示。Arduino 巨型板用于实现基于物联网的太阳能跟踪器的所有软件要求。
3.2 myDevices Cayenne (我的设备卡宴)
- MyDevices 是一家提供完美的物联网解决方案的公司。它为 IoT 提供了端到端平台。在我们的项目中,我们将专注于卡宴,这是来自我的设备的解决方案之一。此工具允许开发人员、设计师和工程师构建物机原型。卡宴使用消息排队电信传输 (MQTT) 协议将任何设备与卡延内克云连接起来。连接后,用户可以通过创建的小部件将设备中的数据发送并接收到 Cayenne 仪表板。MQTT 是基于 TCP/IP 协议的发布订阅消息协议。发布订阅方法使用负责向客户端传递消息的消息代理。MQTT 是用于向卡宴云或卡宴控制的设备发送信息的 API。此连接中的消息代理是云,它管理发送和接收数据的不同客户端(传感器和执行器)。
- 要使用 MQTT 与卡宴, 我们需要使用卡宴库。对于阿尔杜伊诺,可以从 IDE 的图书馆经理安装卡延内MQTT 库。要对基于 Cayenne 物联网平台的物联网应用进行编程,我们将利用预先定义的功能。例如,为了建立 Cayenne 云和配备以太网模块的 Arduino Mega 之间的连接,我们调用 CayenneMQTT 以太网库,在那里我们声明我们的身份验证信息(用户名、密码和客户 ID),这些信息应从 Cayenne 仪表板获得。然后,在程序的设置部分,我们调用 Cayenne.开始 ()功能来建立与 Cayenne 仪表板的连接。对于每个执行器,我们创建一个功能,其整数参数在 0 到 31 之间,称为 CAYENNE IN(虚拟通道)。对于每个传感器,我们创建一个功能,其整数参数在 0 到 31 之间,称为CAYENNE_OUT (VIRTUAL_CHANNEL)。在程序的循环部分,我们称为预先定义的函数 Cayenne.loop (),该函数本身称为功能CAYENNE_OUT和CAYENNE_IN。虚拟通道,因为它的名称建议是一个通道,没有物理存在,它的特点是可视化或命令小部件。它允许它们与相应的传感器或执行器连接。
3.3 The embedded software design(嵌入式软件设计)
嵌入式软件将嵌入到 Arduino Mega 中,以便在以太网模块和 Cayenne 云之间进行交互(参见附录)。其设计如下:
1 功能模式
基于物联网的太阳能跟踪器具有两种功能模式:手动和自动。在 Cayenne 仪表板中创建的按钮具有在两种模式之间切换的作用。非活动时,选择手动模式,否则自动模式。此外,在 Arduino 代码中还建立了一个功能,允许恢复按钮的状态。系统电路中的 LED 反映了此开关的状态。
因此,要使控制器了解所选的操作模式,我们只需要测试 LED 连接的引脚状态。例如,如果 LED 状态较低,控制器将调用手动模式功能执行,否则将调用自动功能。
2 手动模式
如果选择手动模式,用户可以直接控制伺服器的位置,通过 L-R 伺服器将光伏板从东向西定向,或通过 U-D 伺服器从南向北定向。该控制由物联网应用程序仪表板中服务器运动器的相关小部件组成。
在此模式下,控制器调用 Cayenne.loop()功能,该函数本身调用所有功能CAYENNE_IN(包括与伺服器相关的功能)执行。 Cayenne.loop()功能还将调用与传感器相连的所有功能CAYENNE_OUT执行。如果将与 LDR 传感器、光伏电流、电压和功率、温度和湿度相关的数据发送到服务器,以便在物联网应用程序中的相关小部件中可视化这些数据。
3 自动模式
如果选择自动模式,将执行图 4 中显示的算法。该算法首先阅读 LDR 传感器返回的模拟值。然后,它会处理这些数据以命令将光伏面板移向太阳位置的伺服运动器。考虑到基于垂直轴的太阳能跟踪器运动,比较了左侧两个LDR和右侧两个LDR的平均值,如果左侧接收到更多的光,光伏电池板将朝这个方向(顺时针方向)穿过L-R伺服器。当差额结果在 -10 和 10 之间时,后者将停止。此范围用于稳定控制器并降低伺服器的功耗。否则,如果正确的LDR集接收更多的光,光伏面板将朝这个方向移动(逆时针)通过L-R伺服器,并将继续旋转,直到差异结果在范围内[−10,10]。同一方法用于基于水平轴的太阳能跟踪器运动,比较顶部两个LDR和底部两个LDR的平均值。
除了在自动模式下,控制器还将调用 Cayenne.loop()功能将太阳能跟踪器数据发送到 IoT 应用程序。
3.4 Development of the IoT monitoring application(开发 IoT 监控应用程序)
1 硬件与卡宴 IoT 平台的连接
要将硬件(包括传感器和执行器)与物联网络平台对接,我们需要遵循以下步骤:
创建帐户后登录卡宴我的Device网站(图5(a))。
然后,单击 Cayenne API 中的”自带东西”(图 5(b))。
从克里特岛应用程序(图6)复制 MQTT 凭据(用户名、密码和客户 ID),并将其粘贴到 Arduino 源代码中,如前所述。在成功编译并上传整个代码到 Arduino Mega 后,在 Arduino IDE 中打开串行监视器以获取 Cayenne 日志打印(图 7)。一旦我们的设备上线并连接到 Cayenne,上一页(图 6)将自动更新,我们将在在线仪表板中看到我们的设备,如图 8 所见。
然后,要接口传感器和执行器,即创建其小部件,单击”添加新…”,选择”设备/小部件”,然后单击”自定义小部件”(图 9)。然后,选择小部件并填充相关设置(通道号必须与代码相同),最后单击”添加小部件”将其添加到设备的仪表板。对于我们来说,我们为所有传感器选择了”价值”小部件,为模式切换选择了”按钮”小部件,为伺服器选择了”滑块”小部件。
最后,图10说明了用于监测太阳能跟踪器数据的设计物联网应用程序。与太阳跟踪器系统建立连接后,传感器数据可以在其相关部件上可视化,跟踪模式(自动或手动)可以从开关按钮中选择,并通过小部件控制伺服者的角度。还可以通过修改其设置中的表示类型或单击小部件上方的图形图标以图形形式获取传感器数据。
2 警报创建
监控系统中最重要的标准之一是,当发生与其监控设备相关的事件时,它能够发送通知警报通知用户。为此,我们利用 Cayenne 的一个功能为我们的物联网应用程序添加警报,在那里我们可以预先编程我们的应用程序以发送通知警报(短信、电子邮件或两者兼有)或执行指定操作。例如,创建温度警报,以便在监控温度达到阈值时向用户(或收件人)发送电子邮件通知,如图 11 所示。要创建警报,请单击”添加新。”然后选择”触发”,然后设置事件及其操作,最后单击”保存”将其添加到仪表板。
4 原型设计
图12展示了太阳能跟踪器原型在其分离和组装状态。它由光伏面板、R 和 U-D 伺服器和 LDR 传感器组成。该面板一侧连接到 U-Dservomotor,另一侧有轴承,以确保当太阳能跟踪器围绕水平轴旋转时更好的灵活性。装配连接到 L-R 伺服器。LDR 传感器固定在空心气缸内面板的四个角落。如果面板不垂直于太阳,则至少有一个 LDR 将被周围圆柱体造成的阴影覆盖。因此,光强度会有差异。最佳方向是当光的特性在所有LDR传感器中是相等的。图13显示了基于 IoT 的太阳能跟踪系统的整个原型,很明显,硬件部分中的所有报告组件都已用于构建它。
有关所获结果的更多详细信息,请参阅本链接中的论文: https://link.springer.com/chapter/10.1007%2F978-3-030-64565-6_4
5 代码
/***************************************************************
PROJECT: IoT based solar tracker system / the embedded software
Aboubakr El Hammoumi/ aboubakr.elhammoumi@usmba.ac.ma
***************************************************************/
#define CAYENNE_PRINT Serial
#include <CayenneMQTTEthernet.h> //CayenneMQTT library
#include <Servo.h> //Servo motor library
#include <DHT.h> //DHT library
#define DHTTYPE DHT22
#define DHTPIN 2
DHT dht(DHTPIN,DHTTYPE);
//MQTT credentials
char username[]="498d2d00-afe2-11ea-883c-638d8ce4c23d";
char password[]="ab4a8f92d94033c01f6e18ce1d8a84d8c304c9c4";
char clientID[]="17798a40-b968-11ea-93bf-d33a96695544";
Servo servo_x; //up-down servomotor
int servoh = 0;
int servohLimitHigh = 170;
int servohLimitLow = 10;
Servo servo_z; //left-right servomotor
int servov = 0;
int servovLimitHigh = 170;
int servovLimitLow = 10;
int topl,topr,botl,botr;
int threshold_value=10;
float Vout;
void setup()
{ Serial.begin(9600);
Cayenne.begin(username, password, clientID);
servo_x.attach(5);
servo_z.attach(6);
dht.begin();
pinMode(3,OUTPUT);
digitalWrite(3,LOW);
}
void loop()
{ topr= analogRead(A2);
topl= analogRead(A3);
botl= analogRead(A4);
botr= analogRead(A5);
Vout=(analogRead(A1) * 5.0) / 1023;
Serial.println(" Manual-mode");
Cayenne.loop();
if (digitalRead(3)==HIGH){
Serial.println(" Automatic-mode");
servoh = servo_x.read();
servov = servo_z.read();
int avgtop = (topr + topl) / 2;
int avgbot = (botr + botl) / 2;
int avgright = (topr + botr) / 2;
int avgleft = (topl + botl) / 2;
int diffhori= avgtop - avgbot;
int diffverti= avgleft - avgright;
/*tracking according to horizontal axis*/
if (abs(diffhori) <= threshold_value)
{
servo_x.write(servoh); //stop the servo up-down
}else {
if (diffhori > threshold_value)
{ Serial.println(" x - 2 ");
servo_x.write(servoh -2); //Clockwise rotation CW
if (servoh > servohLimitHigh)
{
servoh = servohLimitHigh;
}
delay(10);
}else {
servo_x.write(servoh +2); //CCW
if (servoh < servohLimitLow)
{
servoh = servohLimitLow;
}
delay(10);
}
}
/*tracking according to vertical axis*/
if (abs(diffverti) <= threshold_value)
{
servo_z.write(servov); //stop the servo left-right
}else{
if (diffverti > threshold_value)
{
servo_z.write(servov -2); //CW
if (servov > servovLimitHigh)
{
servov = servovLimitHigh;
}
delay(10);
}else{
servo_z.write(servov +2); //CCW
if (servov < servovLimitLow)
{
servov = servovLimitLow;
}
delay(10);
}
}
}
}
// Cayenne Functions
CAYENNE_IN(8){
int value = getValue.asInt();
CAYENNE_LOG("Channel %d, pin %d, value %d", 8, 3, value);
digitalWrite(3,value);
}
CAYENNE_IN(7){ //up-down servo motor
if (digitalRead(3)==HIGH){ //Automatic_mode
}
else{ //Manual_mode
servo_x.write(getValue.asDouble() * 180);
}
}
CAYENNE_IN(6){ //left-right servo motor
if (digitalRead(3)==HIGH){
}
else{
servo_z.write(getValue.asDouble() * 180);
}
}
CAYENNE_OUT(0) { //Current
float current = Vout/10;
Cayenne.virtualWrite(0, current);
Serial.print("Current: ");
Serial.println(current);
}
CAYENNE_OUT(1) { //Voltage
float voltage = Vout * 2;
Cayenne.virtualWrite(1, voltage);
Serial.print("Voltage: ");
Serial.println(voltage);
}
CAYENNE_OUT(2){ //LDR Top-right
Cayenne.virtualWrite(2, topr);
}
CAYENNE_OUT(3){ //LDR Top-left
Cayenne.virtualWrite(3,topl);
}
CAYENNE_OUT(4){ //LDR Bot-left
Cayenne.virtualWrite(4,botl);
}
CAYENNE_OUT(5){ //LDR Bot-right
Cayenne.virtualWrite(5,botr);
}
CAYENNE_OUT(10) { //Power
float power = (Vout * 2 * Vout)/10 ;
Cayenne.virtualWrite(10, power);
Serial.print("Power: ");
Serial.println(power);
}
CAYENNE_OUT(11){ //Temperature
float t = dht.readTemperature();
//int chk = dht.read(DHT11PIN);
Cayenne.virtualWrite(11, t, TYPE_TEMPERATURE, UNIT_CELSIUS);
Serial.print("temperature: ");
Serial.println(t);
}
CAYENNE_OUT(12){ //Huidity
float h = dht.readHumidity();
//int chk = dht.read(DHT11PIN);
Cayenne.virtualWrite(12, h);
Serial.print(" humidity: ");
Serial.println(h);
}
6 发展示例
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!