今天又去那边测设备咬了好几个包,guoqi真是sb里面的人也太sb了闹心大老爷们拿嘴当屁股胡说,做程序员太弱势了还是sb项目经理产品经理好 就瞎胡沁就行

一、STM32平衡自行车

这是一个比较丑的自行车,,,

嵌入式分享合集47_stm32

自行车平衡理论

模型分析

1 倒立摆

    很显然我们知道自行车在左右方向上不稳定,这是一个很常见的物理模型——倒立摆。

嵌入式分享合集47_三极管_02

    顾名思义,倒立摆的意思就是倒着的摆,比如一个倒着的杆,

嵌入式分享合集47_三极管_03

    倒立摆的特性:不稳定,只要偏离平衡位置,就会有一个力(重力的分力)使系统更加偏离平衡位置,这样偏差就会越来越大。

    一般倒立的杆在前后左右方向都有可能倒下,在二维的平面上不稳定;而自行车仅在左右方向上可能倒下,是一维的倒立摆,这要简单一些。

    以下是几个生活中常见的倒立摆例子:

嵌入式分享合集47_三极管_04

2 自行车的平衡控制

    自行车属于倒立摆模型,倒立摆是不稳定的,那么倒立摆应该如何控制才能平衡呢?

我们把问题拆分一下:

  • 怎样的状态才叫平衡?
  • 我们能控制的是什么?
  • 如何控制才能稳定平衡?

2.1 怎样的状态才叫平衡

    我们要对”平衡”进行数学描述,所谓的平衡其实就是倒立摆的倾角稳定在一个我们想要的值。

嵌入式分享合集47_三极管_03

    通常我们想要平衡在θ = 0处。

2.2 我们能控制的是什么

    对于倒立摆模型,通常我们能控制的是底端的力或速度或位置,不同的控制量对应的控制方法不同。

    对于自行车来说,它的控制方式不像通常的倒立摆那样直接控制底部,而是间接地通过转向来控制,当自行车以一个固定的速度前进时,自行车把手以一定角度进行转向(设为α),自行车会做相应半径的圆周运动,产生相应大小的”离心力”。

    在自行车这个费惯性系里看来,只要对把手进行一定角度的转向(α),就会产生一个相应大小的横向力:

嵌入式分享合集47_单片机_06

    这就是我们进行平衡控制时的实际控制量——把手转角α,只要控制它就能控制回复力。

2.3 如何控制才能平衡

    上面我们已经能够通过转向产生回复力,这个回复力可以把倒立摆”掰回”平衡位置,有往回掰的回复力就能稳定平衡了吗?

    并不是这样,我们再来回顾一下中学物理:

过阻尼状态的摆会以较慢的速度回到平衡位置;欠阻尼状态的摆会很快回到平衡位置,但会在平衡位置来回摆动;临界阻尼状态的摆会以最快的速度稳定在平衡位置。

    结合到实际的自行车平衡中就是:

如果恢复力不够大,就无法矫正,或者矫正速度很慢,这会导致系统不稳定;如果回复力过大,就会导致矫正过度,这也会导致系统不稳定;我们最希望的状态就是回复力刚刚好,刚好使倒立摆快速回到平衡位置,又不至于矫正过度。

    这是一个复杂的数学计算过程,回复力大小会在系统运行时不断地计算(本平衡自行车是20ms计算一次),用到的是PID算法,会在后面详细介绍。

3 自行车平衡需要解决的基本问题
  • 获取左右方向倾角θ
  • 以合适的算法控制转角α使系统稳定平衡

    这将会在下面详细讨论。

姿态检测

1 检测的是什么

    检测的是自行车左右倾斜的角度。

2 怎么检测

    用一个叫gy521的模块,里面用的是mpu6050芯片,带有陀螺仪和加速度传感器。

    gy521的具体使用会在第三篇-实践篇介绍,这里我们知道通过这个模块我们可以得到自行车各个方向的加速度和角速度。注意哦,我们不能直接得到倾斜角度,我们的到的是各个方向的加速度和角速度,需要进行一些复杂的计算才能得到正确的倾斜角度。

常用的算法有互补平衡滤波、卡尔曼滤波。

PID算法

    前面已经分析了,我们通过控制把手转角来控制回复力,我们需要实时计算一个合适的回复力使系统稳定平衡。

