PID灯控算法

根据代码分析,以下是针对PID算法和光敏传感器系统的优化建议,分为算法优化、代码结构优化和系统级优化三部分:


一、PID算法优化

1. 增量式PID + 输出平滑
// 修改PID计算函数
uint16_t PID_calculation_fun(void) {if(PID_Str_Val.Tdata >= PID_Str_Val.T) {// 增量式PID计算float delta = PID_Str_Val.Kp * (PID_Str_Val.En - PID_Str_Val.En_1) +PID_Str_Val.Ki * PID_Str_Val.En + PID_Str_Val.Kd * (PID_Str_Val.En - 2*PID_Str_Val.En_1 + PID_Str_Val.En_2);// 输出变化率限制(避免突变)if (delta > PID_Str_Val.max_delta) delta = PID_Str_Val.max_delta;else if (delta < -PID_Str_Val.max_delta) delta = -PID_Str_Val.max_delta;// 低通滤波平滑输出PID_Str_Val.Dout = PID_Str_Val.output_alpha * delta + (1 - PID_Str_Val.output_alpha) * PID_Str_Val.Dout;PID_Str_Val.currpwm += PID_Str_Val.Dout;// ...限幅和状态更新}return (uint16_t)PID_Str_Val.currpwm;
}

优化点

  • 增量式算法减少阶跃响应超调。
  • 输出变化率限制(max_delta)避免剧烈波动。
  • 低通滤波(output_alpha)平滑最终输出。
2. 动态参数调整
// 根据光照变化动态调整PID参数
if (fabs(PID_Str_Val.En) > 500) {  // 大误差时增强响应PID_Str_Val.Kp = 0.8;PID_Str_Val.Ki = 0.05;
} else {                           // 小误差时抑制振荡PID_Str_Val.Kp = 0.3;PID_Str_Val.Ki = 0.01;
}

二、输入信号处理优化

1. 改进滑动平均滤波
// 使用加权滑动平均(近期数据权重更高)
float sum = 0, weight_total = 0;
for(int i=0; i<FILTER_WINDOW_SIZE; i++) {float weight = 1.0f / (i + 1);  // 权重递减sum += filter_buffer[i] * weight;weight_total += weight;
}
PID_Str_Val.curr = sum / weight_total;
2. 死区处理
// 忽略微小误差(避免频繁调节)
if (fabs(PID_Str_Val.En) < PID_Str_Val.dead_zone) {PID_Str_Val.En = 0;
}

三、系统级优化

1. 自适应采样周期
// 根据光照变化速度动态调整采样周期
if (fabs(PID_Str_Val.En - PID_Str_Val.En_1) > 200) {  // 快速变化时加速采样PID_Str_Val.T = 20;  // 20ms
} else {PID_Str_Val.T = 50;  // 50ms
}
2. 硬件优化
  • ADC配置:提高ADC采样率(修改config.clk),减少软件滤波压力。
  • GPIO抗干扰:在光敏传感器输入端添加RC低通滤波(如100Ω电阻 + 100nF电容)。

四、代码结构优化

1. 模块化PID参数
typedef struct {float Kp, Ki, Kd;float T, Ti, Td;float dead_zone;float max_delta;float output_alpha;
} PID_Params;PID_Params fast_params = {0.8, 0.05, 0.1, 20, 30, 0.2, 10, 5, 0.3};
PID_Params slow_params = {0.3, 0.01, 0.05, 50, 50, 0.1, 5, 2, 0.5};
2. 状态机管理
typedef enum {PID_STATE_INIT,PID_STATE_STEADY,PID_STATE_TRACKING
} PID_State;// 根据状态切换参数
switch (current_state) {case PID_STATE_TRACKING:apply_params(fast_params);break;case PID_STATE_STEADY:apply_params(slow_params);break;
}

五、参数调试建议

  1. 调试顺序

    • 先调 PKp)至系统开始振荡,然后减半。
    • 再调 IKi)至稳态误差消除,但避免积分饱和。
    • 最后调 DKd)抑制超调。
  2. 典型参数参考

    PID_Str_Val.Kp = 0.5;   // 比例(根据实际响应调整)
    PID_Str_Val.Ki = 0.02;  // 积分(较小值防饱和)
    PID_Str_Val.Kd = 0.1;   // 微分(抑制高频噪声)
    PID_Str_Val.dead_zone = 20;  // 死区(约2%量程)
    PID_Str_Val.max_delta = 10;  // 单步最大变化量
    

