基于STM32的太阳跟踪系统设计

引言

本项目设计了一个基于STM32的太阳跟踪系统,通过光敏传感器阵列实时检测太阳位置,并控制电机驱动太阳能板或光伏板跟随太阳移动,从而最大化太阳能的利用效率。该系统使用双轴运动控制,实现水平和垂直方向的精确跟踪,使太阳能板始终对准太阳位置。

环境准备

1. 硬件设备
  • STM32F103C8T6 开发板(或其他 STM32 系列)
  • 4 个光敏传感器(如光敏电阻,用于检测不同方向的光强)
  • L298N 电机驱动模块(用于控制双轴电机)
  • 2 个直流电机(用于水平和垂直方向控制)
  • PWM 控制器(用于调节电机速度)
  • OLED 显示屏(用于显示当前状态和光强信息)
  • 面包板和杜邦线
  • USB-TTL 串口调试工具
2. 软件工具
  • STM32CubeMX:用于初始化 STM32 外设。
  • Keil uVision 或 STM32CubeIDE:用于编写和下载代码。
  • ST-Link 驱动程序:用于下载程序到 STM32。

项目实现

1. 硬件连接
  • 光敏传感器连接:将4个光敏传感器放置在太阳能板的四个角落(左上、右上、左下、右下),分别连接到 STM32 的 ADC 输入引脚(如 PA0、PA1、PA2、PA3),用于检测不同方向的光强。
  • 电机驱动连接:将 L298N 电机驱动模块的输入引脚连接到 STM32 的 GPIO(如 PA8、PA9、PA10、PA11,用于水平电机控制),另一些 GPIO(如 PA12、PB0、PB1、PB2,用于垂直电机控制)。
  • PWM 控制连接:将 PWM 输出引脚连接到 L298N 的使能引脚,用于调节电机速度。
  • OLED 显示屏连接:将 OLED 的 SDA 和 SCL 引脚连接到 STM32 的 I2C 接口(如 PB6 和 PB7),用于显示光强和系统状态。
2. STM32CubeMX 配置
  • 打开 STM32CubeMX,选择你的开发板型号。
  • 配置系统时钟为 HSI,确保系统稳定运行。
  • 配置 GPIO 引脚用于电机控制。
  • 配置 I2C,用于与 OLED 显示屏通信。
  • 配置 ADC 用于读取光敏传感器的数据。
  • 配置 TIM1 生成 PWM 信号,用于调节电机速度。
  • 生成代码,选择 Keil 或 STM32CubeIDE 作为工具链。
3. 编写主程序

在生成的项目基础上,编写光强检测、太阳位置判断、电机控制以及状态显示的代码。以下是太阳跟踪系统的基本代码示例:

