1. 项目概述
这个基于Arduino Uno单片机的太阳追光系统是我去年指导的一个本科毕业设计项目,经过三个月的开发和优化,最终实现了±5°的跟踪精度。系统通过四路光敏电阻实时检测太阳位置,采用双轴舵机驱动结构,配合PID控制算法,使太阳能板始终正对太阳。相比固定式太阳能板,这套系统能提升约35%的能量转换效率。
在项目开发过程中,我们遇到了不少实际问题:光敏电阻的灵敏度调节、舵机响应延迟、PID参数整定等。通过反复测试和算法优化,最终实现了稳定可靠的自动跟踪功能。这个项目不仅涵盖了硬件电路设计、传感器应用、电机控制等嵌入式系统核心知识,还涉及了自动控制理论的实际应用,非常适合作为电子类专业的综合实践课题。
2. 系统设计原理
2.1 光线检测原理
系统采用四路光敏电阻构成测光阵列,布置方式很有讲究。我们将四个光敏电阻分别安装在正四面体的四个面上,这种空间布局可以确保在任何太阳方位角下,至少有两个光敏电阻能接收到较强的光照。
光敏电阻的选型是关键,我们最终选择了GL5528型号,其特性参数如下:
- 亮电阻(10Lux):5-10KΩ
- 暗电阻:1MΩ
- 响应时间:约20ms
- 光谱峰值:540nm
在实际电路设计中,每个光敏电阻与100KΩ的固定电阻构成分压电路。当光照强度变化时,光敏电阻阻值改变,导致分压点电压变化。这个模拟电压信号被送入Arduino的ADC引脚进行采样。
注意:光敏电阻的安装位置要避免相互遮挡,同时要考虑防水防尘。我们使用3D打印的遮光罩来确保每个光敏电阻只接收特定方向的光线。
2.2 跟踪控制策略
系统采用双闭环控制结构:
- 外环:位置环,通过四路光敏电阻的电压差值计算太阳方位
- 内环:速度环,采用PID算法控制舵机转动速度和角度
具体控制流程如下:
- 读取四个光敏电阻的ADC值(lt, rt, ld, rd)
- 计算水平和垂直方向的偏差:
- 水平偏差 = (lt + ld) - (rt + rd)
- 垂直偏差 = (lt + rt) - (ld + rd)
- 将偏差值输入PID控制器
- 输出PWM信号驱动舵机转动
PID控制器的参数整定是个技术活。经过多次试验,我们最终确定的参数为:
- Kp=0.8
- Ki=0.05
- Kd=0.3
这些参数在晴天条件下表现良好,但在多云天气可能需要动态调整。为此我们在代码中预留了参数调节接口,可以通过串口实时修改PID参数。
3. 硬件设计详解
3.1 主控电路设计
系统采用Arduino Uno作为主控制器,其硬件资源配置如下:
| 资源类型 | 用途分配 | 备注 |
|---|---|---|
| 模拟输入A0-A3 | 四路光敏电阻输入 | 10位ADC采样 |
| 数字引脚9 | 水平舵机控制 | PWM输出 |
| 数字引脚10 | 垂直舵机控制 | PWM输出 |
| 数字引脚2-4 | 电机驱动控制 | L298N接口 |
| 串口 | 调试输出 | 波特率9600 |
电源部分需要特别注意,整个系统采用12V/2A直流电源供电,通过LM7805稳压芯片为Arduino提供5V电源。舵机建议单独供电,避免电流过大导致Arduino复位。
3.2 光敏检测电路
光敏电阻检测电路的设计要点:
-
分压电阻选择:我们测试了10KΩ、50KΩ和100KΩ三种阻值,最终选择100KΩ是因为:
- 在强光下(光敏电阻约5KΩ),分压比约为95%
- 在弱光下(光敏电阻约1MΩ),分压比约为9%
- 这样能获得较大的电压变化范围,提高检测灵敏度
-
滤波处理:在每个光敏电阻的输出端并联0.1μF电容,有效滤除高频干扰
-
安装结构:使用3D打印的遮光筒,确保每个光敏电阻的视场角约为90度
电路原理图如下:
c复制// 光敏电阻连接示意图
// +5V ---[LDR]---[100K]---GND
// |
// A0
3.3 舵机驱动系统
选用SG90微型舵机作为执行机构,主要参数:
- 工作电压:4.8-6V
- 扭矩:1.6kg·cm
- 响应速度:0.12s/60°
- 重量:9g
驱动电路设计要点:
- 每个舵机需要独立的PWM信号控制
- 建议为舵机提供独立电源
- 机械结构要保证转动平稳,我们使用3D打印的支架和联轴器
舵机控制代码示例:
arduino复制#include <Servo.h>
Servo horizontal, vertical;
void setup() {
horizontal.attach(9); // 水平舵机接9脚
vertical.attach(10); // 垂直舵机接10脚
}
void loop() {
int posH = map(horzError, -512, 512, 0, 180);
int posV = map(vertError, -512, 512, 0, 180);
horizontal.write(posH);
vertical.write(posV);
delay(15); // 等待舵机到位
}
4. 软件设计与实现
4.1 系统初始化流程
完整的系统初始化包括以下步骤:
- 外设初始化:
arduino复制void setup() {
Serial.begin(9600);
pinMode(LDR_LT, INPUT);
pinMode(LDR_RT, INPUT);
// 其他引脚初始化...
myservo.attach(SERVO_PIN);
myservo.write(90); // 复位到中间位置
delay(1000); // 等待舵机归位
}
- 参数初始化:
arduino复制// PID参数
double Kp = 0.8, Ki = 0.05, Kd = 0.3;
double lastError = 0, integral = 0;
// 光敏电阻校准值
int ldrBase[4] = {0,0,0,0};
- 自动校准:
系统上电后会执行10秒的自校准,记录各光敏电阻的基础值,用于后续的相对光强计算。
4.2 光强检测算法
光强检测的核心代码如下:
arduino复制void readLDRs() {
ldrValues[0] = analogRead(LDR_LT);
ldrValues[1] = analogRead(LDR_RT);
ldrValues[2] = analogRead(LDR_LD);
ldrValues[3] = analogRead(LDR_RD);
// 计算相对光强
for(int i=0; i<4; i++) {
ldrDiff[i] = ldrValues[i] - ldrBase[i];
}
// 计算偏差
horzError = (ldrDiff[0] + ldrDiff[2]) - (ldrDiff[1] + ldrDiff[3]);
vertError = (ldrDiff[0] + ldrDiff[1]) - (ldrDiff[2] + ldrDiff[3]);
}
调试技巧:可以通过串口实时输出四路光敏电阻的值,用Excel绘制曲线,直观观察跟踪效果。
4.3 PID控制实现
PID控制器的实现代码:
arduino复制double computePID(double error) {
static double lastError = 0, integral = 0;
double derivative, output;
integral += error * dt;
derivative = (error - lastError) / dt;
output = Kp*error + Ki*integral + Kd*derivative;
lastError = error;
return output;
}
void controlServos() {
double horzPID = computePID(horzError);
double vertPID = computePID(vertError);
int horzPos = map(horzPID, -MAX_OUTPUT, MAX_OUTPUT, 0, 180);
int vertPos = map(vertPID, -MAX_OUTPUT, MAX_OUTPUT, 0, 180);
horizontal.write(constrain(horzPos, 0, 180));
vertical.write(constrain(vertPos, 0, 180));
}
参数整定经验:
- 先调Kp,使系统能快速响应但不过冲
- 再调Kd,抑制振荡
- 最后调Ki,消除稳态误差
- 在多云天气下,可以适当减小Kp,增加Ki
5. 系统优化与调试
5.1 常见问题排查
在实际调试中,我们遇到了以下典型问题及解决方案:
- 舵机抖动严重:
- 检查电源是否充足,建议舵机单独供电
- 增加PID微分项,抑制高频振荡
- 在机械结构上增加阻尼
- 跟踪延迟大:
- 减小PID采样周期,我们从500ms优化到100ms
- 提高光敏电阻采样速度,增加软件滤波
- 检查舵机响应速度,必要时更换更快的舵机
- 阴天跟踪失效:
- 增加光敏电阻的灵敏度
- 设置光强阈值,低于阈值时停止跟踪
- 加入记忆功能,记住最后有效位置
5.2 性能优化技巧
- 软件滤波算法:
arduino复制// 移动平均滤波
#define FILTER_SIZE 5
int filterBuffer[FILTER_SIZE];
int filterIndex = 0;
int smoothRead(int pin) {
filterBuffer[filterIndex] = analogRead(pin);
filterIndex = (filterIndex + 1) % FILTER_SIZE;
long sum = 0;
for(int i=0; i<FILTER_SIZE; i++) {
sum += filterBuffer[i];
}
return sum / FILTER_SIZE;
}
- 低功耗优化:
- 晴天时减少采样频率
- 夜晚模式关闭所有外设
- 使用硬件定时器唤醒
- 机械结构改进:
- 采用碳纤维支架减轻重量
- 使用精密轴承减少摩擦
- 优化重心位置降低电机负载
6. 扩展应用与改进方向
这个基础系统可以进一步扩展:
-
增加GPS模块,结合地理位置和时间计算太阳位置,作为光敏检测的辅助参考
-
集成无线通信模块,实现远程监控和控制
-
改用步进电机+编码器的方案,提高控制精度
-
添加温度传感器,监测太阳能板工作温度
-
开发手机APP,可视化显示系统状态和发电数据
对于毕业设计来说,现有系统已经能够很好地展示嵌入式系统开发的完整流程。如果想进一步提升项目水平,可以考虑加入人工智能算法,使系统能够学习天气模式,预测太阳轨迹,实现更智能的跟踪控制。