基于单片机设计的太阳能跟踪器
一、前言
随着对可再生能源的需求不断增长,太阳能作为一种清洁、可持续的能源形式,受到越来越多的关注和应用。太阳能光板通常固定在一个固定的角度上,这限制了它们对太阳光的接收效率。为了充分利用太阳能资源,提高太阳能光板的收集效率,需要设计一个能够自动跟踪太阳光的系统。
本项目采用基于单片机的设计方案,主控芯片选择STC89C52。在太阳能光板的四个角上,安装了四个光敏电阻,它们用于检测四个方向太阳光的最强位置。每个光敏电阻通过PCF8591模块与主控芯片相连,利用模数转换器(ADC)采集各个通道的数据值。
通过对四个光敏传感器采集到的数据进行处理和比较,主控芯片能够确定太阳光的最强位置所在。然后,通过控制两个28BYJ-48-5V步进电机的运动,太阳能光板可以实现左右和上下方向的旋转。通过调整太阳能光板的倾斜角度,使其与太阳光保持垂直,以获得最大的太阳能收集效率。
该太阳能跟踪器的设计旨在实现自动化的太阳光追踪,以提高太阳能光板的能源收集效率。通过使用光敏电阻、ADC转换和步进电机控制等技术手段,系统能够准确地确定太阳光的位置,并自动调整太阳能光板的朝向。这将大大提高太阳能系统的能源输出,并为可再生能源的利用做出贡献。
二、系统设计思路
2.1 硬件选型
【1】主控芯片:STC89C52 STC89C52是一款高性价比的单片机,具有丰富的外设和强大的计算能力。采用基于MCS-51内核的8位单片机架构,拥有存储容量大(8KB Flash和256B RAM)和丰富的IO口(32个),适合控制太阳能跟踪器系统的各种功能。
【2】光敏电阻:选择具有高灵敏度和较小尺寸的光敏电阻,并根据光照条件进行选择。通过与PCF8591模块连接,可以将光敏电阻的电阻值变化转换为相应的模拟电压信号。
【3】ADC模块:PCF8591 PCF8591是一款常用的4通道12位ADC模块,适用于将模拟信号转换为数字信号。通过连接4个光敏电阻到PCF8591的4个输入通道上,可以实现数据的采集和转换。
【4】步进电机:28BYJ-48-5V 28BYJ-48-5V步进电机是一个小型、低功耗的步进电机,适用于低速应用。使用两个步进电机可以控制太阳能光板在水平和垂直方向上的旋转,为太阳能跟踪器提供多个方向的调整。
2.2 设计思路
【1】硬件连接:根据项目需求,将STC89C52主控芯片与PCF8591模块、ULN2003驱动模块、28BYJ-48-5V步进电机、光敏电阻等进行正确的引脚连接。
【2】初始化设置:在主函数开始部分,进行必要的初始化设置,例如设置I/O口方向、定义引脚连接、初始化I2C总线等。
【3】光敏电阻采集:通过PCF8591模块采集4个光敏电阻的数据。使用I2C通信协议,向PCF8591模块发送控制字节,选择光敏电阻通道,并通过ADC转换获取光敏电阻的数值。将采集到的数据存储在名为lightSensor
的数组中,每个元素对应一个光敏电阻通道。
【4】确定最强光位置:根据采集到的光敏电阻数据,通过比较找到最强光的位置。遍历lightSensor
数组,记录最大值的索引,表示最强光所在的方向。
【5】步进电机控制:根据最强光的位置控制步进电机的旋转,使太阳能光板朝向最大光的方向。根据最大光位置的索引,使用条件语句判断旋转方向,然后调用StepperMotor_Rotate
函数控制步进电机旋转。根据需求,可以设置旋转步数和旋转方向,以实现精确的转动控制。
【6】延时等待:在步进电机旋转完成后,可以添加适当的延时,以等待太阳能光板调整到新的位置。可以根据实际情况调整延时时间,确保光板稳定后进行下一次采集和控制。
【7】循环执行:将上述步骤放置在一个无限循环中,以实现持续的太阳能跟踪。程序将不断采集光敏电阻数据、确定最强光位置,并通过步进电机控制太阳能光板旋转,以获得最大的太阳能收集效率。
三、项目代码
3.1 PCF8591采集代码
以下是利用PCF8591的光敏电阻采集并通过串口打印的实现代码。
#include <reg52.h>
#include <intrins.h>// 定义PCF8591模块地址
#define PCF8591_ADDR 0x90// 定义光敏电阻通道
#define LDR_CHANNEL_1 0x00
#define LDR_CHANNEL_2 0x01
#define LDR_CHANNEL_3 0x02
#define LDR_CHANNEL_4 0x03// 定义波特率
#define BAUDRATE 9600// 函数声明
void delay(unsigned int time);
void uartInit();
void uartSendByte(unsigned char dat);
void uartSendString(unsigned char *str);
void pcf8591Init();
unsigned char pcf8591ReadChannel(unsigned char channel);void main() {unsigned char ldr1, ldr2, ldr3, ldr4;unsigned char str[20];uartInit(); // 初始化串口pcf8591Init(); // 初始化PCF8591模块while(1) {// 读取光敏电阻数据ldr1 = pcf8591ReadChannel(LDR_CHANNEL_1);ldr2 = pcf8591ReadChannel(LDR_CHANNEL_2);ldr3 = pcf8591ReadChannel(LDR_CHANNEL_3);ldr4 = pcf8591ReadChannel(LDR_CHANNEL_4);// 打印光敏电阻数据到串口sprintf(str, "LDR1: %d, LDR2: %d, LDR3: %d, LDR4: %d\r\n", ldr1, ldr2, ldr3, ldr4);uartSendString(str);delay(1000); // 延时一段时间后再进行下一次采集和打印}
}// 延时函数
void delay(unsigned int time) {unsigned int i, j;for(i = 0; i < time; i++) {for(j = 0; j < 125; j++);}
}// 初始化串口
void uartInit() {TMOD = 0x20; // 设置定时器1为模式2SCON = 0x50; // 设置串口工作方式1,允许接收TH1 = 256 - _cror(_cror(FOSC/12, 4), 4) / BAUDRATE; // 设置波特率TR1 = 1; // 启动定时器1
}// 串口发送单个字节
void uartSendByte(unsigned char dat) {SBUF = dat;while (!TI); // 等待发送完成TI = 0; // 清除发送完成标志位
}// 串口发送字符串
void uartSendString(unsigned char *str) {while (*str) {uartSendByte(*str);str++;}
}// 初始化PCF8591模块
void pcf8591Init() {// 发送启动转换命令I2C_Start(); I2C_Send_Byte(PCF8591_ADDR); // 发送设备地址I2C_Wait_Ack();I2C_Send_Byte(0x40); // 发送转换命令,选择通道0I2C_Wait_Ack();I2C_Stop();
}// 读取PCF8591模块的指定通道的数据值
unsigned char pcf8591ReadChannel(unsigned char channel) {unsigned char value;I2C_Start();I2C_Send_Byte(PCF8591_ADDR); // 发送设备地址I2C_Wait_Ack();I2C_Send_Byte(channel); // 发送通道号I2C_Wait_Ack();I2C_Start(); // 重新启动I2C_Send_Byte(PCF8591_ADDR + 1); // 发送读取命令I2C_Wait_Ack();value = I2C_Read_Byte(); // 读取数据I2C_Send_NAck();I2C_Stop();return value;
}
3.2 主项目框架代码
#include <reg52.h>// 定义PCF8591模块的引脚连接
#define PCF8591_ADDRESS 0x90 // PCF8591模块的I2C地址
#define PCF8591_CONTROL 0x00 // PCF8591模块的控制寄存器地址// 定义步进电机的引脚连接
sbit IN1 = P1^0; // 步进电机引脚1
sbit IN2 = P1^1; // 步进电机引脚2
sbit IN3 = P1^2; // 步进电机引脚3
sbit IN4 = P1^3; // 步进电机引脚4// 定义步进电机旋转方向
#define CW 0 // 顺时针
#define CCW 1 // 逆时针// 定义光敏电阻通道
#define CHANNEL_0 0 // 光敏电阻通道0
#define CHANNEL_1 1 // 光敏电阻通道1
#define CHANNEL_2 2 // 光敏电阻通道2
#define CHANNEL_3 3 // 光敏电阻通道3// 延时函数
void delay(unsigned int ms) {unsigned int i, j;for (i = ms; i > 0; i--)for (j = 110; j > 0; j--);
}// I2C总线启动
void I2C_Start() {SDA = 1;SCL = 1;delay(1);SDA = 0;delay(1);SCL = 0;delay(1);
}// I2C总线停止
void I2C_Stop() {SDA = 0;SCL = 1;delay(1);SDA = 1;delay(1);
}// I2C发送一个字节的数据
void I2C_SendByte(unsigned char dat) {unsigned char i;for (i = 0; i < 8; i++) {SDA = (dat & 0x80) >> 7;dat <<= 1;delay(1);SCL = 1;delay(1);SCL = 0;delay(1);}SDA = 1;delay(1);SCL = 1;delay(1);while (SDA) continue;SCL = 0;
}// 从PCF8591读取一个字节的数据
unsigned char PCF8591_ReadByte() {unsigned char i, dat = 0;SDA = 1;for (i = 0; i < 8; i++) {dat <<= 1;SCL = 0;delay(1);SCL = 1;delay(1);if (SDA) dat |= 0x01;}SCL = 0;return dat;
}// 设置PCF8591的控制字节
void PCF8591_SetControl(unsigned char ctrl) {I2C_Start();I2C_SendByte(PCF8591_ADDRESS);I2C_SendByte(PCF8591_CONTROL);I2C_SendByte(ctrl);I2C_Stop();
}// 读取光敏电阻的数据
unsigned int ReadLightSensor(unsigned char channel) {unsigned int value;PCF8591_SetControl(0x40 | channel); // 选择光敏电阻通道delay(10); // 延时等待转换完成I2C_Start();I2C_SendByte(PCF8591_ADDRESS | 0x01); // 续上一段value = PCF8591_ReadByte(); // 读取高字节value = (value << 8) + PCF8591_ReadByte(); // 读取低字节I2C_Stop();return value;
}// 控制步进电机旋转
void StepperMotor_Rotate(unsigned char direction, unsigned int steps) {unsigned int i;for (i = 0; i < steps; i++) {// 顺时针旋转if (direction == CW) {IN1 = 1; IN2 = 0; IN3 = 0; IN4 = 0;delay(10);IN1 = 0; IN2 = 1; IN3 = 0; IN4 = 0;delay(10);IN1 = 0; IN2 = 0; IN3 = 1; IN4 = 0;delay(10);IN1 = 0; IN2 = 0; IN3 = 0; IN4 = 1;delay(10);}// 逆时针旋转else if (direction == CCW) {IN1 = 0; IN2 = 0; IN3 = 0; IN4 = 1;delay(10);IN1 = 0; IN2 = 0; IN3 = 1; IN4 = 0;delay(10);IN1 = 0; IN2 = 1; IN3 = 0; IN4 = 0;delay(10);IN1 = 1; IN2 = 0; IN3 = 0; IN4 = 0;delay(10);}}
}// 主函数
void main() {unsigned int lightSensor[4];unsigned char maxIndex;while (1) {// 采集光敏电阻数据lightSensor[0] = ReadLightSensor(CHANNEL_0);lightSensor[1] = ReadLightSensor(CHANNEL_1);lightSensor[2] = ReadLightSensor(CHANNEL_2);lightSensor[3] = ReadLightSensor(CHANNEL_3);// 确定最强光位置maxIndex = 0;if (lightSensor[1] > lightSensor[maxIndex]) maxIndex = 1;if (lightSensor[2] > lightSensor[maxIndex]) maxIndex = 2;if (lightSensor[3] > lightSensor[maxIndex]) maxIndex = 3;// 控制步进电机旋转if (maxIndex == 0) {StepperMotor_Rotate(CW, 100); // 右转} else if (maxIndex == 1) {StepperMotor_Rotate(CCW, 100); // 左转} else if (maxIndex == 2) {StepperMotor_Rotate(CW, 100); // 右转StepperMotor_Rotate(CW, 100); // 右转} else if (maxIndex == 3) {StepperMotor_Rotate(CCW, 100); // 左转StepperMotor_Rotate(CCW, 100); // 左转}delay(1000); // 延时一段时间}
}
相关文章:

基于单片机设计的太阳能跟踪器
一、前言 随着对可再生能源的需求不断增长,太阳能作为一种清洁、可持续的能源形式,受到越来越多的关注和应用。太阳能光板通常固定在一个固定的角度上,这限制了它们对太阳光的接收效率。为了充分利用太阳能资源,提高太阳能光板的…...

【踩坑及思考】浏览器存储 cookie 最大值超过 4kb,或 http 头 cookie 超过限制值
背景 本地生产环境:超过最大值 cookie token 不存储;客户生产环境:打开系统空白,且控制台报 http 400 错误; 出现了两种现象 现象一:浏览器对大于 4kb 的 cookie 值不存储 导致用户名密码登录ÿ…...

竞赛选题 深度学习实现行人重识别 - python opencv yolo Reid
文章目录 0 前言1 课题背景2 效果展示3 行人检测4 行人重识别5 其他工具6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习的行人重识别算法研究与实现 ** 该项目较为新颖,适合作为竞赛课题方向,…...

SpringCloud Gateway实现请求解密和响应加密
文章目录 前言正文一、项目简介二、核心代码2.1 自定义过滤器2.2 网关配置2.3 自定义配置类2.4 加密组件接口2.5 加密组件实现,AES算法2.6 启动类,校验支持的算法配置 三、请求报文示例四、测试结果4.1 网关项目启动时4.2 发生请求时 前言 本文环境使用比…...

IDEA创建Springboot多模块项目
一、创建父模块 File --> New --> Project ,选择 “ Spring Initalizr ” ,点击 Next Next Next --> Finish 二、创建子模块 右键根目录,New --> Module 选择 “ Spring Initializr ”,点击Next 此处注意T…...
React:JSX语法入门
JSX语法入门及代码 JSX是一种JavaScript的语法扩展,用于在React中描述用户界面的结构。它允许开发者使用类似HTML的语法来创建React元素,使得代码更具可读性和可维护性。JSX将HTML标签和JavaScript代码结合在一起,可以在其中使用JavaScript表…...

AI大模型架构师专家,你会问什么来测试我的水平,如何解答上述问题,学习路径是什么
0. 沈剑老师的大模型产品应用经验: 提示词三步骤: 假如我是xxx专家,你会问什么来测试我的水平;假如你是xxx专家,你会如何解答上述问题;假如你是xxx专家,上述问题的学习路径是什么;…...

Dev-C调试的基本方法2-1
在Dev-C中调试程序,首先需要在程序中设置断点,之后以调试的方式运行程序。 1 设置断点 当以调试的方式运行程序时,程序会在断点处停下来。点击要设置断点代码行号左侧部分,此时会有如图1所示的红点和绿色对勾,表示断…...
Linux 调试 (objdump/strace/strings)
目录 1. Linux 调试 (objdump/strace/strings)1.1. 查看系统 glibc 版本号1.2. 查看 so/bin 中的依赖1.3. 调试 bin 报错原因1.4. 查看 so/bin 中字符串 1. Linux 调试 (objdump/strace/strings) 1.1. 查看系统 glibc 版本号 1. 第一种 # ldd --version ldd (Ubuntu GLIBC 2.…...
CAS 单点登录详解
什么是CAS? - 简要介绍CAS(Central Authentication Service)的概念和作用。 - 强调CAS的主要目标是提供单点登录和单点登出功能。 CAS的工作原理 - 深入探讨CAS的工作原理,包括认证、票据、验证等核心概念。 - 详细解释CAS服务器和…...

tbh常用的绘图快捷键
1、Altb -> 笔刷 2、Alt/ -> 画笔 3、按住Shift 绘出的线条是直线 4、按住shiftalt 绘出来的线条是水平线或垂直线 5、alte ->橡皮擦 6、alts ->选择工具 7、altq -> 轮廓编辑器 以下操作都是在选中轮廓编辑器下操作的: 按住alt…...
Android-Framework 清除应用用户数据,不清除权限
一、环境 高通865 Android 10 二、具体详情 现象:默认赋予第三方应用的权限,在应用信息中清理用户数据的时候,权限也会被清理掉; 希望:只清理数据,保留权限 相关源码修改如下: frameworks/base/servi…...
CS认证办理流程,CS认证好处
CS资质全名叫“信息系统建设和服务能力评估体系” 所谓的CS认证,是指信息系统建设和服务能力评级。认证一共划分为五个等级,等级从低到高分别用CS1级(初始级)、CS2级(基本级)、CS3级(良好级&…...

macOS 安装brew
参考链接: https://mirrors4.tuna.tsinghua.edu.cn/help/homebrew/ https://www.yii666.com/blog/429332.html 安装中科大源的: https://zhuanlan.zhihu.com/p/470873649...

H5: 使用Web Audio API播放音乐
简介 记录关于自己使用 Web Audio API 的 AudioContext 播放音乐的知识点。 需求分析 1.列表展示音乐; 2.上/下一首、播放/暂停/续播; 3.播放模式切换:循环播放、单曲循环、随机播放; 4.播放状态显示:当前播放的音乐…...

Parasoft C/C++test:汽车网络安全ISO 21434最佳实践
为什么汽车网络安全很重要Why Automotive Cybersecurity Is Important 许多汽车公司向电子道路车辆的转变从根本上改变了整个行业,提高了汽车的互联性和智能性。随着电子汽车变得更加互联和智能,它们也越来越依赖软件来实现车辆操作,驱动更多…...

如何卸载干净 IDEA(图文讲解)windows和Mac教程
大家好,我是sun~ 很多小伙伴会问 Windows / Mac 系统上要怎么彻底卸载 IDEA 呢? 本文通过图片文字,详细讲解具体步骤: 如何卸载干净 IDEA(图文讲解) Windows1、卸载 IDEA 程序2、注册表清理3、残留清理 M…...
Docker搭建Gitlab
拉取镜像:docker pull gitlab/gitlab-ce创建映射目录: mkdir -p /usr/local/gitlab/config mkdir -p /usr/local/gitlab/data mkdir -p /usr/local/gitlab/logs运行容器: docker run -d -p 443:443 -p 8000:8000 -p 222:22 --name gitlab …...

STM32F4X SDIO(四) SDIO控制器
STM32F4X SDIO(四) SDIO控制器 STM32F4X SDIO控制器SDIO控制器框图SDIO控制器时钟适配器寄存器FIFO控制单元命令路径数据路径 SDIO寄存器SDIO控制相关寄存器SDIO电源控制寄存器 (SDIO_POWER)SDIO时钟控制寄存器 (SDIO_CLKCR)SDIO_CK相位 SDIO命令响应相关…...

【flink】Task 故障恢复详解以及各重启策略适用场景说明
文章目录 一. 重启策略种类(Restart Strategies)1. Fixed Delay Restart Strategy2. Failure Rate Restart Strategy3. Fallback Restart Strategy4. No Restart Strategy 二. 故障恢复策略(Failover Strategies)1. (全…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...