MSP432 库函数实现 PID 电机调角度、调速

目录

  • 引脚配置
    • PWM引脚
    • 外部中断测量编码器引脚配置
  • 代码部分
    • 初始化
    • 编码器解读
      • Encoder.c
      • Encoder.h
    • 测速和控制部分
    • 卡尔曼滤波器,用于对所测速度进行滤波
      • kalman.c
      • kalman.h
  • 实验效果
    • 速度滤波效果
    • 控速效果
    • 控角效果

平台:Code Composer Studio 10.4.0
MSP432P401R SimpleLink™ 微控制器 LaunchPad™ 开发套件
(MSP-EXP432P401R)


编码器及所用改进型PID知识见【电赛PID半天入门】从接触编码器到调出好康的PID波形
工程示例

引脚配置

PWM引脚

在这里插入图片描述
在这里插入图片描述

外部中断测量编码器引脚配置

在这里插入图片描述
在这里插入图片描述

代码部分

初始化

/**  ======== mainThread ========*/
void *mainThread(void *arg0)
{My_Task_Init(Key_Task, 1, 1024);My_Task_Init(LED_Task, 1, 1024);GPIO_enableInt(Encoder_1A);GPIO_enableInt(Encoder_1B);My_Uart_Init(&huart1, USB_UART, 115200);My_PWM_Hz_Init(&hpwm1, PWM_1A, 1000);My_PWM_Hz_Init(&hpwm2, PWM_1B, 1000);My_Task_Init(Motor_1_Task, 2, 1024);while(1){usleep(1000);}
}

编码器解读

由于使用的是外部中断检测,该程序仅适用于13线的霍尔编码器电机,
不适用500线的光电编码器电机,实测光电编码器电机在占空比大于44%的时候会由于高强度进入中断使得控制线程不能正常控制电机。

Encoder.c

/** Encoder.c**  Created on: 2021年8月2日*      Author: Royic*/#include "./inc/Encoder.h"motor_type_def Motor_1;int32_t Encoder_1_Count = 0;const float Step_Angle = 360. / (Encoder_1_PPR * Encoder_1_Ratio * 2);void Encoder_1A_Func(void)
{if(GPIO_read(Encoder_1A)){if(GPIO_read(Encoder_1B))Motor_1.angle -= Step_Angle;elseMotor_1.angle += Step_Angle;}else{if(GPIO_read(Encoder_1B))Motor_1.angle += Step_Angle;elseMotor_1.angle -= Step_Angle;}
}void Encoder_1B_Func(void)
{if(GPIO_read(Encoder_1B)){if(GPIO_read(Encoder_1A))Motor_1.angle += Step_Angle;elseMotor_1.angle -= Step_Angle;}else{if(GPIO_read(Encoder_1A))Motor_1.angle -= Step_Angle;elseMotor_1.angle += Step_Angle;}
}void Motor_Get_Speed(motor_type_def *Motor, float Angle_Now, float Delta_S)
{Motor->angle = Angle_Now;Motor->speed = (Motor->angle - Motor->angle_old)/Delta_S;Motor->angle_old = Angle_Now;
}

Encoder.h

/** Encoder.h**  Created on: 2021年8月2日*      Author: Royic*/#ifndef INC_ENCODER_H_
#define INC_ENCODER_H_#include "./inc/main.h"#include <ti/drivers/GPIO.h>#define Encoder_1_PPR 	13
#define Encoder_1_Ratio 10typedef struct
{double angle;double angle_old;double speed;
} motor_type_def;void Motor_Get_Speed(motor_type_def *Motor, float Angle_Now, float Delta_S);extern int32_t Encoder_1_Count;
extern float Motor_1_Angle;
extern motor_type_def Motor_1;#endif

测速和控制部分

#define Motor_Angle_KP	0.5
#define Motor_Angle_KI	0.0025
#define Motor_Angle_KD	15#define Motor_Speed_KP	0.1
#define Motor_Speed_KI	0.001
#define Motor_Speed_KD	1uint8_t Angle_Or_Speed = 1;float Target_Angle = 0;
float Target_Speed = 0;pid_type_def Motor_Angle_PID;
pid_type_def Motor_Speed_PID;
const static fp32 motor_angle_pid[3]	= {Motor_Angle_KP, Motor_Angle_KI, Motor_Angle_KD};
const static fp32 motor_speed_pid[3]	= {Motor_Speed_KP, Motor_Speed_KI, Motor_Speed_KD};Kalman_Typedef Speed_Kalman;void *Motor_1_Task(void *arg0)
{float Control_Var = 0;PID_init(&Motor_Angle_PID, PID_POSITION, motor_angle_pid, 100, 100, 30, 2);PID_init(&Motor_Speed_PID, PID_POSITION, motor_speed_pid, 100, 100, 500, 0);Kalman_Init(&Speed_Kalman, 1e-6, 0.001);while(1){Motor_Get_Speed(&Motor_1, Motor_1.angle, 0.001);KalmanFilter(&Speed_Kalman, Motor_1.speed);if(Angle_Or_Speed){PID_calc(&Motor_Angle_PID, Motor_1.angle, Target_Angle);Control_Var = Motor_Angle_PID.out;}else{PID_calc(&Motor_Speed_PID, Speed_Kalman.out, Target_Speed);Control_Var = Motor_Speed_PID.out;}if(Control_Var > 0){My_PWM_setDuty(&hpwm1, Control_Var);My_PWM_setDuty(&hpwm2, 0);}else{My_PWM_setDuty(&hpwm1, 0);My_PWM_setDuty(&hpwm2, -Control_Var);}if(Angle_Or_Speed)UART_printf(huart1, "%d.%d, %d.%d\r\n", (int)Motor_1.angle, (int)(Motor_1.angle * 100) % 100 , (int)Target_Angle, (int)(Target_Angle * 100) % 100);elseUART_printf(huart1, "%d.%d, %d.%d, %d.%d\r\n", (int)Speed_Kalman.out, (int)(Speed_Kalman.out * 100) % 100 , (int)Target_Speed, (int)(Target_Speed * 100) % 100, (int)Motor_1.speed, (int)(Motor_1.speed * 100) % 100);usleep(1000);}
}

