光伏板智能除尘系统
项目开发背景
光伏能源作为清洁可再生能源的重要组成部分,在全球能源转型中扮演着关键角色。光伏板通过将太阳能转化为电能,为家庭、工业和商业应用提供可持续的电力来源。然而,光伏板通常安装在户外环境中,长期暴露于自然条件下,容易受到灰尘、沙尘、鸟粪等污染物的积累,这会显著降低其发电效率。
灰尘在光伏板表面的沉积会阻挡阳光的照射,导致光能转化率下降,进而影响整个光伏系统的输出功率。研究表明,灰尘积累可使光伏板效率降低高达20%以上,尤其在干旱或多风地区,这一问题更为突出。这不仅造成能源浪费,还可能缩短设备寿命,增加维护成本。
传统的清洁方法主要依赖人工清洗或固定式清洁设备,但这些方式往往效率低下、成本高昂,且无法及时响应环境变化。例如,人工清洗需要定期安排人员操作,在偏远或大规模光伏电站中难以实施;而固定清洁设备可能无法适应不同天气条件,如突发的降雨或风沙天气。
因此,开发一种智能除尘系统显得尤为必要。该系统通过集成传感器和自动化控制技术,能够实时监测光伏板表面的灰尘状况,并在检测到污染超标或下雨时自动启动清洁机制。这不仅提升了清洁的及时性和准确性,还减少了人力干预,降低了运营成本。
本项目的智能除尘系统旨在通过创新的硬件和软件设计,实现高效、低耗的自动化清洁,从而帮助光伏系统维持最佳性能,推动可再生能源的广泛应用。通过结合环境感知与智能决策,该系统有望在各类光伏应用中发挥重要作用,为可持续发展贡献力量。
设计实现的功能
(1)实现通过灰尘传感器检测光伏板表面灰尘积累程度的功能。
(2)实现当灰尘值超过预设阈值或雨滴传感器检测到下雨时,自动启动清洁机构的功能。
(3)实现控制系统驱动28BYJ-48步进电机带动毛刷在光伏板表面进行清扫的功能。
(4)实现手动控制模式,并可记录和显示清洁次数的功能。
项目硬件模块组成
(1) 主控芯片:Arduino Uno R3开发板。
(2) 传感模块:雨滴传感器、灰尘传感器。
(3) 执行模块:28BYJ-48步进电机及驱动板、直流毛刷电机。
(4) 电源模块:12V适配器或直接从光伏板取电。
设计意义
光伏板智能除尘系统的设计意义在于有效提升光伏发电系统的整体性能。通过自动检测灰尘积累并启动清洁,该系统能够确保光伏板表面保持清洁,从而最大化光能吸收效率,提高发电量输出,减少因灰尘遮挡导致的能量损失。
该系统采用自动化控制,减少了对人工清洁的依赖,降低了维护成本和人力资源投入。智能响应机制在检测到灰尘超标或下雨时自动工作,确保清洁及时且高效,提升了系统的可靠性和实用性。
通过记录清洁次数和提供手动控制选项,系统便于用户监控和维护,有助于延长光伏板的使用寿命,并优化设备管理。整体设计基于实际需求,增强了光伏发电系统的可持续性和经济性。
设计思路
光伏板智能除尘系统的设计思路基于Arduino Uno R3开发板作为核心控制器,通过集成传感器和执行模块实现自动化清洁。系统首先利用灰尘传感器实时监测光伏板表面的灰尘积累程度,同时雨滴传感器检测是否下雨,所有传感器数据由Arduino Uno进行处理和分析。
当灰尘传感器检测到的数值超过预设阈值或雨滴传感器检测到下雨时,系统会自动触发清洁机制。Arduino Uno通过驱动板控制28BYJ-48步进电机,带动毛刷在光伏板表面进行往复清扫,同时直流毛刷电机提供旋转动力,确保灰尘被有效清除。
系统还设计有手动控制模式,用户可以通过外部开关或指令手动启动清洁过程,方便在需要时进行干预。Arduino Uno会记录每次清洁的次数,并将数据存储在内部存储器中,便于后续查询和维护。
电源模块采用12V适配器或直接从光伏板取电的方式,为整个系统提供稳定电力,确保在户外环境下可靠运行。所有硬件模块通过Arduino Uno协调工作,实现高效、低功耗的除尘功能。
框架图
系统框架图:
+-------------------------+
| 电源模块 |
| (12V适配器或光伏板) |
+-------------------------+
|
v (供电)
+-------------------------+
| Arduino Uno R3 |
| (主控芯片,处理逻辑和记录)|
+-------------------------+
|
| (读取传感器数据)
v
+-------------------------+
| 传感模块 |
| - 灰尘传感器 |
| - 雨滴传感器 |
+-------------------------+
|
| (传感器数据输入)
v
+-------------------------+
| Arduino Uno R3 |
| (判断阈值,触发清洁动作) |
+-------------------------+
|
| (发送控制信号)
v
+-------------------------+
| 执行模块 |
| - 步进电机驱动板 | --> 步进电机 (28BYJ-48)
| - 直流电机驱动 | --> 直流毛刷电机
+-------------------------+
|
| (用户输入)
v
+-------------------------+
| 手动控制模式 |
| (按钮,用于手动启动) |
+-------------------------+
说明:
- 电源模块为整个系统供电。
- Arduino Uno R3作为主控,接收传感器数据,判断是否启动清洁,并控制执行模块。
- 传感模块检测灰尘和雨水,输入到Arduino。
- 执行模块由步进电机和毛刷电机组成,进行清扫动作。
- 手动控制模式允许用户干预清洁过程。
- 清洁次数记录由Arduino内部处理。
系统总体设计
光伏板智能除尘系统的总体设计旨在通过自动化方式清除光伏板表面的灰尘,以维持其发电效率。系统以Arduino Uno R3开发板作为核心控制器,负责协调各个模块的运行,确保高效可靠的清洁操作。
系统通过传感模块实时监测光伏板表面的状态,灰尘传感器用于检测灰尘积累程度,而雨滴传感器则检测是否下雨。这些传感器将采集的数据传输给主控芯片,为自动控制提供依据。
当灰尘值超过预设阈值或检测到下雨时,系统会自动启动清洁机构。主控芯片根据传感器数据判断条件满足后,发出指令驱动执行模块,实现无人值守的智能响应。
执行模块包括28BYJ-48步进电机及驱动板,以及直流毛刷电机。步进电机负责带动毛刷在光伏板表面进行往复清扫动作,而直流毛刷电机提供旋转动力,确保灰尘被有效清除。整个清扫过程由控制系统精确控制,避免过度磨损。
系统还具备手动控制模式,用户可以根据需要随时启动清洁操作。同时,系统会记录每次清洁的次数,便于维护和数据分析,确保长期运行的可靠性。
电源模块为系统提供稳定电力支持,可选择12V适配器供电或直接从光伏板取电。这种设计保证了系统在不同环境下的灵活性和可持续性,无需频繁外部干预。
系统功能总结
| 序号 | 功能名称 | 功能描述 | 相关硬件模块 |
|---|---|---|---|
| 1 | 灰尘检测 | 通过灰尘传感器检测光伏板表面灰尘积累程度 | 灰尘传感器 |
| 2 | 雨滴检测 | 通过雨滴传感器检测是否下雨 | 雨滴传感器 |
| 3 | 自动清洁决策 | 当灰尘值超过阈值或检测到下雨时,自动决定启动清洁机构 | 主控芯片(Arduino Uno R3) |
| 4 | 清洁执行 | 控制系统驱动步进电机,带动毛刷在光伏板表面进行清扫 | 28BYJ-48步进电机及驱动板、直流毛刷电机 |
| 5 | 手动控制 | 系统具备手动控制模式,用户可手动启动清洁过程 | 主控芯片(Arduino Uno R3) |
| 6 | 清洁记录 | 系统记录并存储清洁次数 | 主控芯片(Arduino Uno R3) |
| 7 | 电源管理 | 为系统提供电力,通过12V适配器或直接从光伏板取电 | 电源模块 |
设计的各个功能模块描述
主控芯片模块基于Arduino Uno R3开发板,负责处理整个系统的控制逻辑。它接收来自传感器的数据,判断灰尘积累是否超过预设阈值或是否检测到下雨,并根据这些条件自动启动清洁流程。此外,该模块支持手动控制模式,允许用户主动触发清洁操作,并内置计数器记录清洁次数,确保系统运行可靠且易于管理。
传感模块包括雨滴传感器和灰尘传感器,用于实时监测光伏板表面的环境状态。灰尘传感器检测灰尘积累程度,并将数据反馈给主控芯片;雨滴传感器识别下雨事件,当检测到降水或灰尘值超标时,系统会触发清洁机制,确保光伏板保持高效运行状态。
执行模块由28BYJ-48步进电机及驱动板、直流毛刷电机组成,负责执行清扫动作。主控芯片驱动步进电机,带动毛刷在光伏板表面进行往复清扫,清除积累的灰尘;直流毛刷电机提供旋转动力,增强清洁效果,确保光伏板表面洁净,提升发电效率。
电源模块采用12V适配器或直接从光伏板取电的方式,为整个系统提供稳定电力供应。它确保主控芯片、传感器和执行模块正常运行,适应户外环境需求,保证系统在多种条件下可靠工作。
上位机代码设计
#include <QApplication>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QTextEdit>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QTimer>
#include <QMessageBox>
#include <QGroupBox>
#include <QProgressBar>
class SolarPanelCleaner : public QMainWindow
{
Q_OBJECT
public:
SolarPanelCleaner(QWidget *parent = nullptr) : QMainWindow(parent)
{
setupUI();
setupSerialPort();
setupConnections();
}
~SolarPanelCleaner()
{
if(serialPort->isOpen())
serialPort->close();
}
private slots:
void connectToDevice()
{
serialPort->setPortName(portComboBox->currentText());
serialPort->setBaudRate(QSerialPort::Baud9600);
serialPort->setDataBits(QSerialPort::Data8);
serialPort->setParity(QSerialPort::NoParity);
serialPort->setStopBits(QSerialPort::OneStop);
serialPort->setFlowControl(QSerialPort::NoFlowControl);
if(serialPort->open(QIODevice::ReadWrite))
{
statusLabel->setText("已连接到: " + portComboBox->currentText());
connectButton->setEnabled(false);
disconnectButton->setEnabled(true);
logTextEdit->append("系统启动成功,连接到设备");
}
else
{
QMessageBox::critical(this, "连接错误", "无法连接到设备");
}
}
void disconnectFromDevice()
{
serialPort->close();
statusLabel->setText("未连接");
connectButton->setEnabled(true);
disconnectButton->setEnabled(false);
logTextEdit->append("断开设备连接");
}
void readData()
{
QByteArray data = serialPort->readAll();
QString receivedData = QString::fromUtf8(data);
if(!receivedData.isEmpty())
{
processReceivedData(receivedData);
logTextEdit->append("接收: " + receivedData.trimmed());
}
}
void sendManualClean()
{
if(serialPort->isOpen())
{
QString command = "CLEAN_MANUAL\n";
serialPort->write(command.toUtf8());
logTextEdit->append("发送: " + command.trimmed());
}
}
void setThreshold()
{
if(serialPort->isOpen())
{
QString threshold = thresholdEdit->text();
QString command = "SET_THRESHOLD:" + threshold + "\n";
serialPort->write(command.toUtf8());
logTextEdit->append("发送: " + command.trimmed());
}
}
void requestStatus()
{
if(serialPort->isOpen())
{
QString command = "GET_STATUS\n";
serialPort->write(command.toUtf8());
logTextEdit->append("发送: " + command.trimmed());
}
}
private:
void setupUI()
{
setWindowTitle("光伏板智能除尘系统");
setMinimumSize(800, 600);
QWidget *centralWidget = new QWidget(this);
setCentralWidget(centralWidget);
QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);
// 连接设置区域
QGroupBox *connectionGroup = new QGroupBox("设备连接");
QHBoxLayout *connectionLayout = new QHBoxLayout(connectionGroup);
portComboBox = new QComboBox();
connectButton = new QPushButton("连接");
disconnectButton = new QPushButton("断开");
disconnectButton->setEnabled(false);
statusLabel = new QLabel("未连接");
connectionLayout->addWidget(new QLabel("端口:"));
connectionLayout->addWidget(portComboBox);
connectionLayout->addWidget(connectButton);
connectionLayout->addWidget(disconnectButton);
connectionLayout->addWidget(statusLabel);
connectionLayout->addStretch();
// 状态显示区域
QGroupBox *statusGroup = new QGroupBox("系统状态");
QGridLayout *statusLayout = new QGridLayout(statusGroup);
dustLabel = new QLabel("0");
rainLabel = new QLabel("否");
cleanCountLabel = new QLabel("0");
motorStatusLabel = new QLabel("停止");
dustProgressBar = new QProgressBar();
dustProgressBar->setRange(0, 100);
dustProgressBar->setValue(0);
statusLayout->addWidget(new QLabel("灰尘浓度:"), 0, 0);
statusLayout->addWidget(dustLabel, 0, 1);
statusLayout->addWidget(dustProgressBar, 0, 2);
statusLayout->addWidget(new QLabel("降雨检测:"), 1, 0);
statusLayout->addWidget(rainLabel, 1, 1);
statusLayout->addWidget(new QLabel("清洁次数:"), 2, 0);
statusLayout->addWidget(cleanCountLabel, 2, 1);
statusLayout->addWidget(new QLabel("电机状态:"), 3, 0);
statusLayout->addWidget(motorStatusLabel, 3, 1);
// 控制区域
QGroupBox *controlGroup = new QGroupBox("系统控制");
QHBoxLayout *controlLayout = new QHBoxLayout(controlGroup);
manualCleanButton = new QPushButton("手动清洁");
statusButton = new QPushButton("刷新状态");
thresholdEdit = new QLineEdit();
thresholdEdit->setPlaceholderText("灰尘阈值");
setThresholdButton = new QPushButton("设置阈值");
controlLayout->addWidget(manualCleanButton);
controlLayout->addWidget(statusButton);
controlLayout->addWidget(thresholdEdit);
controlLayout->addWidget(setThresholdButton);
// 日志区域
QGroupBox *logGroup = new QGroupBox("系统日志");
QVBoxLayout *logLayout = new QVBoxLayout(logGroup);
logTextEdit = new QTextEdit();
logTextEdit->setReadOnly(true);
logLayout->addWidget(logTextEdit);
// 添加到主布局
mainLayout->addWidget(connectionGroup);
mainLayout->addWidget(statusGroup);
mainLayout->addWidget(controlGroup);
mainLayout->addWidget(logGroup);
// 刷新可用串口
refreshPorts();
}
void setupSerialPort()
{
serialPort = new QSerialPort(this);
connect(serialPort, &QSerialPort::readyRead, this, &SolarPanelCleaner::readData);
}
void setupConnections()
{
connect(connectButton, &QPushButton::clicked, this, &SolarPanelCleaner::connectToDevice);
connect(disconnectButton, &QPushButton::clicked, this, &SolarPanelCleaner::disconnectFromDevice);
connect(manualCleanButton, &QPushButton::clicked, this, &SolarPanelCleaner::sendManualClean);
connect(statusButton, &QPushButton::clicked, this, &SolarPanelCleaner::requestStatus);
connect(setThresholdButton, &QPushButton::clicked, this, &SolarPanelCleaner::setThreshold);
}
void refreshPorts()
{
portComboBox->clear();
QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
for(const QSerialPortInfo &port : ports)
{
portComboBox->addItem(port.portName());
}
}
void processReceivedData(const QString &data)
{
QStringList lines = data.split('\n', Qt::SkipEmptyParts);
for(const QString &line : lines)
{
if(line.startsWith("DUST:"))
{
QString dustValue = line.mid(5);
dustLabel->setText(dustValue);
dustProgressBar->setValue(dustValue.toInt());
}
else if(line.startsWith("RAIN:"))
{
QString rainStatus = line.mid(5);
rainLabel->setText(rainStatus == "1" ? "是" : "否");
}
else if(line.startsWith("COUNT:"))
{
QString count = line.mid(6);
cleanCountLabel->setText(count);
}
else if(line.startsWith("MOTOR:"))
{
QString motorStatus = line.mid(6);
motorStatusLabel->setText(motorStatus);
}
}
}
// UI组件
QComboBox *portComboBox;
QPushButton *connectButton;
QPushButton *disconnectButton;
QLabel *statusLabel;
QLabel *dustLabel;
QLabel *rainLabel;
QLabel *cleanCountLabel;
QLabel *motorStatusLabel;
QProgressBar *dustProgressBar;
QPushButton *manualCleanButton;
QPushButton *statusButton;
QLineEdit *thresholdEdit;
QPushButton *setThresholdButton;
QTextEdit *logTextEdit;
QSerialPort *serialPort;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
SolarPanelCleaner window;
window.show();
return app.exec();
}
#include "main.moc"
这个上位机程序使用Qt框架开发,提供了以下功能:
-
设备连接管理:
- 自动检测可用串口
- 连接/断开设备控制
-
状态监控:
- 实时显示灰尘浓度(数值和进度条)
- 降雨检测状态
- 清洁次数统计
- 电机运行状态
-
系统控制:
- 手动启动清洁功能
- 设置灰尘阈值
- 刷新系统状态
-
日志记录:
- 显示所有发送和接收的数据
- 系统操作记录
程序通过串口与Arduino Uno R3通信,使用简单的文本协议进行数据交换。
模块代码设计
#include "stm32f10x.h"
// 硬件引脚定义
#define RAIN_SENSOR_PIN GPIO_Pin_0 // PA0 雨滴传感器(数字输入)
#define DUST_SENSOR_PIN GPIO_Pin_1 // PA1 灰尘传感器(ADC输入)
#define STEPPER_IN1 GPIO_Pin_5 // PA5 步进电机线圈1
#define STEPPER_IN2 GPIO_Pin_6 // PA6 步进电机线圈2
#define STEPPER_IN3 GPIO_Pin_7 // PA7 步进电机线圈3
#define STEPPER_IN4 GPIO_Pin_8 // PA8 步进电机线圈4
#define DC_MOTOR_PIN GPIO_Pin_2 // PA2 直流电机PWM输出
#define MANUAL_BUTTON_PIN GPIO_Pin_3 // PA3 手动按钮(带上拉)
// 系统参数
#define DUST_THRESHOLD 2000 // 灰尘阈值(12位ADC值)
#define CLEAN_CYCLE_STEPS 512 // 完整清洁周期步数
#define STEP_DELAY_MS 2 // 步进电机步间延迟
// 全局变量
volatile uint32_t clean_count = 0; // 清洁次数计数器
uint8_t stepper_sequence[4] = {0x09, 0x0C, 0x06, 0x03}; // 步进电机全步序列
// 系统时钟初始化
void RCC_Configuration(void)
{
// 开启GPIOA时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
// 开启ADC1时钟
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
// 开启TIM2时钟(PWM)
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
}
// GPIO初始化
void GPIO_Configuration(void)
{
// PA0(雨滴传感器) - 浮空输入
GPIOA->CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0);
GPIOA->CRL |= GPIO_CRL_CNF0_1;
// PA1(灰尘传感器) - 模拟输入
GPIOA->CRL &= ~(GPIO_CRL_MODE1 | GPIO_CRL_CNF1);
GPIOA->CRL |= GPIO_CRL_CNF1_0;
// PA5-PA8(步进电机) - 推挽输出 50MHz
GPIOA->CRL &= ~(GPIO_CRL_MODE5 | GPIO_CRL_CNF5);
GPIOA->CRL |= GPIO_CRL_MODE5_0;
GPIOA->CRL &= ~(GPIO_CRL_MODE6 | GPIO_CRL_CNF6);
GPIOA->CRL |= GPIO_CRL_MODE6_0;
GPIOA->CRL &= ~(GPIO_CRL_MODE7 | GPIO_CRL_CNF7);
GPIOA->CRL |= GPIO_CRL_MODE7_0;
GPIOA->CRH &= ~(GPIO_CRH_MODE8 | GPIO_CRH_CNF8);
GPIOA->CRH |= GPIO_CRH_MODE8_0;
// PA2(直流电机PWM) - 复用推挽输出
GPIOA->CRL &= ~(GPIO_CRL_MODE2 | GPIO_CRL_CNF2);
GPIOA->CRL |= GPIO_CRL_MODE2_1 | GPIO_CRL_CNF2_1;
// PA3(手动按钮) - 上拉输入
GPIOA->CRL &= ~(GPIO_CRL_MODE3 | GPIO_CRL_CNF3);
GPIOA->CRL |= GPIO_CRL_CNF3_1;
GPIOA->ODR |= MANUAL_BUTTON_PIN; // 使能上拉
}
// ADC初始化
void ADC_Configuration(void)
{
// 配置ADC1
ADC1->CR2 = ADC_CR2_ADON; // 开启ADC
ADC1->SQR1 = 0; // 1个转换
ADC1->SQR3 = 1; // 通道1(PA1)
ADC1->SMPR2 = ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP1_0; // 239.5周期采样时间
// 校准ADC
ADC1->CR2 |= ADC_CR2_RSTCAL;
while(ADC1->CR2 & ADC_CR2_RSTCAL);
ADC1->CR2 |= ADC_CR2_CAL;
while(ADC1->CR2 & ADC_CR2_CAL);
}
// 定时器2 PWM初始化
void TIM2_Configuration(void)
{
// 72MHz/720 = 100kHz
TIM2->PSC = 720 - 1; // 预分频器
TIM2->ARR = 1000 - 1; // 自动重装载值(周期=10ms)
TIM2->CCR3 = 500; // 占空比50%(初始值)
TIM2->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3PE; // PWM模式1
TIM2->CCER |= TIM_CCER_CC3E; // 开启通道3
TIM2->CR1 = TIM_CR1_ARPE; // 自动重装载预装载使能
TIM2->EGR = TIM_EGR_UG; // 产生更新事件
TIM2->CR1 |= TIM_CR1_CEN; // 启动定时器
}
// 读取雨滴传感器状态
uint8_t Read_Rain_Sensor(void)
{
return (GPIOA->IDR & RAIN_SENSOR_PIN) ? 0 : 1; // 低电平有效
}
// 读取灰尘传感器值
uint16_t Read_Dust_Sensor(void)
{
ADC1->CR2 |= ADC_CR2_ADON;
while(!(ADC1->SR & ADC_SR_EOC)); // 等待转换完成
return ADC1->DR;
}
// 步进电机单步运动
void Stepper_Step(uint8_t step)
{
GPIOA->ODR &= ~(STEPPER_IN1 | STEPPER_IN2 | STEPPER_IN3 | STEPPER_IN4); // 清空所有线圈
if(stepper_sequence[step] & 0x01) GPIOA->ODR |= STEPPER_IN1;
if(stepper_sequence[step] & 0x02) GPIOA->ODR |= STEPPER_IN2;
if(stepper_sequence[step] & 0x04) GPIOA->ODR |= STEPPER_IN3;
if(stepper_sequence[step] & 0x08) GPIOA->ODR |= STEPPER_IN4;
}
// 步进电机旋转指定步数
void Stepper_Rotate(int32_t steps)
{
static uint8_t current_step = 0;
uint32_t i;
if(steps > 0) { // 正转
for(i = 0; i < steps; i++) {
Stepper_Step(current_step);
current_step = (current_step + 1) % 4;
for(volatile uint32_t j = 0; j < STEP_DELAY_MS * 7200; j++); // 简单延时
}
} else { // 反转
for(i = 0; i < -steps; i++) {
Stepper_Step(current_step);
current_step = (current_step + 3) % 4;
for(volatile uint32_t j = 0; j < STEP_DELAY_MS * 7200; j++);
}
}
}
// 直流电机控制
void DC_Motor_Control(uint8_t enable)
{
if(enable) {
TIM2->CCR3 = 700; // 70%占空比
} else {
TIM2->CCR3 = 0; // 停止
}
}
// 执行清洁周期
void Execute_Cleaning_Cycle(void)
{
DC_Motor_Control(1); // 启动直流毛刷电机
Stepper_Rotate(CLEAN_CYCLE_STEPS); // 前进清洁
Stepper_Rotate(-CLEAN_CYCLE_STEPS); // 返回原位
DC_Motor_Control(0); // 停止直流电机
clean_count++; // 增加清洁计数
}
// 读取手动按钮状态
uint8_t Read_Manual_Button(void)
{
return (GPIOA->IDR & MANUAL_BUTTON_PIN) ? 0 : 1; // 低电平有效
}
// 系统初始化
void System_Init(void)
{
RCC_Configuration();
GPIO_Configuration();
ADC_Configuration();
TIM2_Configuration();
}
// 主函数
int main(void)
{
System_Init();
while(1) {
// 读取传感器数据
uint8_t rain_detected = Read_Rain_Sensor();
uint16_t dust_value = Read_Dust_Sensor();
uint8_t manual_trigger = Read_Manual_Button();
// 检查清洁条件:灰尘超标、下雨或手动触发
if(dust_value > DUST_THRESHOLD || rain_detected || manual_trigger) {
Execute_Cleaning_Cycle();
// 简单防抖延时
for(volatile uint32_t i = 0; i < 0xFFFFF; i++);
}
// 空闲延时
for(volatile uint32_t i = 0; i < 0x7FFFF; i++);
}
}
项目核心代码
#include "stm32f10x.h"
// 定义引脚
#define DUST_SENSOR_PIN GPIO_Pin_0 // PA0 - 灰尘传感器
#define RAIN_SENSOR_PIN GPIO_Pin_1 // PA1 - 雨滴传感器
#define MOTOR_EN_PIN GPIO_Pin_2 // PA2 - 毛刷电机使能
#define STEP1_PIN GPIO_Pin_3 // PA3 - 步进电机相位1
#define STEP2_PIN GPIO_Pin_4 // PA4 - 步进电机相位2
#define STEP3_PIN GPIO_Pin_5 // PA5 - 步进电机相位3
#define STEP4_PIN GPIO_Pin_6 // PA6 - 步进电机相位4
#define MANUAL_BTN_PIN GPIO_Pin_7 // PA7 - 手动按钮
// 阈值定义
#define DUST_THRESHOLD 500 // 灰尘阈值
#define ADC_MAX_VALUE 4095 // 12位ADC最大值
// 全局变量
volatile uint32_t clean_count = 0; // 清洁次数计数
volatile uint8_t auto_mode = 1; // 自动模式标志
volatile uint8_t cleaning = 0; // 清洁进行中标志
// 函数声明
void RCC_Configuration(void);
void GPIO_Configuration(void);
void ADC_Configuration(void);
void TIM_Configuration(void);
void NVIC_Configuration(void);
uint16_t Read_Dust_Sensor(void);
uint8_t Read_Rain_Sensor(void);
uint8_t Read_Manual_Button(void);
void Start_Cleaning(void);
void Stop_Cleaning(void);
void Step_Motor_Run(uint16_t steps);
void Delay_ms(uint32_t nTime);
int main(void)
{
// 系统初始化
RCC_Configuration();
GPIO_Configuration();
ADC_Configuration();
TIM_Configuration();
NVIC_Configuration();
uint16_t dust_value = 0;
uint8_t rain_detected = 0;
uint8_t manual_trigger = 0;
while(1)
{
if(auto_mode)
{
// 自动模式:读取传感器数据
dust_value = Read_Dust_Sensor();
rain_detected = Read_Rain_Sensor();
// 判断是否需要清洁
if((dust_value > DUST_THRESHOLD) || rain_detected)
{
if(!cleaning)
{
Start_Cleaning();
}
}
}
else
{
// 手动模式:检测按钮
manual_trigger = Read_Manual_Button();
if(manual_trigger && !cleaning)
{
Start_Cleaning();
}
}
Delay_ms(100); // 100ms检测周期
}
}
// 时钟配置
void RCC_Configuration(void)
{
// 开启GPIOA时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
// 开启ADC1时钟
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
// 开启TIM2时钟
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
}
// GPIO配置
void GPIO_Configuration(void)
{
// 配置PA0为模拟输入(灰尘传感器)
GPIOA->CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0);
GPIOA->CRL |= GPIO_CRL_CNF0_1;
// 配置PA1为输入上拉(雨滴传感器)
GPIOA->CRL &= ~(GPIO_CRL_MODE1 | GPIO_CRL_CNF1);
GPIOA->CRL |= GPIO_CRL_CNF1_1;
GPIOA->BSRR = GPIO_BSRR_BS1;
// 配置PA7为输入上拉(手动按钮)
GPIOA->CRL &= ~(GPIO_CRL_MODE7 | GPIO_CRL_CNF7);
GPIOA->CRL |= GPIO_CRL_CNF7_1;
GPIOA->BSRR = GPIO_BSRR_BS7;
// 配置PA2-PA6为推挽输出
GPIOA->CRL &= ~(GPIO_CRL_MODE2 | GPIO_CRL_CNF2 |
GPIO_CRL_MODE3 | GPIO_CRL_CNF3 |
GPIO_CRL_MODE4 | GPIO_CRL_CNF4 |
GPIO_CRL_MODE5 | GPIO_CRL_CNF5 |
GPIO_CRL_MODE6 | GPIO_CRL_CNF6);
GPIOA->CRL |= (GPIO_CRL_MODE2_0 | GPIO_CRL_CNF2_0 |
GPIO_CRL_MODE3_0 | GPIO_CRL_CNF3_0 |
GPIO_CRL_MODE4_0 | GPIO_CRL_CNF4_0 |
GPIO_CRL_MODE5_0 | GPIO_CRL_CNF5_0 |
GPIO_CRL_MODE6_0 | GPIO_CRL_CNF6_0);
}
// ADC配置
void ADC_Configuration(void)
{
// 校准ADC
ADC1->CR2 |= ADC_CR2_CAL;
while(ADC1->CR2 & ADC_CR2_CAL);
// 设置单次转换模式
ADC1->CR2 &= ~ADC_CR2_CONT;
// 设置通道0采样时间
ADC1->SMPR2 &= ~ADC_SMPR2_SMP0;
ADC1->SMPR2 |= ADC_SMPR2_SMP0_1; // 13.5周期
// 开启ADC
ADC1->CR2 |= ADC_CR2_ADON;
Delay_ms(1);
}
// 定时器配置
void TIM_Configuration(void)
{
// 配置TIM2为1ms定时
TIM2->PSC = 7200 - 1; // 72MHz/7200 = 10kHz
TIM2->ARR = 10 - 1; // 10kHz/10 = 1kHz (1ms)
TIM2->CR1 |= TIM_CR1_ARPE;
TIM2->EGR |= TIM_EGR_UG;
TIM2->CR1 |= TIM_CR1_CEN;
}
// 中断配置
void NVIC_Configuration(void)
{
NVIC->ISER[0] |= (1 << TIM2_IRQn); // 使能TIM2中断
TIM2->DIER |= TIM_DIER_UIE; // 使能更新中断
}
// 读取灰尘传感器值
uint16_t Read_Dust_Sensor(void)
{
ADC1->SQR3 = 0; // 选择通道0
ADC1->CR2 |= ADC_CR2_ADON;
// 启动转换
ADC1->CR2 |= ADC_CR2_SWSTART;
while(!(ADC1->SR & ADC_SR_EOC));
return ADC1->DR;
}
// 读取雨滴传感器
uint8_t Read_Rain_Sensor(void)
{
return (GPIOA->IDR & RAIN_SENSOR_PIN) ? 0 : 1;
}
// 读取手动按钮
uint8_t Read_Manual_Button(void)
{
static uint8_t last_state = 1;
uint8_t current_state = (GPIOA->IDR & MANUAL_BTN_PIN) ? 1 : 0;
// 检测下降沿
if(last_state && !current_state)
{
last_state = current_state;
return 1;
}
last_state = current_state;
return 0;
}
// 开始清洁
void Start_Cleaning(void)
{
cleaning = 1;
// 启动毛刷电机
GPIOA->BSRR = MOTOR_EN_PIN;
// 步进电机运行(来回清扫)
Step_Motor_Run(200); // 前进200步
Step_Motor_Run(200); // 后退200步
// 停止毛刷电机
GPIOA->BRR = MOTOR_EN_PIN;
clean_count++; // 增加清洁计数
cleaning = 0;
}
// 步进电机运行
void Step_Motor_Run(uint16_t steps)
{
uint8_t step_sequence[4] = {0x09, 0x0C, 0x06, 0x03}; // 4相8拍序列
uint16_t i, j;
for(i = 0; i < steps; i++)
{
for(j = 0; j < 4; j++)
{
// 设置步进电机相位
GPIOA->ODR &= ~(STEP1_PIN | STEP2_PIN | STEP3_PIN | STEP4_PIN);
GPIOA->ODR |= (step_sequence[j] << 3); // 从PA3开始
Delay_ms(5); // 步进电机速度控制
}
}
}
// 延时函数(基于TIM2)
void Delay_ms(uint32_t nTime)
{
volatile uint32_t start_time = TIM2->CNT;
while((TIM2->CNT - start_time) < nTime);
}
// TIM2中断服务函数
void TIM2_IRQHandler(void)
{
if(TIM2->SR & TIM_SR_UIF)
{
TIM2->SR &= ~TIM_SR_UIF;
// 定时器中断处理
}
}
总结
光伏板智能除尘系统通过智能化的方式自动维护光伏板表面的清洁,从而提升发电效率。该系统利用传感器实时监测灰尘积累和降雨情况,当检测到灰尘值超过预设阈值或下雨时,会自动触发清洁机制,确保光伏板始终处于最佳工作状态。
在硬件实现上,系统以Arduino Uno R3开发板为核心控制器,结合雨滴传感器和灰尘传感器进行环境数据采集。执行模块包括28BYJ-48步进电机及其驱动板,以及直流毛刷电机,共同协作完成清扫动作,确保清洁过程高效且精准。
此外,系统还提供了手动控制模式,允许用户根据需要随时启动清洁,并能记录清洁次数,便于后期维护和分析。电源模块支持12V适配器或直接从光伏板取电,增强了系统的灵活性和实用性,适用于各种户外环境。
- 点赞
- 收藏
- 关注作者
评论(0)