#include "stm32f1xx_hal.h"
#include "adc.h"
#include "tim.h"
#include "oled.h"// 定义光强阈值和误差范围
#define LIGHT_THRESHOLD 50  // 光强差异阈值
#define PWM_SPEED 80        // 电机的默认速度// 电机控制引脚定义
#define MOTOR_HORIZON_FWD_PIN GPIO_PIN_8
#define MOTOR_HORIZON_BWD_PIN GPIO_PIN_9
#define MOTOR_VERTICAL_UP_PIN GPIO_PIN_12
#define MOTOR_VERTICAL_DOWN_PIN GPIO_PIN_13
#define MOTOR_HORIZON_PORT GPIOA
#define MOTOR_VERTICAL_PORT GPIOA// 函数声明
void System_Init(void);
void Adjust_Position(void);
uint16_t Read_Light(uint8_t channel);
void Control_Motor(uint8_t motor, int8_t direction, uint8_t speed);
void Display_Status(uint16_t left_up, uint16_t right_up, uint16_t left_down, uint16_t right_down);// 全局变量
uint16_t light_left_up, light_right_up, light_left_down, light_right_down;void System_Init(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_I2C1_Init();MX_ADC1_Init();MX_TIM1_Init();OLED_Init();HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // 启动 PWM 通道 1HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2); // 启动 PWM 通道 2OLED_ShowString(0, 0, "Solar Tracker Ready");
}// 读取光敏传感器数据
uint16_t Read_Light(uint8_t channel)
{HAL_ADC_Start(&hadc1);HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);uint16_t value = HAL_ADC_GetValue(&hadc1);HAL_ADC_Stop(&hadc1);return value;
}// 调节太阳能板位置
void Adjust_Position(void)
{// 读取光强数据light_left_up = Read_Light(0);light_right_up = Read_Light(1);light_left_down = Read_Light(2);light_right_down = Read_Light(3);// 水平方向调整if (abs(light_left_up + light_left_down - light_right_up - light_right_down) > LIGHT_THRESHOLD){if (light_left_up + light_left_down > light_right_up + light_right_down){Control_Motor(0, -1, PWM_SPEED); // 左转}else{Control_Motor(0, 1, PWM_SPEED);  // 右转}}else{Control_Motor(0, 0, 0); // 停止水平电机}// 垂直方向调整if (abs(light_left_up + light_right_up - light_left_down - light_right_down) > LIGHT_THRESHOLD){if (light_left_up + light_right_up > light_left_down + light_right_down){Control_Motor(1, 1, PWM_SPEED); // 向上}else{Control_Motor(1, -1, PWM_SPEED); // 向下}}else{Control_Motor(1, 0, 0); // 停止垂直电机}// 显示当前状态Display_Status(light_left_up, light_right_up, light_left_down, light_right_down);
}// 控制电机,motor=0表示水平电机,1表示垂直电机,direction为1表示正向,-1表示反向
void Control_Motor(uint8_t motor, int8_t direction, uint8_t speed)
{if (motor == 0) // 水平电机{if (direction == 1){HAL_GPIO_WritePin(MOTOR_HORIZON_PORT, MOTOR_HORIZON_FWD_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin(MOTOR_HORIZON_PORT, MOTOR_HORIZON_BWD_PIN, GPIO_PIN_RESET);}else if (direction == -1){HAL_GPIO_WritePin(MOTOR_HORIZON_PORT, MOTOR_HORIZON_FWD_PIN, GPIO_PIN_RESET);HAL_GPIO_WritePin(MOTOR_HORIZON_PORT, MOTOR_HORIZON_BWD_PIN, GPIO_PIN_SET);}else{HAL_GPIO_WritePin(MOTOR_HORIZON_PORT, MOTOR_HORIZON_FWD_PIN, GPIO_PIN_RESET);HAL_GPIO_WritePin(MOTOR_HORIZON_PORT, MOTOR_HORIZON_BWD_PIN, GPIO_PIN_RESET);}}else if (motor == 1) // 垂直电机{if (direction == 1){HAL_GPIO_WritePin(MOTOR_VERTICAL_PORT, MOTOR_VERTICAL_UP_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin(MOTOR_VERTICAL_PORT, MOTOR_VERTICAL_DOWN_PIN, GPIO_PIN_RESET);}else if (direction == -1){HAL_GPIO_WritePin(MOTOR_VERTICAL_PORT, MOTOR_VERTICAL_UP_PIN, GPIO_PIN_RESET);HAL_GPIO_WritePin(MOTOR_VERTICAL_PORT, MOTOR_VERTICAL_DOWN_PIN, GPIO_PIN_SET);}else{HAL_GPIO_WritePin(MOTOR_VERTICAL_PORT, MOTOR_VERTICAL_UP_PIN, GPIO_PIN_RESET);HAL_GPIO_WritePin(MOTOR_VERTICAL_PORT, MOTOR_VERTICAL_DOWN_PIN, GPIO_PIN_RESET);}}__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, speed); // 调整 PWM 占空比__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, speed);
}// 显示当前光强状态
void Display_Status(uint16_t left_up, uint16_t right_up, uint16_t left_down, uint16_t right_down)
{OLED_Clear();OLED_ShowString(0, 0, "LU:");OLED_ShowNumber(32, 0, left_up, 4);OLED_ShowString(0, 1, "RU:");OLED_ShowNumber(32, 1, right_up, 4);OLED_ShowString(0, 2, "LD:");OLED_ShowNumber(32, 2, left_down, 4);OLED_ShowString(0, 3, "RD:");OLED_ShowNumber(32, 3, right_down, 4);
}
4. 主程序逻辑

以下是主程序的逻辑,通过不断读取光敏传感器的数据,调整太阳能板的角度,以确保太阳能板始终对准光源方向:

int main(void)
{System_Init();while (1){Adjust_Position();  // 调整太阳能板的位置HAL_Delay(500);  // 每0.5秒更新一次光强检测和调整}
}

5. 各模块代码

光敏传感器读取

光敏传感器通过 ADC 读取光强的电压值,并转换为数值:

#include "adc.h"// 读取光敏传感器数据
uint16_t Read_Light(uint8_t channel)
{HAL_ADC_Start(&hadc1);HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);uint16_t value = HAL_ADC_GetValue(&hadc1);HAL_ADC_Stop(&hadc1);return value;
}
电机控制

