尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

蓝牙加速度计小车:从传感器读姿态到PWM电机控制全解析

蓝牙加速度计小车:从传感器读姿态到PWM电机控制全解析 第一次看到朋友用手机一歪一歪地遥控小车时我觉得这玩意不就是图个新鲜。直到自己动手做了一台蓝牙加速度计小车才发现这个看似简单的“倾斜控制”背后其实串起了一条非常完整的技术链路传感器读姿态、蓝牙串口透明传输、单片机解析协议、电机驱动输出 PWM。每一个环节单独拎出来都不算难但组合在一起能踩的坑比想象中多得多。这篇文章我就从零开始把这个项目的完整实现拆开讲透——硬件怎么选、电路怎么接、代码怎么写、协议怎么定、联调时怎么排查以及我在实际测试中摔过的跟头。如果你正在做课程设计、想入门嵌入式 DIY或者单纯想给家里孩子做一个能玩又能学的遥控车这篇应该能让你少走不少弯路。1. 项目拆解从“会动的蓝牙板”到“倾斜即走”的完整系统1.1 一辆“倾斜控制”的小车到底在做什么蓝牙加速度计小车本质上是一个用姿态传感器替代传统摇杆或按键的遥控车。你手里拿着的控制端手机或者独立的传感器模块能够感知自身的倾斜角度把这个角度换算成方向指令和速度指令通过蓝牙无线链路发送给小车。小车端收到数据后由主控芯片解析再控制电机驱动板输出不同占空比的 PWM 信号最终让左右两个轮子以不同的转速转动实现前进、后退、左转、右转。很多人第一次听到“加速度计控制小车”时第一反应是“这不就是把重力方向算出来嘛”。对核心思路确实是这个但要真正跑起来链路比想象中长不少。倾斜角度怎么读取用手机内置的加速度传感器还是外接一颗 MPU6050数据怎么编码如果只发一个数字那方向、速度、正反转怎么办小车端收到一串字节流怎么从里面精确地捞出有效指令这些都是在动手之前必须想清楚的问题。我在给这个项目做方案设计时把整个系统分成了四层传感层、传输层、决策层、执行层。传感层负责获取物理世界的姿态变化传输层负责把数据无损地从控制端送到小车端决策层把原始数据映射成运动指令执行层负责驱动电机和车轮。这样分层的好处是每一层都可以独立测试、独立替换。比如你想把手机控制换成独立的 MPU6050 手柄只需要改传感层和发送代码小车端完全不用动。1.2 为什么选加速度计而不是摇杆或按键除了“看起来酷”之外加速度计控制还有一个很实际的优势它输出的是连续的模拟量天然适合做比例控制。摇杆虽然也是模拟量但大多数入门级摇杆模块的精度一般而且机械结构容易磨损。按键就更不用说了只有“开”和“关”两个状态做不出细腻的转向。倾斜控制的另一个好处是直观。把控制端往左倾斜小车就往左转往前倾斜小车就前进。这种“所见即所得”的映射关系几乎不需要学习成本。我第一次把控制板交给一个完全没碰过这项目的朋友他玩了十秒钟就上手了。如果是遥控器至少还得解释一下哪个杆是油门、哪个杆是方向。而且加速度计这个传感器本身也很有学习价值。你会用到 I2C 总线、原始数据标定、低通滤波、互补滤波、姿态角换算。这些知识在平衡车、无人机、智能手环里都通用。做一辆小车顺手把这些基础补上性价比很高。1.3 数据流的总览从倾斜到车轮为了后文不迷糊这里先给出一个完整的数据流总览。以手机上常见的方案为例手机倾斜 → 手机内置加速度传感器输出 ax、ay、az → 手机端程序计算俯仰角和横滚角 → 将角度映射为“方向值”和“速度值” → 组成文本帧如$45,80#→ 通过蓝牙串口发送 → HC-05 模块接收 → Arduino 串口读取 → 解析帧 → 差速算法计算左右轮 PWM 值 → L298N 驱动电机 → 车轮转动。如果使用独立的 MPU6050 控制端只是把“手机内置加速度传感器”这一段换成“MPU6050 传感器 另一块单片机 HC-05 发送端”小车的接收端可以做得完全一致。所以后文在讲到小车端接收代码时两种方案是通用的。2. 硬件选型与电路接线各部件搭配的“为什么”2.1 核心部件清单与选型逻辑先交代一下我最终确定的硬件清单后面所有代码和接线都基于这套配置。部件推荐型号选型理由补充说明主控芯片Arduino Nano 或 Uno生态成熟、5V 逻辑电平、软串口灵活也可以用 ESP32自带蓝牙但入门成本略高蓝牙模块HC-05支持主从一体、经典蓝牙串口透传HC-06 只能做从机不推荐做发送端电机驱动L298N 或 TB6612L298N 便宜好买TB6612 效率更高不要用 L293D压降大、发热严重电机TT 减速电机配轮子扭矩够、安装方便、有现成支架建议买带编码器的版本后续扩展速度环电池两节 18650 串联或 7.4V 锂电池电压满足电机驱动容量足够尽量不要用干电池电流不够车架亚克力底盘或成品入门底盘打孔方便扩展性强3D 打印也可以但注意电机座强度控制端可选MPU6050 模块独立传感器方案手机方案不需要买这套配置最大的优势是兼容性。Arduino Nano 的引脚可以直接插在面包板上调试方便HC-05 在淘宝上几块钱一片坏了也不心疼L298N 虽然效率低一点但驱动两个 TT 电机毫无压力。如果预算稍微多一点我会建议把 L298N 换成 TB6612后者导通压降小很多电池续航更久而且模块体积小。2.2 HC-05 的细节主从模式、波特率与电压匹配HC-05 是很多人第一次接触的蓝牙模块但它的脾气也确实多。先说电压问题。HC-05 的核心工作电压是 3.3V虽然多数模块上做了稳压但其 RX 引脚如果不加处理直接接 Arduino 的 5V TX长期运行下去是有风险的。我见过不少人的 HC-05 用着用着就搜不到设备了多半是 RX 引脚被 5V 电平烧了。稳妥的做法是在 Arduino TX 和 HC-05 RX 之间加一个分压电路用 1kΩ 和 2kΩ 电阻串联分压把 5V 降到 3.3V 左右。HC-05 的 TX 引脚输出是 3.3V接 Arduino RX 没有问题因为 Arduino 的 RX 能识别 3.3V 为高电平。再说主从模式。HC-05 默认是“从机”角色也就是可以被手机搜索并连接。我做的这个小车小车端 HC-05 保持默认从机即可。但如果你要做独立 MPU6050 手柄方案控制端那一片 HC-05 应该设置成“主机”角色这样它在上电后会自动去连接小车端。设置方法很简单把模块上的 EN 引脚拉高或者按住模块上的小按钮再上电进入 AT 指令模式然后通过串口发送ATROLE1 // 设为主机 ATNAMECarCtrl // 给模块改个名字 ATUART9600,0,0 // 设置波特率 9600默认波特率是 9600这也是我整篇代码里统一使用的波特率。如果你想改到 115200 也可以但一定要所有相关设备端一致否则联调时会看到一堆乱码很难排查。2.3 完整接线图与电源分配这里给出小车端的接线关系。用 Arduino Nano 举例功能Arduino 引脚连接对端电机驱动 IN1D7L298N IN1电机驱动 IN2D8L298N IN2电机驱动 IN3D9L298N IN3电机驱动 IN4D4L298N IN4电机驱动 ENAD5PWML298N ENA电机驱动 ENBD6PWML298N ENB蓝牙 RXD10软串口 RXHC-05 TX3.3V 电平蓝牙 TXD11软串口 TXHC-05 RX分压后 3.3VMPU6050 SDAA4传感器 SDAMPU6050 SCLA5传感器 SCL电源部分是最容易被新手忽略的。我的建议是电机电源和逻辑电源分开走。7.4V 电池直接接到 L298N 的 12V 输入端子L298N 自带一个 5V 稳压输出可以给 Arduino 供电。但要注意这个 5V 输出的电流能力有限千万不要再拿它去推舵机或者其他大电流外设否则电压一掉Arduino 就会重启。另外在电池正负极两端并联一个 470µF 到 1000µF 的电解电容能够吸收电机启动瞬间的电流冲击非常管用。3. 控制方式双方案手机倾斜直控与独立 MPU6050 传感端3.1 方案A手机 串口蓝牙终端最省事的控制方案就是直接用手机当遥控器。现在安卓平台上有很多蓝牙串口调试 APP比如 Serial Bluetooth Terminal它们可以把手机也虚拟成一个蓝牙串口设备。配合手机里的加速度传感器理论上可以实现“倾斜手机 → 小车跟随倾斜方向”的效果。不过这里有一个需要提前讲清楚的现实问题串口蓝牙 Terminal 类 APP 本身就是用来调试串口数据的它不一定内置加速度计姿态输出功能。就算有的 APP 带了传感器数据发送功能数据格式也是固定的不一定能直接映射成你要的“方向、速度”两个值。所以用手机方案时通常有两选择要么写一个简单的 Android 小程序在后台读取加速度传感器并自定义发送格式要么手动在串口蓝牙终端里通过添加“宏按钮”或“快捷按钮”把预先定义好的指令文本比如$0,80#发送出去。前者适合演示完整效果后者适合实验室快速验证。我自己的做法是写了一个十几行核心逻辑的 Android 小工具重点就是注册 SensorManager 的加速度监听器在 onSensorChanged 里把横滚角和俯仰角换算后拼成字符串再通过 BluetoothSocket 的 OutputStream 写出去。如果你对 Android 开发不熟没关系后面讲的方案B可以完全绕开手机。3.2 方案B独立传感端Arduino MPU6050 HC-05这是我自己实际量产使用的那套方案。原因很简单我不想每次演示都去打开手机 APP、配对蓝牙、还要担心屏幕自动熄灭。做一个独立的“蓝牙手柄”上电自动连接拿起来就能玩省心太多。控制端硬件组成一块 Arduino Nano、一片 MPU6050、一片 HC-05、一个电池。MPU6050 通过 I2C 挂在 Arduino 的 A4/A5 上HC-05 通过软串口接 D2/D3。上电后MPU6050 读取加速度原始值Arduino 计算出手柄当前的俯仰角对应油门和横滚角对应转向然后把它们编码成文本帧通过 HC-05 发送出去。这个方案最大的好处是控制系统完全自主不依赖任何手机 APP也不受手机各种后台消息打扰。而且 MPU6050 本身可以顺便读取陀螺仪数据后续想升级成“体感平衡控制”或者“手势识别”硬件不用大改。3.3 两种方案的权衡对比对比维度手机方案独立 MPU6050 手柄方案额外硬件成本几乎为零需要 MPU6050 第二块主控和蓝牙上手速度快有手机就能测需要多写一个发送端程序延迟取决于 APP 和手机可控程序越简单延迟越低演示效果需要解释“为什么用手机”更有“产品感”可扩展性受限于 APP 功能可以自定义按键、震动、OLED 显示调试难度串口蓝牙终端能看到数据容易定位自己写发送端问题可能出现在两端我的判断标准很简单如果你只是想快速跑通完整链路手机方案优先如果你想做一个“能送人的、完成度高的作品”独立 MPU6050 手柄更值得投入。4. 嵌入式端代码逻辑与运动控制算法4.1 小车端接收代码协议与可靠解析无论控制端是手机还是 MPU6050 手柄小车端接收代码是完全一样的。我的做法是定义了一个非常简单的文本协议$方向值,速度值#其中方向值范围是 -100 到 100负值代表左转正值代表右转速度值范围也是 -100 到 100正值前进负值后退。$是帧起始符,是数据分隔符#是帧结束符。举个例子$30,80#表示“方向右转 30%速度前进 80%”。小车端 Arduino 的接收解析代码核心是用一个状态机逐字节处理#include SoftwareSerial.h SoftwareSerial BTSerial(10, 11); // RX, TX char buf[32]; int idx 0; boolean frameReady false; void setup() { Serial.begin(9600); BTSerial.begin(9600); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); } void loop() { while (BTSerial.available()) { char c BTSerial.read(); if (c $) { // 新的帧开始清空缓冲区 idx 0; frameReady false; } else if (c #) { // 帧结束解析 buf[idx] \0; frameReady true; } else if (idx 31) { buf[idx] c; } if (frameReady) { parseAndAct(buf); frameReady false; idx 0; } } } void parseAndAct(char *s) { // 期望格式: 方向,速度 int sep -1; for (int i 0; s[i]; i) { if (s[i] ,) { sep i; break; } } if (sep 0) return; String head String(s).substring(0, sep); String tail String(s).substring(sep 1); int dir head.toInt(); int speed tail.toInt(); // 这里接入差速控制 drive(dir, speed); }这段代码的关键点在于使用$和#两个边界符。只要帧头帧尾没错就算中间数据偶尔有乱码接收端也能在下一个$处重新同步。如果你只发送35,80这类裸数据而没有边界符一旦丢一个字符后面的数据全会错位而且很难恢复。4.2 从方向速度到电机PWM差速算法接下来是最核心的映射逻辑。对于两轮差速小车左转就是左轮减速、右轮加速右转则反过来。我用的差速公式非常简单int leftSpeed speed dir; int rightSpeed speed - dir;假设 speed80、dir30则 leftSpeed110、rightSpeed50也就是左轮全速、右轮中速小车向右转弯。这里再做一个溢出保护把值约束在 -100 到 100 之间最后映射到 Arduino 的 PWM 输出范围 0-255void drive(int dir, int speed) { int left constrain(speed dir, -100, 100); int right constrain(speed - dir, -100, 100); int pwmLeft abs(map(left, -100, 100, -255, 255)); int pwmRight abs(map(right, -100, 100, -255, 255)); setMotorA(left, pwmLeft); // 处理电机A带正反转方向判断 setMotorB(right, pwmRight); }setMotorA和setMotorB的实现就是根据传入的带符号速度值判断电机正反转然后输出对应的 PWM。以电机 A 为例void setMotorA(int value, int pwm) { if (value 0) { digitalWrite(7, HIGH); digitalWrite(8, LOW); } else { digitalWrite(7, LOW); digitalWrite(8, HIGH); } analogWrite(5, pwm); }这里有个容易迷失的细节map函数把 -100 到 100 映射到 -255 到 255但实际上电机方向是靠 IN1/IN2 引脚电平决定的EN 引脚只需要正的 PWM 值。所以先判断正负决定方向再用绝对值给 PWM。如果你直接map然后用负 PWM 值会出很多莫名奇妙的怪象。4.3 MPU6050 手柄端代码姿态读取与发送现在把手柄端代码贴出来。它的任务有两个读取 MPU6050 的加速度值把它换算成俯仰角和横滚角把角度映射成速度和方向然后组成协议帧发送。#include Wire.h #include MPU6050.h MPU6050 mpu; int lastSendTime 0; void setup() { Wire.begin(); mpu.initialize(); Serial.begin(9600); // 接 HC-05 的 TX/RX } void loop() { int16_t ax, ay, az; mpu.getAcceleration(ax, ay, az); // 将原始值转换为 g 值。默认量程 ±2g灵敏度 16384 LSB/g float axg ax / 16384.0; float ayg ay / 16384.0; float azg az / 16384.0; // 俯仰角和横滚角单位度 float pitch atan2(-axg, azg) * 57.296; float roll atan2(ayg, sqrt(axg * axg azg * azg)) * 57.296; // 死区处理小于 5 度认为不操作 if (abs(pitch) 5) pitch 0; if (abs(roll) 5) roll 0; // 映射俯仰角控制油门横滚角控制方向 int speed constrain(map(pitch * 10, -300, 300, -100, 100), -100, 100); int dir constrain(map(roll * 10, -300, 300, -100, 100), -100, 100); // 每 50ms 发送一次 if (millis() - lastSendTime 50) { Serial.print($); Serial.print(dir); Serial.print(,); Serial.print(speed); Serial.println(#); lastSendTime millis(); } }这里用到了atan2函数它的作用是算出重力在传感器不同轴上的分量夹角。简单说手柄水平放置时重力主要落在 Z 轴上ax 和 ay 接近 0当你往前倾斜手柄ax 方向会产生一个分量atan2(-ax, az)就能算出俯仰角度。注意getAcceleration拿到的原始值是整数需要先除以灵敏度系数 16384 转成 g 值再进行三角函数计算否则结果全错。发送频率我控制在 20Hz也就是 50ms 一帧。这个频率对遥控小车来说足够流畅又不至于把蓝牙链路撑爆。如果想更跟手可以提高到 50Hz但要注意 HC-05 在 9600 波特率下每秒最多传输大约 960 字节一条帧才 8 个字节左右50Hz 完全没有压力。5. 协议设计与串口蓝牙终端联调数据格式、粘包和调试技巧5.1 为什么不能直接发“裸数字”刚开始做这个项目时我图省事直接让控制端发一个 0 到 180 的整数值对应舵机角度。小车端收到后转成 PWM 方向。结果测试时发现一旦蓝牙信号出现瞬时干扰接收端很容易把一个 105 拆成“10”和“5”或者把原本一帧的 150 和下一帧的 50 拼在一起。整个小车就像喝醉了一样乱抽。所以后来我老老实实设计了带边界符的文本帧。边界符的作用是让接收端每收到一个完整帧就处理一次而不是“串口里来多少读多少”。这就像写信必须要有抬头和落款一样收信人才能知道一封信从哪里开始、在哪里结束。文本帧虽然比二进制帧多几个字节但对人眼调试特别友好——你可以直接在手机或电脑上看到发出来的是什么。5.2 串口蓝牙终端的配置与使用方法当控制端是手机时Serial Bluetooth Terminal 是绕不开的工具。我常用的操作流程如下打开手机蓝牙搜索设备找到 HC-05默认名字通常是 HC-05配对密码 1234。打开串口蓝牙终端 APP在设备列表里选择已配对的 HC-05。设置波特率为 9600。连接成功后在输入框里手动输入$0,80#并发送如果小车能前进说明基本链路已经通了。这个 APP 还支持建“快捷按钮菜单”。你可以把几条常用指令配置成按钮比如“前进 50% 速度”、“左转 30%”、“停止”这样测试小车行为时不用每次手输一长串。如果你用的是我自己写的手柄方案那就不太需要这个 APP但它在调试小车端接收代码时非常有用因为你可以完全跳过手柄端直接用手机发指令来验证小车端解析逻辑是否正确。5.3 粘包、拆包与丢字节的处理思路粘包和拆包是串口通信里的经典问题。手机端一帧数据到达 HC-05 时可能会被拆成好几段也可能一次性把好几帧拼在一起到。很多新手在串口中断里写if (BTSerial.available() 0)然后直接读一个字节就会遇到“读到的数据不完整”的情况。正确做法是像第 4 节代码那样只关心字符本身用$和#做切分。不管数据是被拆成多少段来的只要扫描到#就代表一个完整帧到齐了。这里的核心思想是串口是“字节流”而不是“消息流”它只保证字节顺序不保证消息边界。所有需要按帧处理的数据都必须在应用层自己切分。调试时还有一个小技巧在蓝牙串口终端里开启“回显”和“时间戳”功能。这样你能看到每一条命令的完整内容和发送时间能比较直观地判断是控制端发慢了还是小车端解析慢了。如果你的设备支持双向回传也可以让小车收到指令后回一个OK这个对排查链路非常有帮助。5.4 PC 端调试蓝牙 COM 口与驱动问题有时候我会把小车端的 HC-05 连到电脑上调试因为电脑屏幕大串口监视器看起来比手机方便。但在这条路上很多人会被 Windows 的蓝牙驱动折腾一遍。HC-05 连上电脑后系统会分配一个“传出 COM 口”打开设备管理器能看到类似“Standard Serial over Bluetooth link (COM8)”这样的条目。如果你打开串口工具后选这个 COM 口就能像操作普通串口一样读写蓝牙数据。如果电脑蓝牙适配器驱动不对设备管理器里的蓝牙设备会显示成“Generic Bluetooth Radio”或者根本没有串口服务那就需要在设备管理器里更新驱动或者下载对应型号的官方驱动。这里我的实际建议是别在电脑蓝牙上死磕太久直接买一个 9.9 元的 USB 转 TTL 模块把 HC-05 的 TX 接到模块 RX、RX 接到模块 TX用电脑的 USB 串口直接和 HC-05 通信。这个方法稳定可靠而且能同时测试模块的 AT 指令模式和透传模式。同理如果你见过蓝牙 GPS 模块的输出会发现它发出的是一串类似$GPRMC,193330,A,3153.2367,N,12129.5276,E,...的 NMEA 文本帧也是用$开头、以换行结束。它的解析思路和我们的小车协议一模一样只是内容不同。所以我说做一次蓝牙串口项目以后看任何 GPS 模块、智能传感器模块的日志都会觉得眼熟。6. 实测避坑清单电池供电、蓝牙掉线和跑偏排查6.1 供电问题小车一启动就重启我第一次下地测试时小车一通电电机还没转起来Arduino 就重启了。后来一查问题出在供电上。小车电机启动瞬间的电流可以到 1A 甚至更高如果电池内阻大、导线细电机启动时会把系统电压拉低到 Arduino 的复位阈值以下造成单片机重启。解决思路分三步。第一步电池尽量用低内阻的锂电池两节 18650 串联比叠 8 节干电池靠谱得多第二步把电机电源线和逻辑电源线分开电机驱动板的瞬间电流不要和 Arduino 共用地线走太长第三步在电机驱动板电源输入两端并联一个大于 470µF 的电解电容在 Arduino VIN 和 GND 之间也放一个 100µF 电容。电容的作用相当于一个小水库能在电流瞬时增加时把电压稳住。6.2 蓝牙连接不稳定与干扰排查HC-05 工作在 2.4GHz 频段这个频段同时也是 Wi-Fi、蓝牙无线鼠标、无线耳机的“公共食堂”干扰源一多小车就会偶尔出现延迟或者直接断连。有一次我在实验室里测试周围同时开着好几个蓝牙设备小车在远离 5 米时就频繁掉线。我把手机蓝牙和旁边的蓝牙音箱关掉后距离直接拉到了 10 米还能稳定控制。所以遇到蓝牙链路不稳定第一件事不是怀疑模块坏了而是先换个环境、减少同频段设备数量再考虑模块本身的问题。另外要提一下现在很多环境里存在大量 BLE 信标、BLE 广播报文它们虽然和 HC-05 的经典蓝牙协议不冲突但都在同一个 2.4GHz 频段里抢空气。我就遇到过蓝牙广播特别密集的会议室HC-05 的指令偶尔被挤得丢失一两个字节。这种情况很难彻底消除但可以在协议层做容错——如果一帧解析出来的方向或速度值明显超出范围就丢弃不执行而不是用一个错误数值去驱动电机。6.3 小车跑偏、转向不线性与传感器噪声跑偏是最让人头疼的问题之一。明明手柄水平放置小车应该直行但它总是慢慢偏到一边。这涉及两个原因一是电机的一致性不够左右两个 TT 电机的实际转速可能在相同 PWM 下存在 5% 到 10% 的差异二是 MPU6050 本身有零点漂移而且手持时的轻微抖动会被加速度计放大。针对传感器噪声我在代码里加了死区和简单滤波。死区就是前面写的“倾斜角小于 5 度按 0 处理”避免手抖导致小车乱走。滤波的话我用的是一阶低通滤波代码就一行filtered 0.8 * filtered 0.2 * raw;这个公式会让输出更平滑但代价是响应会稍微变慢。在调试时可以把滤波系数调到 0.2快速看到原始数据实际跑车时调到 0.2 到 0.3 之间比较合适。至于电机不一致最简单的办法是给慢的一侧加一个“补偿系数”。你可以在调试时让小车原地转向观察它偏向哪边然后在代码里给对应侧的 PWM 乘一个 1.05 到 1.15 的系数。这个方法不完美因为电机在不同转速下的差异不一样但对入门项目来说完全够用。6.4 我最终确定的调优参数项目跑通后我把所有调参结果整理成了一个表方便自己以后复用也分享给你参数项数值说明蓝牙波特率9600HC-05 默认稳定可靠指令发送频率20Hz50ms 一帧兼顾流畅与稳定死区角度5 度倾斜小于 5 度按 0 处理PWM 最大值255Arduino 默认速度映射范围-100 到 100-100 全速后退100 全速前进方向映射范围-100 到 100-100 最左转100 最右转低通滤波系数0.2值越小越平滑响应越慢电机补偿系数1.05 到 1.15根据实际跑偏情况调整如果方向盘值调到最高时感觉小车反应还是太猛可以把方向映射范围缩小到 -80 到 80让转向更柔和。油门同理设定里的map(pitch * 10, -300, 300, -100, 100)中的 300 改成 450等同于是把 45 度倾斜才对应到全速操作起来更细腻。说到底蓝牙加速度计小车这个项目最大的好处是它把“传感器读取-无线通信-数据解析-电机控制”这一整条链路完整地串了一遍。等你真正把车跑起来那些曾经在资料里看着干巴巴的术语——I2C、串口帧、PWM、差速转向、低通滤波——都会变成你亲手调过的、看得见摸得着的东西。后面如果你想继续扩展可以往小车端加一个测速编码器做闭环速度控制也可以换成 ESP32 直接上 BLE甚至把控制手柄改成手势识别。那条路就是从这辆小车开始的。
返回列表