嵌入式分享合集47_三极管_07

    有一个小球在光滑球面上,小球的位置是x,光滑球面顶端在L处,我们可以控制小球水平方向力F,现在要求让小球稳定平衡在x0处。

    先看简单情况x0=L,此时偏差为L-x,

    我们给出一个比例项(P) F = kp*(L-x),这样就会有一个回复力,当偏差存在时就会有一个力把小球拉回L处。

    这存在的问题是,小球接近L时是会有一定速度的,小球越来越接近L,此时的力仍然是在把小球往L处拉,这会导致小球到达L时(我们想要的位置)速度很大,小球无法立刻停下来,而是会冲过去。

    这样小球就会在L附近来回摆动,这是不稳定的状态,属于欠阻尼状态。

    为了解决上述问题需要加一个微分项(D) F = kd*dx/dt = kd*v,所谓”微分”指的是位置x对时间的微分,说白了就是速度。

    意思就是当速度越大,就产生一个反向的力使速度减小,这样就可以防止出现上面小球冲过去的。

    可以认为这一项具有”预测”功能,预测小球下一时刻的状态从而提前做出反应,预测小球将要到达L处,提前减速。

    也可以认为这一项具有阻尼作用,相当于系统中有一个和速度成比例的阻尼力。

    这个”阻尼力”调得过小会导致欠阻尼状态,调得过大会导致过阻尼状态。

    积分项此时可以不用,积分项是当平衡位置x0不等于L时使用的,

    当平衡位置不是L处,那么当小球静止在平衡位置x0时,由于在坡道上会有一个恒定的横向偏移力,此时比例调节作用为0(Δx=0),微分调节作用也是0(v=0),所以小球在该处无法平衡,会在更远离平衡位置处达到平衡,那么就会有一个长时间存在的偏差。

积分作用就是检测偏差进行累积,对于上面这个长时间存在的偏差进行积分(累积叠加),使系统在长时间范围可以稳定在要求的平衡位置。

平衡自行车-实践篇

    在本文将会介绍平衡自行车的具体制作过程,包括机械、电路和代码。

材料

机械

嵌入式分享合集47_串口_08

电路

嵌入式分享合集47_单片机_09

动力部分

传动方式

    如图,我用的是皮带或者齿轮传送的方式,因为比较好实现。

嵌入式分享合集47_串口_10

电机选择

    这个DIY是不考虑变速情况的,平衡的参数都是按照一个固定速度调的。

所以动力部分的作用就是提供一个恒定的速度,并且这个速度尽可能稳定,尽可能不受外部影响。

    电机应选择扭力大一些、转速稳定的减速电机。

嵌入式分享合集47_串口_11

电机供电

    电机是直接供电还是使用升压模块供电要根据电机特性,有些电机用升压模块可以提高功率,有些大电流电机用升压模块反而可能限制了电流。

    我这里用升压模块升到12v给N20电机供电的。

嵌入式分享合集47_串口_12

    另外,电机通过三极管受stm32控制,通过控制占空比也可以限制电机输出的功率。

转向部分

    转向部分用一个舵机带动把手转动即可。

嵌入式分享合集47_串口_13

电路

    在GitHub工程里有详细的引脚连接表

 https://github.com/nicekwell/balance_bike

供电

  • 用3.3v稳压芯片给整个控制系统供电,包括单片机、GY521模块、蓝牙模块。
  • 用5v稳压芯片给舵机供电。
  • 用12v升压模块给电机供电。

下载

    我是用串口给stm32下载程序的。

嵌入式分享合集47_单片机_14

GY521

    这个模块通过i2c通信,只需要连接4根线。

  • 3.3v
  • GND
  • PB0    GY521 I2C SCL
  • PB1    GY521 I2C SDA (用的是IO模拟i2c)

电机

    点击用12v升压模块供电,由于不需要反转,用三极管即可直接驱动,电路图如下:

嵌入式分享合集47_stm32_15

    加三极管的目的是为了可以通过调节PWM占空比来限制输出功率,但我的实际情况是100%输出时动力才勉强足够。所以如果你不需要限制电机输出功率,或者通过其他方式限制输出功率,也可以不要三极管,不通过单片机控制。

舵机

    舵机是用5v供电的,而单片机是3.3v电平,对于PWM控制脚可以通过2个三极管实现同相的电平转换:

嵌入式分享合集47_嵌入式硬件_16

蓝牙模块

    下图是我使用的蓝牙串口模块,可以实现串口透传,只需要4根线连接:vcc、gnd、txd、rxd。

嵌入式分享合集47_stm32_17

    蓝牙模块是用来调试和遥控的,没有它也能跑。建议还是加上这个模块,在调试PID擦数时会非常方便。

