ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

STM32平衡小车完整制作教程:从原理图到安卓APP

STM32平衡小车完整制作教程:从原理图到安卓APP 简介本资源是一套完整的STM32平衡小车软硬件开发套件面向嵌入式初学者、电子设计竞赛学生及智能车项目开发者解决自平衡控制原理理解难、软硬件协同调试复杂、蓝牙遥控集成门槛高等实际问题。压缩包共351个文件含75个C语言源码.c、71个头文件.h、37个编译中间文件.o/.d及10个Altium Designer原理图.SchDoc与2个PCB工程.PcbDoc覆盖主控、AHRS姿态解算、电机驱动、蓝牙通信等核心模块另有安卓端APK安装包及Java源码支持实时遥控与参数调节。资源大小22.89MB结构清晰含BOM清单、3D电路板图、实物照片及多版本Keil工程uvproj/uvopt便于分模块学习与移植验证。目前已有339人下载学习是少有的集原理图、PCB、双MCU分工源码F103RCT6运动控制C8T6姿态解算、安卓端闭环遥控于一体的高完整性平衡车实践资料。 手里这套资料我整理了很久从硬件到软件再到手机端全都有。很多人做平衡车项目卡在某一环就放弃了——画板子不会、PID调不出来、蓝牙连不上、APK不知道怎么打包。这篇文章我就把自己做STM32平衡小车的完整过程拆开讲一遍原理图怎么画、PCB怎么布局、源码怎么写、安卓端怎么搞每个环节的关键点都给你挑明。先说清楚这套东西能干什么基于STM32F103C8T6主控加上MPU6050姿态传感器、TB6612电机驱动、HC-05蓝牙模块配合自己用AD09画的原理图和PCB实现了两轮自平衡、蓝牙遥控、手机APP实时操控这三个核心功能。适合正在学STM32的嵌入式初学者、准备做毕设或者电赛项目的学生以及想从零搭建一个小型机器人平台的动手党。硬件资料、固件源码、安卓APK和源码都是齐的拿到手就能照着做。1. 项目整体设计与三端架构1.1 先想清楚要做什么功能需求拆解动工之前我习惯先把需求一条条列出来这样后面每一块电路、每一段代码都有明确的目标不会做到一半跑偏。这套平衡小车的核心功能其实可以拆成三个层面自平衡是底层一定要稳车能自己站在原地不倒蓝牙遥控是交互层手机发指令小车响应前、后、左、右姿态反馈是数据层实时把倾角、速度这些状态传回手机显示。自平衡这块核心在于姿态传感器和电机驱动的配合。姿态传感器用MPU6050片上自带陀螺仪和加速度计通过I2C接口把数据给STM32STM32解算出当前车体的倾角再用PID算法算出电机应该往哪个方向转、转多快。这个过程在数学上不复杂但工程上牵扯到滤波、量化误差、响应延时做起来有不少细节。蓝牙遥控这块我选的是HC-05模块工作在经典蓝牙2.0协议下通过UART串口和STM32通信。手机端用Android原生代码写了一个简单的遥控界面界面上有前后左右方向键和一个速度滑块。按下方向键手机通过蓝牙把指令帧发给HC-05HC-05串口转给STM32STM32解析指令帧后调整目标速度或者转向偏置。这套链路延时很低实测下来基本感觉不到卡顿。再把扩展需求也列一下板子用Type-C供电、带电源指示灯、传感器和主控做成可插拔模块、留出串口调试接口方便以后自己做调参和加功能。这些需求不一定全部实现但都要在设计里预留好位置。1.2 硬件端的方案选型为什么是AD09而不是其他EDA原理图和PCB设计这块我选的是Altium Designer 09。虽然现在很多人用AD20、AD21甚至嘉立创EDA但AD09这个版本我自己用了很久界面清爽库文件查找方便生成的PCB文件兼容性好网上参考资源也多用来做这种中小型双层板绰绰有余。如果你用的是新版AD工程文件也能直接打开只是注意一下版本兼容提示。硬件框架上主控选了STM32F103C8T6这是一颗Cortex-M3内核的芯片72MHz主频64KB Flash20KB SRAM对于控制两路电机、读取姿态传感器、解析串口指令这些任务来说性能完全够用。选它的另一个原因是引脚多、封装小LQFP48封装手动焊接难度不大加上网上资料铺天盖地遇到问题几乎都能搜到答案。传感器用MPU6050六轴惯性测量单元内置三轴陀螺仪和三轴加速度计。跟单独买陀螺仪加加速度计方案比MPU6050的DMP数字运动处理器可以直接输出四元数省去自己写姿态解算算法的麻烦。电机驱动用TB6612FNG这是东芝的MOSFET驱动芯片单路最大持续驱动电流1.2A峰值3.2A带低功耗待机模式逻辑电压3.3V到5V都能兼容直接和STM32的GPIO电平对接不用额外做电平转换。1.3 固件端与安卓端软件框架的整体规划固件端编程我用标准外设库Standard Peripheral Library写没用HAL库。原因很直接平衡车这种实时性要求比较高的应用寄存器级的外设配置能让你把每个时钟周期都掌控在手里中断响应时间可预测。当然HAL库也能做但初学阶段我不太推荐因为封装层数太多出了问题不好定位。安卓端用Android Studio开发语言是Java。蓝牙这块用经典蓝牙的socket通信不是BLE低功耗蓝牙——HC-05不支持BLE两者协议栈不一样这个要特别注意。APP结构上分三层蓝牙管理模块负责扫描、配对、连接和数据收发控制界面模块负责UI交互、按钮事件和滑块变化协议解析模块负责组装和解析指令帧。三端联调的时候我的经验是先本地后远程先把PID和小车调稳再把蓝牙模块接上调遥控最后再处理手机APP的指令格式和延时问题。如果一开始就三端全接上出了问题都不知道该查哪一层。2. 硬件电路设计AD09原理图与PCB实战2.1 原理图核心模块设计五块电路一次理清原理图我分成五个模块来画电源管理、主控最小系统、姿态传感器接口、电机驱动、蓝牙串口接口。每个模块单独画框图最后通过电源网络和地网络连在一起。电源管理是首先需要关注的部分。整个系统电压有多个等级电机驱动VM引脚要6V两节18650锂电池串联MCU和蓝牙模块要5VTB6612的VCCMPU6050和逻辑部分要3.3VAMS1117稳压输出。我的做法是两节18650锂电池串联输出7.4V经过一个二极管防反接再分两路一路直接给TB6612的VM供电另一路经过AMS1117-5.0稳压到5V再经过AMS1117-3.3稳压到3.3V。注意AM1117系列压差比较大输入7.4V输出3.3V没问题如果输入只有5V想输出3.3V压差1.7V也勉强够但负载大了发热明显设计时尽量预留余量。主控最小系统这部分STM32F103C8T6需要三个基本电路8MHz外部晶振 两个20pF负载电容BOOT0和BOOT1引脚通过10K下拉电阻接地正常从Flash启动NRST复位引脚接一个100nF电容到地。另外每个电源引脚旁边放一个100nF去耦电容这个不能省。布局上我习惯把晶振放在芯片旁边走线尽量短避免引入高频噪声。姿态传感器接口是I2C总线SDA和SCL上各接一个4.7K上拉电阻到3.3V。这个上拉电阻很有讲究——阻值太大I2C通信速率上不去阻值太小功耗增大且信号边沿变陡容易产生振铃。4.7K是MPU6050数据手册推荐的标准值我实测在400KHz速率下工作正常。MPU6050的AD0引脚接地I2C地址就是0x68接高电平则变成0x69这个在固件初始化的时候要对上。电机驱动模块以TB6612FNG为核心。它有四路输入引脚用于控制两路电机AIN1/AIN2对应A路BIN1/BIN2对应B路两路PWM输入PWMA/PWMB以及STBY使能引脚。设计的时候STBY引脚必须接高电平否则整个芯片进入待机模式电机完全不动。电机输出端A01/A02接电机A的两根线B01/B02接电机B。电机电源VM和逻辑电源VCC要分开VM接7.4VVCC接5V两者之间用一个10uF电解电容和一个100nF陶瓷电容并联去耦。蓝牙串口接口这块HC-05是3.3V逻辑电平但它的TXD/RXD不能直接和STM32的5V电平引脚对接。好在STM32F103C8T6的GPIO大部分容忍5V但保险起见我还是在TXD线上加了一个1K串联电阻限流RXD线因为是从STM32输出到HC-05而HC-05是3.3V电平直接连接即可。文档里我写了串口参数是115200波特率、8位数据、无校验、1位停止位这个要和固件初始化代码保持一致。2.2 PCB布局布线避坑指南从元件摆放到地线处理原理图画好后就是PCB这部分跟原理图比更考验耐心。我的PCB是双层板尺寸控制在100mm×70mm左右板厚1.6mm。两层板对于这个项目来说完全够用只要布局合理不需要做四层。元件摆放的核心原则是功能分区信号流向清晰。我把主控芯片放在板子中央偏上位置方便四周的接口和外围器件都朝它靠拢MPU6050放在板子中央这是姿态传感器的安装位置要求——传感器越接近车体的几何中心测量的加速度越准确角速度的杠杆效应也越小TB6612放在电机接口附近让电机驱动线尽量短HC-05放在板子边缘方便蓝牙天线方向朝外不被其他金属器件遮挡电源模块放在一角发热元件和敏感模拟电路分开。地线处理是这个板子的关键。我用了整块地平面铜皮Ground Pour把顶层和底层的空白区域都铺上地铜通过过孔连接。这样做的好处是每个元器件的地引脚都能就近打孔连接到地平面形成完整的回流路径大幅降低地环路面积减少EMI。我第一次做的时候顶层没铺铜只走信号线结果电机一启动MPU6050的数据就频繁跳变后来顶层铺铜之后情况改善很多。电源走线宽度方面我给自己定了一个经验值电机VM走线宽度不低于40mil5V和3.3V主干线不低于30mil普通信号线15mil。如果板子面积紧张VM至少也要走25mil以上否则大电流时压降很大电机启动瞬间电压跌落会导致MCU复位。然后说一个新手容易忽略的坑——MPU6050附近不要走大电流线路特别是电机驱动线。电机线里流动的是高频PWM电流会产生较强的电磁场干扰MPU6050的I2C信号和模拟电源导致姿态数据噪声很大。我的做法是MPU6050放在板子中央周围只走低频信号线并且在其下方铺一块完整的地铜皮作为屏蔽层。2.3 关键元器件选型这些参数别拍脑袋定元器件选型这块很多新手容易踩的一个坑是只看封装不看参数。我这里把几个关键器件列一下给大家做参考。晶振建议选8MHz 20ppm的无源贴片晶振负载电容10-20pFESR不要太大。如果频率偏差大影响的是系统时钟精度会导致串口波特率偏移、定时器定时不准进而影响PID采样周期的一致性。锂电池选两节18650串联容量根据你的电机功率和使用时长来定。市面上18650容量虚标严重建议选正规品牌的2600mAh到3500mAh。降压芯片用AMS1117-5.0和AMS1117-3.3输出电流能力各有1A和800mA对这个系统足够。注意AMS1117系列输入输出压差至少1.2V以上才能正常稳压所以7.4V转5V没问题5V转3.3V压差只有1.7V处于临界边缘实测下来负载别超过300mA基本稳定。电机推荐用N20微型减速电机带霍尔编码器的那种减速比1:30额定电压6V空载转速大约300转/分。如果你后面想加速度闭环编码器输出是必须的所以选型的时候直接选带编码器的版本一步到位省得后头再换。3. STM32固件实现从姿态解算到PID控制3.1 MPU6050数据读取与姿态解算固件代码的第一个核心块是MPU6050的驱动和姿态解算。初始化流程包括配置I2C时钟400KHz唤醒MPU6050退出睡眠模式设置陀螺仪量程±2000°/s加速度计量程±2g配置数字低通滤波器DLPF截止频率到42Hz配置采样率1KHz。量程选择不是随便定的。平衡车正常运动过程中车体的角速度变化范围一般在±400°/s以内用±2000°/s量程可以保证任何剧烈动作都不会溢出虽然分辨率会低一些但配合滤波完全够用。加速度计量程±2g适合测量倾角因为车体接近竖直时加速度计的静态输出主要是重力分量量程太大会浪费分辨率。姿态解算我用了两种方式工程里两种都写了可以切换。一种是互补滤波算法把陀螺仪积分得到的角度和加速度计计算得到的角度加权融合公式是angle 0.98 * (angle_previous gyro_rate * dt) 0.02 * accel_angle0.98和0.02这两个权重系数是调出来的。陀螺仪短时间内积分很准但长时间会漂移加速度计瞬时值有振动噪声但长期稳定。互补滤波就是信任陀螺仪的短期变化用加速度计的长期稳定来修正漂移。实际测试中这个算法在平衡车上就够用采样周期2ms的条件下角度误差可以控制在±0.5°以内。另一种是MPU6050的DMP数字运动处理器模式直接读取四元数再转成欧拉角。DMP的好处是算法在传感器内部跑不占MCU算力代码也简单。坏处是对MPU6050的寄存器配置比较繁琐一旦出错很难调试。我工程里两种都写了默认跑互补滤波想看输出更平滑可以切换到DMP模式。3.2 两级PID直立环和速度环缺一不可平衡车的控制逻辑可以分成三个环直立环角度环、速度环、转向环。直立环是根本速度环和转向环在直立环的基础上叠加。我的实现方式不是三环全做而是主做直立环和速度环转向环直接用遥控指令的左右偏置量叠加。直立环的控制器输入是车体倾角输出是电机PWM基值。如果车体向前倾倒直立环会让轮子向前加速用惯性力把车体拉回来。直立环的PID参数是整个项目中影响最大的部分我用的是PD控制PWM_balance Kp_angle * angle Kd_angle * gyro_rate这个公式里没有积分项因为直立环要求响应快、稳态误差小加积分反而容易产生振荡。Kp_angle的值大致范围在15-30之间这个值取决于你的PWM分辨率、电机特性和传感器灵敏度需要实测调整Kd_angle在0.3-1.0之间。调参顺序是先只调Kp从小到大找到车体能来回摆动但不倒的临界值然后加Kd抑制振荡让小车慢慢稳定下来。速度环的作用是让小车在平衡的基础上保持设定的速度。如果只靠直立环小车会往一个方向越走越快失去平衡因为车体需要用一定的倾角来获得前进的加速度而这个倾角会让它一直加速。速度环通过检测编码器的转速累加当发现车速过快时给直立环一个额外的倾角偏置让它稍微往反方向倾斜一下来减速。速度环我用PI控制speed_error target_speed - current_speed speed_integral speed_error * dt PWM_speed Kp_speed * speed_error Ki_speed * speed_integral最终叠加到电机PWM上PWM_left PWM_balance - PWM_speed PWM_turn PWM_right PWM_balance - PWM_speed - PWM_turn3.3 电机驱动与编码器读取PWM配置和定时器资源利用STM32F103C8T6的定时器资源很丰富我做如下分配TIM2用来读取左轮编码器TIM4用来读取右轮编码器配置成编码器模式TIM3的CH1和CH2输出PWM给TB6612的PWMA和PWMBTIM1用作控制周期定时器1ms中断一次在中断里执行PID计算和指令解析。PWM频率我选的是10KHz。这个频率下TB6612的开关损耗和电机的电磁噪声能达到一个比较好的平衡。频率太低电机会发出尖锐的啸叫声频率太高驱动芯片的开关损耗增大、发热严重。10KHz电机基本静音芯片温度也正常跑起来很稳。编码器读取这块用的是N20电机自带的霍尔编码器每转输出约11个脉冲减速比1:30所以车轮每转一圈编码器输出330个脉冲。我用的是4倍频计数模式实际每圈计数值是1320配合轮子直径65mm每个脉冲对应约为0.155mm的位移这个分辨率做速度环足够了。编码器接口接在定时器的CH1和CH2上硬件配置成编码器模式后定时器计数器会自动根据A、B两相的相位关系做加减计数完全不用CPU干预代码里只需要在1ms中断里读取定时器的计数器值并清零即可。这个硬件功能比软件判断A、B相的做法效率高出一个量级。3.4 串口协议与蓝牙指令解析固件端的另一个核心是串口协议。HC-05蓝牙模块接到STM32的USART2上115200波特率中断接收。我自定义了一个简单可靠的指令帧格式固定9字节起始字节(0xA5) 功能码(1字节) 数据区(6字节) 校验字节(1字节)功能码定义如下0x01设置目标速度数据区前两个字节是int16_t类型的左右轮速度平均值0x02设置转向偏置数据区前两个字节是int16_t类型的转向量0x03请求回传状态数据区全部填00x04使能/禁能平衡功能数据区第一个字节是1或0校验字节采用简单的异或校验对功能码和数据区的7个字节逐字节异或得到。这样通信过程中只要有一位错误校验就过不了固件直接丢弃这一帧。虽然用CRC32更可靠但在这个低速遥控场景下异或校验完全够用代码也简单。回传状态帧格式也类似功能码0x83数据区装角度int16_t、目标速度int16_t、当前速度int16_t三个变量。APP端每200ms请求一次实时显示小车的状态。4. 安卓蓝牙遥控A从源码到APK打包4.1 经典蓝牙开发流程UUID和Socket是两个关键安卓端蓝牙开发首先必须搞清楚一个概念HC-05是经典蓝牙Bluetooth Classic走的是RFCOMM协议不是BLEBluetooth Low Energy。很多新手在BLE和经典蓝牙之间搞混写了一大堆BLE代码结果连不上HC-05。经典蓝牙开发的流程大致是获取蓝牙适配器BluetoothAdapter检查蓝牙是否开启扫描设备找到HC-05后配对然后通过UUID建立Socket连接。连接的核心代码如下BluetoothSocket socket device.createRfcommSocketToServiceRecord(uuid); socket.connect();这里UUID很关键SPPSerial Port Profile服务的标准UUID是private static final UUID SPP_UUID UUID.fromString(00001101-0000-1000-8000-00805F9B34FB);这个UUID是蓝牙SIG组织规定的串口服务通用UUIDHC-05模块内部默认就支持这个服务。如果你随便写一个UUID大概率连不上。权限这块安卓版本不同差别很大。Android 6.0及以上需要动态申请定位权限因为扫描蓝牙设备需要位置权限Android 12及以上还需要BLUETOOTH_SCAN和BLUETOOTH_CONNECT权限。我工程里做了完整的兼容处理在AndroidManifest.xml里声明了所有可能用到的权限同时在MainActivity里动态检查请求。4.2 遥控界面设计与指令帧组装遥控APP的界面我设计得比较简洁界面上方是一个状态栏显示蓝牙连接状态和当前回传的角度/速度中间是两个方向控制按钮区左侧是前进/后退/左转/右转四个方向键下方是一个速度滑块控制小车的最大速度。界面布局用LinearLayout和RelativeLayout嵌套实现没用复杂的自定义View因为核心功能是遥控不是炫UI。每个按钮的事件处理里调用一个sendCommand方法private void sendCommand(byte funcCode, byte[] data) { if (bluetoothSocket null || !bluetoothSocket.isConnected()) { Toast.makeText(this, 蓝牙未连接, Toast.LENGTH_SHORT).show(); return; } byte[] frame new byte[9]; frame[0] (byte) 0xA5; frame[1] funcCode; System.arraycopy(data, 0, frame, 2, Math.min(data.length, 6)); byte check 0; for (int i 1; i 8; i) { check ^ frame[i]; } frame[8] check; // 通过输出流发送 outputStream.write(frame); outputStream.flush(); }安卓端的发送速度控制逻辑是方向键按下时每100ms发送一次指令松手后发送一次归零指令。每隔200ms发送一次回传状态请求用Handler和Runnable实现定时任务。4.3 APK打包配置SDK版本、签名和混淆APK打包这块我用的是Android Studio的默认Gradle配置。关键参数是minSdkVersion和targetSdkVersion。考虑到国内用户手机系统版本跨度大我把minSdkVersion设为21Android 5.0覆盖了绝大多数设备targetSdkVersion设为32Android 12这样在新的系统权限模型下也能正常请求蓝牙权限。打包之前要注意把蓝牙相关权限在AndroidManifest.xml里声明完整uses-permission android:nameandroid.permission.BLUETOOTH / uses-permission android:nameandroid.permission.BLUETOOTH_ADMIN / uses-permission android:nameandroid.permission.ACCESS_FINE_LOCATION / uses-permission android:nameandroid.permission.BLUETOOTH_SCAN android:usesPermissionFlagsneverForLocation / uses-permission android:nameandroid.permission.BLUETOOTH_CONNECT /最后两个权限是Android 12新增的如果targetSdkVersion低于31系统会自动忽略它们但保险起见还是写上。另外如果targetSdkVersion是32系统会在蓝牙连接时弹窗询问用户授权这个弹窗是系统级的APP自己不能控制代码里要处理好授权回调。签名方面调试用Android Studio默认的debug签名正式发布可以用Build - Generate Signed Bundle / APK生成自己的签名文件。我这里APK直接用debug签名也可以安装到手机上调试但如果你想发给别人装建议手动导出一个release签名APK否则某些手机可能装不上。4.4 连接失败与传输优化的实战处理蓝牙连接这块踩过的坑不少我把常见问题整理一下。首先是扫描不到HC-05。这往往是手机蓝牙缓存了旧的配对信息或者HC-05之前连过其他设备还保持连接状态。解决办法是在手机蓝牙设置里清除配对的HC-05然后给HC-05重新上电再扫描。如果还不行检查HC-05的指示灯慢闪大概2秒闪一次表示可被发现和配对快闪大概0.5秒闪一次表示已连接。状态不对就按住HC-05上的复位键重新进入AT模式。其次是配对成功后连接失败。连接时抛IOException一般是因为UUID不对或者蓝牙socket已经过期。BluetoothDevice的createRfcommSocketToServiceRecord方法在某些ROM上会返回一个失效的socket这时候可以尝试使用反射方法创建socketMethod m device.getClass().getMethod( createRfcommSocket, int.class); BluetoothSocket socket (BluetoothSocket) m.invoke(device, 1);这个反射方法是安卓系统的一个内部接口能解决一部分兼容性问题但并不能保证所有机型都有效。我的代码里做了try-catch反射失败自动回退到标准的createRfcommSocketToServiceRecord方法。数据传输这块串口115200波特率的理论传输速率约11KB/s实际控制指令一帧9字节100ms发一次一分钟才5400字节完全没有带宽压力。但要注意的是安卓端的数据收发必须在子线程里做不能在主线程直接操作socket。我专门开了一个HandlerThread处理收发逻辑避免了接收数据时ANR。5. 常见问题与调参实录5.1 小车抖动、往一个方向跑、一放手就倒这三个问题几乎是每个做平衡车的人都会遇到的我挨个说下排查思路和解决办法。小车高频抖动通常原因是直立环Kd过大或者传感器噪声太大。Kd过大会把高频噪声放大成电机的高频抖动听起来电机发出细微的嗡嗡声。解决办法先把Kd调小到0看是否还抖如果还抖检查MPU6050输出的角度是否毛刺特别多可以在串口上打印角度值连续观察10秒正常波动应该在±0.2°以内。如果波动很大检查I2C通信速率是否太快或者MPU6050附近是否受到电机线干扰。小车一直往一个方向跑不断加速直到倒地这说明速度环没起作用或者作用方向反了。注意PID的方向问题——直立环控制电机让车体保持直立但电机转动会让车体前进车体前进改变了倾角直立环又会纠正倾角两者之间存在耦合。如果速度环方向反了会让情况更糟。快速判断方法把速度环的Kp设为0观察小车往哪个方向跑然后调整速度环的符号让它产生一个阻止小车继续加速的趋势。一放手就倒一点都平衡不住首先检查直立环Kp是否太小。我给的参考值是15-30如果你的板子质量大、电机扭矩小可能需要更大的Kp。其次是检查电机响应是否太慢可以用手机录慢动作视频看电机是否在车体倾倒方向变化的瞬间就反转。电机反应慢可能是因为PWM频率太低、TB6612供电电压不足、或者电机驱动代码里加减速处理太慢。5.2 HC-05蓝牙连不上或者连上频繁断连蓝牙问题要分两层排查硬件层和软件层。硬件层先看HC-05和STM32之间的接线。HC-05的TXD接STM32的RXDPA3HC-05的RXD接STM32的TXDPA2交叉连接不要接反。共地是必须的两块板子不共地就会通信不稳定甚至完全不通。然后看供电HC-05峰值电流能到40mA左右3.3V供电电压不能低于3.0V我用AMS1117-3.3直接供电实测稳定。软件层先确认串口参数是否完全匹配115200、8N1。我遇到过好多次手机端蓝牙串口工具设置的波特率是对的但固件里USART初始化配置错了数据位导致收发数据乱码。另外固件里的串口中断优先级要设得高点防止被PID定时器中断打断导致字节丢失。HC-05默认的波特率是38400但我的固件是用AT指令把它改成115200了的你拿到模块要先确认或重新配置。断连问题最常见的原因是HC-05进入了睡眠或者配对模式。当手机蓝牙和HC-05距离太远或者中间隔了金属板信号衰减会造成连接断开。另外如果两台手机同时配对过同一个HC-05HC-05可能会接到另一台手机的重连请求导致当前连接被挤掉。解决办法是给HC-05设置一个配对PIN码别人不知道就配对不上。5.3 PID参数调整的实用经验先直立环后速度环最后总结一下我给PID调参的完整顺序这个方法帮我在不同的车体结构上快速调出稳定效果。第一步只调直立环。把速度环和转向环的输出全部屏蔽只保留PWM_balance。Kp从小到大慢慢加每次加1-2观察车体是否能来回摆动。当Kp加到某个值车体能摆动几下然后停下来说明Kp接近临界继续加一点让车体能保持直立一小段时间。第二步加Kd抑制振荡。Kd从0.1开始加每次加0.05观察车体的摆动幅度是否减小。Kd太大高频抖动明显Kd太小车体动态响应慢推一下会晃很多下才稳住。最终目标是车体被轻推一下后能在1-2秒内恢复直立没有明显的往复振荡。第三步加速度环。把目标速度设为0让小车原地保持平衡不跑偏。Kp_speed从0.5开始加观察小车是否会被拉回到零速位置。Ki_speed从0.05开始加用来消除静态误差。这里要特别强调Ki_speed不能太大否则积分饱和会让小车大幅度振荡典型的症状就是小车先来回跑几次然后突然朝一个方向冲出去。第四步调转向环。转向环的Kp一般比直立环小很多它只是在直立环的基础上叠加一个小偏差让左右轮出现差速。如果左右轮差速太猛小车会原地打转然后失去平衡所以转向量最终要限幅在直立环PWM输出的30%以内。调参过程中我一直会在手机上用串口助手实时查看角度、速度、PWM三个量画出波形来看比肉眼观察车体直观得多。如果你没有蓝牙串口助手也可以用USB转TTL模块通过有线连接的USART1口来看调试信息。5.4 最终集成联调时的坑干扰、供电、机械结构所有模块单独测试没问题后集成联调阶段还会有一些综合性问题冒出来。电机干扰导致MPU6050数据跳变这个我在前面PCB部分提过但联调阶段还是最容易再次出现。判断方法很简单把小车放在桌面上不启动电机看姿态数据是否稳定然后用手转动轮子看数据是否受影响。如果电机转动会导致角度值跳变几度甚至几十度大概率是PCB布局问题或者电机线太长太靠近传感器。临时处理办法是给电机线套磁环在电机输入引脚并联一个104陶瓷电容和一个电解电容根治办法是重新布局PCB把电机线远离传感器。供电不足导致MCU频繁复位症状是小车跑动时姿态突然归零、蓝牙掉线等。这个是典型的大电流把电源拉垮了问题。电机启动瞬间电流可能达到1A以上如果电源线太细、降压芯片选型余量不足电压就会被拉低到MCU复位阈值以下。之前说的40mil以上VM走线宽度不是随便定的就是这个原因。另外在电池正负极和电源入口处各并联一个470uF电解电容和100nF陶瓷电容能明显改善动态响应。机械结构方面容易忽略的是定位问题。车体的重心尽量低、左右对称MPU6050的安装角度和代码里初始化角度一致否则零偏校准会有问题。这里给一个建议把电池放在车体下方贴着底板放重心低了车体更稳MPU6050的X轴沿着前进方向安装这样代码里的姿态角和遥控方向逻辑好对应。以上都是反复折腾过、踩过坑之后总结出来的经验。硬件设计、固件逻辑、安卓开发这三块内容每一块展开都有很多可以深挖的地方。这套资料里把这些环节都串起来了照着走一遍你对STM32、PID控制、蓝牙通信、安卓开发这几个方向都会有更深的理解。后面我还在整理一个带超声波避障和视觉循迹的升级版本等做完了再继续更新这套平衡小车资料。本文还有配套的精品资源点击获取
返回列表