六、验证与测试

  1. 阶跃响应测试
    • 突然遮挡光源,观察输出是否平稳跟踪。
  2. 抗干扰测试
    • 手动制造光照波动,检查恢复速度。
  3. 长期稳定性
    • 连续运行24小时,确认无漂移或振荡。

通过上述优化,系统将具有更平滑的响应、更低的抖动和更好的适应性。

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

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

相关文章

文件映射mmap与管道文件

在用户态申请内存&#xff0c;内存内容和磁盘内容建立一一映射 读写内存等价于读写磁盘 支持随机访问 简单来说&#xff0c;把磁盘里的数据与内存的用户态建立一一映射关系&#xff0c;让读写内存等价于读写磁盘&#xff0c;支持随机访问。 管道文件&#xff1a;进程间通信机…

在 Java 中调用 ChatGPT API 并实现流式接收(Server-Sent Events, SSE)

文章目录 简介OkHttp 流式获取 GPT 响应通过 SSE 流式推送前端后端代码消息实体接口接口实现数据推送给前端 前端代码创建 sseClient.jsvue3代码 优化后端代码 简介 用过 ChatGPT 的伙伴应该想过自己通过调用ChatGPT官网提供的接口来实现一个自己的问答机器人&#xff0c;但是…

硬盘分区格式之GPT(GUID Partition Table)笔记250407

硬盘分区格式之GPT&#xff08;GUID Partition Table&#xff09;笔记250407 GPT&#xff08;GUID Partition Table&#xff09;硬盘分区格式详解 GPT&#xff08;GUID Partition Table&#xff09;是替代传统 MBR 的现代分区方案&#xff0c;专为 UEFI&#xff08;统一可扩展固…

Vite环境下解决跨域问题

在 Vite 开发环境中&#xff0c;可以通过配置代理来解决跨域问题。以下是具体步骤&#xff1a; 在项目根目录下找到 vite.config.js 文件&#xff1a;如果没有&#xff0c;则需要创建一个。配置代理&#xff1a;在 vite.config.js 文件中&#xff0c;使用 server.proxy 选项来…

交换机与ARP

交换机与 ARP&#xff08;Address Resolution Protocol&#xff0c;地址解析协议&#xff09; 的关系主要体现在 局域网&#xff08;LAN&#xff09;内设备通信的地址解析与数据帧转发 过程中。以下是二者的核心关联&#xff1a; 1. 基本角色 交换机&#xff1a;工作在 数据链…

【Spring】小白速通AOP-日志记录Demo

这篇文章我将通过一个最常用的AOP场景-方法调用日志记录&#xff0c;带你彻底理解AOP的使用。例子使用Spring BootSpring AOP实现。 如果对你有帮助可以点个赞和关注。谢谢大家的支持&#xff01;&#xff01; 一、Demo实操步骤&#xff1a; 1.首先添加Maven依赖 <!-- Sp…

git功能点管理

需求&#xff1a; 功能模块1 已经完成&#xff0c;已经提交并推送到远程&#xff0c;准备交给测试。功能模块2 已经完成&#xff0c;但不提交给测试&#xff0c;继续开发。功能模块3 正在开发中。 管理流程&#xff1a; 创建并开发功能模块1&#xff1a; git checkout main…

QGIS实战系列(六):进阶应用篇——Python 脚本自动化与三维可视化

欢迎来到“QGIS实战系列”的第六期!在前几期中,我们从基础操作到插件应用逐步提升了 QGIS 技能。这一篇,我们将迈入进阶领域,探索如何用 Python 脚本实现自动化,以及如何创建三维可视化效果,让你的 GIS 项目更高效、更立体。 第一步:Python 脚本自动化 QGIS 内置了 Py…

高德地图 3D 渲染-区域纹理图添加

引入-初始化地图&#xff08;关键代码&#xff09; // 初始化页面引入高德 webapi -- index.html 文件 <script src https://webapi.amap.com/maps?v2.0&key您申请的key值></script>// 添加地图容器 <div idcontainer ></div>// 地图初始化应该…

ffmpeg视频转码相关