卡尔曼滤波器,用于对所测速度进行滤波

kalman.c

/*
卡尔曼滤波器
整理By 乙酸氧铍
*/
#include "kalman.h"double KalmanFilter(Kalman_Typedef *klm, double input)
{//预测协方差方程:k时刻系统估算协方差 = k-1时刻的系统协方差 + 过程噪声协方差klm->Now_P = klm->LastP + klm->Q;//卡尔曼增益方程:卡尔曼增益 = k时刻系统估算协方差 / (k时刻系统估算协方差 + 观测噪声协方差)klm->Kg = klm->Now_P / (klm->Now_P + klm->R);//更新最优值方程:k时刻状态变量的最优值 = 状态变量的预测值 + 卡尔曼增益 * (测量值 - 状态变量的预测值)klm->out = klm->out + klm->Kg * (input -klm->out);//因为这一次的预测值就是上一次的输出值//更新协方差方程: 本次的系统协方差赋给 klm->LastP 为下一次运算准备。klm->LastP = (1-klm->Kg) * klm->Now_P;return (klm->out);
}void Kalman_Init(Kalman_Typedef *klm, const double klm_Q, const double klm_R)//温度klm_Q=0.01 klm_R=0.25
{klm->LastP=0.02;		//上次估算协方差klm->Now_P=0;			//当前估算协方差klm->out=0;				//卡尔曼滤波器输出klm->Kg=0;				//卡尔曼增益klm->Q=klm_Q;			//Q:过程噪声协方差 Q参数调滤波后的曲线平滑程度,Q越小越平滑;klm->R=klm_R;			//R:观测噪声协方差 R参数调整滤波后的曲线与实测曲线的相近程度,R越小越接近(收敛越快)
}

kalman.h

#ifndef __KALMAN_H__
#define __KALMAN_H__typedef struct
{/*不用动*/double LastP;//上次估算协方差double Now_P;//当前估算协方差double out;//卡尔曼滤波器输出double Kg;//卡尔曼增益double Q;double R;
}Kalman_Typedef;void Kalman_Init(Kalman_Typedef *klm, const double klm_Q, const double klm_R);
double KalmanFilter(Kalman_Typedef *klm, double input);#endif

实验效果

速度滤波效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

控速效果

先加速再减速
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

控角效果

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

CSS基本知识点——带你走进CSS的新世界

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

JS 三级联动 下拉列表

<!-- 我的思路&#xff1a; 1.页面加载时便进入后台获得第一级的值&#xff1b; 2.当第一级的值改变时&#xff0c;清空第二级和第三级的值&#xff0c;并加载第二级的值 3.当第二级的值改变时&#xff0c;清空第三级的值&#xff0c;并加载第三级的值 --><table> …

20.网页卷去的距离与偏移量

我们先来看看下面的图&#xff1a; scrollLeft:设置或获取位于给定对象左边界与窗口中目前可见内容的最左端之间的距离 &#xff0c;即左边灰色的内容。 scrollTop:设置或获取位于对象最顶端与窗口中可见内容的最顶端之间的距离 &#xff0c;即上边灰色的内容。 offsetLeft:获取…

【电赛】一阶卡尔曼滤波器 滤波效果良好

目录代码kalman.ckalman.h滤波效果很久以前抄的&#xff0c;忘了是从哪弄的了 我把它改成了这种结构体指针传参的形式&#xff0c;方便在比赛中应用。应用举例见MSP432 PID 电机调角度、调速。 它曾助力笔者获2020年电赛省一等奖。 代码 Q:过程噪声协方差 Q参数调滤波后的曲线…

130. Surrounded Regions

题目&#xff1a; Given a 2D board containing X and O, capture all regions surrounded by X. A region is captured by flipping all Os into Xs in that surrounded region. For example, X X X X X O O X X X O X X O X XAfter running your function, the board should …

计算机是如何启动的?

