micro:bit电机驱动板选型、原理与避障小车实战指南
1. 项目概述为什么需要为micro:bit配备电机驱动板如果你玩过micro:bit肯定被它丰富的LED阵列、按钮和传感器所吸引用它做过温度计、计步器甚至简单的游戏机。但当你试图让它“动起来”——比如驱动一个小车轮、让一个风扇转起来或者控制一个机械臂的关节——你可能会立刻碰壁。micro:bit板载的GPIO引脚输出电流非常有限通常只有几毫安而一个普通的小型直流电机启动时可能需要上百毫安的电流。直接连接micro:bit要么无法驱动电机要么可能因过流而损坏。这就是“Motor Driver for micro:bit”这个项目存在的核心价值。它不是一个单一的软件或代码而是一个硬件解决方案通常体现为一块扩展板Shield或一个独立模块。它的本质是一个“电流放大器”和“控制中介”接收来自micro:bit微弱的数字控制信号然后从外部电源如电池盒汲取足够的能量去安全、高效地驱动一个或多个电机。对于任何希望将micro:bit项目从单纯的“电子玩具”升级为“可动机器人”或“自动化装置”的创作者、教育者和学生来说掌握电机驱动的选型与应用是必经之路。简单来说这个项目让你能用几行简单的积木块或Python代码就指挥电机正转、反转、调速从而为你的micro:bit赋予“肌肉”打开通往机器人学、自动化控制的大门。无论是制作一个避障小车、一个自动绘画机还是一个随风转动的模型风车电机驱动板都是连接智能大脑micro:bit和物理动作电机的关键桥梁。2. 核心需求解析与方案选型为micro:bit选择或设计电机驱动方案并非简单地买一个最贵的模块。你需要根据你的具体项目需求权衡几个核心维度。盲目选择可能会导致功能不足、资源浪费甚至项目失败。2.1 明确你的驱动需求电机类型与数量首先你要驱动什么直流电机DC Motor最常见两根线通电就转电压决定转速电流决定扭矩。驱动它需要双向电流实现正反转和PWM调速通过快速开关控制平均电压来调节速度。这是大多数小车项目的核心。步进电机Stepper Motor多根线通常是4或6根可以精确控制旋转角度和速度常用于需要精确定位的场景如3D打印机、CNC机床。驱动它需要更复杂的时序脉冲信号。伺服电机Servo Motor三根线电源、地、信号可以控制转到特定角度通常0-180度。虽然micro:bit的GPIO可以直接驱动一两个小型伺服因为伺服内部有驱动电路只接收PWM信号但数量多或型号大仍需外部电源。严格来说伺服驱动更偏向于提供稳定电源。对于入门和大多数创意项目直流电机是首选。因此我们的驱动板核心需求是驱动1-4个直流电机并能独立控制每个电机的方向和速度。2.2 关键性能参数考量确定了电机类型接下来看驱动板的能力指标驱动电流与电压这是硬性指标。查看你的电机铭牌或规格书找到它的“工作电压”如3V, 6V, 12V和“堵转电流”电机被卡住不转时的电流这是最大瞬时电流。驱动板的持续输出电流必须大于电机正常工作电流峰值电流最好能覆盖堵转电流。对于micro:bit项目常用的小型N20减速电机玩具车常用工作电压3-6V工作电流约100-300mA。因此一个单路持续电流1A以上的驱动芯片就绰绰有余。控制方式与接口如何用micro:bit控制它PWM速度 方向信号需要两个GPIO引脚控制一个电机。一个输出PWM波调速另一个输出高低电平控制正反转。这是最灵活的方式。双PWM信号需要两个GPIO引脚通过两个PWM信号占空比的差值来控制速度和方向一个全占空比另一个变化或两者反向变化。软件稍复杂。I2C/串行通信驱动板集成MCUmicro:bit通过I2C或串口发送指令如“电机1正转速度50%”。这种方式占用GPIO少可以驱动更多电机但需要额外的通信协议知识。集成度与易用性扩展板形式直接插在micro:bit上方接线极其简单电源也常通过板子提供。最适合教育场景和快速原型。独立模块形式通过杜邦线连接更灵活可以用于其他主控板但接线稍繁琐。电源管理电机是“电老虎”必须使用独立于micro:bit的电源供电如4节AA电池盒。好的驱动板应有电源滤波电路防止电机启停产生的电压尖峰干扰micro:bit导致复位。同时板载的电压转换电路能为micro:bit提供稳定的3.3V或5V电源实现单电源供电整个系统。2.3 常见驱动方案对比基于以上需求市场上有几种成熟的芯片方案对应不同的驱动板产品方案/芯片核心特点适用场景典型产品举例L9110S / L293D经典双H桥驱动芯片。L9110S电流较小~800mAL293D需外接散热。电路简单成本极低。驱动1-2个小功率直流电机或4-5个伺服。适合超低成本、功能简单的项目。很多廉价的micro:bit电机驱动模块TB6612FNG现代MOSFET H桥驱动。效率高、发热小、电流能力强单路1.2A持续3.2A峰值。集成待机与短路保护。驱动1-2个中小功率直流电机的首选方案。性能、功耗、保护俱佳。Kitronik、DFRobot等品牌的驱动板常用DRV8833与TB6612类似的双H桥电机驱动性能参数接近同样高效低热。同TB6612是另一个优秀选择。有些模块设计更紧凑。Adafruit等厂商有对应模块基于MCU的智能驱动集成STM32等单片机通过I2C/UART控制。可驱动多路电机4路以上集成编码器接口。复杂的多电机协同项目如四驱麦克纳姆轮小车、需要精确位置反馈的项目。一些高级机器人扩展板实操心得对于绝大多数micro:bit教育项目和爱好者创作TB6612FNG或DRV8833方案的驱动板是最佳平衡点。它们性能足够、发热低、有基本保护且市面上对应的扩展板资源丰富教程齐全。除非预算极其紧张否则不推荐老旧的L293D它的效率低、发热大。3. 硬件连接与电路原理详解以最常见的基于TB6612FNG的双电机扩展板为例我们来彻底搞懂硬件如何连接以及背后的电路原理。知其然更要知其所以然。3.1 扩展板引脚连接全解析一块典型的micro:bit电机驱动扩展板其连接可以分为三大部分与控制器的连接大脑指令扩展板的金手指引脚直接插入micro:bit的edge connector。关键引脚对应关系如下P0, P1, P8, P12, P13, P14, P15, P16这些是micro:bit可用的GPIO引脚。驱动板会占用其中4个来控制两个电机。通常电机A由P0(PWM速度) 和P8(方向) 控制。电机B由P1(PWM速度) 和P12(方向) 控制。这种分配不是绝对的但已成为许多扩展板如Kitronik的Motor Driver Board的事实标准因为MakeCode和MicroPython的电机驱动库默认就映射这些引脚。你在编程时必须遵循板子的实际定义。3.3V 和 GND为扩展板上的逻辑电路如TB6612FNG的内部控制部分供电。与动力源的连接能量供给这是最重要也最易出错的部分。扩展板上会有一个单独的电源端子螺丝端子或PH2.0接口标注为“VMOT”、“VCC”或“BAT/-”。你必须将外部电池盒如4节AA提供6V连接到这里而不是micro:bit的USB口USB口提供的5V/500mA完全不足以驱动电机。同时扩展板内部通常有一个低压差线性稳压器LDO将电池电压如6V降为稳定的3.3V并通过金手指反向供给micro:bit。这样你只需要给扩展板接一次电池整个系统micro:bit 驱动板 电机就都有电了。与执行器的连接动力输出扩展板上有两组输出端子分别对应电机AM1A, M1B和电机BM2A, M2B。将你的直流电机的两根线任意连接到一组端子的两个螺丝孔上。如果电机转向与你期望相反只需将两根线对调即可。注意事项在连接电池前务必双重检查电池正负极是否与端子标注一致。反接极有可能瞬间烧毁驱动芯片。建议使用可开关的电池盒方便调试时断电。3.2 H桥驱动原理如何让电机正反转驱动板的核心——无论是TB6612还是L9110——内部都是一个叫做“H桥”的电路。理解它你就理解了所有直流电机驱动的本质。想象一个电机的两根线是A和B。要让电机正转就需要A接正极B接负极反转则A接负极B接正极。H桥用四个开关现代芯片中用MOSFET晶体管巧妙地实现了这个功能。Vmotor (电池) | [SW1]---电机---[SW2] | | [SW3]--- ---[SW4] | GND (电池-)正转闭合SW1和SW4断开SW2和SW3。电流路径Vmotor - SW1 - 电机 - SW4 - GND。反转闭合SW2和SW3断开SW1和SW4。电流路径Vmotor - SW2 - 电机 - SW3 - GND。刹车闭合SW1和SW2或SW3和SW4将电机两端短接到同一电位电机惯性转动产生的反电动势会形成回路快速消耗能量停止。停止/滑行断开所有开关电机依靠惯性自由滑行。驱动芯片如TB6612的“方向”引脚内部逻辑就是控制这四组开关的状态组合。而“PWM速度”引脚则是以极高的频率例如25kHz快速切换“正转”或“反转”状态。例如50%占空比的正转PWM意味着在一半时间内电路处于正转状态另一半时间所有开关断开滑行宏观上电机就以一半的转速运行。这种方式称为“锁存衰减模式”比单纯调节电压效率高得多且低速时扭矩更平稳。4. 软件编程实战从积木块到Python硬件连接妥当后就可以让micro:bit发号施令了。编程环境首选微软的MakeCode图形化和MicroPython代码两者都有成熟的电机驱动库。4.1 MakeCode图形化编程MakeCode提供了最直观的方式其“引脚”和“高级”分类中通常有电机相关的积木块。但更规范的做法是添加专用的扩展库。添加电机驱动扩展在MakeCode编辑器中点击“扩展”。在搜索框中输入“motor”或“kitronik”找到如“kitronik-motor-driver”或“pxt-motor-driver”的扩展并添加。添加后左侧积木区会出现新的“Motor”类别。核心积木块与代码示例Motor.motorOn(motor, direction, speed)这是最常用的积木。你需要指定哪个电机A或B、方向Forward或Reverse和速度0-100%。Motor.motorOff(motor)停止指定电机。示例让小车交替前进后退// 当开机时设置电机A和B的速度为50% // 注意这里假设扩展板电机A连在M1B连在M2且引脚映射符合扩展库默认设置 Motor.motorOn(Motor.Motor.M1, Motor.Direction.Forward, 50) Motor.motorOn(Motor.Motor.M2, Motor.Direction.Forward, 50) basic.pause(2000) // 前进2秒 Motor.motorOff(Motor.Motor.M1) Motor.motorOff(Motor.Motor.M2) basic.pause(500) // 停止0.5秒 Motor.motorOn(Motor.Motor.M1, Motor.Direction.Reverse, 30) Motor.motorOn(Motor.Motor.M2, Motor.Direction.Reverse, 30) basic.pause(1500) // 后退1.5秒 Motor.motorOff(Motor.Motor.M1) Motor.motorOff(Motor.Motor.M2)实操心得在MakeCode中电机的停止有“滑行停止”和“刹车停止”之分。上述motorOff是滑行停止。有些扩展库提供Motor.brake(motor)积木用于刹车停止效果更迅速但机械冲击大。根据小车惯性大小选择惯性大的小车建议用刹车防止滑行过远。4.2 MicroPython代码编程对于追求更灵活控制或已有编程基础的用户MicroPython是更强大的选择。你需要了解如何直接通过控制GPIO引脚的电平与PWM来实现驱动。理解引脚映射与控制逻辑 假设使用前文提到的标准引脚映射电机A: P0-PWM, P8-方向电机B: P1-PWM, P12-方向。方向控制方向引脚P8, P12是数字输出。高电平(1)可能代表正转低电平(0)代表反转具体取决于电路设计可互换。速度控制速度引脚P0, P1需要配置为PWM输出。通过改变PWM对象的duty_u16()值0-65535对应0-100%来控制速度。编写驱动函数与类 直接操作底层引脚虽然灵活但代码冗长。更好的做法是封装一个简单的电机驱动类提高代码复用性和可读性。from microbit import pin0, pin1, pin8, pin12, sleep import machine # 用于PWM class DCMotor: def __init__(self, pwm_pin, dir_pin, reverseFalse): 初始化一个直流电机对象。 :param pwm_pin: PWM引脚对象如 pin0 :param dir_pin: 方向控制引脚对象如 pin8 :param reverse: 是否反转方向逻辑用于硬件接线差异校正 self.pwm machine.PWM(pwm_pin) self.pwm.freq(1000) # 设置PWM频率为1kHz避免电机啸叫 self.dir_pin dir_pin self.reverse reverse self.stop() def set_speed(self, speed): 设置电机速度。 :param speed: -100 到 100 之间的整数。负值反转0停止。 # 限制速度范围 speed max(-100, min(100, speed)) if speed 0: self.stop() return # 设置方向 direction speed 0 if self.reverse: direction not direction self.dir_pin.write_digital(1 if direction else 0) # 设置PWM占空比 (取绝对值) duty abs(speed) * 65535 // 100 self.pwm.duty_u16(duty) def stop(self): 停止电机滑行停止 self.pwm.duty_u16(0) # 占空比设为0即停止输出PWM # 注意这里没有设置方向引脚保持高阻态或原状态均可 def brake(self): 刹车停止需要硬件支持如将电机两端短接 # 对于简单H桥刹车通常需要同时控制两个引脚这里仅作示意。 # 更复杂的控制需要根据具体驱动芯片手册实现。 self.pwm.duty_u16(0) # 假设有另一个控制引脚的逻辑此处简化 print(Brake function needs hardware-specific implementation.) # 初始化两个电机对象假设为标准引脚映射 motor_A DCMotor(pin0, pin8) # M1: P0-PWM, P8-DIR motor_B DCMotor(pin1, pin12) # M2: P1-PWM, P12-DIR # 示例让小车画正方形轨迹 def move_forward(speed, duration_ms): motor_A.set_speed(speed) motor_B.set_speed(speed) sleep(duration_ms) def turn_right(speed, duration_ms): motor_A.set_speed(speed) motor_B.set_speed(-speed) # 右轮反转或停转实现原地转弯 sleep(duration_ms) def stop_all(): motor_A.stop() motor_B.stop() sleep(500) # 主循环 for _ in range(4): # 画一个正方形 move_forward(50, 1000) # 50%速度前进1秒 stop_all() turn_right(40, 600) # 右转0.6秒 stop_all() # 结束 motor_A.stop() motor_B.stop()注意事项上述brake()函数是示意。真正的刹车功能需要驱动芯片支持特定的控制模式如TB6612的STBY和IN1/IN2特定组合。在编写高级控制时务必查阅你所使用的驱动芯片的数据手册。5. 典型项目实战构建一个避障小车理论最终要服务于实践。让我们整合所有知识打造一个经典的micro:bit避障小车。这个项目将用到电机驱动、超声波传感器或红外避障模块和基本的控制逻辑。5.1 物料清单与硬件组装核心控制器micro:bit V2 一块动力与驱动基于TB6612的micro:bit电机驱动扩展板 一块N20减速电机带轮胎 两个用于差速驱动或四个用于四轮驱动电机支架、小车底盘套件 一套4节AA电池盒带开关 一个感知模块HC-SR04超声波模块 一个或红外避障传感器 两到三个连接线杜邦线公对公、公对母若干组装步骤组装底盘按照小车底盘套件说明书将电机安装到支架上并固定到底盘。确保左右轮对称转动顺畅。连接电机将两个电机的线分别接入驱动扩展板的电机A和电机B输出端子。暂时不用区分正反后续在软件中调整。安装扩展板与传感器将micro:bit插入驱动扩展板。将超声波模块的Trig引脚接micro:bit的P2Echo引脚接P3VCC接扩展板的3.3V或5V视模块电压GND接GND。如果使用红外避障通常数字输出接P2,P3,P4等。连接电源将电池盒的输出线正确连接到驱动扩展板的电源输入端子。此时先不要打开电池开关5.2 避障逻辑与代码实现我们采用“随机转向”的经典避障逻辑一直前进遇到障碍物则后退一小段然后随机向左或向右转一个角度继续前进。MakeCode实现 你需要添加“Sonar”扩展用于超声波或直接使用数字读引脚用于红外。// 定义引脚和变量 let distance 0 let turnDirection 0 // 主循环 basic.forever(function () { // 读取前方距离以厘米为单位假设超声波TrigP2, EchoP3 distance sonar.ping(DigitalPin.P2, DigitalPin.P3, PingUnit.Centimeters) // 如果距离大于10厘米且不为00通常表示超范围则前进 if (distance 10 distance ! 0) { Motor.motorOn(Motor.Motor.M1, Motor.Direction.Forward, 60) Motor.motorOn(Motor.Motor.M2, Motor.Direction.Forward, 60) } else { // 遇到障碍物停止 - 后退 - 随机转向 Motor.motorOff(Motor.Motor.M1) Motor.motorOff(Motor.Motor.M2) basic.pause(200) // 后退 Motor.motorOn(Motor.Motor.M1, Motor.Direction.Reverse, 40) Motor.motorOn(Motor.Motor.M2, Motor.Direction.Reverse, 40) basic.pause(500) // 随机选择左转或右转 turnDirection Math.randomRange(0, 1) Motor.motorOff(Motor.Motor.M1) Motor.motorOff(Motor.Motor.M2) basic.pause(200) if (turnDirection 0) { // 左转右轮前进左轮后退或停止 Motor.motorOn(Motor.Motor.M1, Motor.Direction.Forward, 0) // 左轮停 Motor.motorOn(Motor.Motor.M2, Motor.Direction.Forward, 50) // 右轮转 } else { // 右转 Motor.motorOn(Motor.Motor.M1, Motor.Direction.Forward, 50) // 左轮转 Motor.motorOn(Motor.Motor.M2, Motor.Direction.Forward, 0) // 右轮停 } basic.pause(300) // 转向持续时间 // 转向结束后循环会继续重新检测距离并前进 } basic.pause(100) // 每次循环间隔100ms避免检测过于频繁 })MicroPython实现 这里需要更精确的超声波测距函数。from microbit import * import machine import utime import random # --- 初始化电机使用前文定义的DCMotor类--- # 假设已粘贴DCMotor类定义在此 motor_A DCMotor(pin0, pin8) motor_B DCMotor(pin1, pin12) # --- 超声波测距函数 --- def get_distance_sonar(trig_pin, echo_pin): # 发送10us的高电平触发信号 trig_pin.write_digital(1) utime.sleep_us(10) trig_pin.write_digital(0) # 等待回声引脚变高并记录开始时间 while echo_pin.read_digital() 0: pass start utime.ticks_us() # 等待回声引脚变低并记录结束时间 while echo_pin.read_digital() 1: pass end utime.ticks_us() # 计算时间差声音速度约343m/s (0.0343 cm/us) # 距离 (时间 * 声速) / 2 (因为声音是来回) duration utime.ticks_diff(end, start) distance_cm (duration * 0.0343) / 2 # 如果距离异常大超过400cm返回一个很大的值 if distance_cm 400: return 999 return distance_cm # --- 主避障逻辑 --- def main(): trig pin2 echo pin3 trig.write_digital(0) while True: dist get_distance_sonar(trig, echo) print(Distance:, dist, cm) if dist 15: # 安全距离设为15厘米 # 前进 motor_A.set_speed(50) motor_B.set_speed(50) else: # 遇到障碍 # 1. 停止 motor_A.stop() motor_B.stop() sleep(200) # 2. 后退 motor_A.set_speed(-40) motor_B.set_speed(-40) sleep(500) # 3. 随机转向 motor_A.stop() motor_B.stop() sleep(200) if random.randint(0, 1) 0: # 左转 motor_A.set_speed(0) motor_B.set_speed(60) else: # 右转 motor_A.set_speed(60) motor_B.set_speed(0) sleep(400) # 转向时间 # 4. 停止转向循环将继续进入下一次检测 motor_A.stop() motor_B.stop() sleep(100) # 主循环延迟 if __name__ __main__: main()5.3 调试与优化技巧电机转向校正上传代码后如果小车前进时是倒退或转圈说明左右电机转向不一致。不要急着改硬件接线在软件中调整最方便。在初始化电机对象时使用reverse参数。例如如果左轮接电机A应该前进时却反转则将motor_A DCMotor(pin0, pin8, reverseTrue)。电源噪声处理电机启动瞬间电流很大可能导致micro:bit复位。如果遇到此问题确保电池电量充足旧电池内阻大压降更严重。在驱动板的电源输入端并联一个大容量电解电容如470uF 16V可以吸收瞬间电流冲击。在给micro:bit供电的3.3V线上并联一个100uF的电解电容和一个0.1uF的陶瓷电容进一步滤波。PWM频率选择电机在特定的PWM频率下可能会发出刺耳的啸叫声。通过调整PWM频率如从1kHz改为20kHz可以消除或减轻这种噪音。在MicroPython中修改pwm.freq(20000)即可。“死区”设置有些电机在很低的速度PWM占空比下无法启动表现为抖动或不转。可以在驱动函数中设置一个“死区”例如速度绝对值小于10时直接设置为0停止或强制提升到10。6. 进阶应用与问题排查掌握了基础驱动和避障小车后你可以探索更复杂的应用也会遇到一些更深层次的问题。6.1 进阶应用思路PID速度控制如果电机带有编码器可以测量实际转速你可以实现PID闭环控制让小车在负重或上坡时也能保持恒定速度。这需要读取编码器脉冲计算实际转速并与目标转速比较通过PID算法动态调整PWM输出。这是机器人控制的核心算法之一。多传感器融合结合巡线传感器、陀螺仪micro:bit内置、颜色传感器等可以让小车完成更复杂的任务如精确巡线、保持平衡两轮平衡车、颜色分拣等。无线遥控与通信利用micro:bit的无线电功能可以用另一块micro:bit制作遥控器实现蓝牙或2.4G无线控制。或者让多辆小车之间进行简单的通信与协作。机械臂控制通过驱动板控制多个伺服电机可以构建一个多自由度的机械臂结合超声波或视觉传感器需要外接摄像头模块实现抓取功能。6.2 常见问题与排查技巧实录即使按照教程操作你也可能会遇到一些棘手的问题。下面是我在实际项目和教学中总结的“故障排查树”问题1电机完全不转micro:bit正常亮灯。排查步骤查电源首先用万用表测量驱动板电机电源输入端子的电压。电池开关打开了吗电池有电吗电压是否在电机额定范围内查接线电机线是否牢固拧在端子上尝试交换同一组电机的两根线看是否反转如果反转说明之前接线虚焊或接触不良。查软件代码是否正确下载到了micro:bit程序是否真的运行到了电机控制部分尝试写一个最简单的测试程序只让一个电机全速正转。查控制信号用逻辑分析仪或示波器如果没有可以用一个LED和电阻串联接到控制引脚和GND之间看闪烁检查micro:bit输出的PWM和方向信号是否正常。如果没有信号检查代码中的引脚定义是否正确。问题2电机抖动、转速不稳或啸叫。可能原因与解决电源功率不足这是最常见原因。电机负载加重时电池电压被拉低导致驱动芯片工作不稳定。换用新的碱性电池或镍氢充电电池或者使用大容量锂电池。PWM频率不当频率太低如几百Hz会导致电机振动和噪音频率太高如超出芯片允许范围可能导致驱动异常。尝试将频率调整到5kHz-20kHz之间。机械卡阻检查电机轴和车轮是否被线缆或其他东西卡住。空载不装车轮测试电机是否运转顺畅。问题3micro:bit在电机启动时自动复位或程序跑飞。根本原因电机是感性负载启停会产生巨大的反电动势和电源噪声通过共地或电源线干扰micro:bit。解决方案电源隔离与滤波如前所述在驱动板电源入口加大电容100uF以上。最好使用独立的稳压模块为micro:bit供电与电机电源完全隔离。软件消抖在电机启动命令后增加一个短暂的延时如sleep(50)避免多个电机同时瞬间启动造成最大电流冲击。检查接地确保所有GND点电池、驱动板、micro:bit、传感器都良好连接在同一点上形成“星型接地”避免地线环路引入噪声。问题4驱动芯片异常发热甚至烫手。可能原因电机电流过大检查电机堵转电流是否远超驱动芯片的持续电流额定值。为电机选择带减速箱的型号可以降低对瞬间扭矩电流的需求。散热不良TB6612等芯片在持续大电流下也需要散热。如果芯片底部有散热焊盘确保PCB设计有足够的铺铜并连接到GND以帮助散热。可以加装小型散热片。工作模式问题如果长时间让电机处于“刹车”状态即短接电机两端芯片内部MOSFET会以较大电流导通产生热量。非必要不使用刹车模式滑行停止即可。最后的个人体会为micro:bit添加电机驱动能力是从“数字世界”迈向“物理世界”的关键一步。这个过程里硬件连接的严谨性远大于软件编程的复杂性。我最常对新手的建议是先确保每一根线都连接正确且牢固再用最简单的代码测试每一个独立功能比如只让一个电机转最后再把它们组合起来。耐心和细致的调试比任何复杂的算法都更能保证项目的成功。当你第一次看到自己编写的小车成功避开障碍物时那种连接虚拟与现实的成就感正是创客精神的精髓所在。