搜索
bottom↓
回复: 136

我的STM32自平衡小车+DIY遥控器

  [复制链接]

出0入0汤圆

发表于 2014-4-9 15:18:55 | 显示全部楼层 |阅读模式
借鉴坛子里面的各种开源资料,我的自平衡小车也摇摇晃晃的站起来了,虽然和坛子里面的大神比起来差的太远,但是也是经过自己琢磨的。以此回馈论坛,将所有的资料都上传(不敢说开源,反正都是从坛子里面下载的):

/*************************************************************************************/
硬件部分:
自平衡小车:
      主控制器:STM32F103RB  72Mhz
      传感器   :MPU6050    I2C 协议传输 (直接采用STM32的硬件I2C+DMA读取的,速度相当快哦)
      电机驱动:L298N电机驱动模块 双H桥直流电机驱动 ,这个不用我多说,淘宝上一大把
      无线传输:NRF24L01  SPI协议传输 (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的驱动都是移植并修改的,请直接参考程序即可:
/*************************************************************************************/





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2014-4-9 15:20:59 | 显示全部楼层
无图无真相:

http://v.youku.com/v_show/id_XNjg1ODkwMjQ0.html  最初的调试
http://v.youku.com/v_show/id_XNjk2MTk5NTg4.html  遥控板视频

出0入0汤圆

 楼主| 发表于 2014-4-9 15:33:06 | 显示全部楼层
忘了件匿名的上位机贴出来了:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-4-10 22:24:30 | 显示全部楼层
真心不错,遥控器来感觉挺爽的,什么时候我也来玩玩系统,哈哈

出100入101汤圆

发表于 2014-4-10 23:14:15 | 显示全部楼层
学习了!

出0入0汤圆

发表于 2014-4-11 07:27:24 来自手机 | 显示全部楼层
下来看看,学习

出0入0汤圆

发表于 2014-4-11 10:57:07 | 显示全部楼层
学习                           

出0入0汤圆

发表于 2014-4-11 11:18:57 | 显示全部楼层
楼主上传的很详细!多谢!

出0入0汤圆

发表于 2014-4-11 17:04:10 | 显示全部楼层
xuexile ,多些楼主

出0入0汤圆

 楼主| 发表于 2014-4-12 11:46:12 | 显示全部楼层
JIFEINOVEL 发表于 2014-4-10 22:24
真心不错,遥控器来感觉挺爽的,什么时候我也来玩玩系统,哈哈

恩恩 可以做一个送给小侄子当玩具 呵呵

出0入0汤圆

 楼主| 发表于 2014-4-12 11:47:40 | 显示全部楼层

我也是从坛子里面学习的,大家都都互相学习嘛,才会有进步。。。

出0入0汤圆

 楼主| 发表于 2014-4-12 11:48:54 | 显示全部楼层
961306474 发表于 2014-4-11 11:18
楼主上传的很详细!多谢!

再多的资料 消化了才是自己的资料,,,加油

出0入0汤圆

发表于 2014-4-12 13:44:10 | 显示全部楼层
头像够吊,嘿嘿

出0入0汤圆

 楼主| 发表于 2014-4-12 16:22:46 | 显示全部楼层
bbsview 发表于 2014-4-12 13:44
头像够吊,嘿嘿

  

出0入0汤圆

发表于 2014-4-12 17:34:59 | 显示全部楼层
lc125253647 发表于 2014-4-12 11:48
再多的资料 消化了才是自己的资料,,,加油

嗯嗯,我会努力的!

出0入0汤圆

发表于 2014-4-13 10:47:44 | 显示全部楼层
问下楼主,用STM32电机编码器脉冲接哪个引脚?是外部定时器吗?大概怎么运用?

出0入0汤圆

 楼主| 发表于 2014-4-13 12:00:15 | 显示全部楼层
w475696010 发表于 2014-4-13 10:47
问下楼主,用STM32电机编码器脉冲接哪个引脚?是外部定时器吗?大概怎么运用? ...

一般情况下是接在通用定时器的通道1和2 (具体哪个引脚,还要看你用的哪个定时器,再根据定时器的映射找到对应的IO引脚),用定时器的正交编码器模式 就可以了(这种模式叫做M法测速,既是在等间隔的时间T内测量脉冲数M,适合测量高速情况);
不过我的程序 是用的另外一方法,叫做T法测速(就是测量一个脉冲高电平持续的时间T,适合测量低速情况),,这种情况接在四个通道的任何一个都可以!

出0入0汤圆

发表于 2014-4-13 14:55:47 | 显示全部楼层
lc125253647 发表于 2014-4-13 12:00
一般情况下是接在通用定时器的通道1和2 (具体哪个引脚,还要看你用的哪个定时器,再根据定时器的映射找 ...

谢谢楼主,我在看这东西,第一次用STM32,呵呵

出0入0汤圆

发表于 2014-4-13 16:11:12 | 显示全部楼层
我用的STM32f103rb,不知道在什么上找定时器的映射图?我在STM32中文参考手册上找到只有定时器1到4的图,不知道对于我的型号使用不

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2014-4-13 20:38:10 | 显示全部楼层
w475696010 发表于 2014-4-13 16:11
我用的STM32f103rb,不知道在什么上找定时器的映射图?我在STM32中文参考手册上找到只有定时器1到4的图,不 ...

你用的是STM32F10XX系列的参考手册,整个手册里面的内容针对整个系列,具体要查某个型号芯片的引脚映射还要看 具体某个芯片手册。。。

你截图上的内容是参考手册的第8章的3.7小节 (8.3.7)里面有对定时器复用功能的重映射的说明,从这里也可以发现其实和芯片手册里面是一样的!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-4-14 08:34:22 | 显示全部楼层
哇塞谢谢楼主,终于知道这东西了。感激中。。。。

出0入0汤圆

发表于 2014-4-16 16:55:55 | 显示全部楼层
楼主把相关硬件也贴出来啊,供大家学习!!!

出0入0汤圆

 楼主| 发表于 2014-4-16 17:59:23 | 显示全部楼层
yst1571661 发表于 2014-4-16 16:55
楼主把相关硬件也贴出来啊,供大家学习!!!

我的车子用的都是一些模块的组合,比如STM32最小系统,电机驱动模块,NRF2401模块,MPU6050模块。。。。
这些模块可以自己做,不过我都是在淘宝上买的,很容易搜索。。。。

出0入0汤圆

发表于 2014-4-19 16:56:07 | 显示全部楼层
楼主的小车模型,能不能给个链接啊,非常感谢

出0入0汤圆

发表于 2014-4-20 23:01:16 | 显示全部楼层
不错,也想玩玩,向楼主学习学习......

出0入0汤圆

发表于 2014-4-22 19:16:35 | 显示全部楼层
最近也在开始搞这些,载下来模仿

出0入0汤圆

发表于 2014-5-8 13:52:31 | 显示全部楼层
楼主问下,你在粗的时候,用输入捕获是怎么捕获的哦。比如我想用TIM3_1和TIM3_2来做捕获,能做到吗?大概怎么弄,我 到网上查了说用PWM捕获只能一个定时器做一个捕获?用不同方法一个定时器能做两个捕获,这个具体怎么回事,谢谢楼主!

出0入0汤圆

发表于 2014-5-8 14:02:58 | 显示全部楼层
我看你用的是定时器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通道,怎么完成捕获不是很清楚

出0入0汤圆

发表于 2014-5-8 14:19:26 | 显示全部楼层
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_TimeBaseInitTypeDef  TIM_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在整个工程中什么作用?也不是很明白

出0入0汤圆

发表于 2014-5-8 15:50:33 | 显示全部楼层
我找到正点原子的资料看懂了TIM3大部分操作,还有TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; //CC1S=01         选择输入端 IC1映射到TI1上和TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01         选择输入端 IC1映射到TI1上  这两个地方,怎么知道哪个定时器的哪个通道对应于哪个捕获通道的?  还有前面问的TIM4还是没看懂他到底作用是干嘛???谢谢楼主解答

出0入0汤圆

发表于 2014-5-8 16:01:14 | 显示全部楼层
                (*Speed1)=(u16)(1000000/(Timer_count1));
                (*Speed2)=(u16)(1000000/(Timer_count2));  楼主,这里为什么用1000000除以高电平时间?
还有void Test_Speed(u16 *Current_speed1,u16 *Current_speed2)
{
static short SPEED_BUF[2][FILTER_NUM2];
  u8 i=0;

static u8 filter_cnt=0;
int SPEED_SUM=0;


SPEED_BUF[0][filter_cnt]=(*Current_speed1);
SPEED_BUF[1][filter_cnt]=(*Current_speed2);
SPEED_SUM=0;
for(i=0;i<FILTER_NUM2;i++)
{
  SPEED_SUM+=SPEED_BUF[0][i];
}
*Current_speed1=(u16)(SPEED_SUM/FILTER_NUM2);
SPEED_SUM=0;
for(i=0;i<FILTER_NUM2;i++)
{
  SPEED_SUM+=SPEED_BUF[1][i];
}
*Current_speed2=(u16)(SPEED_SUM/FILTER_NUM2);
filter_cnt++;
if(filter_cnt==FILTER_NUM2)        filter_cnt=0;




}

这个函数的目的是不是将得到的速度进行10次求平均处理?

出0入0汤圆

发表于 2014-5-8 20:16:22 | 显示全部楼层
楼主,还是没看明白 怎么把 speed1 和speed2传给 u16 *Current_speed1,u16 *Current_speed2的

出0入0汤圆

发表于 2014-5-9 09:01:43 | 显示全部楼层
麻烦楼主看到了回下,谢谢。。。!

出0入0汤圆

 楼主| 发表于 2014-5-9 10:39:30 | 显示全部楼层
w475696010 发表于 2014-5-8 13:52
楼主问下,你在粗的时候,用输入捕获是怎么捕获的哦。比如我想用TIM3_1和TIM3_2来做捕获,能做到吗?大概怎 ...

测速有T测法和M测法,其实一般自平衡要用M测法,也就是通过STM32的定时器的正交编码器模式,记录编码盘的脉冲数,这种方法要求码盘安装在高速轴上面,而且线数大才有可靠地精度。。。。由于我的电机高速轴没有引出来,只能安装在输出轴(低速轴)上面,100线的码盘用M测法数据跳跃太大,肯本没有精度,所以我的程序用的是T测法,既是将STM32定时器配置成输入捕获模式,测量两个脉冲时间的时间T来转换成速度。。。。。。具体的转换公式你可以在论坛里面搜到!

出0入0汤圆

 楼主| 发表于 2014-5-9 10:40:53 | 显示全部楼层
w475696010 发表于 2014-5-8 14:02
我看你用的是定时器TIM3,的通道1和2
//初始化TIM5输入捕获参数  TIM_ICMode_ICAP
        TIM_ICInitStructure.T ...

如果配置成输入捕获模式的话,四个通道都可以用,若是配置成正交编码器模式,则只能在通道1 2 上面

出0入0汤圆

 楼主| 发表于 2014-5-9 10:41:53 | 显示全部楼层
w475696010 发表于 2014-5-8 14:19
void TIM4_IRQHandler(void)//0.5ms interput
{       
  if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)// ...

哦 ,定时器我没有用到,定时器是我以前用M法测速的时候用到的,后来就注释掉了

出0入0汤圆

 楼主| 发表于 2014-5-9 10:49:58 | 显示全部楼层
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)

第二个问题你说对了,我用的指针做形参

出0入0汤圆

 楼主| 发表于 2014-5-9 10:51:56 | 显示全部楼层
w475696010 发表于 2014-5-8 20:16
楼主,还是没看明白 怎么把 speed1 和speed2传给 u16 *Current_speed1,u16 *Current_speed2的 ...

我使用的指针变量作为函数的形参,实际传入的就是变量的地址,那么就可以在函数里面改变传入地址里面的内容了。。。。。

出0入0汤圆

 楼主| 发表于 2014-5-9 10:52:33 | 显示全部楼层
w475696010 发表于 2014-5-9 09:01
麻烦楼主看到了回下,谢谢。。。!

最近 才看到。。。。

出0入0汤圆

发表于 2014-5-9 14:43:24 | 显示全部楼层
楼主好人!谢谢回答的这么详细,哪我的电机是
空载转速: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[0][i];
}
*Current_speed1=(u16)(SPEED_SUM/FILTER_NUM2);
你这里将速度求平均数,但是这10个速度的采样间隔是多少,也没看见,不会连续采样求10次平均把。