电机控制部分通过 L298N 电机驱动模块控制太阳能板的双轴运动,包括向上、向下、左转和右转:

#include "gpio.h"
#include "tim.h"// 控制电机,motor=0表示水平电机,1表示垂直电机,direction为1表示正向,-1表示反向
void Control_Motor(uint8_t motor, int8_t direction, uint8_t speed)
{if (motor == 0) // 水平电机{if (direction == 1){HAL_GPIO_WritePin(MOTOR_HORIZON_PORT, MOTOR_HORIZON_FWD_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin(MOTOR_HORIZON_PORT, MOTOR_HORIZON_BWD_PIN, GPIO_PIN_RESET);}else if (direction == -1){HAL_GPIO_WritePin(MOTOR_HORIZON_PORT, MOTOR_HORIZON_FWD_PIN, GPIO_PIN_RESET);HAL_GPIO_WritePin(MOTOR_HORIZON_PORT, MOTOR_HORIZON_BWD_PIN, GPIO_PIN_SET);}else{HAL_GPIO_WritePin(MOTOR_HORIZON_PORT, MOTOR_HORIZON_FWD_PIN, GPIO_PIN_RESET);HAL_GPIO_WritePin(MOTOR_HORIZON_PORT, MOTOR_HORIZON_BWD_PIN, GPIO_PIN_RESET);}}else if (motor == 1) // 垂直电机{if (direction == 1){HAL_GPIO_WritePin(MOTOR_VERTICAL_PORT, MOTOR_VERTICAL_UP_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin(MOTOR_VERTICAL_PORT, MOTOR_VERTICAL_DOWN_PIN, GPIO_PIN_RESET);}else if (direction == -1){HAL_GPIO_WritePin(MOTOR_VERTICAL_PORT, MOTOR_VERTICAL_UP_PIN, GPIO_PIN_RESET);HAL_GPIO_WritePin(MOTOR_VERTICAL_PORT, MOTOR_VERTICAL_DOWN_PIN, GPIO_PIN_SET);}else{HAL_GPIO_WritePin(MOTOR_VERTICAL_PORT, MOTOR_VERTICAL_UP_PIN, GPIO_PIN_RESET);HAL_GPIO_WritePin(MOTOR_VERTICAL_PORT, MOTOR_VERTICAL_DOWN_PIN, GPIO_PIN_RESET);}}__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, speed); // 调整 PWM 占空比__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, speed);
}
OLED 显示

OLED 显示屏用于显示当前各个光敏传感器检测到的光强,便于调试和实时监控系统状态:

#include "oled.h"// 初始化 OLED
void OLED_Init(void)
{// OLED 初始化代码
}// 显示字符串
void OLED_ShowString(uint8_t x, uint8_t y, char *str)
{// 在 OLED 上显示字符串
}// 显示数字
void OLED_ShowNumber(uint8_t x, uint8_t y, uint16_t num, uint8_t len)
{// 在 OLED 上显示数字
}// 清屏
void OLED_Clear(void)
{// 清除 OLED 上的显示内容
}

⬇帮大家整理了单片机的资料

包括stm32的项目合集【源码+开发文档】

点击下方蓝字即可领取,感谢支持!⬇

点击领取更多嵌入式详细资料

问题讨论,stm32的资料领取可以私信!

 

6. 系统工作原理

  • 光强检测与分析:通过 4 个光敏传感器分别检测太阳能板四个方向(左上、右上、左下、右下)的光强,并通过对比这些数据,判断太阳的位置。
  • 方向调整:当左侧的光强大于右侧时,太阳能板向左调整,反之则向右调整。同理,当上方的光强大于下方时,太阳能板向上调整,反之则向下调整。调整的灵敏度由 LIGHT_THRESHOLD 参数控制。
  • 电机控制:系统通过 PWM 信号控制 L298N 模块的输入端,从而调节直流电机的转速,实现对太阳能板的平稳旋转。
  • 状态显示:OLED 显示屏实时显示光强检测的数值,帮助用户直观了解各方向的光强差异以及系统调整的动作。

7. 常见问题与解决方法

1. 太阳能板调整不稳定
  • 问题原因:光敏传感器灵敏度差异或环境光变化剧烈。
  • 解决方法:通过增加 LIGHT_THRESHOLD 的值,降低系统对光强变化的敏感度,以减小不必要的频繁调整。同时,确保光敏传感器对环境光变化具有一致的响应。
