赞
踩
L298N是一个常用的双H桥电机驱动器模块,用于控制直流电机或步进电机的方向和速度。它适用于许多电机控制应用,如机器人、小车、舵机等。
l298n的使用方法有好几种,我所使用的是最简单的一种,使用方法如下:
输出A: 通道A输出 ,连接1电机的正负
输出B: 通道B输出 ,连接2电机正反
12V供电: 主电源正极输入
供电GND: 主电源正负极极输入
5V输出: 5v电压输出端,可用于给MCU单片机供电
ENA: 通道A使能 (插上跳线帽)
ENB: 通道B使能 (插上跳线帽)
IN1~IN4: 逻辑输入IN1 ~ IN2控制通道A,逻辑输入IN3~IN4控制通道B(分别接入4路PWM)
板载5V跳线帽: 接上后板载5V输出有效
MPU6050是一款常用的六轴陀螺仪和加速度计传感器模块,广泛用于嵌入式系统、机器人、飞行器、运动控制等应用。它集成了三轴陀螺仪和三轴加速度计,能够提供精确的姿态和运动数据,通常称为六轴运动陀螺仪。
陀螺仪的三个角度:
Pitch:俯仰角(抬头低头)
Roll:滚转角(翻身)
Yaw:偏航角(转弯)
MPU6050是使用IIC通信协议与单片机进行通信,以此来获取陀螺仪的角度和角加速度数据。
VCC:电源正
GND:地
SCL: I2C串行时 钟线/SPI串行时钟端口
SDA: I2C串行 数据线/SPI串行数据输入
XDA:连接其他I2C设备的主机数据口(不需要接单片机)
XCL:给I2C设备提供主时钟(不需要接单片机)
ADO:I2C器件地址选择位,地址管脚(不需要接单片机)
INT:中断引脚(接单片机的引脚组成外部中断或者不接使用其他中断)
- // MPU6050 IIC PB8 PB9
- //初始化
- void IIC_Init(void)
- {
-
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9; //端口配置
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M
- GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB
-
- }
-
-
- //获取mpu6050角度值
- void Get_Angle(void)
- {
- Read_DMP(); //===读取加速度、角速度、倾角
- Angle_Balance=Pitch; //===更新平衡倾角
- Angle_Turn=Yaw;
- Gyro_Balance=gyro[1]; //===更新平衡角速度
- Gyro_Turn=gyro[2]; //更新转向角速度
-
- Acceleration_Z=accel[2]; //===更新Z轴加速度计
- Gyro_Z=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_ZOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_ZOUT_L); //读取Z轴陀螺仪
- }
霍尔编码电机是一种具有霍尔传感器的电机,通常用于测量电机的转速和位置。霍尔传感器是一种用于检测磁场的传感器,可以用来测量电机转子的位置和速度。这种编码方式常用于电机控制和位置反馈系统中。
原理:霍尔编码电机通常集成了霍尔传感器,这些传感器可以检测电机的转子上的永磁磁极。通过检测磁场的变化,霍尔传感器可以确定电机转子的位置和速度。
位置反馈:霍尔编码电机提供了位置反馈,可以告诉你电机的当前位置。这对于需要精确控制电机的应用非常重要,如机器人、CNC机床和自动化系统。
速度反馈:除了位置反馈,霍尔编码电机还可以提供速度反馈。通过测量位置变化的速度,你可以获得电机的实时速度信息。
闭环控制:霍尔编码电机通常与闭环控制系统一起使用。闭环控制可以根据实际的位置和速度反馈调整电机的控制信号,以实现精确的位置和速度控制。
编码方式:霍尔编码电机通常使用不同的霍尔编码方式,如单通道霍尔编码、双通道霍尔编码和四通道霍尔编码。这些编码方式提供不同的精度和分辨率。
应用:霍尔编码电机广泛用于需要精确控制的应用,包括工业自动化、机器人、医疗设备、自动门、摄像机云台等
引脚说明:
1、M1电机动力线1 ( 12V)(接l298n的输出端)
2、GND编码器电源-
3、C1编码器A相(接单片机定时器捕获引脚)
4、C2编码器B相(接单片机定时器捕获引脚)
5、3V3编码器电源+ ( 5V)
6、M2电机动力线2 ( 12V )(接l298n的输出端)
- #include "encoder.h"
- #include "stm32f10x_gpio.h"
-
- //TIM3 CH1 PA6
- //TIM3 CH2 PA7
- void Encoder_Init_TIM3(void)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_ICInitTypeDef TIM_ICInitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//使能定时器4的时钟
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PB端口时钟
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //端口配置
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
- GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOB
-
- TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
- TIM_TimeBaseStructure.TIM_Prescaler = 0x00; // 预分频器
- TIM_TimeBaseStructure.TIM_Period = 65535; //设定计数器自动重装值
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM向上计数
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
- TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3
- TIM_ICStructInit(&TIM_ICInitStructure);
- TIM_ICInitStructure.TIM_ICFilter = 10;
- TIM_ICInit(TIM3, &TIM_ICInitStructure);
- TIM_ClearFlag(TIM3, TIM_FLAG_Update);//清除TIM的更新标志位
- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
- //Reset counter
- TIM_SetCounter(TIM3,0);
- TIM_Cmd(TIM3, ENABLE);
- }
-
- //TIM4 CH1 PB6
- //TIM4 CH2 PB7
-
- void Encoder_Init_TIM4(void)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_ICInitTypeDef TIM_ICInitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//使能定时器4的时钟
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能PB端口时钟
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //端口配置
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
- GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB
-
- TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
- TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器
- TIM_TimeBaseStructure.TIM_Period = 65535; //设定计数器自动重装值
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM向上计数
- TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
- TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3
- TIM_ICStructInit(&TIM_ICInitStructure);
- TIM_ICInitStructure.TIM_ICFilter = 10;
- TIM_ICInit(TIM4, &TIM_ICInitStructure);
- TIM_ClearFlag(TIM4, TIM_FLAG_Update);//清除TIM的更新标志位
- TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
- //Reset counter
- TIM_SetCounter(TIM4,0);
- TIM_Cmd(TIM4, ENABLE);
- }
-
-
-
- int Read_Encoder(u8 TIMX)
- {
- int Encoder_TIM;
- switch(TIMX)
- {
- case 3: Encoder_TIM= (short)TIM3 -> CNT; TIM3 -> CNT=0;break;
- case 4: Encoder_TIM= (short)TIM4 -> CNT; TIM4 -> CNT=0;break;
- default: Encoder_TIM=0;
- }
- return Encoder_TIM;
- }
-
-
-
- void TIM4_IRQHandler(void)
- {
- if(TIM4->SR&0X0001)//溢出中断
- {
- }
- TIM4->SR&=~(1<<0);//清除中断标志位
- }
-
-
- void TIM3_IRQHandler(void)
- {
- if(TIM3->SR&0X0001)//溢出中断
- {
- }
- TIM3->SR&=~(1<<0);//清除中断标志位
- }
-
-
- #include "motor.h"
- // TIM5 PA2 PA3
- // TIM8 PC6 PC7
-
- void TIM5_PWM_Init(u16 arr,u16 psc){
-
- GPIO_InitTypeDef GPIO_InitStructure;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_OCInitTypeDef TIM_OCInitStructure;
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3; //TIM5_CH3 //TIM_CH4
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- TIM_TimeBaseStructure.TIM_Period=arr;
- TIM_TimeBaseStructure.TIM_Prescaler=psc;
- TIM_TimeBaseStructure.TIM_ClockDivision=0;
- TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
-
- TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
-
- TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
- TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
- TIM_OCInitStructure.TIM_Pulse=0;
- TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
-
- TIM_OC3Init(TIM5, &TIM_OCInitStructure);
- TIM_OC4Init(TIM5, &TIM_OCInitStructure);
-
- TIM_CtrlPWMOutputs(TIM5,ENABLE); //MOE 主输出使能
-
- TIM_OC3PreloadConfig(TIM5, TIM_OCPreload_Enable); //CH3预装载使能
- TIM_OC4PreloadConfig(TIM5, TIM_OCPreload_Enable); //CH4预装载使能
-
- TIM_ARRPreloadConfig(TIM5, ENABLE); //使能TIM5在ARR上的预装载寄存器
-
- TIM_Cmd(TIM5, ENABLE); //使能TIM5
-
- }
- void TIM8_PWM_Init(u16 arr,u16 psc){
-
- GPIO_InitTypeDef GPIO_InitStructure;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_OCInitTypeDef TIM_OCInitstruct;
-
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM8 ,ENABLE);
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE); //时钟使能
-
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6 | GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
-
- GPIO_Init(GPIOC,&GPIO_InitStructure);
-
- TIM_TimeBaseStructure.TIM_Period = arr;
- TIM_TimeBaseStructure.TIM_Prescaler =psc;
- TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
-
- TIM_OCInitstruct.TIM_OCMode=TIM_OCMode_PWM1;
- TIM_OCInitstruct.TIM_OCNPolarity=TIM_OCNPolarity_High;
- TIM_OCInitstruct.TIM_OCPolarity=TIM_OCPolarity_High;
- TIM_OCInitstruct.TIM_OutputState=TIM_OutputState_Enable;
- TIM_OCInitstruct.TIM_OCIdleState = TIM_OCIdleState_Set;
- TIM_OCInitstruct.TIM_OCNIdleState=TIM_OCNIdleState_Reset;
-
- TIM_OC1Init(TIM8,&TIM_OCInitstruct);
- TIM_OC2Init(TIM8,&TIM_OCInitstruct);
-
- TIM_OC1PreloadConfig(TIM8,TIM_OCPreload_Enable);
- TIM_OC2PreloadConfig(TIM8,TIM_OCPreload_Enable);
-
- TIM_CtrlPWMOutputs(TIM8,ENABLE); //MOE 主输出使能
-
- TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIM3在ARR上的预装载寄存器
-
- TIM_Cmd(TIM8, ENABLE); //使能TIM3
- TIM_CtrlPWMOutputs(TIM8, ENABLE);// 主输出使能,当使用的是通用定时器时,这句不需要 s
-
- }
0.96寸OLED(Organic Light Emitting Diode)显示屏是一种小尺寸的有机发光二极管显示屏,通常用于嵌入式系统、小型电子设备和Arduino项目中。它提供了高亮度、高对比度、低功耗以及较宽的视角,非常适合小型信息显示和用户界面设计。
OLED通常有2种,第一种是IIC通讯,第二种是SPI通讯。IIC协议更加简单,使用起来方便,但是性能没有SPI强,但是在OLED上使用IIC是完全足够了。这里就不详细讲解IIC和SPI的区别了,有兴趣的同学可以去下面的网站看看大佬写的文章。
平衡车使用OLED的主要目的是用来观察一下数据,比如:编码器的数据、陀螺仪角度数据、使用按键调PID参数时的参数数据等等。
- //初始化OLED
- void OLED_Init(void)
- {
-
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE ); //使能GPIOC时钟
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_11;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- GPIO_SetBits(GPIOC,GPIO_Pin_12|GPIO_Pin_11);
-
- delay_ms(200);
-
- OLED_WR_Byte(0xAE,OLED_CMD);//--display off
- OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
- OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
- OLED_WR_Byte(0x40,OLED_CMD);//--set start line address
- OLED_WR_Byte(0xB0,OLED_CMD);//--set page address
- OLED_WR_Byte(0x81,OLED_CMD); // contract control
- OLED_WR_Byte(0xFF,OLED_CMD);//--128
- OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap
- OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse
- OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
- OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
- OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction
- OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset
- OLED_WR_Byte(0x00,OLED_CMD);//
-
- OLED_WR_Byte(0xD5,OLED_CMD);//set osc division
- OLED_WR_Byte(0x80,OLED_CMD);//
-
- OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
- OLED_WR_Byte(0x05,OLED_CMD);//
-
- OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period
- OLED_WR_Byte(0xF1,OLED_CMD);//
-
- OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
- OLED_WR_Byte(0x12,OLED_CMD);//
-
- OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh
- OLED_WR_Byte(0x30,OLED_CMD);//
-
- OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable
- OLED_WR_Byte(0x14,OLED_CMD);//
-
- OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
- }
-
HC-06是一种常见的蓝牙串口模块,通常被用于将串口设备(如Arduino或其他微控制器)与蓝牙无线通信连接起来。以下是一些关于HC-06蓝牙模块的重要信息:
功能:HC-06蓝牙模块是一个串口蓝牙模块,可通过UART串口与其他设备通信。它可以用作透明串口传输,将串口数据通过蓝牙连接传输到其他设备,也可以用于构建蓝牙串口通信的应用程序。
通信距离:通常,HC-06模块的通信距离在10米左右,但这取决于环境条件和障碍物。
配对:HC-06通常以主从设备的方式工作,其中一个设备(通常是手机或电脑)充当主机,而HC-06模块充当从设备。在首次使用时,通常需要将HC-06模块与主机设备进行蓝牙配对。
配置:HC-06模块通常有一个AT命令模式,您可以使用这些命令来配置模块的参数,如蓝牙名称、波特率等。要进入AT命令模式,通常需要将模块上的特定引脚连接到地,并重启模块。
电源:HC-06通常需要3.3V或5V电源供电,具体的电源要求可以查看模块的规格。
应用:HC-06模块广泛用于各种项目,例如蓝牙遥控器、传感器数据传输、蓝牙串口通信等。它是一个经济实惠的解决方案,用于在项目中添加蓝牙功能。
注意事项:使用HC-06模块时需要小心处理电源和引脚连接,以免损坏模块。还需要注意模块的默认配置,例如波特率和配对密码。
- #include "hc06.h"
-
-
- u8 res; //设置全局变量
- void HC06_Init(u16 arr)
- {
- GPIO_InitTypeDef GPIO_InitStrue;
- USART_InitTypeDef USART_InitStrue;
- NVIC_InitTypeDef NVIC_InitStrue;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //GPIO端口使能
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //串口端口使能
-
- GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;
- GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;
- GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;
- GPIO_Init(GPIOB,&GPIO_InitStrue);
-
- GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;
- GPIO_InitStrue.GPIO_Pin=GPIO_Pin_11;
- GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;
- GPIO_Init(GPIOB,&GPIO_InitStrue);
-
- USART_InitStrue.USART_BaudRate=arr;
- USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
- USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;
- USART_InitStrue.USART_Parity=USART_Parity_No;
- USART_InitStrue.USART_StopBits=USART_StopBits_1;
- USART_InitStrue.USART_WordLength=USART_WordLength_8b;
-
- USART_Init(USART3,&USART_InitStrue);
-
- USART_Cmd(USART3,ENABLE); //ʹ�ܴ���2
-
- USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);//���������ж�
-
- NVIC_InitStrue.NVIC_IRQChannel=USART3_IRQn;
- NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;
- NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=0;
- NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;
- NVIC_Init(&NVIC_InitStrue);
-
- }
-
- void USART3_IRQHandler(void)
- {
-
- if(USART_GetITStatus(USART3,USART_IT_RXNE)!=RESET)
- {
- res= USART_ReceiveData(USART3);
- USART_SendData(USART3,res); //串口3发送数据给蓝牙模块接收,也就是手机app接收到的数据
- }
- }
PID(Proportional-Integral-Derivative)控制算法是一种用于控制系统的反馈控制算法。它通过比较实际输出与期望目标值之间的差异(误差),来调整控制器的输出,以使系统保持在期望的状态。PID控制算法由三个主要组成部分组成,分别是比例(Proportional)、积分(Integral)和微分(Derivative)。
以下是每个部分的解释以及PID控制的工作原理:
比例(Proportional)部分:比例部分的作用是根据当前误差的大小来调整控制输出。它与误差成正比,如果误差增大,比例部分的输出也增大,反之亦然。这个部分的作用是快速减小误差,但它单独使用时可能导致系统出现震荡。
积分(Integral)部分:积分部分的作用是积累误差并进行修正,以减小静态误差。它根据误差的积累来调整控制输出,通常用于减小比例控制导致的静态误差。积分部分的存在可以确保系统最终收敛到期望值,即使存在系统参数变化或外部干扰。
微分(Derivative)部分:微分部分的作用是预测误差的未来变化趋势,以减小控制输出的突变。它对误差的变化率进行调整,有助于防止系统在接近期望值时出现过冲或震荡。微分部分可以提高系统的稳定性。
PID控制算法的总输出是这三个部分的加权和,通常表示为:
Output=Kp⋅P+Ki⋅I+Kd⋅D
其中,P 是比例部分的输出,I 是积分部分的输出,D 是微分部分的输出,而 Kp、Ki 和 Kd 则是控制器的参数,通过调整这些参数可以实现不同的控制效果。
PID控制算法在自动化控制系统中广泛应用,如温度控制、电机控制、飞行控制等。通过适当调整参数,PID控制器可以实现系统快速响应、减小静态误差和维持系统稳定性。
- //直立环(比例p、微分d)
- int balance(float Angle,float Gyro){
- static float Bias;
- int balance;
- Bias=Angle-ZHONGZHI;
- balance=Bias*Kzp+Gyro*Kzd;
- return balance;
-
- }
-
- //速度环(比例p、积分i)
- int velocity(int Encoder_left,int Encoder_right){
- static float Velocity, Encoder_Least, Encoder;
- static float Encoder_Integral;
-
- Ksi=Ksp/200;
-
- Encoder_Least = (Encoder_Left+Encoder_Right)-0;
- Encoder=Encoder*0.7+Encoder_Least*0.3;
- Encoder_Integral=Encoder_Integral+Encoder;
- Encoder_Integral=Encoder_Integral-Target_Velocity; //改变Target_Velocity就是控制小车前进后退
- if(Encoder_Integral>15000) Encoder_Integral=15000;
- if(Encoder_Integral<-15000) Encoder_Integral=-15000;
-
- Velocity=Encoder*Ksp+Encoder_Integral*Ksi;
- return Velocity;
-
-
- }
- //转向环(比例p、微分d)
- int Turn(float yaw,float Gyro)
- {
- float Turn;
- float Bias;//目标角度
- Ktd=Ktp/100;
- Bias=yaw-0;
- Turn=Bias*Ktp+Gyro*Ktd;
- return Turn;
- }
平衡小车
平衡小车之家资料
链接: https://pan.baidu.com/s/1J6Rluf0T4mVtif2dqRtWxw?pwd=ghjm 提取码: ghjm
本人自制平衡车代码
链接: https://pan.baidu.com/s/1J6Rluf0T4mVtif2dqRtWxw?pwd=ghjm 提取码: ghjm
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。