再次感谢楼主的街道

出0入0汤圆

发表于 2014-5-9 14:50:49 | 显示全部楼层
还有一个问题是速度采集回来了,变成 Current_speed 那么后续处理这些速度参数在哪里处理的,我还没找到,想问下谢谢!

出0入0汤圆

发表于 2014-5-9 14:58:12 | 显示全部楼层
做得挺好的

出0入0汤圆

 楼主| 发表于 2014-5-9 16:03:48 | 显示全部楼层
w475696010 发表于 2014-5-9 14:43
楼主好人!谢谢回答的这么详细,哪我的电机是
空载转速:8100RPM(转每分钟)

你的电机自带有编码器,肯定要用M测速,不能用我的方法。。。。。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-5-9 16:26:17 | 显示全部楼层
哦,我看了下STM32正交编码就是产生PWM波输出?

出0入0汤圆

发表于 2014-5-9 16:27:12 | 显示全部楼层
我对正交编码不了解,我上百度看看

出0入0汤圆

发表于 2014-5-9 16:38:01 | 显示全部楼层
我网上查了下,正交编码是对输入的PWM波进行分析处理,但是必须知道两路相互垂直的波,意思是一个点击的两个编码器都要用?分别接CH1和CH2(因为前面你说了这种模式下只有这两个通道能用),那是不是两个电机就要用两个定时器,也就是4个定时器通道?如果是这样,我在设计电路板的时候没有想到这种方法,4个编码接口都接在了TIM3的CH1 、CH2、CH3、CH4