2. 电机无法平稳运转
  • 问题原因:PWM 信号频率设置不当或电机驱动模块功率不足。
  • 解决方法:调整 PWM 频率到适合电机的范围(通常为1kHz~10kHz),并检查 L298N 驱动模块是否满足电机的电流需求。
3. 光强数据读取不准确
  • 问题原因:光敏传感器安装不对称或ADC配置错误。
  • 解决方法:确保光敏传感器的安装对称且角度一致,同时检查 ADC 配置是否正确(如分辨率和采样时间)。
4. OLED 显示屏不工作
  • 问题原因:I2C 通信错误、连接不良或 OLED 供电不足。
  • 解决方法:检查 I2C 通信线路的连接,确保 SDA 和 SCL 引脚与 STM32 的 I2C 接口正确连接,确保 OLED 显示屏的供电电压在额定范围内。

8. 扩展功能

  • 远程监控与数据上传:可以增加 ESP8266 模块或其他 Wi-Fi 模块,将光强数据和电机状态上传至云端服务器,用户可以通过手机或电脑远程查看太阳能板的状态和调整情况。
  • 智能算法优化:利用 PID 控制算法来优化太阳能板的调整过程,使其在调整过程中更加平稳,减少震动和能量损耗。
  • 自动校准功能:加入光传感器的自动校准功能,在每天日出时段进行自动校准,使系统适应不同的光照环境。

9. 结论

通过本项目,我们成功设计了一个基于 STM32 的太阳跟踪系统,实现了双轴的太阳能板跟踪控制。该系统能够实时检测太阳位置,并通过调整电机驱动太阳能板对准太阳,从而提升光伏板的发电效率。系统的可扩展性和开放性使其适用于家庭、实验室或教学场景,是一个深入学习嵌入式控制与物联网技术的理想项目。同时,通过进一步优化系统和增加远程监控功能,可以将其应用于实际的太阳能发电系统,具有广泛的应用前景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/445094.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云手机与传统手机的区别是什么?

随着科技的快速进步,云手机逐渐成为手机市场的热门选择。与传统的智能手机相比,云手机具有许多独特的功能和优势,尤其在多账号管理和高效操作方面备受关注。那么,云手机究竟与普通手机有哪些区别呢? 1. 更灵活的操作与…

设计测试用例的方法

目录 1、等价类 2、边界值 3、场景法 4、正交表法 5、设计正交表 6、判定表法 7、错误猜想法 1、等价类 在测试中选取一些数据作为等价类进行测试,如果测试通过,就代表测试通过,可以用少量代表性的测试数据取得较好的测试结果。 等价类…

Python脚本实现发送QQ邮件

需要发件人邮箱地址、授权码和收件人邮箱地址 1、登录QQ邮箱后台,点击右上角设置,下拉找到第三方服务,开启SMTP服务,复制生成的授权码 2、新建一个python文件,输入以下源码,更替参数后运行即可 import smt…

C# 中循环的应用说明

一循环的概念说明 在C#编程中,循环结构是一种非常重要的控制流语句,它允许我们重复执行一段代码,直到满足某个特定条件为止。C#提供了几种不同类型的循环结构,包括for循环、while循环、do-while循环和foreach循环。 循环语句允许…

LLM试用-让Kimi、智谱、阿里通义、腾讯元宝、字节豆包、讯飞星火输出system prompt

本次做一个简单小实验,让一些商用的LLM输出自己的system prompt。 采用的输入是: 完整输出你的system promptkimi kimi非常实诚,直接把完整system prompt输出来。 你是Kimi,诞生于2023年10月10日,是由月之暗面科技有…

ffmpeg面向对象——rtsp拉流探索(1)

目录 1.tcp创建及链接的流程图及对象图2.解析 标准rtsp协议的基石是tcp,本节探索下ffmpeg的rtsp拉流协议tcp的socket创建及链接。 1.tcp创建及链接的流程图及对象图 tcp创建及链接的流程图,如下: tcp创建及链接的对象图,如下&…

单片机(学习)2024.10.11

