我的STM32自平衡小车+DIY遥控器
借鉴坛子里面的各种开源资料,我的自平衡小车也摇摇晃晃的站起来了,虽然和坛子里面的大神比起来差的太远,但是也是经过自己琢磨的。以此回馈论坛,将所有的资料都上传(不敢说开源,反正都是从坛子里面下载的):/*************************************************************************************/
硬件部分:
自平衡小车:
主控制器:STM32F103RB72Mhz
传感器 :MPU6050 I2C 协议传输 (直接采用STM32的硬件I2C+DMA读取的,速度相当快哦)
电机驱动:L298N电机驱动模块 双H桥直流电机驱动 ,这个不用我多说,淘宝上一大把
无线传输:NRF24L01SPI协议传输 (3.3V供电的,不要输入5V )
光电编码器:增量式编码器 AB两相输出 5V 3.3V 都可以 建议3.3V
电源板 :7805 OR 2940 5V稳压芯片都可以,主要是给主控部分和编码器提供稳定电能。
减速电机:关于电机的选择是容易被忽视的,电机的好换直接关系着平衡车能不能站立。我的建议是,尽量选择转速和力矩都大一些的,因为转速太小不容易回正,力矩过小载荷也就相应的小, 最好是选择带有编码盘的直流减速电机,这样可以免去编码盘的安装(安装不好,根本测不到数据,很蛋疼滴!),当然这类电机一般都很贵!你也可以选择尾部带有伸出轴的减速电机,也好方便你安装码盘。最最最重要的就是,一定要选择空挡间隙小的电机,不然就会和我的一样,在平衡位置晃来晃去的!切记!
以上是我的自平衡的硬件部分,很简单吧,其实自平衡的硬件不难,很多都可以在淘宝上买到模块,当然,你也可以自己DIY
下面是我的手持遥控板的硬件部分:
主控器:STC89C51 12MHZ
按键 :8路独立式按键原理图几乎在所有的教材上面都有记住 51单片机P0口是没有内部上拉电阻的,如果你把按键放在P0口,就需要外接10K的上拉。若是接到其他I/O口,可以不用外接。
无线模块:NRF24L01 SPI协议用I/O口模拟SPI协议 感觉还可以
LED部分: 具体个数由你们自己安排,仅仅为了调试方便,提示程序运行+按键提示++
电源部分:5V稳压+3.3V稳压两个 5V给单片机,LED和按键上拉部分,3.3V则是提供给NRF2401
/*************************************************************************************/
好了接下来就是软件部分了:
自平衡部分:
因为我正好也在学习操作系统,所以也就将整个用户程序放在操作系统上运行,一来可以熟悉操作系统编程,而来也可以直观体验操作系统与普通裸机程序的不同。
软件平台:uC/OS-II操作系统时钟1ms书上说一般在10ms_100ms之间,我测试1ms还可以,CPU占用率只有20% 不到
底层I2C模块:也是借鉴论坛里面的资料(原谅我连贡献者ID都不知道了。。。。),经过我一直修改成了我工程的底层函数。由STM32的硬件I2C+DMA+中断的模式传输,不仅省去了CPU等待的时间损耗,也加快了速度---我还是将最初从坛子里面下载的硬件I2C源程序贴在这里,以此感谢那位大神:
数据融合部分采用卡尔曼算法,不多说,也是从坛子里面借鉴的!
控制部分采用PID算法,分为直立部分,速度控制部分和转向部分。直立控制(PD)是整个控制的核心,所以必须放在主要位置(我的程序是2ms控制一次);速度控制(PI)构成直立部分的一个干扰,频率要低一些,我采用的100ms ;最后的转向部分(P)就是简单的将遥控指令比例后输出即可;(整个算法借鉴第七届全国大学生“飞思卡尔”杯智能汽车竞赛电磁组直立行车参考设计方案(版本1.0)我也会在下面贴出来,务必仔细阅读一遍以上)
这里我需要感谢的就是四轴板块的匿名,我借鉴了他的上位机来在线调试PID参数,这样就不用调一次参数下载一次程序,建议大家采用这种方法;我的程序里面有匿名上位机的协议,需要了解上位机协议的可以参阅RC.c文件。
手持遥控部分:这里就不多说了,模拟SPI协议和NRF2401的驱动都是移植并修改的,请直接参考程序即可:
/*************************************************************************************/
无图无真相:
http://v.youku.com/v_show/id_XNjg1ODkwMjQ0.html最初的调试
http://v.youku.com/v_show/id_XNjk2MTk5NTg4.html遥控板视频 忘了件匿名的上位机贴出来了:
真心不错,遥控器来感觉挺爽的,什么时候我也来玩玩系统,哈哈 学习了! 下来看看,学习 学习 楼主上传的很详细!多谢! xuexile ,多些楼主 JIFEINOVEL 发表于 2014-4-10 22:24
真心不错,遥控器来感觉挺爽的,什么时候我也来玩玩系统,哈哈
恩恩 可以做一个送给小侄子当玩具 呵呵{:lol:} gw1428jk 发表于 2014-4-11 17:04
xuexile ,多些楼主
我也是从坛子里面学习的,大家都都互相学习嘛,才会有进步。。。 961306474 发表于 2014-4-11 11:18
楼主上传的很详细!多谢!
再多的资料 消化了才是自己的资料,,,加油 头像够吊,嘿嘿 bbsview 发表于 2014-4-12 13:44
头像够吊,嘿嘿
{:lol:}{:lol:} {:lol:} lc125253647 发表于 2014-4-12 11:48
再多的资料 消化了才是自己的资料,,,加油
嗯嗯,我会努力的! 问下楼主,用STM32电机编码器脉冲接哪个引脚?是外部定时器吗?大概怎么运用? w475696010 发表于 2014-4-13 10:47
问下楼主,用STM32电机编码器脉冲接哪个引脚?是外部定时器吗?大概怎么运用? ...
一般情况下是接在通用定时器的通道1和2 (具体哪个引脚,还要看你用的哪个定时器,再根据定时器的映射找到对应的IO引脚),用定时器的正交编码器模式 就可以了(这种模式叫做M法测速,既是在等间隔的时间T内测量脉冲数M,适合测量高速情况);
不过我的程序 是用的另外一方法,叫做T法测速(就是测量一个脉冲高电平持续的时间T,适合测量低速情况),,这种情况接在四个通道的任何一个都可以! lc125253647 发表于 2014-4-13 12:00
一般情况下是接在通用定时器的通道1和2 (具体哪个引脚,还要看你用的哪个定时器,再根据定时器的映射找 ...
谢谢楼主,我在看这东西,第一次用STM32,呵呵{:lol:} 我用的STM32f103rb,不知道在什么上找定时器的映射图?我在STM32中文参考手册上找到只有定时器1到4的图,不知道对于我的型号使用不 w475696010 发表于 2014-4-13 16:11
我用的STM32f103rb,不知道在什么上找定时器的映射图?我在STM32中文参考手册上找到只有定时器1到4的图,不 ...
你用的是STM32F10XX系列的参考手册,整个手册里面的内容针对整个系列,具体要查某个型号芯片的引脚映射还要看 具体某个芯片手册。。。
你截图上的内容是参考手册的第8章的3.7小节 (8.3.7)里面有对定时器复用功能的重映射的说明,从这里也可以发现其实和芯片手册里面是一样的!
哇塞谢谢楼主,终于知道这东西了。感激中。。。。 楼主把相关硬件也贴出来啊,供大家学习!!! yst1571661 发表于 2014-4-16 16:55
楼主把相关硬件也贴出来啊,供大家学习!!!
我的车子用的都是一些模块的组合,比如STM32最小系统,电机驱动模块,NRF2401模块,MPU6050模块。。。。
这些模块可以自己做,不过我都是在淘宝上买的,很容易搜索。。。。 楼主的小车模型,能不能给个链接啊,非常感谢 不错,也想玩玩,向楼主学习学习......{:victory:} 最近也在开始搞这些,载下来模仿 楼主问下,你在粗的时候,用输入捕获是怎么捕获的哦。比如我想用TIM3_1和TIM3_2来做捕获,能做到吗?大概怎么弄,我 到网上查了说用PWM捕获只能一个定时器做一个捕获?用不同方法一个定时器能做两个捕获,这个具体怎么回事,谢谢楼主! 我看你用的是定时器TIM3,的通道1和2
//初始化TIM5输入捕获参数TIM_ICMode_ICAP
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; //CC1S=01 选择输入端 IC1映射到TI1上
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM_ICInitStructure.TIM_ICFilter = 0x0;//IC1F=0000 配置输入滤波器 不滤波
TIM_ICInit(TIM3, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输入端 IC1映射到TI1上
TIM_ICInit(TIM3, &TIM_ICInitStructure);
这里捕获的裸机过程不是很清楚,分配的TIM_Channel通道,怎么完成捕获不是很清楚 void TIM4_IRQHandler(void)//0.5ms interput
{
if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)//溢出中断
{
}
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);//清除TIMx的中断待处理位:TIM 中断源
}
/*************************************************************************/
//通用定时器中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void Timerx_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值10Khz的计数频率
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_ITConfig(//使能或者失能指定的TIM中断
TIM4, //TIM2
TIM_IT_Update|//TIM 中断源
TIM_IT_Trigger, //TIM 触发中断源
ENABLE//使能
);
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;//TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_Cmd(TIM4, ENABLE);//使能TIMx外设
}
/*************************************************************************/
这个时钟4在整个工程中什么作用?也不是很明白 我找到正点原子的资料看懂了TIM3大部分操作,还有TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; //CC1S=01 选择输入端 IC1映射到TI1上和TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输入端 IC1映射到TI1上这两个地方,怎么知道哪个定时器的哪个通道对应于哪个捕获通道的?还有前面问的TIM4还是没看懂他到底作用是干嘛???谢谢楼主解答 (*Speed1)=(u16)(1000000/(Timer_count1));
(*Speed2)=(u16)(1000000/(Timer_count2));楼主,这里为什么用1000000除以高电平时间?
还有void Test_Speed(u16 *Current_speed1,u16 *Current_speed2)
{
static short SPEED_BUF;
u8 i=0;
static u8 filter_cnt=0;
int SPEED_SUM=0;
SPEED_BUF=(*Current_speed1);
SPEED_BUF=(*Current_speed2);
SPEED_SUM=0;
for(i=0;i<FILTER_NUM2;i++)
{
SPEED_SUM+=SPEED_BUF;
}
*Current_speed1=(u16)(SPEED_SUM/FILTER_NUM2);
SPEED_SUM=0;
for(i=0;i<FILTER_NUM2;i++)
{
SPEED_SUM+=SPEED_BUF;
}
*Current_speed2=(u16)(SPEED_SUM/FILTER_NUM2);
filter_cnt++;
if(filter_cnt==FILTER_NUM2) filter_cnt=0;
}
这个函数的目的是不是将得到的速度进行10次求平均处理? 楼主,还是没看明白 怎么把 speed1 和speed2传给 u16 *Current_speed1,u16 *Current_speed2的 麻烦楼主看到了回下,谢谢。。。! w475696010 发表于 2014-5-8 13:52
楼主问下,你在粗的时候,用输入捕获是怎么捕获的哦。比如我想用TIM3_1和TIM3_2来做捕获,能做到吗?大概怎 ...
测速有T测法和M测法,其实一般自平衡要用M测法,也就是通过STM32的定时器的正交编码器模式,记录编码盘的脉冲数,这种方法要求码盘安装在高速轴上面,而且线数大才有可靠地精度。。。。由于我的电机高速轴没有引出来,只能安装在输出轴(低速轴)上面,100线的码盘用M测法数据跳跃太大,肯本没有精度,所以我的程序用的是T测法,既是将STM32定时器配置成输入捕获模式,测量两个脉冲时间的时间T来转换成速度。。。。。。具体的转换公式你可以在论坛里面搜到! w475696010 发表于 2014-5-8 14:02
我看你用的是定时器TIM3,的通道1和2
//初始化TIM5输入捕获参数TIM_ICMode_ICAP
TIM_ICInitStructure.T ...
如果配置成输入捕获模式的话,四个通道都可以用,若是配置成正交编码器模式,则只能在通道1 2 上面 w475696010 发表于 2014-5-8 14:19
void TIM4_IRQHandler(void)//0.5ms interput
{
if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)// ...
哦 ,定时器我没有用到,定时器是我以前用M法测速的时候用到的,后来就注释掉了 w475696010 发表于 2014-5-8 16:01
(*Speed1)=(u16)(1000000/(Timer_count1));
(*Speed2)=(u16)(1000000/(Timer_count2));楼主,这里为 ...
第一个问题,为什么要用1000 000 去除,那是因为角速度W=2*pi/T;也就是说角速度和你测得时间成反比,我的时间单位是us ,转换成秒不就是相当于乘以1000 000 所以W=1000 000 *(1/T)
第二个问题你说对了,我用的指针做形参 w475696010 发表于 2014-5-8 20:16
楼主,还是没看明白 怎么把 speed1 和speed2传给 u16 *Current_speed1,u16 *Current_speed2的 ...
我使用的指针变量作为函数的形参,实际传入的就是变量的地址,那么就可以在函数里面改变传入地址里面的内容了。。。。。 w475696010 发表于 2014-5-9 09:01
麻烦楼主看到了回下,谢谢。。。!
最近 才看到。。。。{:lol:} 楼主好人!谢谢回答的这么详细,哪我的电机是
空载转速:8100RPM(转每分钟)
减速后速:120RPM(转每分钟)
直 径:30mm
电机长度:42mm
总共长度:85mm
出轴直径:6mm
出轴长度:35mm
输出功率:17W
扭 矩:大扭矩
空载电流:75mA
堵转电流:1400mA
减速箱型号:日本定制(全金属精密行星减速箱)
减速比:66:1
编码器:光电式
输出路数:AB双路输出
每圈脉冲:12CPR(脉冲每圈)
这个参数,用T法还是M法好哪?
还有楼主,还是没看明白 怎么把 speed1 和speed2传给 u16 *Current_speed1,u16 *Current_speed2的这连个参数我找了好久,都没看见代码里在哪个地方比如:把speed1的地址给Current_speed1,
另外for(i=0;i<FILTER_NUM2;i++)
{
SPEED_SUM+=SPEED_BUF;
}
*Current_speed1=(u16)(SPEED_SUM/FILTER_NUM2);
你这里将速度求平均数,但是这10个速度的采样间隔是多少,也没看见,不会连续采样求10次平均把。
再次感谢楼主的街道{:loveliness:}{:biggrin:} 还有一个问题是速度采集回来了,变成 Current_speed 那么后续处理这些速度参数在哪里处理的,我还没找到,想问下谢谢!{:lol:} 做得挺好的 w475696010 发表于 2014-5-9 14:43
楼主好人!谢谢回答的这么详细,哪我的电机是
空载转速:8100RPM(转每分钟)
你的电机自带有编码器,肯定要用M测速,不能用我的方法。。。。。 哦,我看了下STM32正交编码就是产生PWM波输出? 我对正交编码不了解,我上百度看看 我网上查了下,正交编码是对输入的PWM波进行分析处理,但是必须知道两路相互垂直的波,意思是一个点击的两个编码器都要用?分别接CH1和CH2(因为前面你说了这种模式下只有这两个通道能用),那是不是两个电机就要用两个定时器,也就是4个定时器通道?如果是这样,我在设计电路板的时候没有想到这种方法,4个编码接口都接在了TIM3的CH1 、CH2、CH3、CH4 楼主,貌似我的TIM4 CH1、CH2引出来了的,分别是PB6、PB7脚对吗,哪我就可以用正交编码? w475696010 发表于 2014-5-9 16:38
我网上查了下,正交编码是对输入的PWM波进行分析处理,但是必须知道两路相互垂直的波,意思是一个点击的两 ...
你的编码器有AB两厢输出的,其相位刚好相差90度,可以通过相位先后来判断轮子的转向,然后你真的要用到两个定时器才能配置两个编码器。。。不过 你也不必重新做板子,大不了只测量一个轮子的速度来代表整个车子的速度。。。。。 坑爹啊,引脚是解出来了,但是没有上拉,只有以后改进控制板的时候用正交编码了。。。。 w475696010 发表于 2014-5-9 17:10
坑爹啊,引脚是解出来了,但是没有上拉,只有以后改进控制板的时候用正交编码了。。。。 ...
STM32 不是内部有上拉输入配置么? 意思是把这两个引脚配置成上拉输入模式,然后用PWM输入模式,就能用了,谢谢哈! 楼主,如果点击速度策回来了,这个速度该怎么处理我还是不是很清楚,你有没有关于M测速法的一些资料地址,我去看看。 谢谢楼主了!(其实我第一次用STM32,呵呵谢谢楼主指点!) w475696010 发表于 2014-5-9 17:37
意思是把这两个引脚配置成上拉输入模式,然后用PWM输入模式,就能用了,谢谢哈! 楼主,如果点击速度策回来 ...
我记得就只在智能小车这个分贴看的,哪个帖子就不记得了,你在这个论坛找找看,或许可以找到很多资料了 mark多谢楼主 谢谢楼主,我找找。。。 楼主,你卡尔曼滤波的输入值是什么哦?
/***************Kalman***filter************************************/
void Kalman_Filter(float angle_m,float gyro_m) //gyro_m:gyro_measure 比如这两个参数需要什么样的规格?比如说我用的是 加速度传感器 +三轴角度传感器(我只采集一个方向值), 在这种情况下,我的值需要怎么处理后给卡尔曼?哪个采集值分别对应于哪个参数?
2、还有就是这个滤波过后输出值是什么,是机器实际偏离角度?但是是哪个变量表示最后输出,我没看懂。
/******************************************//******************************************/
谢谢楼主解答哈!{:handshake:} 我的意思就是卡尔曼滤波,那几个参数需要自己修改,哪几个参数需要自己传入(并且传入参数的要求),哪个参数是最后的结果? 楼主,你代码里面:
void ACC_FIR(float datax,float datay,float dataz)
void ACC_Filter(float datax,float datay,float dataz) //平均值滤波
void filter_HB(float new_data1,float new_data2,float new_data3)
这几个函数在整个代码中的作用?还有
#define Sensitivity_Ac 0.00549333170567949//0.00122073125 //v/g
#define Sensitivity_Gy 0.006103515625//0.013733329264198//0.006103515625//v/deg/s
GYRO_DATA.X= (G_x-GYRO_OFFSET.X)*Sensitivity_Gy;
GYRO_DATA.Y= (G_y-GYRO_OFFSET.Y)*Sensitivity_Gy;
GYRO_DATA.Z= (G_z-GYRO_OFFSET.Z)*Sensitivity_Gy;
ACC_DATA.X=(A_x-ACC_OFFSET.X)*Sensitivity_Ac;
ACC_DATA.Y=(A_y-ACC_OFFSET.Y)*Sensitivity_Ac;
ACC_DATA.Z=(A_z-ACC_OFFSET.Z)*Sensitivity_Ac;
为什么要做这样的运算,其目的是什么,我的只有一个加速度输出量,和一个角度输出量,这该如何是好? void complementry_Filter(float gyro_m,float acc_m);这个函数作用也有点奇怪,这是修正ADC结果吗?但是修正的标准是什么? w475696010 发表于 2014-5-10 17:36
void complementry_Filter(float gyro_m,float acc_m);这个函数作用也有点奇怪,这是修正ADC结果吗?但是 ...
我的代码里面有很多我尝试过的算法,都没有删掉,只是注释掉。。。你知道 姿态解算有互补滤波融合和卡尔曼融合两种方法么?
void complementry_Filter(float gyro_m,float acc_m);和前面的 void Kalman_Filter(float angle_m,float gyro_m)其作用都是将加速度和角速度数据进行融合 最后得到实时准确的角度+角速度
前者是互补的列程 后面是卡尔曼的 我放在里面是为了对比两者的效果哪个好一些。。。最后卡尔曼更稳定。。。。。你可以试试互补 可能在不同的车上 两者的效果会有不一样吧。。。。。 w475696010 发表于 2014-5-10 17:30
楼主,你代码里面:
void ACC_FIR(float datax,float datay,float dataz)
void ACC_Filter(float datax,flo ...
我的代码里面有很多我尝试过的算法,都没有删掉,只是注释掉。。。你知道 姿态解算有互补滤波融合和卡尔曼融合两种方法么?
void complementry_Filter(float gyro_m,float acc_m);和前面的 void Kalman_Filter(float angle_m,float gyro_m)其作用都是将加速度和角速度数据进行融合 最后得到实时准确的角度+角速度
前者是互补的列程 后面是卡尔曼的 我放在里面是为了对比两者的效果哪个好一些。。。最后卡尔曼更稳定。。。。。你可以试试互补 可能在不同的车上 两者的效果会有b w475696010 发表于 2014-5-10 17:30
楼主,你代码里面:
void ACC_FIR(float datax,float datay,float dataz)
void ACC_Filter(float datax,flo ...
采集到6050数据 需要减去偏移修正。。。。。然后为什么要乘以一个系数,那是因为我要转换成物理意义上的角速度和加速度参量。。。。。 谢谢楼主,原来是这样子。。我也都试试看。 楼主你真正的执行核心流程是不是一下:
void TaskCONTROL(void *pdata)
{
INT8U err;
pdata=pdata;
while(1)
{
OSSemPend(MPU6050_EVENT_BUF,0,&err);
Kalman_Filter(ACC_DATA.Y,GYRO_DATA.X); //gyro_m:gyro_measure
PID_Control(1,0,0);
Nrf_Check_Event(); //检测是否有数据接收
IWDG_Feed();//喂狗 <<1400ms
OSTimeDly (2);
}
}
其实你是把MPU信号给了卡尔曼,然后是给PID得出PWM控制电机,这样就能平衡了,下一步就是检测遥控,然后是喂狗,延时,如此死循环。那么之前你的滤波函数里面,其实只用了Kalman_Filter(ACC_DATA.Y,GYRO_DATA.X);这个函数,不晓得我弄对没有{:lol:}{:lol:} 楼主用硬件iic没有问题吗,感觉stm32的硬件iic经常出问题的啊。还有就是姿态采集的频率是多少,我的好像做到10ms采集一次就提高不了了额。 学习一下 学习一下有空我也弄
w475696010 发表于 2014-5-11 08:50
楼主你真正的执行核心流程是不是一下:
void TaskCONTROL(void *pdata)
{
是的 。。。。 chy 发表于 2014-5-11 10:52
楼主用硬件iic没有问题吗,感觉stm32的硬件iic经常出问题的啊。还有就是姿态采集的频率是多少,我的好像做 ...
硬件I2c +DMA 没有问题很稳定的 lc125253647 发表于 2014-5-11 17:51
硬件I2c +DMA 没有问题很稳定的
呵呵,不错, 楼主把我共享出来的"STM32的硬件I2C+DMA+中断的模式传输" 修改运用得很好, 赞一个 {:victory:} ...
前段时间,在玩BLDC,准备想搞独轮车的, 乱七八遭的事情太多了, 一直还有没有动手... foxpro2005 发表于 2014-5-11 19:31
呵呵,不错, 楼主把我共享出来的"STM32的硬件I2C+DMA+中断的模式传输" 修改运用得很好, 赞一个 {:victo ...
感谢你贡献了很实用的底层模块,以前一直用的IO模拟I2C。。。速度太慢了。。。。 楼主,你的卡尔曼或者互补滤波器怎么用的哦?我用滤波器的时候,摇晃小车速度比较慢的时候效果一般
但是摇晃小车速度变快,那么延时就很明显,这个你是怎么解决的哦? w475696010 发表于 2014-5-15 20:38
楼主,你的卡尔曼或者互补滤波器怎么用的哦?我用滤波器的时候,摇晃小车速度比较慢的时候效果一般
但是摇 ...
试着先不加积分项,,,从微分 比例 参数调。。。。我一开始也和你差不多 调参数是个经验活 哦,谢谢楼主哈。。 楼主,问下关于小车速度和位置问题,下面是找的别人的代码:速度怎么就是左右轮子的脉冲值乘以0.5?原理不是很清楚,比如说我的小车轮子半径为r、小车采用的编码器,能得到小车的实际位置,那么我的小车速度用 实际改变位置(距离)/采样时间=速度? 还有下面代码小车的距离是通过对速度低通滤波后得到的position_dot_filter+=position_dot*0.15; 但是这个怎么就变成距离了?总结一句话,不知道该怎样得到速度值和位置值。
position_dot=(speed_real_LH+speed_real_RH)*0.5;
// position_dot=-PWM*0.0027;
position_dot_filter*=0.85; //车轮速度滤波
position_dot_filter+=position_dot*0.15;
position+=position_dot_filter;
而你的PID用的是结构体方式,但是感觉没有用全,只用了一部分下面代码看的不是很明白。
if(Stand)
{
errorAngle =angle; //设立平衡位置
PTerm = errorAngle *pid_out.P;//*Singal(errorAngle);//
DTerm= gyroData*pid_out.D;//
axisPID=(short)(PTerm+DTerm+0.5);
} 我的电机带AB相的编码器 是不是就可以不用正交编码器了
我把编码器输入的两相接到外部中断引脚上 在中断里面测速 感谢大神分享~ justdomyself 发表于 2014-5-20 14:37
我的电机带AB相的编码器 是不是就可以不用正交编码器了
我把编码器输入的两相接到外部中断引脚上 在 ...
STM32 定时器的正交编码器模式不就是专门为AB两厢输出的编码器定制的么? 直接输入给定时器的两个通道 CH1 和CH2 由硬件得出带符号的速度值 ,符号代表方向 数值代表大小。。。。为什么还要接到外部中断去处理? w475696010 发表于 2014-5-19 18:57
楼主,问下关于小车速度和位置问题,下面是找的别人的代码:速度怎么就是左右轮子的脉冲值乘以0.5?原理不 ...
你采样的左右两边的轮子的车速 当然要取平均得到整个车子的均速。。。然后对车速积分不就得到 位移了。。。 lc125253647 发表于 2014-5-28 19:49
STM32 定时器的正交编码器模式不就是专门为AB两厢输出的编码器定制的么? 直接输入给定时器的两个通道 CH ...
画板子的时候没有考虑到这里一点 没有连到TIM1的管教上,
当时只想着用外部中断去计数 没用过stm32的正交编码器 justdomyself 发表于 2014-5-28 19:57
画板子的时候没有考虑到这里一点 没有连到TIM1的管教上,
当时只想着用外部中断去计数 没用过stm3 ...
看看 你配置的那个引脚 是不是某个定时器的复用引脚 或许还可以挽救 PA0 PA1PWM输出控制电机
PA2PA3接的一路A\B相信号检测 估计没用 justdomyself 发表于 2014-5-28 21:17
PA0 PA1PWM输出控制电机
PA2PA3接的一路A\B相信号检测 估计没用
PA2 和 PA3接在定时器2的通道3 和4,虽然不能用正交编码器模式 ,但是可以配置成一般编码器模式的,即只能将A或者B的某一相接入通道,配置成外部时钟输入去激发定时器计时,这样就可以在等间隔时间去读取计数器值了,这样读取的速度只有大小,没有方向。。。。。不过,你可以在软件里面 利用PWM的输出极性来判断方向的。。。。。
不错呀。。。。 给力,顶顶。。 谢谢楼主的共享,回去也做一个玩玩 mark。。。。。。。 楼主,引脚接口能否说下在哪里修改呀~找了好久没找到 kindlw 发表于 2014-6-11 21:35
楼主,引脚接口能否说下在哪里修改呀~找了好久没找到
举个列子 你要改那个功能模块的引脚接口?
比如I2C模块的引脚:你可以大致 main>BSP_INIT>I2C_EE_Init> 里面就有关于 GPIO的配置。。。。
其他 就按照此方法查找。。。。。右键>go to defien of....
谢谢楼主,我的小车终于搞定了,哇哈哈哈,不过还要继续完善。。。。谢谢啦{:handshake:} w475696010 发表于 2014-7-15 13:37
谢谢楼主,我的小车终于搞定了,哇哈哈哈,不过还要继续完善。。。。谢谢啦 ...
很好 很强大。。。最近一直在忙着考试好久没有玩这个了 。。。。 非常好的资料。谢 学习一下
牛,顶起 感谢楼主,平衡小车,准备开工,学习了 mark一下,自平衡小车 一直以为STM32的硬件I2C有问题,实际上自己也测试了,确实是有问题,今天又看到有人用硬件I2C,下下来研究一下。 多谢楼主,先收了,回头再看 xylslss 发表于 2014-8-19 17:40
一直以为STM32的硬件I2C有问题,实际上自己也测试了,确实是有问题,今天又看到有人用硬件I2C,下下来研究 ...
我也是借鉴 坛子里面的 硬件I2C互相学习 正在做自平衡,谢谢分享{:smile:} 非常好的东西,谢谢分享。
页:
[1]
2