代码结构

    代码提交在GitHub,点击阅读原文直达。

    主要分为3个部分:

  • 基础的驱动程序,实现电机、舵机、gy521数据读取;
  • 平衡控制系统,核心是一个20ms定时器,每20ms进行一次数据采集、计算和响应;
  • 遥控和调试系统,实现log输出、接收遥控信息。

平衡控制

    main函数会初始化一个定时器20ms中断一次,调用 main/balance.c 里的 balance_tick 函数,平衡算法在 main/balance.c 实现。

    每20ms到来会执行一次:

  • 读取传感器加速度和角速度信息。
  • 互补平衡滤波计算当前姿态。
  • 用PID算法计算出前轮转角。

遥控和调试

    两部分:状态输出和指令接收。

状态输出

    在main函数的while循环里,利用串口中断构建一个简单的界面显示状态。

指令接收

    串口接收到的数据会传给main/control.c,该文件分析串口数据,解释成相应的操作。主要是PID参数调节  

二、电压5V的来历

V来自于TTL电平。5为True,0为False,之后用了压降更低的PN节,衍生出了3.3这个电平。

    12V和24V来自于汽车电瓶,早年乘用车又12V和24V两个系统,现在一般小型车12V,商用车24V,再究其由来应该是铅酸电池。

    所以3.3V和5V一般出现在信号电路或者单片机等VCC供电,而12V/24V一般出现在低压动力电,例如主板、显卡、轴流风机、监控器。硬件决定系统基础,如果锂电池早点应用的话估计还会有3.7/7.4这个系统。

    为什么很多单片机的工作电压是5v?

    因为大多数芯片都是5V的TTL电平,要做到电平兼容,电平匹配,避免要电平转换操作,所有很多单片机的工作电压都是5V。早期(196x)的晶体管电路(TTL)单管的压降是0.7V。一个电路里经常有多个晶体管串联。比如4管串联,电源至少保证0.7x4=2.8v才能保证电路正常工作。所以最早有3V 5V等标准。后来LM7805(197x)电源IC出来以后,5V成了事实标准。

    TTL指的是TTL电平,0~5V之间,小于0.2V输出低电平,高于3.4V输出高电平。全称Transistor-Transistor Logic,即BJT-BJT逻辑门电路,是数字电子技术中常用的一种逻辑门电路,应用较早,技术已比较成熟。TTL主要有BJT(Bipolar Junction Transistor 即双极结型晶体管,晶体三极管)和电阻构成,具有速度快的特点。最早的TTL门电路是74系列,后来出现了74H系列,74L系列,74LS,74AS,74ALS等系列。

    但是由于TTL功耗大等缺点,正逐渐被CMOS电路取代,TTL输出高电平》2.4V,输出低电平《0.4V。在室温下,一般输出高电平是3.5V,输出低电平是0.2V。最小输入高电平和低电平:输入高电平》=2.0V,输入低电平《=0.8V,噪声容限是0.4V。

    为什么很多都是5V,而且有大量电源芯片支持的也是5V。

    电压浮动为5%,而电压标准,在A/D当中使用,标准应该是5.12V。

嵌入式分享合集47_三极管_18

    因为512 是2的N次方,这样A/D 的每一个字都是一个整数,当作为无符号计算的时候,更简单,但是没见到哪个成品用这个电压的,大部分都是5V,为什么不用呢?

    因为做5.12的标准电压成本会成倍增长。5V与5.12V精度差别在百倍,小数点后0.12V,基本很难做到高精度标准电压,市场通用电压为5V,上浮一定百分比。

    2008年11月发布的STC12系列单片机数据手册中,STC12C系列的单片机电压范围是3.3~5.5V;STC12L系列的单片机电压范围是2.2~3.6V。如果选择STC12C系列的单片机,只要单片机的工作频率不是太高,使用3.7V供电是没有任何顾虑的,官方声称单片机的抗干扰能力可以达到4000V,但实际应用说法不一。

嵌入式分享合集47_三极管_19

    大多数单片机都是 TTL 电平,各自的高低电平定义不一样;

    当电源电压为5V时:51,AVR单片机是5V;

    当电源电压为3.3V时:51,AVR单片机高电平是3.3V;

    ARM如LPC2138,电源电压只能为3.3V,IO输出高电平为3.3V;

    但IO口可承受5V电压现在单片机工作电压主要有两种:一种工作在3.3V 一种工作在5V。