分销网站,广告喷绘机器多少钱一台,宝安中心医院体检,网站功能模块什么意思说明#xff1a;本文章适用于STM32初学者#xff0c;想完成一个好玩且有深度的项目但不知道从何下手的同学。
任务需求
我们要做一个东西必须要清楚我们的目的是什么#xff1f;这个东西要干什么#xff0c;有什么作用#xff0c;最终我们理想的效果是什么#xff1f;在…说明本文章适用于STM32初学者想完成一个好玩且有深度的项目但不知道从何下手的同学。
任务需求
我们要做一个东西必须要清楚我们的目的是什么这个东西要干什么有什么作用最终我们理想的效果是什么在此我罗列一下我们做出来的风力摆所应达到的效果需求.如下所示
一长约 60cm~70cm 的细管上端用万向节固定在支架上下方悬挂一组2~4 只直流风机构成一风力摆如图1 所示。风力摆上安装一向下的激光笔静止时激光笔的下端距地面不超过 20cm。设计一测控系统控制驱动各风机使风力摆按照一定规律运动激光笔在地面画出要求的轨迹。 1 从静止开始15s 内控制风力摆做类似自由摆运动使激光笔稳定地在地面画出一条长度不短于 50cm 的直线段其线性度偏差不大于±2.5cm并且具有较好的重复性
2 从静止开始15s 内完成幅度可控的摆动画出长度在30~60cm 间可设置长度偏差不大于±2.5cm 的直线段并且具有较好的重复性
3 可设定摆动方向风力摆从静止开始15s 内按照设置的方向角度摆动画出不短于20cm 的直线段
4 将风力摆拉起一定角度30°~45°放开5s 内使风力摆制动达到静止状态。
5 以风力摆静止时激光笔的光点为圆心驱动风力摆用激光笔在地面画圆30s 内需重复3 次圆半径可在15~35cm 范围内设置激光笔画出的轨迹应落在指定半径±2.5cm 的圆环内
6 在要求5后继续作圆周运动在距离风力摆 1~2m 距离内用一台 50~60W 台扇在水平方向吹向风力摆台扇吹 5s 后停止风力摆能够在5s 内恢复5规定的圆周运动激光笔画出符合要求的轨迹
任务分析
风力摆是通过六轴传感器MPU6050检测平台的水平角度进行反馈 控制四个 8520 空心杯电机的转动带动螺旋桨转动实现激光点按照特定 轨迹运动的机构。那么让他怎么摆呢我们必须需要一个陀螺仪去测量我们的速度信息角度角速度角加速度对这些速度信息进行处理然后送入我们的PID控制进行姿态的控制。 并且为避免硬件部分导致的效果不好尽量避免在整个摆杆的外部有很多线去拉扯。所以我们制作PCB并且电池装在摆杆上仅需要两根电源线即可。一体化设计尽可能的做到轻量化小巧而精致
材料基础部分 MPU6050陀螺仪获取风力摆姿态信息。 HC-05蓝牙模块无线切换风力摆运动状态。 空心杯电机体积小功率大抗干扰较强 电机驱动(SI2302):驱动空心杯电机*4 点状激光头
硬件说明
点状激光头 –固定在底部主控板上
MPU6050 陀螺仪模块-焊接在中间板上
四个电机ABCD对应固定在主控板上 电机两个正转两个反转分别对应 X、Y 的/-两个方向螺旋桨两正两反在这里螺旋桨做推力方向如果上电没有推力可以将扇叶反着安装即可这样可以良好的避免异常情况下的射桨等极端情况。
MOSSI2302原理图 MPU6050陀螺仪原理图
PCB 效果图
模块使用方法
HC-05蓝牙模块 使用前要先在AT模式进行配置。配置蓝牙名称、密码、波特率、主从机等AT指令蓝牙模块指示灯快闪是普通模式慢闪是进入AT模式。 我们拿到蓝牙模块后 1通过杜邦线将蓝牙模块的VCC,GND,TX,RX分别接入USB TO TTL模块串口的VCC,GND,RX,TX引脚。
(2)打开串口上位机软件本人使用的是正点原子配套的XCOM,先按住蓝牙模块上的黑色按键在上电我们可以看到蓝牙模块上的指示灯开始慢闪这样我们就进入了AT模式。❗❗❗注意以这种方式进入AT模式我们在串口上位机中波特率要设置为38400才能保持正常通信。 3在上位机中发送AT注意要以回车结尾若收到OK说明通信成功之后就可以设置其他内容了。我们可以查询手册去发送相关指令我只提咱们常用的几个指令以下若配置成功则返回OK 设置/查询设备名称
ATNAME Beijing\r\n ——设置模块设备名为“Beijing” ATNAME?\r\n ——查询模块设备名 设置/查询-配对码 ATPSWDParam\r\n Param配对码自己随意设置 AT PSWD\r\n 默认值1234 设置/查询-串口参数 设置串口波特率1152002 位停止位Even 校验 ATUART1152001,2,\r\n AT UART——查询波特率
4设置波特率为115200密码名称随便设随自己心意这样我们就配置好了到时候接单片机串口通信的管脚就好随程序而定 MPU6050陀螺仪
原理大家有兴趣的可以百度我就不在此赘述。 简言之这个模块自带DMP可以解算出欧拉角MPU6050得出来的姿态角有三种PITCH俯仰角、ROLL横滚角、YAW航向角。我们安装时要平放着放在车上。那么我们的车要立起来要么是俯仰角要么是横滚角航向角是Z轴上的我们暂时不用。 SCL和SDA是连接MCU的IIC接口MCU通过这个IIC接口来控制MPU6050,INT是中断触发接口陀螺仪每成功捕捉到一次数据INT引脚的电平就会拉低触发外部中断。如果接GND则MPU6050的IIC地址是:0X68如果接VDD则是0X69我们默认接地。 我们所用到的管脚 VCC,GND,SCL,SDA,AD0,INT关键 ❗❗❗陀螺仪要水平放置不然可能会自检过不了从而无法使用。
原理分析理清思路
风力摆我们可以理想化的看成一根长杆做单摆运动而我们学过大学物理可以建立相应的物理模型单摆运动模型 我们以只有一个方向摆动即x轴为例列出理想化的单摆模型 其中f(x)表示位移、A 表示振幅、 表示角速度、φ 表示相位周期 T 与 之间的关系为T2π/w
根据公式我们可以估算出单摆运动的周期
取 L(摆杆长度)为1m g重力加速度我们取 10m/s² 那么T2*3.14 * (1/10)½1.98s
我们可以取极限L0.3或L2得到大家的周期的取值范围有 T1.09 ~2.81s然后我们就可以实测然后我们就可以根据单摆周期的实验法去测得我们的周期这里我们测量的是十次单摆周期秒表计时为 11.5s。
对于f(x) A* sin(ωt φ) A振幅是我们需要设定的摆动幅度 φ相位在这里可以理解为开始时对应的位移我们设为 0 ω2π/T (已知常数) t自变量u32 TimeCnt;//运动时间计数器 在 5ms 定时器中断中 TimeCnt5 显然公式可化为 显然我们采用的方法是将连续的函数用离散值去代替类似于积分的思想将一个完整周期分成一个个很短的时间而我们这一个个很短的时间就使用我们MCU的计时器来完成我们设定一个5ms的外部中断 每触发一次中断TimeCnt5这里的TimeCnt就代表运动的时间而每5ms取的这些点映射到2π的周期上就记录对应点位移随着时间在 A 范围内正弦函数周期性变化情况从而控制风力摆在X轴摆动的位移。其他方向类比即可而方向的调整可利用xy方向振幅的变化来改变摆动的角度以及xy方向相差的相位即可改变摆动的图案。 风力摆实际位移 离地高度 float Height675单位 mm 角度由陀螺仪模块反馈获得X 方向为 RollY 方向为 Pitch 激光点位置 float Measure_X可以通过测得的角度三角转换得出 测量值Measure_Xtan(Roll)* Height; 加入初始值、弧度单位换算即 Measure_X(float)tan((Roll-ZHONGZHI_B)/1802PI)*Height;
风力摆理论位移 我们要控制激光点的位置满足单摆运动因此有目标值 Target_X Alpha(float)TimeCnt/Period2PI; //PIπ Target_XAmplitude_xsin(Alpha); //X 方向目标值函数 PID 公式 pwmKpe(k)Ki*∑e(k)Kd[ek-e(k-1)] 我们就可以通过控制 Amplitude_x 来控制摆动的幅度
之后将实际与理论值装载入PID闭环中完成风力摆的控制。
李萨如图形
定义李萨如图形由在互相垂直的方向上的两个频率成简单整数比的简谐振动所合成的规则的、稳定的闭合曲线 要点互相垂直 · 简谐运动 · 频率成整数比 风力摆系统满足要求我们来看下李萨如图形的数学定义
其中 n≥1 且 0≤φ≤π/2 , 设 nq/p; n 称为曲线的参数是两个正弦振动的频率比; 当风力摆同时参与两个互相垂直方向上的简谐运动风力摆的位移是这两个振动的矢量和 又有李萨如图形特殊情形 若 abn1则曲线是椭圆 若 φπ/2 则这椭圆其实是圆 若 φ0 则这椭圆其实是线段
则可以引出我们的PID控制系统入口参数就是风力摆理论上在X/Y方向对应的位移及实际上在X/Y方向的位移。我们只要将X、Y对应方向上的位移用代码表示出来传入PID控制系统即可。我们只需要通过蓝牙去控制振幅比例相位差即可实现直线画圆甚至任意图案。
PID框架搭建
函数功能位置式PID控制器 入口参数风力摆实际位移目标位移 返回值电机PWM 根据位置式离散PID公式 pwmKpe(k)Ki∑e(k)Kd[ek-e(k-1)] e(k)代表本次偏差 e(k-1)代表上一次的偏差 ∑e(k)代表e(k)以及之前的偏差的累积和;其中k为1,2,k; pwm代表输出
int Position_PID_X (float value,float Target)
{ static float Bias,Pwm,Integral_bias,Last_Bias;Biasvalue-Target; //计算偏差Integral_biasBias; //求出偏差的积分PwmPosition_KP*Bias //PID控制器比例项Position_KI*Integral_bias //PID控制器积分项Position_KD*(Bias-Last_Bias); //PID控制器微分项 Last_BiasBias; //保存上一次偏差 return Pwm; //增量输出
}int Position_PID_Y (float value,float Target)
{ static float Bias,Pwm,Integral_bias,Last_Bias;Biasvalue-Target; //计算偏差Integral_biasBias; //求出偏差的积分PwmPosition_Kp*Bias //PID控制器比例项Position_Ki*Integral_bias //PID控制器积分项Position_Kd*(Bias-Last_Bias); //PID控制器微分项 Last_BiasBias; //保存上一次偏差 return Pwm; //增量输出
}
Measure_X(float)tan((Roll-ZHONGZHI_B)/1802PI)Height; Target_XAmplitude_xsin(Alpha); //X 方向目标值函数
则PID运算的函数为 int Position_PID_X (Measure_X,Target_X) Y方向同理。
系统初始参数
中断函数编写
我们采用外部中断即通过陀螺仪的INT引脚进行中断的触发不清楚的朋友可以去看我关于平衡车的文章陀螺仪每成功采样一次数据即触发一次中断相应 TimeCnt5将数据压入PID控制器后PID返回的PWM值加载到电机上。
void EXTI9_5_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line5)!0)//一级判定{if(PBin(5)0)//二级判定{EXTI_ClearITPendingBit(EXTI_Line5);//清除中断标志位//1.采集编码器数据MPU6050角度信息。mpu_dmp_get_data(Pitch,Roll,Yaw); //角度MPU_Get_Gyroscope(gyrox,gyroy,gyroz); //陀螺仪MPU_Get_Accelerometer(aacx,aacy,aacz); //加速度TimeCnt5; //运行时间定时器 //2.将数据压入闭环控制中计算出控制输出量。Get_RC();Alpha(float)TimeCnt/Period*2*PI; //float不可省略单摆周期处理成三角函数2π周期Target_XAmplitude_x*sin(Alpha); //X方向目标值函数Target_YAmplitude_y*sin(AlphaPhase); //Y方向目标值函数Measure_X(float)tan((Roll-ZHONGZHI_B)/180*2*PI)*Height;Measure_Y(float)tan((Pitch-ZHONGZHI_A)/180*2*PI)*Height;Motor_XPosition_PID_X(Measure_X,Target_X);Motor_YPosition_PID_Y(Measure_Y ,Target_Y);Xianfu_Pwm(5800);//限幅5800满占空比5800避免出现异常 if(Turn_Off()0) Set_Pwm(Motor_X,Motor_Y);}}
}限幅函数
void Xianfu_Pwm(int amplitude)
{ if(Motor_X-amplitude) Motor_X-amplitude; if(Motor_Xamplitude) Motor_Xamplitude; if(Motor_Y-amplitude) Motor_Y-amplitude; if(Motor_Yamplitude) Motor_Yamplitude;
}赋值函数
void Set_Pwm(int Motor_X,int Motor_Y)
{if(Motor_X0) PWMA10,PWMC1Motor_X;else PWMA1-Motor_X,PWMC10;if(Motor_Y0) PWMB10,PWMD1Motor_Y;else PWMB1-Motor_Y,PWMD10;}
蓝牙串口指令
void Get_RC(void)
{float Xishu1.4142; //系统设定振幅与圆周运动时半径R相差√2倍static int flag_mode;flag_modeDebug_key; //通过调试界面下方的按键控制运动方式0失能,1直线,2圆周,3稳态if(flag_mode1) //摆动模式{Flag_Stop0; //开启输出Data_AmplitudeBasic_Amplitude;//初始振幅Data_Phase0; //直线运动相位差为0
// PeriodData_Period;//周期避免异常周期一般不做修改测试好后做全局变量宏定义switch(Flag_Direction)//方向按钮控制振幅比例系数(tan(Data_Period))重力、摇杆、按键三种控制模式不做区分{case 1: Data_Gama0; break;case 2: Data_GamaPI/4; break;case 3: Data_GamaPI/2; break;case 4: Data_Gama3*PI/4; break;case 5: Data_Gama-PI/3; break;case 6: Data_Gama-2*PI/3; break;case 7: Data_Gama-5*PI/6; break;case 8: Data_Gama-PI/6; break;case 0: Data_Gama0; break;}}else if(flag_mode2) //圆周模式{Flag_Stop0; //开启输出Data_AmplitudeBasic_Amplitude;//初始振幅Data_GamaPI/4; //振幅比例系数(tan(PI/4)1)
// PeriodData_Period;//周期避免异常周期一般不做修改测试好后做全局变量宏定义switch(Flag_gear) //高低速挡位控制相位差控制旋转方向{case 1: Data_PhasePI/2; break;case 2: Data_Phase3*PI/2; break;default: Data_PhasePI/2; break;}}else if(flag_mode3) //稳定模式{Flag_Stop0; //开启输出Data_Amplitude0; //振幅为0维持稳定Data_GamaPI/4; //振幅比例系数(tan(PI/4)1)Phase0; //相位差为0
// PeriodData_Period;//周期避免异常周期一般不做修改测试好后做全局变量宏定义}else if(flag_mode0) //自由模式{Flag_Stop1; //关闭输出Data_Amplitude0; //振幅为0维持稳定Data_GamaPI/4; //振幅比例系数(tan(PI/4)1)Phase0; //相位差为0
// PeriodData_Period;//周期避免异常周期一般不做修改测试好后做全局变量宏定义}
/********根据模式对应的数据计算得到所需要的参数振幅、振幅比例系数、相位差**********/Amplitude_xData_Amplitude*sin(Data_Gama)*Xishu;//振幅XAmplitude_yData_Amplitude*cos(Data_Gama)*Xishu;//振幅YPhaseData_Phase; //相位差
// PeriodData_Period;//周期避免异常周期一般不做修改测试好后做全局变量宏定义}其中 Data_Amplitude Data_Gama Data_Phase
题目要求中的自稳我们可直接将振幅设置为0即可 要求画圆我们就调整相位差即可。 这三个参数是我们蓝牙模式需要调整的参数大家使用自己习惯的蓝牙控制指令去修改即可。
蓝牙串口USART
u8 flag_mode;
void USART3_IRQHandler(void)
{int Bluetooth_data;if(USART_GetITStatus(USART3,USART_IT_RXNE)!RESET)//接收中断标志位拉高{Bluetooth_dataUSART_ReceiveData(USART3);//保存接收的数据//*************************调试界面下方按键*************************************//if(Bluetooth_data97Bluetooth_data105) //键值a-i 模式调节{switch(Bluetooth_data){case 0x61: Debug_key1; break; //指令a直线模式(修改振幅可修改角度振幅A/Btan(a))case 0x62: Debug_key2; break; //指令b圆周模式case 0x63: Debug_key3; break; //指令c稳态模式case 0x64: Debug_key4; break; //指令d默认状态电机失能case 0x65: Debug_key0; break; //指令e默认状态电机失能case 0x66: Debug_key0; break; //指令f默认状态电机失能case 0x67: Debug_key7; break; //指令g默认状态电机失能case 0x68: Basic_Amplitude-10; break; //指令h默认状态case 0x69: Basic_Amplitude10; break; //指令i默认状态电机失能}} //*************************直线方向调节*************************************//if((Bluetooth_data65Bluetooth_data72)||(Bluetooth_data90)) {switch(Bluetooth_data){case 0x41: Flag_Direction1; break; //指令A向前case 0x42: Flag_Direction2; break; //指令B右前case 0x43: Flag_Direction3; break; //指令C向右case 0x44: Flag_Direction4; break; //指令D右后case 0x45: Flag_Direction5; break; //指令E向后case 0x46: Flag_Direction6; break; //指令F左后case 0x47: Flag_Direction7; break; //指令G向左case 0x48: Flag_Direction8; break; //指令H左前default: Flag_Direction0; break; //指令Z停止}}
//****************************高低速档位*************************************************//if(Bluetooth_data88Bluetooth_data89) {switch(Bluetooth_data){case 0x58: Flag_gear1; break; //指令X高速档case 0x59: Flag_gear2; break; //指令Y低速档}}}}我这里将平衡小车之家蓝牙APP指令代码作为举例供大家参考。大家可以多尝试去设置不同的值观察风力摆摆出的图案加强学习加强理解。
PID调参
对于一个控制系统我们期望的响应结果是稳系统稳定不震荡不发散、快系统响应快速、准系统静态误差小。对PID控制器的调节结果评价也是如此。 PID系数的作用
比例系数Kp
三个参数中的绝对主力不可或缺。Kp增大可以加快系统响应减小静差但系统超调量会加大稳定性变差。比例控制是一种立即控制只要有偏差就立即输出控制量。大部分系统只需要P控制即可实现基本的稳快准需求。
积分系数Ki
三个参数中的一般主力用于消除静差、Ki减小可以降低超调量使系统的稳定性增强。积分控制是一种修复控制只要有偏差就会逐渐去往消除偏差的方向去控制。
微分系数Kd
三个参数中的预备人员一般不用在反馈量噪声比较大时可能会使系统震荡。Kd增大可以加快系统响应减小超调量适用于迟滞系统或无阻尼系统。微分控制是一种提前控制以偏差的变化率为基准进行控制。
在风力摆系统中我们需要风力摆有非常高的跟随性也就是单摆的位移图像能够尽可能的和我们理论的sin图像重合。所以很简单我们只需要尽可能的加大D微分项即可微分控制是一种提前控制以偏差的变化率为基准进行控制。我们要有良好的跟随性所以D一定要很大。所以像风力摆这种需要跟随性的系统我们通常采用PD控制器。我们的系统PWM限幅是5800所以我们可以取D项为1500而P只需要一点点即可我们设置为10积分项我们这里不需要可以根据自己的硬件实际情况去修改PID的值只要保证D项非常大即可大家可以试出一个理想的参数。
总结
风力摆模型实际上就是一个物理中的单摆模型我们在分析问题时要思考如何将一个物理模型用代码去表示出来并且寻找到需要压入PID控制的真正参数。在这里我们实际稳定的是位移。我们可能会找成角度但是静下心来想一想角度的稳定是很困难的。我们必须知道这道题真正的其实是李萨如图形运动的合成。这样才能实现画出各种各样的图案。这道题其实和平衡车很像用到的代码模块基本都是一样的唯一就是PID的代码需要改变。但换汤不换药只要我们能熟悉PID的编写把每个模块都调熟相信一定会学到很多东西也肯定能够在之后的电赛中取得很好的成绩。本人通过平衡小车之家的代码例程学习而来给大家作出分享。
如果觉得对你有帮助的话欢迎一键三连哦❤️