光伏板智能清洁与健康监测系统
项目开发背景
随着全球对可再生能源需求的不断增长,光伏发电作为一种清洁能源形式,正被广泛应用于各类场景中。然而,光伏板在户外长期运行过程中,容易受到灰尘、鸟粪、雨雪等污染物的覆盖,导致其表面透光率下降,进而显著降低发电效率。据统计,灰尘积累可使光伏板输出功率减少高达20%以上,这不仅造成能源浪费,还增加了维护成本。因此,开发一种高效、自动化的清洁与监测系统,成为提升光伏系统整体性能的关键需求。
传统的光伏板清洁方式主要依赖人工定期清洗或简单机械装置,这些方法效率低下、成本高昂,且无法实时响应天气变化。例如,在雨天或高湿度环境下,不必要的清洁操作可能浪费资源,甚至损坏设备。同时,光伏板的老化、故障等问题往往难以及时发现,影响系统长期稳定运行。这凸显了对智能系统的迫切需求,能够结合环境感知与自动控制,实现精准、高效的维护。
本项目的光伏板智能清洁与健康监测系统正是基于上述挑战而设计,它通过集成灰尘传感器和雨滴传感器,实时监测板面污染程度和天气状况,确保清洁操作只在必要时启动。系统利用步进电机驱动滚刷进行自动清洁,避免人为干预,提高效率。此外,电流传感器持续追踪光伏板输出功率,结合数据分析评估其健康状态,帮助早期识别潜在故障,延长设备寿命。
通过Wi-Fi模块将清洁记录和发电数据上传至云平台,系统实现了远程监控与大数据分析,为用户提供可视化报告和预警功能。这不仅提升了光伏系统的可靠性和经济性,还推动了智能能源管理的发展,符合当前物联网技术在绿色能源领域的应用趋势。总体而言,该系统旨在解决光伏维护中的痛点,为可持续能源的高效利用提供有力支持。
设计实现的功能
(1) 通过灰尘传感器与雨滴传感器判断板面清洁度与天气状况。
(2) 自动控制步进电机带动滚刷对板面进行清洁。
(3) 通过电流传感器监测光伏板实时输出功率,评估其健康状态。
(4) 将清洁记录与发电效率数据通过Wi-Fi上传至云平台。
项目硬件模块组成
(1)主控芯片:STM32F103C8T6单片机。
(2)传感模块:雨滴传感器、GP2Y1014AU0F灰尘传感器、ACS712电流传感器。
(3)执行模块:42步进电机及DM542驱动器、清洁滚刷。
(4)通信模块:ESP8266 Wi-Fi模块。
设计意义
该系统通过集成多种传感器与执行机构,实现了光伏板清洁与健康状态的自动化管理,能够有效提升光伏发电系统的整体运行效率。自动清洁功能可减少灰尘积累对发电效率的影响,确保光伏板在最佳状态下工作,从而最大化能源产出。
通过实时监测光伏板的输出功率与清洁度,系统能够及时识别性能异常或污染问题,有助于预防潜在故障并延长设备使用寿命。这种主动维护方式降低了人工巡检和清洁的频率,减少了运维成本。
数据上传功能使得发电效率与清洁记录可远程访问与分析,为系统优化和决策提供支持。这增强了光伏电站的智能化管理水平,推动可再生能源设施的可持续运营。
设计思路
该系统设计以STM32F103C8T6单片机作为核心控制器,负责协调各模块工作,实现光伏板面的智能清洁与健康状态监测。系统通过集成多种传感器与执行器,自动判断环境条件并执行清洁操作,同时收集关键数据用于分析和记录。
灰尘传感器与雨滴传感器实时检测光伏板表面的灰尘积累和天气状况,当灰尘达到一定阈值或检测到雨滴时,系统会判断需要进行清洁。这些传感器数据由主控芯片处理,以确定清洁的触发时机,确保在合适条件下启动清洁流程,避免不必要的操作。
清洁功能通过42步进电机和DM542驱动器控制滚刷的运动,主控芯片根据传感器输入自动发出指令,驱动电机带动滚刷对光伏板表面进行清扫。这一过程无需人工干预,提高了清洁效率并减少了维护成本,同时确保光伏板始终保持较高透光率。
健康监测部分利用ACS712电流传感器实时采集光伏板的输出电流数据,计算出实时功率输出。主控芯片分析这些数据以评估光伏板的健康状态,例如通过功率变化趋势判断是否存在性能下降或故障,从而提供早期预警和维护建议。
数据通信模块采用ESP8266 Wi-Fi模块,将清洁记录和发电效率数据上传至云平台。主控芯片处理后的信息通过Wi-Fi传输,实现远程监控和数据分析,便于用户查看历史记录和系统性能,优化光伏系统的运行管理。
框架图
+-------------------+ +-------------------+ +-------------------+
| | | | | |
| 光伏板系统 |----->| 传感模块 |----->| 主控芯片 |
| | | | | STM32F103C8T6 |
+-------------------+ +-------------------+ +-------------------+
| |
| |
+-------+-------+ +-------+-------+
| | | |
+-----+-----+ +-----+-----+ +-----+-----+ +-----+-----+
| 雨滴传感器 | | 灰尘传感器 | | 执行模块 | | 通信模块 |
| | | GP2Y1014 | | 步进电机 | | ESP8266 |
+-----------+ +-----------+ | DM542驱动 | +-----------+
| 清洁滚刷 |
+-----------+
|
v
+-------------------+
| |
| 云平台 |
| |
+-------------------+
数据流说明:
- 传感模块(雨滴/灰尘/电流传感器)采集光伏板状态及环境数据,输入主控芯片。
- 主控芯片处理数据后:
- 控制执行模块(步进电机驱动滚刷)进行清洁操作。
- 通过通信模块(Wi-Fi)将清洁记录与发电数据上传至云平台。
系统总体设计
光伏板智能清洁与健康监测系统以STM32F103C8T6单片机作为核心控制器,负责协调整个系统的运行。该系统通过集成多种传感器模块来实时监测光伏板的状态,其中雨滴传感器用于检测天气状况如降雨,而GP2Y1014AU0F灰尘传感器则评估板面的灰尘积累程度,从而判断清洁需求。
基于传感器输入的数据,系统自动控制执行模块进行清洁操作。当检测到灰尘积累或特定天气条件时,主控芯片会驱动42步进电机通过DM542驱动器带动清洁滚刷,对光伏板表面进行均匀而高效的清扫,确保板面保持最佳透光状态以提升发电效率。
同时,系统通过ACS712电流传感器持续监测光伏板的实时输出功率,以此评估其健康状态和性能变化。这些数据有助于识别潜在的故障或效率下降问题,为维护决策提供依据。
所有收集到的清洁记录和发电效率数据通过ESP8266 Wi-Fi模块传输至云平台,实现远程数据存储和分析。这使用户能够实时监控系统运行状况,并基于历史数据优化清洁和维护策略。
系统功能总结
| 功能编号 | 功能描述 |
|---|---|
| 1 | 通过灰尘传感器与雨滴传感器判断板面清洁度与天气状况 |
| 2 | 自动控制步进电机带动滚刷对板面进行清洁 |
| 3 | 通过电流传感器监测光伏板实时输出功率,评估其健康状态 |
| 4 | 将清洁记录与发电效率数据通过Wi-Fi上传至云平台 |
设计的各个功能模块描述
主控芯片模块采用STM32F103C8T6单片机作为系统的核心控制单元,负责协调和处理所有传感器数据,根据灰尘和雨滴传感器的输入判断光伏板表面的清洁状况和天气条件,并据此控制执行模块的运作,同时监控电流传感器数据以评估光伏板的健康状态。
传感模块包括雨滴传感器、GP2Y1014AU0F灰尘传感器和ACS712电流传感器,雨滴传感器用于检测是否有降雨情况,灰尘传感器监测光伏板表面的灰尘积累水平以评估清洁度,电流传感器则实时测量光伏板的输出电流,从而计算功率并分析其发电效率与健康状态。
执行模块由42步进电机、DM542驱动器和清洁滚刷组成,主控芯片根据传感模块的数据自动控制步进电机驱动滚刷在光伏板表面进行移动清洁,确保板面保持最佳状态以提升发电效率。
通信模块使用ESP8266 Wi-Fi模块,将系统收集的清洁记录和发电效率数据通过无线网络上传至云平台,实现远程数据存储和监控功能。
上位机代码设计
#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <chrono>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib")
class PVMonitoringSystem {
private:
SOCKET clientSocket;
bool isConnected;
std::string cloudPlatformIP;
int cloudPlatformPort;
struct SensorData {
double dustLevel;
double rainLevel;
double currentOutput;
double efficiency;
std::string timestamp;
bool cleaningStatus;
};
std::vector<SensorData> dataHistory;
public:
PVMonitoringSystem() : isConnected(false), cloudPlatformIP("192.168.1.100"), cloudPlatformPort(8080) {
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cerr << "WSAStartup failed" << std::endl;
}
}
~PVMonitoringSystem() {
disconnectFromCloud();
WSACleanup();
}
bool connectToCloud() {
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (clientSocket == INVALID_SOCKET) {
std::cerr << "Socket creation failed" << std::endl;
return false;
}
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(cloudPlatformPort);
serverAddr.sin_addr.s_addr = inet_addr(cloudPlatformIP.c_str());
if (connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
std::cerr << "Connection to cloud platform failed" << std::endl;
closesocket(clientSocket);
return false;
}
isConnected = true;
std::cout << "Connected to cloud platform successfully" << std::endl;
return true;
}
void disconnectFromCloud() {
if (isConnected) {
closesocket(clientSocket);
isConnected = false;
std::cout << "Disconnected from cloud platform" << std::endl;
}
}
std::string getCurrentTimestamp() {
auto now = std::chrono::system_clock::now();
auto time_t = std::chrono::system_clock::to_time_t(now);
std::stringstream ss;
ss << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S");
return ss.str();
}
SensorData readSensorData() {
SensorData data;
// 模拟传感器数据读取
data.dustLevel = (rand() % 1000) / 10.0; // 0-100 μg/m3
data.rainLevel = (rand() % 100) / 10.0; // 0-10 mm
data.currentOutput = (rand() % 10000) / 10.0; // 0-1000 A
data.efficiency = (rand() % 10000) / 100.0; // 0-100%
data.timestamp = getCurrentTimestamp();
data.cleaningStatus = (data.dustLevel > 50.0 && data.rainLevel < 1.0);
return data;
}
void controlCleaningSystem(bool shouldClean) {
if (shouldClean) {
std::cout << "启动清洁系统:步进电机带动滚刷清洁光伏板..." << std::endl;
// 模拟清洁过程
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "清洁完成" << std::endl;
} else {
std::cout << "当前无需清洁" << std::endl;
}
}
void assessHealthStatus(const SensorData& data) {
std::cout << "=== 光伏板健康状态评估 ===" << std::endl;
std::cout << "时间: " << data.timestamp << std::endl;
std::cout << "灰尘浓度: " << data.dustLevel << " μg/m3" << std::endl;
std::cout << "降雨量: " << data.rainLevel << " mm" << std::endl;
std::cout << "输出电流: " << data.currentOutput << " A" << std::endl;
std::cout << "发电效率: " << data.efficiency << "%" << std::endl;
if (data.efficiency > 80.0) {
std::cout << "状态: 优秀" << std::endl;
} else if (data.efficiency > 60.0) {
std::cout << "状态: 良好" << std::endl;
} else if (data.efficiency > 40.0) {
std::cout << "状态: 一般" << std::endl;
} else {
std::cout << "状态: 需要维护" << std::endl;
}
std::cout << "=========================" << std::endl;
}
std::string formatDataForCloud(const SensorData& data) {
std::stringstream json;
json << "{";
json << "\"timestamp\":\"" << data.timestamp << "\",";
json << "\"dust_level\":" << data.dustLevel << ",";
json << "\"rain_level\":" << data.rainLevel << ",";
json << "\"current_output\":" << data.currentOutput << ",";
json << "\"efficiency\":" << data.efficiency << ",";
json << "\"cleaning_status\":" << (data.cleaningStatus ? "true" : "false");
json << "}";
return json.str();
}
bool sendDataToCloud(const std::string& data) {
if (!isConnected) {
if (!connectToCloud()) {
return false;
}
}
int bytesSent = send(clientSocket, data.c_str(), data.length(), 0);
if (bytesSent == SOCKET_ERROR) {
std::cerr << "数据发送失败" << std::endl;
return false;
}
std::cout << "数据已上传至云平台: " << data << std::endl;
return true;
}
void saveDataToFile(const SensorData& data) {
std::ofstream file("pv_monitoring_log.csv", std::ios::app);
if (file.is_open()) {
if (file.tellp() == 0) {
file << "时间戳,灰尘浓度(μg/m3),降雨量(mm),输出电流(A),发电效率(%),清洁状态\n";
}
file << data.timestamp << "," << data.dustLevel << "," << data.rainLevel << ","
<< data.currentOutput << "," << data.efficiency << ","
<< (data.cleaningStatus ? "是" : "否") << "\n";
file.close();
}
}
void runMonitoringCycle() {
std::cout << "开始光伏板监控周期..." << std::endl;
SensorData currentData = readSensorData();
dataHistory.push_back(currentData);
// 显示传感器数据
std::cout << "\n当前传感器读数:" << std::endl;
std::cout << "灰尘传感器: " << currentData.dustLevel << " μg/m3" << std::endl;
std::cout << "雨滴传感器: " << currentData.rainLevel << " mm" << std::endl;
std::cout << "电流传感器: " << currentData.currentOutput << " A" << std::endl;
// 评估健康状况
assessHealthStatus(currentData);
// 控制清洁系统
controlCleaningSystem(currentData.cleaningStatus);
// 上传数据到云平台
std::string cloudData = formatDataForCloud(currentData);
sendDataToCloud(cloudData);
// 保存数据到本地文件
saveDataToFile(currentData);
std::cout << "监控周期完成" << std::endl;
}
void displayHistoricalData() {
if (dataHistory.empty()) {
std::cout << "暂无历史数据" << std::endl;
return;
}
std::cout << "\n=== 历史数据记录 ===" << std::endl;
for (const auto& data : dataHistory) {
std::cout << "时间: " << data.timestamp
<< " | 灰尘: " << data.dustLevel
<< " | 降雨: " << data.rainLevel
<< " | 电流: " << data.currentOutput
<< " | 效率: " << data.efficiency << "%"
<< " | 清洁: " << (data.cleaningStatus ? "是" : "否") << std::endl;
}
}
};
int main() {
PVMonitoringSystem monitoringSystem;
std::cout << "光伏板智能清洁与健康监测系统 - 上位机软件" << std::endl;
std::cout << "========================================" << std::endl;
// 连接到云平台
if (monitoringSystem.connectToCloud()) {
std::cout << "云平台连接成功" << std::endl;
} else {
std::cout << "云平台连接失败,将在本地模式下运行" << std::endl;
}
int choice;
do {
std::cout << "\n请选择操作:" << std::endl;
std::cout << "1. 执行监控周期" << std::endl;
std::cout << "2. 查看历史数据" << std::endl;
std::cout << "3. 退出系统" << std::endl;
std::cout << "输入选择 (1-3): ";
std::cin >> choice;
switch (choice) {
case 1:
monitoringSystem.runMonitoringCycle();
break;
case 2:
monitoringSystem.displayHistoricalData();
break;
case 3:
std::cout << "系统退出中..." << std::endl;
break;
default:
std::cout << "无效选择,请重新输入" << std::endl;
}
// 模拟实时监控间隔
if (choice == 1) {
std::this_thread::sleep_for(std::chrono::seconds(2));
}
} while (choice != 3);
return 0;
}
模块代码设计
#include "stm32f10x.h"
// 引脚定义
#define DUST_SENSOR_PIN GPIO_Pin_0
#define DUST_SENSOR_PORT GPIOA
#define RAIN_SENSOR_PIN GPIO_Pin_1
#define RAIN_SENSOR_PORT GPIOA
#define CURRENT_SENSOR_PIN GPIO_Pin_2
#define CURRENT_SENSOR_PORT GPIOA
#define STEP_PUL_PIN GPIO_Pin_0
#define STEP_DIR_PIN GPIO_Pin_1
#define STEP_PORT GPIOE
#define WIFI_TX_PIN GPIO_Pin_9
#define WIFI_RX_PIN GPIO_Pin_10
#define WIFI_PORT GPIOA
// 函数声明
void RCC_Configuration(void);
void GPIO_Configuration(void);
void ADC_Configuration(void);
void USART_Configuration(void);
void TIM_Configuration(void);
void NVIC_Configuration(void);
uint16_t Read_Dust_Sensor(void);
uint16_t Read_Rain_Sensor(void);
uint16_t Read_Current_Sensor(void);
void StepMotor_Run(uint32_t steps, uint8_t direction);
void WiFi_SendData(uint16_t dust, uint16_t rain, uint16_t current);
// 系统时钟配置
void RCC_Configuration(void)
{
// 开启外部高速时钟
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
// 等待HSE就绪
while(!(RCC->CR & RCC_CR_HSERDY));
// 配置FLASH预取指缓存
FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_2;
// HCLK = SYSCLK
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
// PCLK2 = HCLK
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
// PCLK1 = HCLK/2
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
// 配置PLL: HSE * 9 = 72 MHz
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
// 开启PLL
RCC->CR |= RCC_CR_PLLON;
// 等待PLL就绪
while((RCC->CR & RCC_CR_PLLRDY) == 0);
// 选择PLL作为系统时钟
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
// 等待时钟切换完成
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08);
// 开启GPIO时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPEEN | RCC_APB2ENR_AFIOEN;
// 开启ADC1时钟
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
// 开启USART1时钟
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
// 开启TIM2时钟
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
}
// GPIO配置
void GPIO_Configuration(void)
{
// 配置ADC引脚为模拟输入
GPIOA->CRL &= ~(GPIO_CRL_CNF0 | GPIO_CRL_CNF1 | GPIO_CRL_CNF2);
GPIOA->CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_MODE1 | GPIO_CRL_MODE2);
// 配置步进电机引脚为推挽输出
GPIOE->CRL &= ~(GPIO_CRL_CNF0 | GPIO_CRL_CNF1);
GPIOE->CRL |= (GPIO_CRL_MODE0 | GPIO_CRL_MODE1);
// 配置WiFi模块引脚
// PA9 (TX) - 复用推挽输出
GPIOA->CRH &= ~(GPIO_CRH_CNF9 | GPIO_CRH_MODE9);
GPIOA->CRH |= (GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9);
// PA10 (RX) - 浮空输入
GPIOA->CRH &= ~(GPIO_CRH_CNF10 | GPIO_CRH_MODE10);
GPIOA->CRH |= GPIO_CRH_CNF10_0;
}
// ADC配置
void ADC_Configuration(void)
{
// 复位ADC1
ADC1->CR2 = 0;
// 设置ADC工作在独立模式
ADC1->CR1 = 0;
// 设置数据对齐方式为右对齐
ADC1->CR2 &= ~ADC_CR2_ALIGN;
// 设置单次转换模式
ADC1->CR2 &= ~ADC_CR2_CONT;
// 开启ADC
ADC1->CR2 |= ADC_CR2_ADON;
// 等待ADC稳定
for(volatile int i=0; i<1000; i++);
}
// USART配置
void USART_Configuration(void)
{
// 复位USART1
USART1->CR1 = 0;
USART1->CR2 = 0;
USART1->CR3 = 0;
// 设置波特率为115200
// 72MHz / (16 * 115200) = 39.0625
USART1->BRR = (39 << 4) | 1; // 39.0625
// 使能发送和接收
USART1->CR1 |= USART_CR1_TE | USART_CR1_RE;
// 使能USART1
USART1->CR1 |= USART_CR1_UE;
}
// 定时器配置
void TIM_Configuration(void)
{
// 配置TIM2用于步进电机脉冲生成
// 72MHz / (719 + 1) = 100kHz
TIM2->PSC = 719;
TIM2->ARR = 99; // 1kHz脉冲频率
// 向上计数模式
TIM2->CR1 &= ~TIM_CR1_DIR;
// 使能TIM2更新中断
TIM2->DIER |= TIM_DIER_UIE;
}
// NVIC配置
void NVIC_Configuration(void)
{
// 设置TIM2中断优先级
NVIC->IP[TIM2_IRQn] = 0x10;
// 使能TIM2中断
NVIC->ISER[TIM2_IRQn >> 5] = (1 << (TIM2_IRQn & 0x1F));
}
// 读取灰尘传感器
uint16_t Read_Dust_Sensor(void)
{
// 设置通道0
ADC1->SQR3 = 0;
// 启动转换
ADC1->CR2 |= ADC_CR2_ADON;
// 等待转换完成
while(!(ADC1->SR & ADC_SR_EOC));
return ADC1->DR;
}
// 读取雨滴传感器
uint16_t Read_Rain_Sensor(void)
{
// 设置通道1
ADC1->SQR3 = 1;
// 启动转换
ADC1->CR2 |= ADC_CR2_ADON;
// 等待转换完成
while(!(ADC1->SR & ADC_SR_EOC));
return ADC1->DR;
}
// 读取电流传感器
uint16_t Read_Current_Sensor(void)
{
// 设置通道2
ADC1->SQR3 = 2;
// 启动转换
ADC1->CR2 |= ADC_CR2_ADON;
// 等待转换完成
while(!(ADC1->SR & ADC_SR_EOC));
return ADC1->DR;
}
// 步进电机运行
volatile uint32_t step_count = 0;
volatile uint32_t target_steps = 0;
volatile uint8_t motor_direction = 0;
void StepMotor_Run(uint32_t steps, uint8_t direction)
{
target_steps = steps;
motor_direction = direction;
step_count = 0;
// 设置方向
if(direction)
STEP_PORT->BSRR = STEP_DIR_PIN;
else
STEP_PORT->BRR = STEP_DIR_PIN;
// 启动定时器
TIM2->CR1 |= TIM_CR1_CEN;
}
// WiFi发送数据
void WiFi_SendData(uint16_t dust, uint16_t rain, uint16_t current)
{
char buffer[64];
// 构造JSON格式数据
sprintf(buffer, "{\"dust\":%d,\"rain\":%d,\"current\":%d}\r\n",
dust, rain, current);
// 发送数据
for(int i=0; buffer[i] != '\0'; i++)
{
while(!(USART1->SR & USART_SR_TXE));
USART1->DR = buffer[i];
}
}
// TIM2中断服务函数
void TIM2_IRQHandler(void)
{
if(TIM2->SR & TIM_SR_UIF)
{
TIM2->SR &= ~TIM_SR_UIF;
// 生成步进脉冲
STEP_PORT->ODR ^= STEP_PUL_PIN;
if(STEP_PORT->ODR & STEP_PUL_PIN)
{
step_count++;
if(step_count >= target_steps)
{
TIM2->CR1 &= ~TIM_CR1_CEN; // 停止定时器
}
}
}
}
// 主函数
int main(void)
{
// 系统初始化
RCC_Configuration();
GPIO_Configuration();
ADC_Configuration();
USART_Configuration();
TIM_Configuration();
NVIC_Configuration();
uint16_t dust_value, rain_value, current_value;
while(1)
{
// 读取传感器数据
dust_value = Read_Dust_Sensor();
rain_value = Read_Rain_Sensor();
current_value = Read_Current_Sensor();
// 判断是否需要清洁
if(dust_value > 2000 && rain_value < 1000) // 灰尘多且无雨
{
StepMotor_Run(1000, 1); // 运行1000步,正向
}
// 发送数据到云平台
WiFi_SendData(dust_value, rain_value, current_value);
// 延时5秒
for(volatile int i=0; i<5000000; i++);
}
}
项目核心代码
#include "stm32f10x.h"
// 定义传感器和电机控制引脚
#define RAIN_SENSOR_PIN GPIO_Pin_0 // PA0
#define DUST_ADC_CHANNEL 1 // PA1, ADC1 Channel1
#define CURRENT_ADC_CHANNEL 2 // PA2, ADC1 Channel2
#define STEP_PIN GPIO_Pin_5 // PA5
#define DIR_PIN GPIO_Pin_6 // PA6
// 定义阈值
#define DUST_THRESHOLD 1000 // 灰尘阈值
#define RAIN_THRESHOLD 500 // 雨滴阈值
#define CURRENT_THRESHOLD 100 // 电流异常阈值
// 全局变量
volatile uint32_t dust_value = 0;
volatile uint32_t rain_value = 0;
volatile uint32_t current_value = 0;
volatile uint8_t clean_flag = 0;
// 函数声明
void SystemClock_Config(void);
void GPIO_Config(void);
void ADC_Config(void);
void USART_Config(void);
void Stepper_Motor_Control(uint8_t direction, uint32_t steps);
uint32_t Read_ADC(uint8_t channel);
void Read_Sensors(void);
void WiFi_Send_Data(const char* data);
void Delay_ms(uint32_t ms);
int main(void) {
// 系统初始化
SystemClock_Config();
GPIO_Config();
ADC_Config();
USART_Config();
// 初始化步进电机
GPIOA->ODR &= ~(STEP_PIN | DIR_PIN); // 初始状态低电平
while (1) {
// 读取传感器数据
Read_Sensors();
// 判断是否需要清洁:灰尘超过阈值且无雨
if ((dust_value > DUST_THRESHOLD) && (rain_value < RAIN_THRESHOLD)) {
clean_flag = 1;
Stepper_Motor_Control(1, 1000); // 正向清洁
Stepper_Motor_Control(0, 1000); // 反向复位
clean_flag = 0;
}
// 监测电流异常
if (current_value < CURRENT_THRESHOLD) {
// 发电效率异常处理
char alert_data[50];
sprintf(alert_data, "ALERT:Low current:%lu", current_value);
WiFi_Send_Data(alert_data);
}
// 上传数据到云平台
char upload_data[100];
sprintf(upload_data, "Dust:%lu,Rain:%lu,Current:%lu,Clean:%u",
dust_value, rain_value, current_value, clean_flag);
WiFi_Send_Data(upload_data);
Delay_ms(5000); // 5秒间隔
}
}
void SystemClock_Config(void) {
// 启用HSE并配置PLL输出72MHz系统时钟
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY));
RCC->CFGR |= RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY));
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
// 启用外设时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_ADC1EN | RCC_APB2ENR_USART1EN;
}
void GPIO_Config(void) {
// 配置PA0为输入(雨滴传感器)
GPIOA->CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0);
GPIOA->CRL |= GPIO_CRL_CNF0_1; // 浮空输入
// 配置PA1、PA2为模拟输入(灰尘和电流传感器)
GPIOA->CRL &= ~(GPIO_CRL_MODE1 | GPIO_CRL_CNF1);
GPIOA->CRL &= ~(GPIO_CRL_MODE2 | GPIO_CRL_CNF2);
// 配置PA5、PA6为推挽输出(步进电机控制)
GPIOA->CRL &= ~(GPIO_CRL_MODE5 | GPIO_CRL_CNF5);
GPIOA->CRL |= GPIO_CRL_MODE5_0; // 输出模式,最大速度10MHz
GPIOA->CRL &= ~(GPIO_CRL_MODE6 | GPIO_CRL_CNF6);
GPIOA->CRL |= GPIO_CRL_MODE6_0;
// 配置PA9为复用推挽输出(USART1 TX)
GPIOA->CRH &= ~(GPIO_CRH_MODE9 | GPIO_CRH_CNF9);
GPIOA->CRH |= GPIO_CRH_MODE9_1 | GPIO_CRH_CNF9_1;
// 配置PA10为浮空输入(USART1 RX)
GPIOA->CRH &= ~(GPIO_CRH_MODE10 | GPIO_CRH_CNF10);
GPIOA->CRH |= GPIO_CRH_CNF10_1;
}
void ADC_Config(void) {
// 配置ADC1
ADC1->CR2 |= ADC_CR2_ADON; // 开启ADC
ADC1->CR2 |= ADC_CR2_CAL; // 开始校准
while (ADC1->CR2 & ADC_CR2_CAL);
ADC1->CR2 |= ADC_CR2_CONT; // 连续转换模式
ADC1->CR2 |= ADC_CR2_EXTTRIG; // 启用外部触发
ADC1->CR2 |= ADC_CR2_EXTSEL; // 软件触发
ADC1->SQR1 |= (1 << 20); // 1个转换在序列中
}
void USART_Config(void) {
// 配置USART1
USART1->BRR = 0x1D4C; // 72MHz/9600 = 7500 (0x1D4C)
USART1->CR1 |= USART_CR1_UE | USART_CR1_TE; // 启用USART和发送
}
void Stepper_Motor_Control(uint8_t direction, uint32_t steps) {
// 设置方向
if (direction) {
GPIOA->BSRR = DIR_PIN; // 设置方向引脚高
} else {
GPIOA->BRR = DIR_PIN; // 设置方向引脚低
}
// 生成步进脉冲
for (uint32_t i = 0; i < steps; i++) {
GPIOA->BSRR = STEP_PIN; // 步进引脚高
Delay_ms(1);
GPIOA->BRR = STEP_PIN; // 步进引脚低
Delay_ms(1);
}
}
uint32_t Read_ADC(uint8_t channel) {
ADC1->SQR3 = channel; // 设置转换通道
ADC1->CR2 |= ADC_CR2_SWSTART; // 开始转换
while (!(ADC1->SR & ADC_SR_EOC)); // 等待转换完成
return ADC1->DR; // 返回转换结果
}
void Read_Sensors(void) {
// 读取雨滴传感器(数字输入)
rain_value = (GPIOA->IDR & RAIN_SENSOR_PIN) ? 0 : 1024; // 假设雨滴时低电平
// 读取灰尘传感器
dust_value = Read_ADC(DUST_ADC_CHANNEL);
// 读取电流传感器
current_value = Read_ADC(CURRENT_ADC_CHANNEL);
}
void WiFi_Send_Data(const char* data) {
// 通过USART1发送数据到ESP8266
while (*data) {
while (!(USART1->SR & USART_SR_TXE)); // 等待发送缓冲区空
USART1->DR = *data++;
}
while (!(USART1->SR & USART_SR_TC)); // 等待发送完成
}
void Delay_ms(uint32_t ms) {
// 简单延时函数
for (uint32_t i = 0; i < ms * 8000; i++) {
__asm__("nop");
}
}
总结
光伏板智能清洁与健康监测系统通过智能化手段实现了对光伏板的高效维护与实时监控,有效提升了发电效率并延长了设备使用寿命。该系统集成了多种传感器与执行机构,能够自动判断板面清洁度与天气状况,并执行精准的清洁操作。
在功能实现上,系统利用灰尘和雨滴传感器检测环境参数,自动控制步进电机带动滚刷进行清洁,同时通过电流传感器监测光伏板输出功率,评估其健康状态。所有数据通过Wi-Fi模块上传至云平台,便于远程分析与记录。
硬件方面,系统以STM32F103C8T6单片机为核心,搭配雨滴、灰尘和电流传感器采集信息,并通过步进电机与驱动器执行清洁任务。通信模块ESP8266确保了数据的稳定传输,构建了一个完整的物联网应用框架。
总体而言,这一系统不仅实现了光伏板的自动化清洁与健康评估,还通过云平台实现了数据的集中管理,为光伏发电系统的智能化运维提供了可靠支持。
- 点赞
- 收藏
- 关注作者
评论(0)