从打开电源到开始操作&#xff0c;计算机的启动是一个非常复杂的过程。 我一直搞不清楚&#xff0c;这个过程到底是怎么回事&#xff0c;只看见屏幕快速滚动各种提示......这几天&#xff0c;我查了一些资料&#xff0c;试图搞懂它。下面就是我整理的笔记。 零、boot的含义 先问…

hdu 1536(博弈)

传送门&#xff1a;S-Nim 题意&#xff1a;给n个数的集合s&#xff0c; 再给m 组数据&#xff0c;每组表示 k 堆石子&#xff0c;每次可以取的个数只能是集合s中的数量。问先手胜还是输&#xff1f; 分析&#xff1a;sg函数的经典运用&#xff0c;先预处理出所有数量为0~10000的…

写了个 Markdown 命令行小工具,希望能提高园友们发文的效率!

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

MSP432P401R TI Drivers 库函数学习笔记(七)I2C驱动OLED屏幕

目录API (机翻)上机实战引脚配置I2C引脚配置工作指示灯LED1引脚配置文件结构I2C 初始化、读写函数myI2C.cmyI2C.hOLED初始化和测试代码main.cmain.hOLED 驱动程序OLED.cOLED.hOLED_Font.h任务管理myTask.cmyTask.h显示效果平台&#xff1a;Code Composer Studio 10.4.0 MSP432…

xcode5. 安装cocos2d-x 学习中。。。

xcode5. 安装cocos2d&#xff0d;x 学习中。。。 找了一些帖子 没搞出来&#xff0c;后来找到原因了 如今的cocos2d版本号在xcode.5上 没右模版了。用命令行 来运行。看了官方的文档。最终攻克了&#xff5e;&#xff5e;&#xff5e; 对于自己解决的问题都会感到点兴奋。。…

在WPF中实现玻璃模糊效果

在WPF中实现玻璃模糊效果还是比较简单的&#xff0c;主要方式如下&#xff1a; 添加一个Rectangle或其它控件作为玻璃放到顶部图层 将底部图像作为Brush&#xff08;大多数的时候用VisualBrush&#xff09;填充到Rectangle中 对该Rectangle添加高斯模糊效果 在该Rectangle上叠加…

【2013.4.6】微软暑期实习生答案(zz)

这套题难度评价&#xff1a;与去年相比技术上更多考得是语言细节而非算法&#xff0c;很多常规的智力题都是以前老题了&#xff0c;所以总体感觉难度不是很大&#xff0c;但是想拿高分也比较困难。最后吐槽下出题&#xff0c;居然有两道题不严谨&#xff0c;确实让很多同学在做…

【cartographer_ros】五: 发布和订阅陀螺仪Imu信息

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

css reset

最近在想把自己写的demo写成一个完整的项目&#xff0c;在写css reset的时候想参考别人的css reset是怎么来写的&#xff0c;也有想直接下载normalize.css这样的css reset直接用。但是看了张神写的对css reset的重新审视受益匪浅&#xff0c;文章发布的比较早原文地址http://ww…

MSP432P401R TI Drivers 库函数学习笔记(八)ADC

目录API (机翻)上机实战引脚配置ADC引脚配置串口引脚配置指示工作状态的LED1引脚配置代码部分ADC初始化和读取函数myADC.cmyADC.h获取数据并通过串口发送main.cmain.h任务管理函数myTask.cmyTask.h串口代码myUart.cmyUart.h实验结果平台&#xff1a;Code Composer Studio 10.4.…

PHP 杂谈《重构-改善既有代码的设计》之三 重新组织数据

介绍承接上文的PHP 杂谈《重构-改善既有代码的设计》之 重新组织你的函数继续重构方面的内容。这章主要针对数据的重构。1、争论的声音——直接访问Field还是通过函数&#xff08;Accessor&#xff09;访问Field2.修改Array为Object&#xff1a;当你看到一个Array很像一个数据结…

轻松获取LAMP环境的配置参数

大家是否遇到过去了新公司&#xff0c;公司内的LAMP&#xff0c;LNMP等所有的环境都是配置好的&#xff08;已经在提供服务了&#xff09;&#xff0c;公司又没有留下部署文档&#xff0c;甚至安装LAMP&#xff0c;LAMP等环境的人已经和你交接完离职了&#xff0c;那么线上服务…

Python迷宫生成器

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

数组的操作

有关操作数组的方法(函数): (常用)push() 从尾部添加新元素 操作的是原数组 pop() 从尾部删除一个元素 unshift() 从开头添加元素 shift() 从开头删除元素 slice(start, end) 获取数组中某些元素&#xff0c;返回一个新数组&#xff1b;从start下标位置起开始截取到end下标(不…

MSP430F5529 DriverLib 库函数I2C驱动OLED屏幕

目录I2C驱动代码MSP430F5529_I2C.cMSP430F5529_I2C.hOLED初始化及测试OLED驱动代码OLED.cOLED.hOLED_Font.h显示效果平台&#xff1a;Code Composer Studio 10.4.0 MSP430F5529 LaunchPad™ Development Kit (MSP‑EXP430F5529LP) I2C驱动代码 P3.0为SDA&#xff0c;P3.1为S…