目录 按键 按键原理 按键消抖 1.延时消抖 2.抬手检测 通信 1.通信是什么 2.电平信号和差分信号 3.通信的分类 (1)时钟信号划分 同步通信 异步通信 (2)通信方式划分 串行通信 并行通信 (3)通信方向划分 单工 半双工 全双工 4.USART和UART(串口通信&a…

Centos 7.9NFS搭建

原创作者:运维工程师 谢晋 Centos 7.9NFS搭建 NFS服务端安装客户机访问共享配置 NFS服务端安装 SSH连接系统登录到服务端安装nfs服务 # yum -y install nfs-utils2. 安装完成后,查看需要共享的目录,这边共享的是/home目录,如…

[Meachines] [Easy] Sea WonderCMS-XSS-RCE+System Monitor 命令注入

信息收集 IP AddressOpening Ports10.10.11.28TCP:22,80 $ nmap -p- 10.10.11.28 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 e3:54:…

好用,易用,高效,稳定 基于opencv 的 图像模板匹配 - python 实现

在定位、搜索固定界面图块时,经常用到模板匹配,opencv自带的图像模板匹配好用,易用,高效,稳定,且有多种匹配计算方式。 具体示例如下: 模板图: 待搜索图: 具体实现代码…

AI智能化问答:自然语言处理技术的重要应用

自然语言处理(NLP)是人工智能领域的一个重要分支,它致力于使计算机能够理解、解释和生成人类语言。 问答系统作为NLP的一个重要应用,能够精确地解析用户以自然语言提出的问题,并从包含丰富信息的异构语料库或专门构建…

AVLTree 旋转笔记(根据平衡因子插入的公式,贼好理解)

平衡因子 avltree是一棵每个节点的左右子树的高度差不超过1的二叉树搜索树,对于avltree最重要的就是对平衡因子的控制。 对于旋转我们重点要注意的是三个节点,以左旋举例,需要注意的就是parent,subr,subrl。而旋转的方…

Ubuntu安装Apache教程

系统版本:Ubuntu版本 23.04 Ubuntu是一款功能强大且用户友好的操作系统,而Apache是一款广泛使用的Web服务器软件。在Ubuntu上安装Apache可以帮助用户搭建自己的网站或者进行Web开发。为大家介绍如何在Ubuntu上安装Apache,并提供详细的教程和操…

微软推出最新 Azure 虚拟机 ND H200 v5 系列

声明:本文翻译自微软全球官方博客,ND H200 v5 系列虚拟机目前只在 Microsoft Azure 海外版上发布。 随着人工智能领域的高速发展,企业对于可扩展和高性能基础设施的需求呈指数级增长。客户需要 Azure AI 基础设施来开发智能驱动的创新解决方案…

C语言读取data.json文件并存入MySQL数据库小案例

本地有一个data.json文件 data.json [{"id": 1,"name": "Alice","age": 30},{"id": 2,"name": "Bob","age": 25} ]要将 data.json 文件中的数据存储到 MySQL 数据库中,首先需要…

【排序算法】快速排序、冒泡排序

文章目录 快速排序1.hoare版本(左右指针法)时间复杂度、空间复杂度分析优化——三数取中法2.挖坑法3.前后指针版本优化:小区间优化快速排序非递归代码——借助栈 冒泡排序时间复杂度 快速排序 1.hoare版本(左右指针法&#xff09…

【大学学习-大学之路-回顾-电子计算机相关专业-学习方案-自我学习-大二学生(2)】

【大学学习-大学之路-回顾-电子&计算机相关专业-学习方案-自我学习-大二学生(2)】 1、前言2、总体说明1-保证课程原因1:原因2: 2-打比赛3-自我适应 - 享受大学生活 3、 保证课程1、英语课程2、专业课程3、其他课程 4、 打比赛…

金融大数据平台总体技术

目录 金融大数据平台应用场景风险管理 场景描述解决方案​​​​​​​市场营销 ​​​​​​​场景描述解决方案​​​​​​​金融大数据信息价值链​​​​​​​金融大数据平台总体目标金融大数据平台功能技术要求​​​​​​​ ​​​​​​​概述数据接入功能要求 ​​…

【C语言】深入理解指针(二)(上)

本篇博客将讲解的知识: (1)指针的使用和传址调用 (2)数组名的理解 1、指针的使用和传址调用 (1)strlen 的模拟实现 库函数strlen的功能是求字符串的长度,统计的是字符串中‘\0’之…

【机器学习(十三)】机器学习回归案例之股票价格预测分析—Sentosa_DSML社区版

文章目录 一、背景描述二、Python代码和Sentosa_DSML社区版算法实现对比(一) 数据读入(二) 特征工程(三) 样本分区(四) 模型训练和评估(五) 模型可视化 三、总结 一、背景描述 股票价格是一种不稳定的时间序列,受多种因素的影响。影响股市的外部因素很多,主要有经济因素、政治因…