出0入0汤圆

发表于 2014-5-9 17:00:37 | 显示全部楼层
楼主,貌似我的TIM4 CH1、CH2引出来了的,分别是PB6、PB7脚对吗,哪我就可以用正交编码?

出0入0汤圆

 楼主| 发表于 2014-5-9 17:01:45 | 显示全部楼层
w475696010 发表于 2014-5-9 16:38
我网上查了下,正交编码是对输入的PWM波进行分析处理,但是必须知道两路相互垂直的波,意思是一个点击的两 ...

你的编码器有AB两厢输出的,其相位刚好相差90度,可以通过相位先后来判断轮子的转向,然后你真的要用到两个定时器才能配置两个编码器。。。不过 你也不必重新做板子,大不了只测量一个轮子的速度来代表整个车子的速度。。。。。

出0入0汤圆

发表于 2014-5-9 17:10:59 | 显示全部楼层
坑爹啊,引脚是解出来了,但是没有上拉,只有以后改进控制板的时候用正交编码了。。。。

出0入0汤圆

 楼主| 发表于 2014-5-9 17:12:16 | 显示全部楼层
w475696010 发表于 2014-5-9 17:10
坑爹啊,引脚是解出来了,但是没有上拉,只有以后改进控制板的时候用正交编码了。。。。 ...