ffmpeg视频转码相关 简介参数 实战举栗子获取视频时长视频转码mp4文件转为hls m3u8 ts等文件图片转视频抽取视频第一帧获取基本信息 转码日志输出详解转码耗时测试 简介 FFmpeg 是领先的多媒体框架&#xff0c;能够解码、编码、 转码、复用、解复用、流、过滤和播放 几乎所有人…

【ISP】HDR技术中Sub-Pixel与DOL的对比分析

一、原理对比 Sub-Pixel&#xff08;空间域HDR&#xff09; • 核心机制&#xff1a;在单个像素内集成一大一小两个子像素&#xff08;如LPD和SPD&#xff09;&#xff0c;利用其物理特性差异&#xff08;灵敏度、满阱容量&#xff09;同时捕捉不同动态范围的信号。 ◦ 大像素&…

Vulnhub-IMF靶机

本篇文章旨在为网络安全渗透测试靶机教学。通过阅读本文&#xff0c;读者将能够对渗透Vulnhub系列IMF靶机有一定的了解 一、信息收集阶段 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/imf-1,162/ 因为靶机为本地部署虚拟机网段&#xff0c;查看dhcp地址池设置。得…

Linux内核中TCP协议栈的实现:tcp_close函数的深度剖析

引言 TCP(传输控制协议)作为互联网协议族中的核心协议之一,负责在不可靠的网络层之上提供可靠的、面向连接的字节流服务。Linux内核中的TCP协议栈实现了TCP协议的全部功能,包括连接建立、数据传输、流量控制、拥塞控制以及连接关闭等。本文将深入分析Linux内核中tcp_close…

java+postgresql+swagger-多表关联insert操作(七)

入参为json&#xff0c;然后根据需要对多张表进行操作&#xff1a; 入参格式&#xff1a; [{"custstoreName":"swagger-测试经销商01","customerName":"swagger-测试客户01","propertyNo":"swaggertest01",&quo…

R语言——绘制生命曲线图(细胞因子IL5)

绘制生命曲线图&#xff08;根据细胞因子&#xff09; 说明流程代码加载包读取Excel文件清理数据重命名列名处理IL-5中的"<"符号 - 替换为检测下限的一半首先找出所有包含"<"的值检查缺失移除缺失值根据IL-5中位数将患者分为高低两组 创建生存对象拟…

Python----计算机视觉处理(Opencv:道路检测完整版:透视变换,提取车道线,车道线拟合,车道线显示,)

Python----计算机视觉处理&#xff08;Opencv:道路检测之道路透视变换) Python----计算机视觉处理&#xff08;Opencv:道路检测之提取车道线&#xff09; Python----计算机视觉处理&#xff08;Opencv:道路检测之车道线拟合&#xff09; Python----计算机视觉处理&#xff0…

【Oracle篇】跨字符集迁移:基于数据泵的ZHS16GBK转AL32UTF8全流程迁移

&#x1f4ab;《博主主页》&#xff1a;奈斯DB-CSDN博客 &#x1f525;《擅长领域》&#xff1a;擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控&#xff1b;并对SQLserver、NoSQL(MongoDB)有了解 &#x1f496;如果觉得文章对你有所帮…

【C++算法】50.分治_归并_翻转对

文章目录 题目链接&#xff1a;题目描述&#xff1a;解法C 算法代码&#xff1a;图解 题目链接&#xff1a; 493. 翻转对 题目描述&#xff1a; 解法 分治 策略一&#xff1a;计算当前元素cur1后面&#xff0c;有多少元素的两倍比我cur1小&#xff08;降序&#xff09; 利用单…

深入讲解:智能合约中的读写方法

前言 在探秘区块链开发:智能合约在 DApp 中的地位及与传统开发差异一文中我提到对于智能合约中所有的写入其实都算是交易。而在一个完整的智能合约代码中最大的两个组成部分就是读取和写入。 本文将为你深入探讨该两者方法之间的区别。 写方法 写方法其实就是对区块链这一…

Go语言类型捕获及内存大小判断

代码如下&#xff1a; 类型捕获可使用&#xff1a;reflect.TypeOf()&#xff0c;fmt.Printf在的%T。 内存大小判断&#xff1a;len()&#xff0c;unsafe.Sizeof。 package mainimport ("fmt""unsafe""reflect" )func main(){var i , j 1, 2f…