tag 标签: mpu6050

相关帖子
相关博文
  • 热度 3
    2024-2-1 05:12
    420 次阅读|
    0 个评论
    MPU6050是一种集成了3轴陀螺仪和3轴加速度计的微型电子运动传感器,广泛应用于飞行控制系统、游戏控制器的运动检测等领域。它通过I2C接口与微控制器进行通信,可以测量设备在空间中的加速度和角速度。 PID(比例-积分-微分)控制器是一种常用的反馈控制器。它的工作原理是通过比较期望值和实际值之间的误差,然后通过比例、积分和微分三个环节来调整控制量,使系统的实际输出逐渐接近期望输出。 以下是一个简单的C语言实现的PID控制器代码: //```c #define Kp 1.0 // 比例系数 #define Ki 0.5 // 积分系数 #define Kd 0.1 // 微分系数 #define OUTPUT_LIMIT 100.0 // 输出限幅 #define INTEGRAL_LIMIT 1000.0 // 积分项限幅 float setpoint, input, error, Pout, Iout, Dout, last_error, output; int integral = 0; bool is_saturated = false; // 标志位,表示是否饱和 void PID_update(float setpoint, float input) { error = setpoint - input; Pout = Kp * error; // 检查饱和情况,如果输出大于等于上限或小于等于下限,则停止积分 = OUTPUT_LIMIT || output <= -OUTPUT_LIMIT) { is_saturated = true; } else { is_saturated = false; } if (!is_saturated) { integral += Ki * error; // 限制积分项增长 INTEGRAL_LIMIT) { integral = INTEGRAL_LIMIT; } else if (integral < -INTEGRAL_LIMIT) { integral = -INTEGRAL_LIMIT; } } Dout = Kd * (error - last_error); last_error = error; output = Pout + Iout + Dout; // 应用输出限幅 OUTPUT_LIMIT) { output = OUTPUT_LIMIT; } else if (output < -OUTPUT_LIMIT) { output = -OUTPUT_LIMIT; } } //``` 这段代码引入了`OUTPUT_LIMIT`和`INTEGRAL_LIMIT`两个常数来定义输出和积分项的限制。`is_saturated`变量用于标识输出是否处于饱和状态,从而决定是否继续积分。最后,对最终的`output`进行限幅处理,确保其不会超出定义的范围。
  • 热度 3
    2024-2-1 04:58
    822 次阅读|
    1 个评论
    MPU6050是一种集成了3轴陀螺仪和3轴加速度计的微型电子运动传感器,广泛应用于飞行控制系统、游戏控制器的运动检测等领域。它通过I2C接口与微控制器进行通信,可以测量设备在空间中的加速度和角速度。 在控制理论中,PID(比例-积分-微分)控制器是一种常用的反馈控制器。它的工作原理是通过比较期望值和实际值之间的误差,然后通过比例、积分和微分三个环节来调整控制量,使系统的实际输出逐渐接近期望输出。 以下是一个简单的C语言实现的PID控制器代码: //```c #define Kp 1.0 // 比例系数 #define Ki 0.5 // 积分系数 #define Kd 0.1 // 微分系数 float setpoint, input, error, Pout, Iout, Dout, last_error, output; int integral = 0; void PID_update(float setpoint, float input) { error = setpoint - input; Pout = Kp * error; integral += Ki * error; Dout = Kd * (error - last_error); last_error = error; output = Pout + Iout + Dout; } //``` 在这个代码中,`setpoint`是期望的输出值,`input`是实际的输入值。`Pout`、`Iout`、`Dout`分别代表比例、积分和微分环节的输出。`last_error`用于存储上一次的误差,以便计算微分环节的输出。`output`是最终的控制量输出。 注意,这只是一个简单的PID控制器实现,实际应用中可能需要根据系统的具体情况进行调整和优化。例如,可能需要添加抗饱和机制,或者使用更复杂的控制算法。
  • 热度 2
    2016-4-9 13:07
    2800 次阅读|
    0 个评论
    由于硬件上采用了mpu6050模块,这模块是自带姿态解算和卡尔曼滤波功能的,所以省了不少事儿。直接通过串口读模块发送的数据,然后按照模块固定的协议把数据解析出来,就能得到三轴角速度,三轴加速度,三轴角度。其实mpu6050内部只集成了陀螺仪测角速度,加速度计测加速度,没有直接测量角度的传感器,但是角度可以通过角速度积分得到,并且通过重力加速度在各轴上的分量进行校正,通过数据融合的算法(比如卡尔曼滤波),就可以比较准确的得到角度啦。当然这个过程都在模块内部完成,我们只是应用的话不需要太关注(以后做四轴的话应该得好好研究一下姿态解算和数据融合方面的东西)。 好了,废话不多说。先说代码思路,然后就上代码。Stm32F405的usart3连接模块,接收数据,通过DMA直接存到一个11字节的数组GYRO_buffer 里面,当数组存满了,也就是接受到了完整的一帧数据(一帧数据包括可能是角度数据、加速度数据或者是角速度数据,要根据帧头的第二个字节加以区分,具体的数据帧格式见附件里面的模块资料),然后触发DMA中断,在中断中对数据进行解析,得到最终数据,存储到一个GYRO结构体变量中,这个变量被设置为全局变量,可以在其他的函数中使用该变量的值,做姿态的控制。 代码: #include "main.h"   GYRO gyro = {1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0}; unsigned char GYRO_buffer ;   void usart3_configuration(void) {          //一定注意配置顺序,先除能再使能等等          USART_InitTypeDef usart3;          GPIO_InitTypeDef  gpio;          NVIC_InitTypeDef  nvic;          DMA_InitTypeDef   dma;                     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);          RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);                   /*配置GPIO*/          GPIO_PinAFConfig(GPIOC,GPIO_PinSource10,GPIO_AF_USART3);          GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_USART3);          gpio.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;          gpio.GPIO_Mode = GPIO_Mode_AF;          gpio.GPIO_OType = GPIO_OType_PP;          gpio.GPIO_Speed = GPIO_Speed_100MHz;          gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;          GPIO_Init(GPIOC,gpio);                   /*配置DMA*/                  DMA_Cmd(DMA1_Stream1,DISABLE);          while(DMA_GetCmdStatus(DMA1_Stream1) != DISABLE);//等待DMA可配置          DMA_DeInit(DMA1_Stream1);          dma.DMA_Channel= DMA_Channel_4;          dma.DMA_PeripheralBaseAddr = (uint32_t)(USART3-DR);          dma.DMA_Memory0BaseAddr = (uint32_t)GYRO_buffer;          dma.DMA_DIR = DMA_DIR_PeripheralToMemory;          dma.DMA_BufferSize = 11;          dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;          dma.DMA_MemoryInc = DMA_MemoryInc_Enable;          dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;          dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;          dma.DMA_Mode = DMA_Mode_Circular;          dma.DMA_Priority = DMA_Priority_VeryHigh;          dma.DMA_FIFOMode = DMA_FIFOMode_Disable;          dma.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;          dma.DMA_MemoryBurst = DMA_MemoryBurst_Single;          dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;          DMA_Init(DMA1_Stream1,dma);          DMA_Cmd(DMA1_Stream1,ENABLE);                   /*配置NVIC*/          nvic.NVIC_IRQChannel = DMA1_Stream1_IRQn;          nvic.NVIC_IRQChannelPreemptionPriority = 1;          nvic.NVIC_IRQChannelSubPriority = 1;          nvic.NVIC_IRQChannelCmd = ENABLE;          NVIC_Init(nvic);                   DMA_ITConfig(DMA1_Stream1,DMA_IT_TC,ENABLE);                   /*配置usart3*/          usart3.USART_BaudRate = 115200;          usart3.USART_WordLength = USART_WordLength_8b;          usart3.USART_StopBits = USART_StopBits_1;          usart3.USART_Parity = USART_Parity_No;          usart3.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;          usart3.USART_HardwareFlowControl = USART_HardwareFlowControl_None;          USART_Init(USART3,usart3);/*usart3初始化*/          //USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);/*配置usart3中断:读数据寄存器非空则中断*/          USART_Cmd(USART3,ENABLE);/*使能usart3*/          USART_DMACmd(USART3,USART_DMAReq_Rx,ENABLE);          }   void DMA1_Stream1_IRQHandler(void) {          if(DMA_GetITStatus(DMA1_Stream1, DMA_IT_TCIF1))          {                    DMA_ClearFlag(DMA1_Stream1, DMA_FLAG_TCIF1);                    DMA_ClearITPendingBit(DMA1_Stream1, DMA_IT_TCIF1);                    if(GYRO_buffer == 0x55)                    {                             switch(GYRO_buffer )                             {                                      case 0x51:                                                gyro.AX = ((short)(GYRO_buffer 8 | GYRO_buffer ))/32768.0*16;//g                                                gyro.AY = ((short)(GYRO_buffer 8 | GYRO_buffer ))/32768.0*16;                                                gyro.AZ = ((short)(GYRO_buffer 8 | GYRO_buffer ))/32768.0*16;                                                gyro.Temperature = ((short)(GYRO_buffer 8 | GYRO_buffer )) /340.0f+36.53f;                                                led_red_on();                                                led_green_off();                                                break;                                      case 0x52:                                                gyro.GX = ((short)(GYRO_buffer 8 | GYRO_buffer ))/32768.0*2000;//°/s                                                gyro.GY = ((short)(GYRO_buffer 8 | GYRO_buffer ))/32768.0*2000;                                               gyro.GZ = ((short)(GYRO_buffer 8 | GYRO_buffer ))/32768.0*2000;                                                gyro.Temperature = ((short)(GYRO_buffer 8 | GYRO_buffer )) /340.0f+36.53f;                                                led_red_off();                                                led_green_on();                                                break;                                      case 0x53:                                                gyro.PITCH = ((short)(GYRO_buffer 8 | GYRO_buffer ))/32768.0*180;//度                                                gyro.ROLL = ((short)(GYRO_buffer 8 | GYRO_buffer ))/32768.0*180;                                                gyro.YAW = ((short)(GYRO_buffer 8 | GYRO_buffer ))/32768.0*180;                                                gyro.Temperature = ((short)(GYRO_buffer 8 | GYRO_buffer )) /340.0f+36.53f;                                                led_red_on();                                                led_green_on();                                                break;                             }                    }          } } 其中GYRO结构体的结构是这样的: typedef struct {          float AX;          float AY;          float AZ;          float GX;          float GY;          float GZ;          float PITCH;          float ROLL;          float YAW;          float Temperature; }GYRO;   我开始在调试的过程中一直进不了DMA中断,后来发现是DMA配置的问题。下面把DMA配置部分的代码单独调出来说一下          /*配置DMA*/                  DMA_Cmd(DMA1_Stream1,DISABLE);          while(DMA_GetCmdStatus(DMA1_Stream1) != DISABLE);//等待DMA可配置          DMA_DeInit(DMA1_Stream1);          dma.DMA_Channel= DMA_Channel_4;          dma.DMA_PeripheralBaseAddr = (uint32_t)(USART3-DR);          dma.DMA_Memory0BaseAddr = (uint32_t)GYRO_buffer;          dma.DMA_DIR = DMA_DIR_PeripheralToMemory;          dma.DMA_BufferSize = 11;          dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;          dma.DMA_MemoryInc = DMA_MemoryInc_Enable;          dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;          dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;          dma.DMA_Mode = DMA_Mode_Circular;          dma.DMA_Priority = DMA_Priority_VeryHigh;          dma.DMA_FIFOMode = DMA_FIFOMode_Disable;          dma.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;          dma.DMA_MemoryBurst = DMA_MemoryBurst_Single;          dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;          DMA_Init(DMA1_Stream1,dma);          DMA_Cmd(DMA1_Stream1,ENABLE); 配置的时候首先用DMA_Cmd(DMA1_Stream1,DISABLE);除能DMA,因为DAM在运行过程中是不能配置的。然后用while(DMA_GetCmdStatus(DMA1_Stream1) != DISABLE);语句等待DMA被除能(可能是因为除能需要一定的时间吧,现在也不是很清楚为啥),确定DMA除能后,开始配置DMA,配置完成后,用DMA_Cmd(DMA1_Stream1,ENABLE);重新使能DMA。然后在使能usart3之后,还要加上USART_DMACmd(USART3,USART_DMAReq_Rx,ENABLE);语句,使能usart3的DAM功能。          关于stm32的DMA功能具体的配置,网上有很多资料,就不详细说啦。这里只把我看了网上的资料后仍然没有解决,最终基本靠自己摸索解决的问题写出来,供大家参考。
  • 热度 16
    2015-4-22 22:05
    1156 次阅读|
    0 个评论
    1、引言 四轴飞行器是一种结构紧凑、飞行方式独特的垂直起降式飞行器,与普通的飞行器相比具有结构简单,故障率低和单位体积能够产生更大升力等优点,在军事和民用多个领域都有广阔的应用前景,非常适合在狭小空间内执行任务。因此四旋翼飞行器具有广阔的应用前景,吸引了众多科研人员,成为国内外新的研究热点。 本设计主要通过利用惯性测量单元(IMU)姿态获取技术、PID电机控制算法、2.4G无线遥控通信技术和高速空心杯直流电机驱动技术来实现简易的四轴方案。整个系统的设计包括飞控部分和遥控部分,飞控部分采用机架和控制核心部分一体设计增加系统稳定性,遥控部分采用模拟摇杆操作输入使操作体验极佳,两部分之间的通信采用2.4G无线模块保证数据稳定传输。飞行控制板采用高速单片机STM32作为处理器,采用含有三轴陀螺仪、三轴加速度计的运动传感器MPU6050作为惯性测量单元,通过2.4G无线模块和遥控板进行通信,最终根据PID控制算法通过PWM方式驱动空心杯电机来达到遥控目标。 2、系统总体设计 系统硬件的设计主要分要遥控板和飞控板两个部分,遥控板采用常见羊角把游戏手柄的外形设计,控制输入采用四向摇杆,无线数据传输采用2.4G无线模块。飞控板采用控制处理核心和机架一体的设计即处理器和电机都集成在同一个电路板上,采用常规尺寸能够采用普通玩具的配件。系统软件的设计同样包括遥控板和飞控板两部分的工作,遥控板软件的设计主要包括ADC的采集和数据的无线发送。飞控板的软件的设计主要包括无线数据的接收,自身姿态的实时结算,电机PID增量的计算和电机的驱动。整个四轴飞行器系统包括人员操作遥控端和飞行器控制端,遥控端主控制器STM32通过ADC外设对摇杆数据进行采集,把采集到的数据通过2.4G无线通信模块发送至飞控端。飞控板的主要工作就是通过无线模块进行控制信号的接收,并且利用惯性测量单元获得实时系统加速度和角速度原始数据,并且最终解算出当前的系统姿态,然后根据遥控板发送的目标姿态和当姿态差计算出PID电机增量,然后通过PWM驱动电机进行系统调整来实现飞行器的稳定飞行。系统的总体设计框图如图1所示。 图1 系统总体设计框图 2、四轴飞行器的硬件设计 2.1主控单元选择 从成本和性能综合考虑,飞控板和遥控板的主控单元都采用意法半导体公司的增强型高速单片机STM32F103作为主控的,STM32F103是基于的ARM 32位的Cortex-M3内核架构,稳定工作频率可达72MHz,是一个具有丰富资源、高速时钟的精简指令的微处理器。STM32F103拥有从64K或128K字节的闪存程序可选存储器,高达20K字节的SRAM,2个12位模数转换器多达16个输入通道,7通道DMA控制器,多达80个快速I/O端口,串行单线调试(SWD)和JTAG接口调试模式,多达7个定时器,多达2个I2C接口(支持SMBus/PMBus),多达3个USART接口(支持ISO7816接口,LIN,IrDA接口和调制解调控制),多达2个SPI接口(18M位/秒),CAN接口(2.0B主动),USB2.0全速接口。主控单元原理图如图2所示。 图2 主控单元原理图 【分页导航】 第1页: 系统总体设计及主控单元选择 第2页: 飞控板电路设计 第3页: 遥控板电路设计 第4页: 飞控板系统软件设计 第5页: 遥控板系统软件设计 2.2 飞控板电路设计 飞控板的核心设计是MPU6050测量传感器、NRF2401无线模块以及飞控板电机驱动等模块的设计。飞控系统的惯性测量单元采用MPU6050作为测量传感器,MPU6050的驱动方式采用IIC接口,时钟引脚SCL连接到STM32的PB10,数据引脚连接到STM32的PB11引脚,数据中断引脚连接到PB5,为了增强驱动能力在每个引脚上都加入了10K的上拉电阻,原理图的设计如图3所示。 图3 飞控板惯性测量单元原理图 相对于其他模块电系统也是比较重要的部分,飞控系统采用3.7V高放电倍率锂电池进行供电。主控芯片供电部分和IMU传感器部分采用各自独立的LDO进行供电,这样确保了系统的稳定性和IMU传感器数据采集的准确性,稳压直流电源模块的原理图设计如图4所示。 图4 飞控板电源稳压原理图 飞控板与遥控板数据的通信同样采用的是基于2.4G频段的NRF2401模块,确保了数据的稳定传输。STM32的SPI1外设对2.4G模块进行操作驱动,引脚的连接如下表1所示。 NRF2.4G为采用3.3V供电无线模块,系统采用与单片机相同的电源网络对其供电,同时加入0.1UF电容进行滤波确保模块正常工作,无线模块的具体原理图连接如图5所示。 图5 飞控板无线模块原理图 飞控板的驱动系统采用的是四个分布对称十字交叉的高速空心杯电机,电机的驱动开关部分采用N沟道增强型场效应晶体管进行控制,通过修改STM32对应引脚上的PWM信号来进行开关MOS管实现电机运行开与关,从而实现电机运转速度的调节。电机1、2、3、4分别采用STM32的定时器2的通道0、通道1、通道2和通道3的PWM进行控制。电机1的控制端连接PA0,电机2的控制端采用PA1,电机2的控制端采用PA2,电机3的控制端采用PA3控制,电机的驱动原理图如图6所示。 图6 飞控板电机驱动原理图 【分页导航】 第1页: 系统总体设计及主控单元选择 第2页: 飞控板电路设计 第3页: 遥控板电路设计 第4页: 飞控板系统软件设计 第5页: 遥控板系统软件设计 2.3遥控板电路设计 遥控板主控单元通过SPI总线驱动2.4G无线模块,通过8位并口驱动1602液晶显示,通过ADC输入引脚对摇杆和电池电量进行采集,通过引脚驱动三极管开关驱动蜂鸣器提示。遥控板的核心设计是摇杆模拟数据进行采集模块、NRF2401无线模块等设计。 采用STM32单片机ADC1的通道4、通道5、通道6和通道7进行摇杆模拟数据进行采集并转换为数字量,分别连接到PA4、PA5、PA6和PA7引脚,并且加入滤波电容减少杂质信号的影响。遥控板摇杆输入原理图设计如图7所示。 图7 遥控板摇杆输入原理图设计 遥控板采用NRF2.4G模块的驱动采用STM32的自带外设SPI2进行驱动,各个功能引脚的连接如表2所示。 NRF2.4G模块采用3.3V供电,在供电端口外加0.1UF滤波存储电容确保无线系统的稳定性,的具体原理图连接8所示。 图8 遥控板无线模块原理图 【分页导航】 第1页: 系统总体设计及主控单元选择 第2页: 飞控板电路设计 第3页: 遥控板电路设计 第4页: 飞控板系统软件设计 第5页: 遥控板系统软件设计 3、四轴飞行器的软件设计 四轴飞行器的软件设计主要包括飞控板软件的设计和遥控板软件的设计。整体软件在MDK环境下采用C语言编写,采用ST-LINK仿真器对程序进行调试与下载。 3.1飞控板系统软件设计 飞控程序的主要设计思想是开机对无线模块的初始化、MPU6050的初始化、PWM电机初始化。随后对整个系统IMU继续零偏处理,随后等待进入解锁信息的传入。飞控采用定时器中断的方式,在中断中进行对时间的处理,每次中断计次标志就会自增,根据不同的中断积累即不同时间的间隔分别处理优先级不同的任务。飞控系统程序设计流程图如图9所示。 图9 飞控系统程序设计流程图 飞控系统每0.5毫秒中断一次,每次中断就会检查一次无线模块数据的接收,确保飞控系统的控制信息的实时性。每两次中断即1毫秒读取一次IMU单元的数据,通过滤波算法获得较为准确的系统加速度、角速度的原始数据。每四次中断即2毫秒通过IMU的原始数据计算下当前飞控板系统的姿态,然后结合遥控端的目标姿态,根据两者的差值通过PID控制算法进行对各个电机的调速控制。每200次中断即100毫秒,飞控系统会采集一次电池电压,然后把电池电压发送给遥控板,用来高速操作人员当前电压的大小。 MPU6050作为系统的惯性测量单元,是整个系统正常运行基础。MPU6050的驱动总线为IIC方式,为了程序的方便性本系统选用PB10和PB11模拟IIC来驱动。IMU读取出来的数据只是最简单的加速度、陀螺仪角速度的原始数据,需要通过进一步的处理才能得到本系统想要的姿态角度。飞控板姿态结算流程图如图10所示。 根据处理过后的MPU数据来获得当前的姿态,具体的姿态获取理论上是根据各个角度的积分得到当前的系统姿态欧拉角。本系统的设计实现是采用四元数算法对MPU6050最滤波后的数据进行计算得到最终的欧拉角。 整个飞控系统的运行动作是通过调整飞控姿态来实现的,本系统设计在当前姿态的基础上,根据接收到的遥控器的目标姿态对空心杯电机进行基于PID算法的PWM控制调速,从而实现飞控系统的各种基本运动。飞控板会对系统惯性测量单元传感器的原始数据进行滤波,然后对滤波后的数据进行实时结算,最后根据遥控板发送来的目标信息进行计算出电机的控制增量,最后根据PID控制算法对电机进行控制输出,飞控姿态控制流程图如图11所示。 图10 飞控板姿态结算流程图 图11 飞控板姿态控制流程图 【分页导航】 第1页: 系统总体设计及主控单元选择 第2页: 飞控板电路设计 第3页: 遥控板电路设计 第4页: 飞控板系统软件设计 第5页: 遥控板系统软件设计 3.2遥控板系统软件设计 遥控板的作用就是把操作人员的操作动作转化成信号传给飞行控制板,同时将一些控制信息和飞控板传回来的信息进行实时的显示和处理。飞控板摇杆数据的采集用到了STM32的ADC功能STM32F103xx增强型产品内嵌2个12位的模拟/数字转换器(ADC),每个ADC共用多达16个外部通道,可以实现单次或扫描转换。而且STM32的ADC可以采用DMA通道,这样可以进一步的节省硬件资源,加快系统实时性。采用SPI1驱动NRF无线模块,进行与飞控板的数据通信,遥控板系统软件流程如图12所示。 图12 遥控板软件流程图 本系统采用STM32的ADC1的通道4、通道5、通道6和通道7进行摇杆模拟数据进行采集,ADC和DMA的配置代码如下: ADC_Configuration(); //ADC 功能配置 DMA_Configuration(); //DMA 功能配置 下面是ADC和DMA的启动和时能代码如下: ADC_SoftwareStartConvCmd(ADC1, ENABLE); //启动 ADC1 转换 DMA_Cmd(DMA1_Channel1, ENABLE); //启动 DMA 通道 采用STM32外设SPI1驱动NRF2.4G模块,SPI初始化代码如下: Spi1_Init(); 采用无线模块的通道40进行通信,2401初始化函数如下: Nrf24l01_Init(MODEL_RX2,40); //通道40 2.4G无线模块NRF2401的接收函数如下: Nrf_Check_Event(); //读取NRF2401数据 通过2401将控制信号发送,发送函数如下: NRF_TxPacket_AP(NRF24L01_TXDATA_RC,32); //将控制信号发给四轴 4、结论 本文描述了一个简易四轴飞行器系统的设计实现,整个方案分为遥控控制板各飞行控制板两部分,通过2.4G无线模块进行控制通信,飞控系统采用IMU系统获取姿态信息根据反馈控制算法进行电机控制从而实现飞行控制。本系统飞控板采用一体设计使得系统简单、紧凑,遥控板采用摇杆输入使系统控制体验良好,最终实现飞行器的基本运动。实践证明该四轴飞行器飞行稳定、可靠,取得了较好效果。 参考文献 李尧. 四旋翼飞行器控制系统设计 . 大连:大连理工大学, 2013. 谭浩强. C程序设计教程 . 北京:清华大学出版社, 2010. 刘火良. STM32库开发实战指南 . 北京:机械工业出版社, 2013. 白志刚. 自动调节系统解析与PID整定 . 北京:化学工业出版社, 2012. 朱君. 四旋翼无人飞行器控制系统设计及控制方法研究 . 内蒙古:内蒙古科技大学, 2012. 曾勇. 四旋翼飞行器容错控制系统设计与实现 . 成都:电子科技大学, 2013. 宋佳佳. 小型四旋翼飞行器实验平台设计 . 武汉:华中科技大学, 2013. 刘军. 例说STM32 . 北京:北京航空航天大学出版社, 2011. 张瑾等. 电路设计与制板Protel 99SE入门与提高 . 北京:人民邮电出版社, 2007. 蒙博宇. STM3自学笔记 . 北京:北京航空航天大学出版社, 2012. 刘金琨. 先进PID控制MATLAB仿真 . 第3版. 北京:电子工业出版社, 2011. 霍罡等. 可编程序控制器模拟量及PID算法应用案例 . 北京:高等教育出版社, 2013. 【分页导航】 第1页: 系统总体设计及主控单元选择 第2页: 飞控板电路设计 第3页: 遥控板电路设计 第4页: 飞控板系统软件设计 第5页: 遥控板系统软件设计
  • 热度 23
    2015-4-9 13:00
    3211 次阅读|
    0 个评论
    1、引言 四轴飞行器是一种结构紧凑、飞行方式独特的垂直起降式飞行器,与普通的飞行器相比具有结构简单,故障率低和单位体积能够产生更大升力等优点,在军事和民用多个领域都有广阔的应用前景,非常适合在狭小空间内执行任务。因此四旋翼飞行器具有广阔的应用前景,吸引了众多科研人员,成为国内外新的研究热点。 本设计主要通过利用惯性测量单元(IMU)姿态获取技术、PID电机控制算法、2.4G无线遥控通信技术和高速空心杯直流电机驱动技术来实现简易的四轴方案。整个系统的设计包括飞控部分和遥控部分,飞控部分采用机架和控制核心部分一体设计增加系统稳定性,遥控部分采用模拟摇杆操作输入使操作体验极佳,两部分之间的通信采用2.4G无线模块保证数据稳定传输。飞行控制板采用高速单片机STM32作为处理器,采用含有三轴陀螺仪、三轴加速度计的运动传感器MPU6050作为惯性测量单元,通过2.4G无线模块和遥控板进行通信,最终根据PID控制算法通过PWM方式驱动空心杯电机来达到遥控目标。 2、系统总体设计 系统硬件的设计主要分要遥控板和飞控板两个部分,遥控板采用常见羊角把游戏手柄的外形设计,控制输入采用四向摇杆,无线数据传输采用2.4G无线模块。飞控板采用控制处理核心和机架一体的设计即处理器和电机都集成在同一个电路板上,采用常规尺寸能够采用普通玩具的配件。系统软件的设计同样包括遥控板和飞控板两部分的工作,遥控板软件的设计主要包括ADC的采集和数据的无线发送。飞控板的软件的设计主要包括无线数据的接收,自身姿态的实时结算,电机PID增量的计算和电机的驱动。整个四轴飞行器系统包括人员操作遥控端和飞行器控制端,遥控端主控制器STM32通过ADC外设对摇杆数据进行采集,把采集到的数据通过2.4G无线通信模块发送至飞控端。飞控板的主要工作就是通过无线模块进行控制信号的接收,并且利用惯性测量单元获得实时系统加速度和角速度原始数据,并且最终解算出当前的系统姿态,然后根据遥控板发送的目标姿态和当姿态差计算出PID电机增量,然后通过PWM驱动电机进行系统调整来实现飞行器的稳定飞行。系统的总体设计框图如图1所示。 图1 系统总体设计框图 2、四轴飞行器的硬件设计 2.1主控单元选择 从成本和性能综合考虑,飞控板和遥控板的主控单元都采用意法半导体公司的增强型高速单片机STM32F103作为主控的,STM32F103是基于的ARM 32位的Cortex-M3内核架构,稳定工作频率可达72MHz,是一个具有丰富资源、高速时钟的精简指令的微处理器。STM32F103拥有从64K或128K字节的闪存程序可选存储器,高达20K字节的SRAM,2个12位模数转换器多达16个输入通道,7通道DMA控制器,多达80个快速I/O端口,串行单线调试(SWD)和JTAG接口调试模式,多达7个定时器,多达2个I2C接口(支持SMBus/PMBus),多达3个USART接口(支持ISO7816接口,LIN,IrDA接口和调制解调控制),多达2个SPI接口(18M位/秒),CAN接口(2.0B主动),USB2.0全速接口。主控单元原理图如图2所示。 图2 主控单元原理图 【分页导航】 第1页: 系统总体设计及主控单元选择 第2页: 飞控板电路设计 第3页: 遥控板电路设计 第4页: 飞控板系统软件设计 第5页: 遥控板系统软件设计 2.2 飞控板电路设计 飞控板的核心设计是MPU6050测量传感器、NRF2401无线模块以及飞控板电机驱动等模块的设计。飞控系统的惯性测量单元采用MPU6050作为测量传感器,MPU6050的驱动方式采用IIC接口,时钟引脚SCL连接到STM32的PB10,数据引脚连接到STM32的PB11引脚,数据中断引脚连接到PB5,为了增强驱动能力在每个引脚上都加入了10K的上拉电阻,原理图的设计如图3所示。 图3 飞控板惯性测量单元原理图 相对于其他模块电系统也是比较重要的部分,飞控系统采用3.7V高放电倍率锂电池进行供电。主控芯片供电部分和IMU传感器部分采用各自独立的LDO进行供电,这样确保了系统的稳定性和IMU传感器数据采集的准确性,稳压直流电源模块的原理图设计如图4所示。 图4 飞控板电源稳压原理图 飞控板与遥控板数据的通信同样采用的是基于2.4G频段的NRF2401模块,确保了数据的稳定传输。STM32的SPI1外设对2.4G模块进行操作驱动,引脚的连接如下表1所示。 NRF2.4G为采用3.3V供电无线模块,系统采用与单片机相同的电源网络对其供电,同时加入0.1UF电容进行滤波确保模块正常工作,无线模块的具体原理图连接如图5所示。 图5 飞控板无线模块原理图 飞控板的驱动系统采用的是四个分布对称十字交叉的高速空心杯电机,电机的驱动开关部分采用N沟道增强型场效应晶体管进行控制,通过修改STM32对应引脚上的PWM信号来进行开关MOS管实现电机运行开与关,从而实现电机运转速度的调节。电机1、2、3、4分别采用STM32的定时器2的通道0、通道1、通道2和通道3的PWM进行控制。电机1的控制端连接PA0,电机2的控制端采用PA1,电机2的控制端采用PA2,电机3的控制端采用PA3控制,电机的驱动原理图如图6所示。 图6 飞控板电机驱动原理图 【分页导航】 第1页: 系统总体设计及主控单元选择 第2页: 飞控板电路设计 第3页: 遥控板电路设计 第4页: 飞控板系统软件设计 第5页: 遥控板系统软件设计 2.3遥控板电路设计 遥控板主控单元通过SPI总线驱动2.4G无线模块,通过8位并口驱动1602液晶显示,通过ADC输入引脚对摇杆和电池电量进行采集,通过引脚驱动三极管开关驱动蜂鸣器提示。遥控板的核心设计是摇杆模拟数据进行采集模块、NRF2401无线模块等设计。 采用STM32单片机ADC1的通道4、通道5、通道6和通道7进行摇杆模拟数据进行采集并转换为数字量,分别连接到PA4、PA5、PA6和PA7引脚,并且加入滤波电容减少杂质信号的影响。遥控板摇杆输入原理图设计如图7所示。 图7 遥控板摇杆输入原理图设计 遥控板采用NRF2.4G模块的驱动采用STM32的自带外设SPI2进行驱动,各个功能引脚的连接如表2所示。 NRF2.4G模块采用3.3V供电,在供电端口外加0.1UF滤波存储电容确保无线系统的稳定性,的具体原理图连接8所示。 图8 遥控板无线模块原理图 【分页导航】 第1页: 系统总体设计及主控单元选择 第2页: 飞控板电路设计 第3页: 遥控板电路设计 第4页: 飞控板系统软件设计 第5页: 遥控板系统软件设计 3、四轴飞行器的软件设计 四轴飞行器的软件设计主要包括飞控板软件的设计和遥控板软件的设计。整体软件在MDK环境下采用C语言编写,采用ST-LINK仿真器对程序进行调试与下载。 3.1飞控板系统软件设计 飞控程序的主要设计思想是开机对无线模块的初始化、MPU6050的初始化、PWM电机初始化。随后对整个系统IMU继续零偏处理,随后等待进入解锁信息的传入。飞控采用定时器中断的方式,在中断中进行对时间的处理,每次中断计次标志就会自增,根据不同的中断积累即不同时间的间隔分别处理优先级不同的任务。飞控系统程序设计流程图如图9所示。 图9 飞控系统程序设计流程图 飞控系统每0.5毫秒中断一次,每次中断就会检查一次无线模块数据的接收,确保飞控系统的控制信息的实时性。每两次中断即1毫秒读取一次IMU单元的数据,通过滤波算法获得较为准确的系统加速度、角速度的原始数据。每四次中断即2毫秒通过IMU的原始数据计算下当前飞控板系统的姿态,然后结合遥控端的目标姿态,根据两者的差值通过PID控制算法进行对各个电机的调速控制。每200次中断即100毫秒,飞控系统会采集一次电池电压,然后把电池电压发送给遥控板,用来高速操作人员当前电压的大小。 MPU6050作为系统的惯性测量单元,是整个系统正常运行基础。MPU6050的驱动总线为IIC方式,为了程序的方便性本系统选用PB10和PB11模拟IIC来驱动。IMU读取出来的数据只是最简单的加速度、陀螺仪角速度的原始数据,需要通过进一步的处理才能得到本系统想要的姿态角度。飞控板姿态结算流程图如图10所示。 根据处理过后的MPU数据来获得当前的姿态,具体的姿态获取理论上是根据各个角度的积分得到当前的系统姿态欧拉角。本系统的设计实现是采用四元数算法对MPU6050最滤波后的数据进行计算得到最终的欧拉角。 整个飞控系统的运行动作是通过调整飞控姿态来实现的,本系统设计在当前姿态的基础上,根据接收到的遥控器的目标姿态对空心杯电机进行基于PID算法的PWM控制调速,从而实现飞控系统的各种基本运动。飞控板会对系统惯性测量单元传感器的原始数据进行滤波,然后对滤波后的数据进行实时结算,最后根据遥控板发送来的目标信息进行计算出电机的控制增量,最后根据PID控制算法对电机进行控制输出,飞控姿态控制流程图如图11所示。 图10 飞控板姿态结算流程图 图11 飞控板姿态控制流程图 【分页导航】 第1页: 系统总体设计及主控单元选择 第2页: 飞控板电路设计 第3页: 遥控板电路设计 第4页: 飞控板系统软件设计 第5页: 遥控板系统软件设计 3.2遥控板系统软件设计 遥控板的作用就是把操作人员的操作动作转化成信号传给飞行控制板,同时将一些控制信息和飞控板传回来的信息进行实时的显示和处理。飞控板摇杆数据的采集用到了STM32的ADC功能STM32F103xx增强型产品内嵌2个12位的模拟/数字转换器(ADC),每个ADC共用多达16个外部通道,可以实现单次或扫描转换。而且STM32的ADC可以采用DMA通道,这样可以进一步的节省硬件资源,加快系统实时性。采用SPI1驱动NRF无线模块,进行与飞控板的数据通信,遥控板系统软件流程如图12所示。 图12 遥控板软件流程图 本系统采用STM32的ADC1的通道4、通道5、通道6和通道7进行摇杆模拟数据进行采集,ADC和DMA的配置代码如下: ADC_Configuration(); //ADC 功能配置 DMA_Configuration(); //DMA 功能配置 下面是ADC和DMA的启动和时能代码如下: ADC_SoftwareStartConvCmd(ADC1, ENABLE); //启动 ADC1 转换 DMA_Cmd(DMA1_Channel1, ENABLE); //启动 DMA 通道 采用STM32外设SPI1驱动NRF2.4G模块,SPI初始化代码如下: Spi1_Init(); 采用无线模块的通道40进行通信,2401初始化函数如下: Nrf24l01_Init(MODEL_RX2,40); //通道40 2.4G无线模块NRF2401的接收函数如下: Nrf_Check_Event(); //读取NRF2401数据 通过2401将控制信号发送,发送函数如下: NRF_TxPacket_AP(NRF24L01_TXDATA_RC,32); //将控制信号发给四轴 4、结论 本文描述了一个简易四轴飞行器系统的设计实现,整个方案分为遥控控制板各飞行控制板两部分,通过2.4G无线模块进行控制通信,飞控系统采用IMU系统获取姿态信息根据反馈控制算法进行电机控制从而实现飞行控制。本系统飞控板采用一体设计使得系统简单、紧凑,遥控板采用摇杆输入使系统控制体验良好,最终实现飞行器的基本运动。实践证明该四轴飞行器飞行稳定、可靠,取得了较好效果。 参考文献 李尧. 四旋翼飞行器控制系统设计 . 大连:大连理工大学, 2013. 谭浩强. C程序设计教程 . 北京:清华大学出版社, 2010. 刘火良. STM32库开发实战指南 . 北京:机械工业出版社, 2013. 白志刚. 自动调节系统解析与PID整定 . 北京:化学工业出版社, 2012. 朱君. 四旋翼无人飞行器控制系统设计及控制方法研究 . 内蒙古:内蒙古科技大学, 2012. 曾勇. 四旋翼飞行器容错控制系统设计与实现 . 成都:电子科技大学, 2013. 宋佳佳. 小型四旋翼飞行器实验平台设计 . 武汉:华中科技大学, 2013. 刘军. 例说STM32 . 北京:北京航空航天大学出版社, 2011. 张瑾等. 电路设计与制板Protel 99SE入门与提高 . 北京:人民邮电出版社, 2007. 蒙博宇. STM3自学笔记 . 北京:北京航空航天大学出版社, 2012. 刘金琨. 先进PID控制MATLAB仿真 . 第3版. 北京:电子工业出版社, 2011. 霍罡等. 可编程序控制器模拟量及PID算法应用案例 . 北京:高等教育出版社, 2013. 【分页导航】 第1页: 系统总体设计及主控单元选择 第2页: 飞控板电路设计 第3页: 遥控板电路设计 第4页: 飞控板系统软件设计 第5页: 遥控板系统软件设计
相关资源