STM32 不是内部有上拉输入配置么?

出0入0汤圆

发表于 2014-5-9 17:37:26 | 显示全部楼层
意思是把这两个引脚配置成上拉输入模式,然后用PWM输入模式,就能用了,谢谢哈! 楼主,如果点击速度策回来了,这个速度该怎么处理我还是不是很清楚,你有没有关于M测速法的一些资料地址,我去看看。   谢谢楼主了!(其实我第一次用STM32,呵呵谢谢楼主指点!)

出0入0汤圆

 楼主| 发表于 2014-5-9 20:05:53 | 显示全部楼层
w475696010 发表于 2014-5-9 17:37
意思是把这两个引脚配置成上拉输入模式,然后用PWM输入模式,就能用了,谢谢哈! 楼主,如果点击速度策回来 ...

我记得就只在智能小车这个分贴看的,哪个帖子就不记得了,你在这个论坛找找看,或许可以找到很多资料了

出0入0汤圆

发表于 2014-5-9 22:49:16 来自手机 | 显示全部楼层
mark多谢楼主

出0入0汤圆

发表于 2014-5-10 08:26:53 | 显示全部楼层
谢谢楼主,我找找。。。

出0入0汤圆

发表于 2014-5-10 15:21:21 | 显示全部楼层
楼主,你卡尔曼滤波的输入值是什么哦?
/***************Kalman***filter************************************/

