ESP32与TB6612FNG双轮机器人:从硬件选型到代码调试全攻略
1. 项目概述与核心价值
如果你对嵌入式开发和机器人感兴趣,想从零开始搭建一个能跑能转的智能小车,那么基于ESP32和TB6612FNG的方案绝对是一个绝佳的起点。我这些年玩过不少电机驱动模块,从L298N到DRV8833,最后发现TB6612FNG在小型机器人项目里是个“甜点级”的选择——它体积小巧、驱动能力强,最关键的是发热控制得相当不错,不像某些老式驱动芯片,跑一会儿就烫得能煎鸡蛋。而ESP32,作为一款集成了Wi-Fi和蓝牙的双核微控制器,其性能远超我们熟悉的Arduino Uno,为机器人后续的无线遥控、传感器数据回传甚至简单的边缘计算提供了巨大的想象空间。
这个项目的核心,就是解决“如何让两个轮子听话地动起来”这个基础问题。听起来简单,但里面涉及了电源管理、PWM信号生成、电机驱动逻辑以及代码架构等多个环节。很多新手会卡在电机接线后乱转、供电不足导致ESP32重启或者代码逻辑混乱导致动作不协调这些问题上。我将通过这篇指南,不仅带你完成一个能执行预设动作(前进、后退、左转、右转)的双轮机器人,更会深入拆解每一步背后的原理和实操中容易踩的坑。无论你是刚接触硬件的学生,还是想为某个创意项目添加移动能力的开发者,这套经过实测的方案都能让你少走很多弯路。
2. 核心硬件选型与电路设计解析
2.1 主控与驱动芯片的“黄金搭档”
为什么是ESP32 + TB6612FNG?这个组合不是随便选的,背后有清晰的工程考量。
首先看主控ESP32。对于移动机器人来说,主控的功耗、计算能力和I/O口数量至关重要。ESP32 DEVKIT V1开发板价格亲民,提供了丰富的GPIO(我们本项目只用其中7个),更重要的是它内置的Wi-Fi/蓝牙模块。这意味着你的机器人基础平台一旦搭好,几乎零成本就获得了无线通信能力,后续升级为手机APP遥控或Web控制小车非常方便。相比之下,如果使用STM32等纯控制芯片,要实现无线功能还得额外加模块,增加复杂度和成本。
再来看电机驱动芯片TB6612FNG。它是东芝公司的一款双通道H桥驱动器,最大连续输出电流达1.2A(峰值3.2A),足以驱动市面上大多数小型减速电机。我选择它而非更常见的L298N,主要基于三点:一是效率,TB6612FNG的MOSFET内阻更小,发热量显著低于L298N,这意味着你可以用更小的散热片甚至不用散热片,让机器人结构更紧凑;二是支持待机(STBY)模式,可以通过一个引脚彻底关断电机输出,实现零功耗待机,对于电池供电的设备这是延长续航的关键功能;三是外围电路简单,芯片内部已经集成了必要的保护二极管和逻辑电路,基本不需要外接元件就能工作,对新手极其友好。
2.2 电源系统设计:稳定是一切的前提
电源部分是机器人稳定运行的基石,也是最容易出问题的地方。原方案使用4节AA电池(6V)同时为ESP32和电机供电,这是一个简洁的方案,但有几个细节必须注意。
电压匹配问题:ESP32开发板的VIN引脚允许的输入电压范围通常是5V-12V,而6V电池组是合适的。TB6612FNG的电机驱动电压(VM)范围是2.5V-13.5V,6V也在范围内。但请注意,普通AA电池在电机启动的大电流冲击下,电压会瞬间跌落。你可能遇到过机器人一动,ESP32就重启的情况,这往往就是电源电压被拉低导致的。
我的经验是,如果使用镍氢充电电池(单节1.2V,4节4.8V),电压可能处于ESP32 VIN要求的下限边缘,尤其在电量不足时。因此,我强烈建议使用优质的碱性电池或可充电的锂离子电池包(如两节18650串联,标称7.4V),并确保电池是全新的或满电的。另一个更稳妥的方案是采用双电源系统:一块小容量锂电池(如3.7V)通过升压模块给ESP32提供稳定的5V,另一块电池(6V或7.4V)专门给TB6612FNG供电,两者共地。这虽然增加了复杂度,但彻底解决了电机干扰主控的问题,适合后续添加更多传感器时采用。
接线与布线实践:原教程提到使用“电线分接头”来并联电源。在实际操作中,我推荐两种更可靠的做法:
- 使用面包板或PCB:将电池正极引线接入面包板的正极总线,然后从总线上分别引出两根线到ESP32的VIN和TB6612FNG的VM。负极同理。这样可以确保连接牢固,避免杜邦线松脱。
- 焊接一个简单的电源分配板:如果你有焊接条件,可以用一小块洞洞板,焊接一个接线端子用来接电池,然后引出两组VCC和GND线。这看起来多了一步,但对于后续的调试和扩展来说,整洁可靠的电源线能省去无数麻烦。
注意:务必确保ESP32和TB6612FNG的GND(地线)连接在一起,即“共地”。这是所有电路正常通信的基础,如果地线没有连通,控制信号将无法被正确识别。
2.3 电机与底盘的选择要点
项目原文对底盘一笔带过,但底盘和电机的选择直接影响机器人的性能。淘宝或亚马逊上十几块钱的“两轮机器人底盘套件”通常包含两个减速电机、轮子、底盘板和万向轮。
电机参数解读:拿到电机,你需要关注几个关键参数:工作电压(如3-6V)、空载转速(如200RPM)、减速比(如1:48)和空载电流。对于这种小型底盘,通常配的是N20或TT马达。工作电压决定了你的电池电压选择,空载转速和减速比决定了机器人的最大速度(转速越低,扭力越大,速度越慢)。我建议选择转速在100-200RPM之间的电机,速度适中,便于控制,扭力也足够带动小车本体。
安装与调整:安装电机时,确保它们被牢固地固定在底盘上,并且两个轮子在同一轴线上,否则机器人会跑偏。如果发现机器人总是自动偏向一边,除了代码调速,也要检查机械结构是否对称。
3. 软件环境搭建与库文件深度剖析
3.1 Arduino IDE配置与ESP32支持安装
虽然现在有PlatformIO等更强大的开发环境,但对于初学者,Arduino IDE以其简单直观仍是首选。要让Arduino IDE支持ESP32,需要添加开发板支持网址。
- 打开Arduino IDE,进入“文件” -> “首选项”。
- 在“附加开发板管理器网址”框中,填入以下网址(如果已有其他网址,用逗号分隔):
https://espressif.github.io/arduino-esp32/package_esp32_index.json - 点击“确定”保存。
- 打开“工具” -> “开发板” -> “开发板管理器”。
- 在搜索框中输入“esp32”,找到由“Espressif Systems”提供的“ESP32”开发板包,点击安装。
这个过程可能需要几分钟,取决于你的网络。安装完成后,在“工具” -> “开发板”列表中就能选择“ESP32 Dev Module”或其他对应的型号。
3.2 TB6612FNG_ESP32库的安装与源码导读
原项目使用的TB6612FNG_ESP32库是对另一个通用库的适配版本。我们按照指导安装它:
- 访问GitHub仓库:
https://github.com/pablopeza/TB6612FNG_ESP32 - 点击绿色的“Code”按钮,选择“Download ZIP”,将库文件下载到本地。
- 在Arduino IDE中,选择“项目” -> “加载库” -> “添加.ZIP库…”。
- 找到并选中你刚刚下载的ZIP文件。
安装成功后,你可以在“文件” -> “示例”中找到“TB6612FNG_ESP32”库提供的示例草图。但我不建议初学者直接运行复杂示例,我们先来理解这个库的核心。
这个库的核心是Motor类。当你用Motor motor1 = Motor(AIN1, AIN2, PWMA, offsetA, STBY, 5000, 8, 1);这样的语句创建一个电机对象时,你实际上是在配置驱动逻辑:
AIN1, AIN2:控制电机方向的GPIO引脚。PWMA:控制电机速度的PWM引脚。offsetA(偏移量):这是一个关键参数,值为1或-1。它决定了drive(255)是正转还是反转。因为电机两根线接法不同会导致旋转方向相反,通过这个参数可以在软件层面统一校正,而不用重新焊接硬件。我通常先设为1,如果方向反了,就改为-1。STBY:待机引脚。拉高(HIGH)使能电机驱动,拉低(LOW)则进入低功耗待机状态,电机自由停止。5000:PWM频率,单位是赫兹(Hz)。5000Hz是一个常用值,频率太低电机可能啸叫,太高则可能超过驱动芯片的响应能力。8:PWM分辨率位数。ESP32的LEDC(PWM)通道支持1-16位分辨率。8位分辨率意味着速度有256级(0-255),这是我们熟悉的Arduino AnalogWrite兼容模式。1:使用的PWM通道号。ESP32有多个LEDC通道,每个通道需独立编号。
理解这些参数,你就能在后续调试中游刃有余。例如,如果电机转动时有明显的“滋滋”高频噪音,可以尝试适当降低PWM频率(如改为1000Hz)。
4. 硬件连接与焊接实操指南
4.1 TB6612FNG模块的预处理
市面上购买的TB6612FNG模块,为了节省成本和适应不同焊接方式,通常不预焊排针。这意味着第一步就是焊接。
焊接步骤与技巧:
- 准备工具:一把尖头电烙铁(温度调至350°C左右)、焊锡丝、助焊剂(可选但推荐)、排针(通常模块随附)。
- 固定排针:将排针的短针一端从模块PCB的正面(有丝印字符的一面)插入孔中。为了固定,可以将排针插在一块面包板上,然后将模块扣在排针上,这样焊接时排针就不会晃动。
- 焊接:用烙铁头同时接触焊盘和排针引脚,约1-2秒后送入焊锡丝。焊锡熔化并流满焊盘后,先移开焊锡丝,再移开烙铁。一个好的焊点应该呈光滑的圆锥形。
- 检查:焊接完成后,检查所有引脚,确保没有虚焊(焊点不光滑、有裂缝)或桥接(相邻引脚被焊锡短路)。可以用放大镜观察,或用万用表的通断档测量相邻引脚是否短路。
实操心得:焊接时,烙铁在焊盘上停留时间不宜过长,通常2-3秒足够,否则可能烫坏焊盘或芯片。如果焊锡不流动,可能是烙铁温度不够或焊盘氧化,加点助焊剂能大大改善。焊接完务必清洗残留的助焊剂,尤其是松香型助焊剂,时间长了会腐蚀引脚。
4.2 接线图与信号流详解
接线是连接大脑(ESP32)与肌肉(电机)的神经。我们必须清晰理解每一根线的作用。下面这个表格整理了所有连接关系:
| ESP32 GPIO引脚 | 连接至 TB6612FNG 引脚 | 信号功能说明 |
|---|---|---|
| GPIO13(D13) | AIN1 | 电机A(左轮)方向控制线1 |
| GPIO12(D12) | BIN1 | 电机B(右轮)方向控制线1 |
| GPIO14(D14) | AIN2 | 电机A(左轮)方向控制线2 |
| GPIO27(D27) | BIN2 | 电机B(右轮)方向控制线2 |
| GPIO26(D26) | PWMA | 电机A(左轮)PWM速度控制 |
| GPIO25(D25) | PWMB | 电机B(右轮)PWM速度控制 |
| GPIO33(D33) | STBY | 驱动芯片使能/待机控制 |
| VIN(或5V) | 不直接连接 | 接收来自电池的正极电源 |
| GND | GND | 与电池、TB6612FNG共地 |
| TB6612FNG 引脚 | 连接至 电机/电源 | 功能说明 |
|---|---|---|
| A01, A02 | 电机1(左轮)的两根线 | 驱动电机A的输出端 |
| B01, B02 | 电机2(右轮)的两根线 | 驱动电机B的输出端 |
| VM | **电池正极 (+) ** | 电机驱动电源输入(接电池) |
| VCC | 通常悬空或接5V | 芯片逻辑电源(本例中可由内部从VM产生) |
| GND | 电池负极 (-)及ESP32 GND | 电源地 |
信号流解析:
- 方向控制(AIN1/AIN2, BIN1/BIN2):这是H桥控制的核心。以电机A为例,当AIN1=HIGH, AIN2=LOW时,电流从A01流向A02,电机正转;当AIN1=LOW, AIN2=HIGH时,电流反向,电机反转;当两者同为HIGH或LOW时,电机刹车(制动)。
- 速度控制(PWMA, PWMB):ESP32在这两个引脚上输出PWM信号。PWM的占空比(高电平时间占整个周期的比例)决定了输出到电机的平均电压,从而控制转速。占空比0%代表停止,100%代表全速。
- 使能控制(STBY):这个引脚必须设置为HIGH,TB6612FNG才会工作。如果设置为LOW,则所有输出关闭,电机处于自由停止状态。你可以利用这个引脚实现一个紧急停止开关。
接线实操建议:
- 颜色编码:我习惯用统一颜色的线表示相同功能。例如,红色接所有VCC/VIN/VM,黑色或棕色接所有GND,黄色、绿色用于控制信号,蓝、白用于电机线。这能在复杂的线束中快速定位。
- 先信号后电源:建议先连接ESP32和TB6612FNG之间的7根控制线,检查无误后再连接电源线。最后连接电机线。这样可以避免因接线错误导致意外短路。
- 电机线极性:电机两根线暂时不用区分正负,任意连接A01/A02即可。如果转动方向与预期相反,在代码中通过修改
offset参数或交换库函数中的方向逻辑来纠正,这比重新焊接硬件要方便得多。
5. 核心代码逐行解读与个性化修改
原项目的代码是一个很好的演示,但它只是让机器人执行一套固定的动作序列。我们来深入理解它,并把它改造成一个更易于控制和扩展的框架。
5.1 基础代码结构解析
#include <TB6612_ESP32.h> // 引脚定义 #define AIN1 13 #define BIN1 12 #define AIN2 14 #define BIN2 27 #define PWMA 26 #define PWMB 25 #define STBY 33 const int offsetA = 1; const int offsetB = 1; // 初始化电机对象 Motor motor1 = Motor(AIN1, AIN2, PWMA, offsetA, STBY, 5000, 8, 1); Motor motor2 = Motor(BIN1, BIN2, PWMB, offsetB, STBY, 5000, 8, 2); void setup() { // 初始化代码通常放在这里,例如初始化串口、设置STBY引脚模式等。 // 原示例中setup为空,但库的构造函数可能已处理了STBY。为保险起见,我们可以显式设置。 pinMode(STBY, OUTPUT); digitalWrite(STBY, HIGH); // 使能电机驱动 } void loop() { // 演示动作序列 delay(2000); motor1.drive(255, 2000); motor1.brake(); delay(2000); // ... 其余动作 }关键点分析:
Motor对象的初始化在全局区域,这意味着setup()函数执行前,对象就已创建,相关的PWM通道和GPIO模式可能已被库函数设置。drive(speed, duration)函数:speed范围-255到255,正负代表方向;duration是持续时间(毫秒),如果省略,则电机持续运行直到调用brake()或新的drive指令。forward(motor1, motor2, speed):这是一个库提供的便利函数,它同时控制两个电机向前转。其内部实现其实就是分别调用两个电机的drive函数并赋予相同的正速度。
5.2 创建可遥控的机器人框架
原代码是一个简单的演示。让我们把它升级一下,创建一个可以通过串口指令控制的机器人,这为后续连接蓝牙或Wi-Fi打下基础。
#include <TB6612_ESP32.h> // 引脚定义保持不变 #define AIN1 13 // ... 省略其他引脚定义 const int offsetA = 1; const int offsetB = 1; Motor motor1 = Motor(AIN1, AIN2, PWMA, offsetA, STBY, 5000, 8, 1); Motor motor2 = Motor(BIN1, BIN2, PWMB, offsetB, STBY, 5000, 8, 2); // 速度常量,方便调整 const int TURN_SPEED = 150; const int MOVE_SPEED = 200; void setup() { Serial.begin(115200); // 初始化串口通信,用于接收指令 pinMode(STBY, OUTPUT); digitalWrite(STBY, HIGH); // 上电即使能驱动 Serial.println("Robot Ready! Commands: f(forward), b(back), l(left), r(right), s(stop)"); } void loop() { if (Serial.available() > 0) { char command = Serial.read(); // 读取一个字符指令 executeCommand(command); } } void executeCommand(char cmd) { switch (cmd) { case 'f': // 前进 forward(motor1, motor2, MOVE_SPEED); Serial.println("Moving FORWARD"); break; case 'b': // 后退 back(motor1, motor2, MOVE_SPEED); // 注意:原库的back函数可能需要正速度值 Serial.println("Moving BACKWARD"); break; case 'l': // 左转(原地左转) left(motor1, motor2, TURN_SPEED); Serial.println("Turning LEFT"); break; case 'r': // 右转(原地右转) right(motor1, motor2, TURN_SPEED); Serial.println("Turning RIGHT"); break; case 's': // 停止 brake(motor1, motor2); Serial.println("STOP"); break; default: Serial.println("Unknown command"); break; } }这个改进版代码,让你可以在Arduino IDE的串口监视器里输入单个字符(f, b, l, r, s)来控制机器人。这是一个巨大的进步,因为它将机器人的行为从“预编程”变成了“实时交互”。
5.3 高级控制:差速转向与速度渐变
原地转向(left/right函数)对于狭窄空间调头很有用,但更自然的转向方式是差速转向,即让两个轮子以不同速度转动,像坦克一样。同时,突然的启动和停止对电机和机械结构都有冲击,加入速度渐变(软启动/软停止)会更平顺。
// 差速转向函数:左转则右轮快,左轮慢或反转 void differentialTurn(int leftSpeed, int rightSpeed, int duration = 0) { motor1.drive(leftSpeed); motor2.drive(rightSpeed); if (duration > 0) { delay(duration); brake(motor1, motor2); } } // 软启动函数 void softStart(Motor &m, int targetSpeed, int rampTime = 500) { int step = targetSpeed > 0 ? 1 : -1; int currentSpeed = 0; unsigned long startTime = millis(); while (abs(currentSpeed) < abs(targetSpeed)) { currentSpeed += step; m.drive(currentSpeed); delay(rampTime / abs(targetSpeed)); // 计算每增加一个速度单位应延迟的时间 } // 达到目标速度后,持续驱动 m.drive(targetSpeed); } // 在executeCommand中调用差速转向 case 'L': // 温和的左转(差速) differentialTurn(-TURN_SPEED/2, TURN_SPEED/2); // 左轮慢速反转,右轮正转 Serial.println("Differential Left"); break;softStart函数通过逐步增加PWM占空比来实现平滑加速,对齿轮箱和电池都非常友好。differentialTurn则提供了更灵活的转向控制,你可以通过调整左右轮速度比来控制转弯半径。
6. 上传代码、调试与故障排查实录
6.1 代码上传步骤与常见错误
- 选择开发板与端口:在Arduino IDE的“工具”菜单下,确保“开发板”选择了“ESP32 Dev Module”(或你具体使用的型号)。“端口”选择你的ESP32连接的COM口(Windows)或/dev/ttyUSB*(Linux/Mac)。如果端口列表是灰色的,可能是驱动未安装,需要安装CP210x或CH340等USB转串口芯片的驱动。
- 编译与上传:点击“验证”(对勾图标)编译代码。如果没有错误,再点击“上传”(右箭头图标)。上传时,ESP32开发板上的某些LED可能会快速闪烁,这是正常现象。
- 常见上传错误:
Failed to connect to ESP32: Timed out waiting for packet header:上传超时。解决方法:按住ESP32开发板上的“BOOT”按钮不松手,然后点击上传按钮,等到IDE显示“正在连接…”时,再松开“BOOT”按钮。这是ESP32进入下载模式的经典操作。A fatal error occurred: Could not open /dev/ttyUSB0, the port doesn't exist:端口被占用或选择错误。确保没有其他软件(如串口监视器、其他IDE)占用该端口,并重新拔插USB线试试。- 编译错误
fatal error: TB6612_ESP32.h: No such file or directory:库没有正确安装。检查库是否安装在Arduino IDE的libraries文件夹内,或者通过“项目” -> “加载库” -> “管理库…”搜索“TB6612”尝试安装其他可能兼容的库。
6.2 上电调试与问题排查
代码上传成功后,给机器人装上电池,准备第一次“行走测试”。建议按以下顺序排查:
- 电源检查:首先,不接电机,只连接ESP32和TB6612FNG的电源。用万用表测量ESP32的VIN引脚和GND之间是否有约6V电压,测量TB6612FNG的VM和GND之间是否也有约6V。同时观察ESP32是否正常启动(板载LED可能亮起)。
- 信号检查:利用一个简单的测试代码,让某个控制引脚(如AIN1)周期性地输出HIGH和LOW,用万用表电压档或示波器测量该引脚对GND的电压,看是否在0V和3.3V之间变化。这可以确认ESP32的GPIO工作正常。
- 电机单独测试:将电机直接连接到电池(注意时间要短,避免堵转烧坏),确认电机本身是好的,并能正反转。
- 集成测试与问题速查:连接所有线路,运行一个简单的单电机测试程序(例如只让
motor1.drive(100)持续2秒)。如果电机不转,请对照下表排查:
| 现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 电机完全不转,无声音 | 1. 电源未接通或电压不足。 2. STBY引脚未设置为HIGH。 3. 电机线未接好或电机损坏。 4. TB6612FNG芯片损坏。 | 1. 用万用表检查VM、VIN电压。 2. 检查代码中 digitalWrite(STBY, HIGH)是否执行,或用导线直接将STBY引脚连接到VCC(3.3V)试试。3. 将电机直接接电池测试。 4. 触摸TB6612FNG芯片,如果常温且其他条件正常,可能损坏。 |
| 电机抖动或发出“滋滋”声但不转 | 1. PWM频率可能不适合该电机。 2. 电源功率不足,带载后电压骤降。 3. 电机堵转(机械卡死)。 | 1. 尝试在初始化Motor对象时,将PWM频率参数(5000)改为1000或500。2. 检查电池电量,尝试用更粗的电源线或更换动力更强的电池(如18650)。 3. 用手轻轻转动轮子,检查是否有阻力。 |
| 一个电机转,另一个不转 | 1. 不转的电机接线错误或接触不良。 2. 对应的控制引脚定义错误或损坏。 3. 代码中对应的 Motor对象初始化参数有误。 | 1. 交换两个电机的接线,如果问题跟随电机走,则是电机或其接线问题;如果问题留在原通道,则是ESP32或TB6612FNG该通道的问题。 2. 用万用表测量不转电机对应的AIN1/AIN2/PWMA引脚在运行时的电压变化。 3. 检查代码中两个 Motor对象的引脚参数是否正确。 |
| 电机转向与预期相反 | 电机线极性接反。 | 不要重新焊接!这是最简单的软件修复问题。修改代码中对应电机的offset常量,将1改为-1,或者交换AIN1和AIN2的引脚定义。 |
| 机器人前进时走弧线 | 两个电机的实际转速有差异(即使PWM值相同)。 | 这是非常常见的现象,由于电机个体差异、轮子摩擦不同导致。需要在代码中进行“校准”。在setup()里为每个电机设置一个微调系数。例如:motor1.drive(200 * 0.95); // 左电机稍慢,motor2.drive(200);,通过反复测试找到一个平衡值。 |
| ESP32运行一段时间后自动重启 | 电机启动或堵转时电流过大,导致电池电压瞬间跌落,触发ESP32的欠压复位。 | 1. 优化电源:使用容量更大、内阻更低的电池(如锂聚合物电池)。 2. 在ESP32的VIN和GND之间并联一个大电容(如1000uF 16V),作为能量缓冲池。 3. 在代码中实现软启动(如前文所述),避免电流突变。 |
6.3 性能优化与扩展思考
当你的机器人能可靠地执行基本动作后,可以考虑以下优化和扩展:
- 增加传感器:最自然的是增加超声波模块(HC-SR04)实现避障。将Trig和Echo引脚连接到ESP32的空闲GPIO,在
loop()中周期性地测量距离,当距离小于阈值时,调用brake()和back()或turn()函数。 - 无线控制:利用ESP32的蓝牙,可以很容易地将其与手机APP(如Arduino Bluetooth Controller)配对,实现更直观的控制。升级到Wi-Fi,则可以创建一个Web服务器,通过浏览器在任何地方控制机器人。
- 使用PlatformIO:对于更复杂的项目,建议从Arduino IDE迁移到Visual Studio Code + PlatformIO。它提供更好的代码管理、库依赖管理和调试功能。
- 结构加固:检查底盘螺丝是否紧固,线缆是否用扎带固定好,避免在运动中被轮子卷入。可以在底盘前端加装一个防撞条(如泡沫条)。
这个基于ESP32和TB6612FNG的双轮机器人平台,其价值远不止于完成教程中的几个动作。它为你打开了一扇通往嵌入式系统、机器人控制、传感器融合和物联网的大门。从让轮子转起来开始,到让它能看、能听、能思考,每一步的探索都充满乐趣。我建议你在实现基础功能后,不要停下,尝试去添加第一个传感器,编写第一个避障逻辑,你会发现,这个小小的双轮平台,能承载的创意远超你的想象。