void Kalman_Filter(float angle_m,float gyro_m)        //gyro_m:gyro_measure   比如这两个参数需要什么样的规格?比如说我用的是 加速度传感器 +三轴角度传感器(我只采集一个方向值), 在这种情况下,我的值需要怎么处理后给卡尔曼?哪个采集值分别对应于哪个参数?

2、还有就是这个滤波过后输出值是什么,是机器实际偏离角度?但是是哪个变量表示最后输出,我没看懂。
/******************************************//******************************************/

谢谢楼主解答哈!

出0入0汤圆

发表于 2014-5-10 15:48:01 | 显示全部楼层
我的意思就是卡尔曼滤波,那几个参数需要自己修改,哪几个参数需要自己传入(并且传入参数的要求),哪个参数是最后的结果?

出0入0汤圆

发表于 2014-5-10 17:30:55 | 显示全部楼层
楼主,你代码里面:
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;

为什么要做这样的运算,其目的是什么,我的只有一个加速度输出量,和一个角度输出量,这该如何是好?

出0入0汤圆

发表于 2014-5-10 17:36:34 | 显示全部楼层
void complementry_Filter(float gyro_m,float acc_m);这个函数作用也有点奇怪,这是修正ADC结果吗?但是修正的标准是什么?

出0入0汤圆

 楼主| 发表于 2014-5-10 20:24:03 | 显示全部楼层
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)  其作用都是将加速度和角速度数据进行融合 最后得到实时准确的角度+角速度

前者是互补的列程 后面是卡尔曼的 我放在里面是为了对比两者的效果哪个好一些。。。最后卡尔曼更稳定。。。。。你可以试试互补 可能在不同的车上 两者的效果会有不一样吧。。。。。

出0入0汤圆

 楼主| 发表于 2014-5-10 20:24:25 | 显示全部楼层
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

出0入0汤圆

 楼主| 发表于 2014-5-10 20:26:54 | 显示全部楼层
w475696010 发表于 2014-5-10 17:30
楼主,你代码里面:
void ACC_FIR(float datax,float datay,float dataz)
void ACC_Filter(float datax,flo ...

采集到6050数据 需要减去偏移修正。。。。。然后为什么要乘以一个系数,那是因为我要转换成物理意义上的角速度和加速度参量。。。。。

出0入0汤圆

发表于 2014-5-11 08:30:47 | 显示全部楼层
谢谢楼主,原来是这样子。。我也都试试看。

出0入0汤圆

发表于 2014-5-11 08:50:51 | 显示全部楼层
楼主你真正的执行核心流程是不是一下:
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);这个函数,不晓得我弄对没有

出0入0汤圆

发表于 2014-5-11 10:52:36 来自手机 | 显示全部楼层
楼主用硬件iic没有问题吗,感觉stm32的硬件iic经常出问题的啊。还有就是姿态采集的频率是多少,我的好像做到10ms采集一次就提高不了了额。

出0入0汤圆

发表于 2014-5-11 16:56:09 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2014-5-11 17:45:39 | 显示全部楼层
学习一下  有空我也弄

出0入0汤圆

 楼主| 发表于 2014-5-11 17:49:58 | 显示全部楼层
w475696010 发表于 2014-5-11 08:50
楼主你真正的执行核心流程是不是一下:
void TaskCONTROL(void *pdata)
{

是的 。。。。

出0入0汤圆

 楼主| 发表于 2014-5-11 17:51:01 | 显示全部楼层
chy 发表于 2014-5-11 10:52
楼主用硬件iic没有问题吗,感觉stm32的硬件iic经常出问题的啊。还有就是姿态采集的频率是多少,我的好像做 ...

硬件I2c +DMA 没有问题  很稳定的

出0入76汤圆

发表于 2014-5-11 19:31:42 | 显示全部楼层
lc125253647 发表于 2014-5-11 17:51
硬件I2c +DMA 没有问题  很稳定的

呵呵,不错, 楼主把我共享出来的"STM32的硬件I2C+DMA+中断的模式传输" 修改运用得很好, 赞一个 ...

前段时间,在玩BLDC,准备想搞独轮车的, 乱七八遭的事情太多了, 一直还有没有动手...

出0入0汤圆

 楼主| 发表于 2014-5-11 20:56:50 | 显示全部楼层
foxpro2005 发表于 2014-5-11 19:31
呵呵,不错, 楼主把我共享出来的"STM32的硬件I2C+DMA+中断的模式传输" 修改运用得很好, 赞一个 {:victo ...

感谢你贡献了很实用的底层模块,以前一直用的IO模拟I2C。。。速度太慢了。。。。

出0入0汤圆

发表于 2014-5-15 20:38:04 | 显示全部楼层
楼主,你的卡尔曼或者互补滤波器怎么用的哦?我用滤波器的时候,摇晃小车速度比较慢的时候效果一般
但是摇晃小车速度变快,那么延时就很明显,这个你是怎么解决的哦?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2014-5-15 22:22:24 | 显示全部楼层
w475696010 发表于 2014-5-15 20:38
楼主,你的卡尔曼或者互补滤波器怎么用的哦?我用滤波器的时候,摇晃小车速度比较慢的时候效果一般
但是摇 ...

试着先不加积分项,,,从微分 比例 参数调。。。。我一开始也和你差不多 调参数是个经验活

出0入0汤圆

发表于 2014-5-16 08:55:01 | 显示全部楼层
哦,谢谢楼主哈。。

出0入0汤圆

发表于 2014-5-19 18:57:46 | 显示全部楼层
楼主,问下关于小车速度和位置问题,下面是找的别人的代码:速度怎么就是左右轮子的脉冲值乘以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[Roll];        //设立平衡位置
PTerm = errorAngle *pid_out.P[Roll];//*Singal(errorAngle);//
DTerm=         gyroData[Roll]*pid_out.D[Roll];//
axisPID[Roll]=(short)(PTerm+DTerm+0.5);

}

出0入8汤圆

发表于 2014-5-20 14:37:39 | 显示全部楼层
我的电机带AB相的编码器    是不是就可以不用正交编码器了

我把编码器输入的两相接到外部中断引脚上   在中断里面测速

出0入0汤圆

发表于 2014-5-20 17:46:47 | 显示全部楼层
感谢大神分享~

出0入0汤圆

 楼主| 发表于 2014-5-28 19:49:00 | 显示全部楼层
justdomyself 发表于 2014-5-20 14:37
我的电机带AB相的编码器    是不是就可以不用正交编码器了

我把编码器输入的两相接到外部中断引脚上   在 ...

STM32 定时器的正交编码器模式不就是专门为AB两厢输出的编码器定制的么? 直接输入给定时器的两个通道 CH1 和CH2 由硬件得出带符号的速度值 ,符号代表方向 数值代表大小  。。。。为什么还要接到外部中断去处理?

出0入0汤圆

 楼主| 发表于 2014-5-28 19:51:17 | 显示全部楼层
w475696010 发表于 2014-5-19 18:57
楼主,问下关于小车速度和位置问题,下面是找的别人的代码:速度怎么就是左右轮子的脉冲值乘以0.5?原理不 ...

你采样的左右两边的轮子的车速 当然要取平均得到整个车子的均速。。。然后对车速积分不就得到 位移了。。。

出0入8汤圆

发表于 2014-5-28 19:57:16 | 显示全部楼层
lc125253647 发表于 2014-5-28 19:49
STM32 定时器的正交编码器模式不就是专门为AB两厢输出的编码器定制的么? 直接输入给定时器的两个通道 CH ...

画板子的时候没有考虑到这里一点   没有连到TIM1的管教上,

当时只想着用外部中断去计数     没用过stm32的正交编码器

出0入0汤圆

 楼主| 发表于 2014-5-28 20:00:20 | 显示全部楼层
justdomyself 发表于 2014-5-28 19:57
画板子的时候没有考虑到这里一点   没有连到TIM1的管教上,

当时只想着用外部中断去计数     没用过stm3 ...

看看 你配置的那个引脚 是不是某个定时器的复用引脚 或许还可以挽救

出0入8汤圆

发表于 2014-5-28 21:17:22 | 显示全部楼层
PA0 PA1  PWM输出控制电机

PA2  PA3接的一路A\B相信号检测     估计没用      

出0入0汤圆

 楼主| 发表于 2014-5-28 21:46:54 | 显示全部楼层
justdomyself 发表于 2014-5-28 21:17
PA0 PA1  PWM输出控制电机

PA2  PA3接的一路A\B相信号检测     估计没用

PA2 和 PA3  接在定时器2的通道3 和4,虽然不能用正交编码器模式 ,但是可以配置成一般编码器模式的,即只能将A或者B的某一相接入通道,配置成外部时钟输入去激发定时器计时,这样就可以在等间隔时间去读取计数器值了,这样读取的速度只有大小,没有方向。。。。。不过,你可以在软件里面 利用PWM的输出极性来判断方向的。。。。。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-5-29 19:44:08 | 显示全部楼层
不错呀。。。。

出0入0汤圆

发表于 2014-5-30 16:42:32 | 显示全部楼层
给力,顶顶。。

出0入0汤圆

发表于 2014-6-10 10:22:23 | 显示全部楼层
谢谢楼主的共享,回去也做一个玩玩

出0入0汤圆

发表于 2014-6-10 10:32:43 | 显示全部楼层
mark。。。。。。。

出0入0汤圆

发表于 2014-6-11 21:35:54 | 显示全部楼层
楼主,引脚接口能否说下在哪里修改呀~找了好久没找到

出0入0汤圆

 楼主| 发表于 2014-6-15 21:00:48 | 显示全部楼层
kindlw 发表于 2014-6-11 21:35
楼主,引脚接口能否说下在哪里修改呀~找了好久没找到

举个列子 你要改那个功能模块的引脚接口?

比如I2C模块的引脚:你可以大致 main>BSP_INIT>I2C_EE_Init> 里面就有关于 GPIO的配置。。。。
其他 就按照此方法查找。。。。。右键>go to defien of....


出0入0汤圆

发表于 2014-7-15 13:37:27 | 显示全部楼层
谢谢楼主,我的小车终于搞定了,哇哈哈哈,不过还要继续完善。。。。谢谢啦

出0入0汤圆

 楼主| 发表于 2014-7-15 21:22:21 | 显示全部楼层
w475696010 发表于 2014-7-15 13:37
谢谢楼主,我的小车终于搞定了,哇哈哈哈,不过还要继续完善。。。。谢谢啦 ...

很好 很强大  。。。最近一直在忙着考试  好久没有玩这个了 。。。。

出0入0汤圆

发表于 2014-8-5 08:43:58 来自手机 | 显示全部楼层
非常好的资料。谢

出0入0汤圆

发表于 2014-8-5 14:55:52 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2014-8-5 21:30:57 | 显示全部楼层
牛,顶起

出0入0汤圆

发表于 2014-8-12 11:05:52 | 显示全部楼层
感谢楼主,平衡小车,准备开工,学习了

出0入0汤圆

发表于 2014-8-19 16:58:04 | 显示全部楼层
mark一下,自平衡小车

出0入0汤圆

发表于 2014-8-19 17:40:50 | 显示全部楼层
一直以为STM32的硬件I2C有问题,实际上自己也测试了,确实是有问题,今天又看到有人用硬件I2C,下下来研究一下。

出0入0汤圆

发表于 2014-8-20 09:08:04 | 显示全部楼层
多谢楼主,先收了,回头再看

出0入0汤圆

 楼主| 发表于 2014-8-22 15:59:41 | 显示全部楼层
xylslss 发表于 2014-8-19 17:40
一直以为STM32的硬件I2C有问题,实际上自己也测试了,确实是有问题,今天又看到有人用硬件I2C,下下来研究 ...

我也是借鉴 坛子里面的 硬件I2C  互相学习

出0入0汤圆

发表于 2014-9-15 16:55:57 | 显示全部楼层
正在做自平衡,谢谢分享

出0入0汤圆

发表于 2014-10-14 19:30:26 | 显示全部楼层
非常好的东西,谢谢分享。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 15:51

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表