基于Micro:bit与ESP32的3D打印教育机器人:从设计到编程全解析
1. 项目概述:为什么我们需要一个“价廉物美”的教育机器人?
如果你接触过创客教育或者STEM项目,一定对Micro:bit这块小巧的开发板不陌生。它设计初衷就是为了让编程和硬件交互变得像搭积木一样简单,特别适合中小学生入门。但不知道你有没有发现一个现象:很多Micro:bit的机器人套件,要么是结构简单的塑料小车底盘,功能单一;要么就是集成度很高的商业产品,价格不菲,而且内部“黑盒化”,学生除了写写控制逻辑,很难接触到机械结构、传感器集成等更深层的知识。
这就是“SiRo 2.0”这个项目试图解决的问题。它的核心目标非常明确:用最低的成本和最高的开放性,打造一个功能全面、可深度定制的Micro:bit机器人平台。“SiRo”这个名字,我理解是“Simple Robot”的缩写,直指其设计哲学。2.0版本意味着它是在初代基础上迭代优化的产物。整个机器人的身体,几乎全部由3D打印部件构成,这意味着任何拥有一台普通FDM 3D打印机的人,都可以在家复刻出所有的结构件。电子核心是Micro:bit,通过一个扩展驱动板连接电机和传感器,而为了增强算力和连接能力,项目中还提到了ESP32,这通常是作为Wi-Fi/蓝牙协处理器或者高级传感器中枢来使用的。
这个组合的巧妙之处在于,它精准地覆盖了教育机器人的几个核心需求:低成本(3D打印材料很便宜)、易得性(Micro:bit和ESP32都是通用元件)、可扩展性(3D打印意味着你可以随时修改设计,增加传感器支架)以及教育深度(从图形化编程到Python代码,从基础巡线到物联网应用,可以随着学习阶段不断升级)。它不仅仅是一个玩具,更是一个开放的硬件学习平台。接下来,我们就从设计思路开始,一步步拆解如何实现它。
2. 整体设计与核心思路拆解
2.1 模块化架构:如何平衡简单与强大?
SiRo 2.0的设计采用了清晰的模块化思想,这直接决定了它的灵活性和可维护性。我们可以把整个机器人分成三个主要层次:
- 决策与控制层:以Micro:bit为核心。它负责运行用户编写的核心程序逻辑,处理来自按钮、加速度计、磁力计等内置传感器的输入,并通过GPIO引脚输出控制信号(如PWM电机信号)。对于初学者,可以用MakeCode图形化编程快速让机器人动起来;对于进阶者,可以用MicroPython编写更复杂的算法。
- 驱动与扩展层:这是连接大脑(Micro:bit)和身体(执行器)的关键。Micro:bit本身的驱动能力很弱,无法直接驱动电机。因此,需要一块电机驱动扩展板。这块板子通常基于TB6612FNG或L9110S这类双路电机驱动芯片,它接收Micro:bit发来的控制信号,并转换为足够的电流来驱动两个直流减速电机。同时,这块扩展板上还会引出排针,方便连接更多的外部传感器(如巡线、超声波模块)。
- 感知与通讯增强层:由ESP32模块担当。Micro:bit虽然有蓝牙,但Wi-Fi能力和更复杂的传感器数据处理能力有限。ESP32在这里可以扮演两个角色:一是作为网络网关,让机器人通过Wi-Fi连接到物联网平台,实现远程控制或数据上报;二是作为专用传感器处理器,接管一些对实时性要求高或数据量大的传感器(如摄像头、多个模拟传感器),处理后再把结果打包发送给Micro:bit,减轻主控的压力。
这种架构的优势是显而易见的。教学上,可以分阶段学习:先只用Micro:bit+驱动板做基础移动和避障;然后引入ESP32,学习物联网通信;最后可以尝试用ESP32进行图像识别等高级任务。在维护和调试时,问题也被隔离了,电机不转可能是驱动板问题,连不上网则是ESP32的配置问题,排查起来思路清晰。
2.2 机械结构设计:3D打印的考量与优化
全部采用3D打印结构件,是控制成本的关键,但也带来了工程挑战。设计时需要考虑以下几点:
- 强度与重量的权衡:机器人的底盘需要一定的强度来承载电池、电路板和传感器。通常我们会选择PLA材料,它打印容易、强度尚可。在设计中,对于承重部位(如电机安装座、电池盒与底盘的连接处)会增加加强筋,并适当增加壁厚和填充率(建议填充率20%-25%)。而对于非承重的外壳或装饰件,则可以降低填充率以节省材料和打印时间。
- 装配友好性:设计必须考虑到实际组装体验。这意味着要合理设计卡扣、螺丝柱和定位孔。例如,电机应该能轻松卡入或嵌入底座,并用螺丝从底部固定;上下盖的对接最好有导柱和卡扣,避免只用螺丝导致错位。所有需要穿线(电机线、传感器线)的地方,要预留足够的过线孔,并在边缘做倒角,防止割伤线材。
- 可扩展性预留:一个好的教育机器人设计应该像一块画布。在底盘和上层结构上,应该预留标准的安装孔位(例如M3螺丝孔阵列),这样学生就可以用简单的L型支架,轻松地将额外的超声波传感器、舵机云台甚至机械臂安装到机器人上,而无需重新设计整个底盘。
在SiRo 2.0的具体设计中,你可能会看到一个两层或三层的结构。底层是底盘,直接安装两个带编码器的直流减速电机和万向轮;中间层是电池仓和主控板(Micro:bit+驱动板);上层则可以安装ESP32、传感器阵列(如五路巡线模块)或一个可活动的传感器支架。
2.3 电子系统选型:为什么是这些芯片?
- 电机驱动芯片(TB6612FNG vs L9110S):这是驱动板的核心。TB6612FNG是更专业的选择,它内置H桥电路,驱动能力强(连续电流1.2A),发热小,并且有独立的待机控制引脚,安全性更好。L9110S则更便宜、外围电路更简单,但驱动能力和耐压值稍低。对于SiRo这种小型教育机器人,两者都能胜任,但TB6612FNG的稳定性和保护功能更值得推荐。
- ESP32模块的选择:市面上有ESP32-DevKitC、NodeMCU-32S等多种开发板。对于集成到机器人上,我们更关心尺寸和引脚引出方式。一个带有完整USB-TTL芯片的开发板可能过大,更优的选择是使用ESP32-WROOM-32E模组,然后自己设计一块小的转接板,只引出需要的引脚(如TX/RX与Micro:bit通信,几个GPIO接传感器,电源引脚)。这能极大地节省空间。如果为了简便,直接使用现成的ESP32开发板也可以,但需要注意固定方式。
- 传感器阵列:教育机器人常见的传感器有:
- 五路巡线传感器:用于巡线比赛。选择数字输出的型号(遇到黑线输出低电平)比模拟型号更易于Micro:bit处理。
- 超声波测距模块(HC-SR04):用于避障。注意其需要5V触发信号,而Micro:bit是3.3V逻辑,中间可能需要电平转换,或者选择工作电压范围包含3.3V的型号。
- 灰度传感器:可以当作简单的单路巡线传感器,也可以用来检测环境光。
- 碰撞传感器:机械式开关,用于检测物理碰撞,是最简单的传感器。
注意:在为Micro:bit选择外部传感器时,首要关注其工作电压。Micro:bit的GPIO逻辑电平是3.3V,且耐受电压较低。直接将5V传感器信号接入可能损坏主板。稳妥的做法是:要么选择支持3.3V的传感器型号,要么在信号线上使用电平转换模块。
3. 核心部件制作与组装详解
3.1 3D打印件的准备与后处理
拿到或设计好STL模型文件后,打印前的设置直接影响成品质量。
- 切片参数建议:
- 层高:0.2mm。这是一个在打印质量和时间之间的良好平衡点。
- 壁厚:至少2.4mm(即3条打印线宽)。对于受力件,可以增加到3.2mm或更多。
- 填充图案与密度:选择“网格”或“蜂窝”填充,强度较好。密度15%-20%用于非承重件,25%用于底盘等承重件。
- 支撑:对于有悬空结构的部分(如传感器支架的顶部),必须生成支撑。建议使用“树状支撑”,它更节省材料且容易拆除。
- 打印平台附着:一定要打开“裙边”或“ brim”,防止打印件翘边,这对于大型底盘部件至关重要。
打印完成后,需要进行后处理:
- 小心拆除支撑:使用钳子或专用工具,从边缘开始慢慢剥离,避免损坏模型本体。
- 清理毛刺和螺纹孔:用美工刀或锉刀清理打印留下的线头。对于螺丝孔,最好用对应规格的丝锥(如M3丝锥)手动攻一下丝,这样螺丝拧进去会非常顺滑,且不易滑牙。如果没有丝锥,直接用螺丝强行拧入也可以,但容易损坏塑料螺纹。
- 必要时进行打磨:如果装配要求高精度,可以用细砂纸(如400目以上)对结合面进行轻微打磨。
3.2 电路系统的连接与集成
这是将一堆离散元件变成智能机器人的关键一步,务必仔细。
- 步骤一:焊接电机驱动扩展板(如果购买的是散件套件)。核对原理图,将电机驱动芯片、电容、排针等焊接到PCB上。焊接排针时,可以先将排针插到Micro:bit上,然后将扩展板对准焊盘焊接,这样能保证完美的对齐。
- 步骤二:连接电机与轮子。将直流减速电机的两根线焊接到驱动板的电机输出端子(OUTA/OUTB)。注意两个电机的接线顺序要一致,否则后续调试时,一个电机正转另一个反转,机器人会原地打转。通常,我们定义左侧电机接驱动板的M1通道,右侧电机接M2通道。
- 步骤三:集成ESP32。如果使用独立的ESP32开发板,最简单的通信方式是串口(UART)。将ESP32的TX引脚连接到Micro:bit的一个RX引脚(如P1),ESP32的RX连接到Micro:bit的TX引脚(如P0)。同时,需要共地(GND)。供电方面,可以从驱动板的5V输出取电给ESP32。这样就建立了一个双向通信链路。
- 步骤四:安装传感器。以五路巡线模块为例,它通常有VCC、GND和五个数字输出引脚。VCC接3.3V(注意电压匹配),GND共地,五个输出引脚分别接到Micro:bit的剩余IO口(如P2, P8, P12, P13, P14)。用热熔胶或螺丝将传感器模块固定在底盘前部,离地高度约1-1.5厘米,并通过测试程序调整其灵敏度。
实操心得:在最终固定所有线缆之前,务必先进行“裸板测试”。即不安装外壳,将主要电路连接好,上传一个简单的测试程序(如让两个电机一正一反转动),确保所有基础功能正常。这能避免在组装完成后才发现问题,导致又得拆开的麻烦。
3.3 整机组装与走线技巧
组装顺序建议从下往上:
- 将电机用螺丝固定在底盘底部的指定位置。
- 安装轮子和万向轮。
- 将电池盒(建议使用4节AA电池盒或18650锂电池盒)固定在底盘上。
- 将驱动板、Micro:bit、ESP32(如果空间够)安装到中间层或上层。
- 连接所有线缆:电池到驱动板电源输入,电机到驱动板输出,传感器到对应IO口,ESP32与Micro:bit的串口线。
- 走线管理:这是让机器人内部看起来专业的关键。使用扎带或尼龙线扣将线缆捆扎整齐,沿着底盘边缘走线。避免线缆缠绕进轮轴或齿轮。过长的线可以折叠后用扎带固定。良好的走线不仅能防止意外拉扯脱落,也便于后期检修。
- 最后盖上顶板,拧紧螺丝。
4. 软件编程与功能实现
硬件组装完毕,接下来是赋予机器人灵魂的软件部分。我们将分层次实现功能。
4.1 Micro:bit基础驱动与运动控制
首先,我们需要让机器人能听话地移动。在MakeCode中,我们需要利用电机驱动扩展板对应的积木块(如果没有,可能需要手动添加扩展,或使用发送数字信号的通用积木)。
核心是理解电机控制信号:对于TB6612驱动芯片,通常需要两个引脚控制一个电机的方向和速度。例如,用P15和P16控制左电机。
- P15为方向引脚(高电平正转,低电平反转)。
- P16为PWM速度引脚(0-1023的模拟值,控制速度)。
一个让机器人前进2秒的MakeCode积木逻辑如下(假设驱动板已正确映射引脚):
当 开机 时 设置左电机方向引脚 P15 为 高电平 (正转) 设置右电机方向引脚 P13 为 高电平 (正转) 循环无限次 在引脚 P16 模拟写入 800 (左电机速度) 在引脚 P14 模拟写入 800 (右电机速度) 暂停 2000 毫秒 在引脚 P16 模拟写入 0 (停止) 在引脚 P14 模拟写入 0 暂停 1000 毫秒在MicroPython中,控制则更加灵活和精确:
from microbit import * from machine import time_pulse_us import utime # 定义电机引脚 LEFT_DIR = pin15 LEFT_PWM = pin16 RIGHT_DIR = pin13 RIGHT_PWM = pin14 # 初始化引脚 LEFT_DIR.write_digital(0) RIGHT_DIR.write_digital(0) def motor_control(left_speed, right_speed): # 控制左电机 if left_speed >= 0: LEFT_DIR.write_digital(1) # 正转 LEFT_PWM.write_analog(abs(left_speed)) # 速度值 0-1023 else: LEFT_DIR.write_digital(0) # 反转 LEFT_PWM.write_analog(abs(left_speed)) # 控制右电机(同理) if right_speed >= 0: RIGHT_DIR.write_digital(1) RIGHT_PWM.write_analog(abs(right_speed)) else: RIGHT_DIR.write_digital(0) RIGHT_PWM.write_analog(abs(right_speed)) # 示例:前进、右转、停止 motor_control(800, 800) # 前进 utime.sleep_ms(2000) motor_control(400, -400) # 原地右转 utime.sleep_ms(1000) motor_control(0, 0) # 停止通过封装motor_control函数,我们可以轻松实现前进、后退、转弯等基本动作。
4.2 传感器数据读取与巡线算法
以五路巡线传感器为例,它返回的是5个数字值(0或1,0通常代表检测到黑线)。我们可以将这五个状态组合成一个字节或一个整数来判断机器人的位置。
# 定义五路传感器引脚 S1 = pin2 # 最左侧 S2 = pin8 S3 = pin12 # 中间 S4 = pin13 S5 = pin14 # 最右侧 def read_line_sensors(): # 读取五个传感器的值,并组合成一个0-31的整数 # 假设传感器遇到黑线输出0,白线输出1 val = (S1.read_digital() << 4) | (S2.read_digital() << 3) | (S3.read_digital() << 2) | (S4.read_digital() << 1) | S5.read_digital() # 但通常我们更关心“黑线”状态,所以可以取反逻辑 # 这里我们定义一个状态:传感器在黑线上为1,不在为0 black_val = ((not S1.read_digital()) << 4) | ((not S2.read_digital()) << 3) | ((not S3.read_digital()) << 2) | ((not S4.read_digital()) << 1) | (not S5.read_digital()) return black_val # 简单的PD巡线算法 def line_following_PD(): last_error = 0 Kp = 10 # 比例系数,需要根据实际调试 Kd = 5 # 微分系数,需要根据实际调试 base_speed = 600 while True: sensor_state = read_line_sensors() error = 0 # 根据传感器状态计算偏差error。例如,定义中间传感器(S3)为0点。 # 只有S3在黑线上:error=0 # S2和S3在黑线上:error=-1 # S3和S4在黑线上:error=1 # S1和S2在黑线上:error=-2 ... 以此类推 # 这里是一个简化的映射,实际需要根据你的传感器排布精确计算 if sensor_state == 0b00100: # 只有中间传感器检测到线 error = 0 elif sensor_state in [0b00010, 0b00110, 0b00011]: error = 1 elif sensor_state in [0b01000, 0b01100, 0b11000]: error = -1 elif sensor_state in [0b00001, 0b00000]: # 严重偏右 error = 2 elif sensor_state in [0b10000, 0b00000]: # 严重偏左 error = -2 else: # 丢失线路的处理,例如原地缓慢旋转寻找 motor_control(200, -200) utime.sleep_ms(50) continue # PD计算 turn = Kp * error + Kd * (error - last_error) last_error = error left_speed = base_speed - turn right_speed = base_speed + turn # 限制速度在合理范围 left_speed = max(-1023, min(1023, left_speed)) right_speed = max(-1023, min(1023, right_speed)) motor_control(int(left_speed), int(right_speed)) utime.sleep_ms(20) # 控制循环周期这个PD(比例-微分)算法是巡线机器人中最常用且有效的算法之一。Kp决定了机器人对偏差的反应速度,Kd则能抑制振荡,让运动更平滑。这两个参数必须通过实际测试反复调整。
4.3 ESP32的协同工作:Wi-Fi控制与数据上传
现在,我们让ESP32加入工作。假设我们想让机器人通过Wi-Fi接收简单的移动指令。我们在ESP32上编写一个Arduino程序,创建一个Wi-Fi热点和Web服务器。
// ESP32 Arduino代码 #include <WiFi.h> #include <WebServer.h> const char* ssid = "SiRo_Robot"; const char* password = "12345678"; WebServer server(80); // 与Micro:bit通信的串口 #define RXD2 16 // 接Micro:bit的TX (P0) #define TXD2 17 // 接Micro:bit的RX (P1) void handleRoot() { String html = "<html><body>"; html += "<h1>SiRo 2.0 Control</h1>"; html += "<p><a href=\"/forward\"><button>Forward</button></a></p>"; html += "<p><a href=\"/left\"><button>Turn Left</button></a></p>"; html += "<p><a href=\"/stop\"><button>STOP</button></a></p>"; html += "</body></html>"; server.send(200, "text/html", html); } void handleForward() { Serial2.write('F'); // 通过串口2发送字符'F'给Micro:bit server.send(200, "text/plain", "Going Forward"); } void handleLeft() { Serial2.write('L'); server.send(200, "text/plain", "Turning Left"); } void handleStop() { Serial2.write('S'); server.send(200, "text/plain", "Stopped"); } void setup() { Serial.begin(115200); // 用于调试 Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2); // 与Micro:bit通信 WiFi.softAP(ssid, password); IPAddress IP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(IP); server.on("/", handleRoot); server.on("/forward", handleForward); server.on("/left", handleLeft); server.on("/stop", handleStop); server.begin(); Serial.println("HTTP server started"); } void loop() { server.handleClient(); }同时,在Micro:bit上,我们需要编写一个程序来监听串口,并根据接收到的字符执行相应动作。
# Micro:bit MicroPython代码 - 串口控制 from microbit import * import music # 初始化串口,与ESP32通信 uart.init(baudrate=9600, tx=pin0, rx=pin1) # 注意:此处tx/rx与ESP32程序中的收发要交叉连接 while True: if uart.any(): # 检查是否有数据 incoming = uart.read(1) # 读取一个字节 if incoming == b'F': display.show(Image.ARROW_N) motor_control(800, 800) # 前进 elif incoming == b'L': display.show(Image.ARROW_W) motor_control(-400, 400) # 左转 elif incoming == b'S': display.show(Image.NO) motor_control(0, 0) # 停止 music.play(music.BA_DING) sleep(50)这样,当手机或电脑连接到机器人ESP32创建的Wi-Fi热点,访问其IP地址,就能看到一个简单的网页控制界面,点击按钮即可远程控制机器人移动。你可以进一步扩展,让ESP32将传感器数据上传到物联网平台(如ThingsBoard、Blynk),实现更复杂的监控功能。
5. 调试、优化与功能扩展
5.1 常见问题排查速查表
在制作和运行过程中,你几乎一定会遇到下面这些问题。这里提供一个快速排查指南:
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 机器人上电后毫无反应 | 1. 电源未接通或电池没电。 2. 电源开关损坏或未打开。 3. 主控板(Micro:bit)未正确插入或损坏。 | 1. 用万用表测量电池盒输出电压,确保在4.8V-6V之间。 2. 检查开关导通性。 3. 单独给Micro:bit通过USB供电,看LED阵列是否点亮。 |
| 只有一个电机转动,或转动方向相反 | 1. 电机接线错误或接触不良。 2. 电机驱动板对应通道损坏。 3. 程序中对左右电机的引脚定义错误。 | 1. 交换不转的电机的两根线,看是否转动,以判断是电机问题还是驱动问题。 2. 用万用表测量驱动板输出端电压,在电机应转动时是否有电压变化。 3. 仔细核对代码中控制左右电机的引脚编号与实际焊接是否一致。 |
| 巡线时机器人剧烈摆动或跑飞 | 1. PD控制参数(Kp, Kd)设置不当。 2. 传感器离地高度不合适。 3. 传感器未校准,对赛道颜色反应不准确。 | 1.先调Kp:增大Kp让反应更快,但过大会振荡;再调Kd:增大Kd能抑制振荡,但过大会响应迟钝。从小值开始慢慢试。 2. 调整传感器支架高度,使其距离赛道约1cm左右。 3. 编写一个传感器校准程序,在白色区域和黑色区域分别读取传感器值,取中间值作为阈值。 |
| Wi-Fi连接不上或控制无响应 | 1. ESP32供电不足。 2. ESP32与Micro:bit串口接线错误或波特率不匹配。 3. 手机/电脑未连接到机器人热点。 | 1. 确保ESP32的5V供电稳定,可尝试单独供电测试。 2. 检查TX-RX是否交叉连接(ESP32的TX接Micro:bit的RX)。确保两端代码的波特率(如9600)完全相同。 3. 在手机Wi-Fi列表中找到“SiRo_Robot”并连接。 |
| 3D打印件在螺丝孔处开裂 | 1. 打印填充率过低。 2. 螺丝拧得过紧。 3. 螺丝孔设计太小,没有预留足够的壁厚。 | 1. 增加该部件的填充率至30%以上。 2. 拧螺丝时感觉有阻力即可,切勿用蛮力。 3. 重新设计模型,加大螺丝孔的直径,并在孔周围增加“火山口”式的加强结构。 |
5.2 性能优化与进阶技巧
当基础功能都实现后,你可以通过以下方式让SiRo 2.0变得更强大、更稳定:
- 电源管理优化:电机启动瞬间电流很大,可能导致Micro:bit重启。可以在电池输出端并联一个大容量电解电容(如470uF 16V),起到缓冲作用。如果使用18650锂电池,务必搭配带有过充过放保护的充电管理板。
- 运动控制优化:基础的开环速度控制(直接给PWM值)在不同电池电压和地面摩擦下速度不一致。如果电机带编码器,可以引入PID速度闭环控制。Micro:bit通过读取编码器脉冲计算实际转速,并与目标转速比较,动态调整PWM输出,让机器人速度更稳定。
- 传感器融合:不要只依赖一种传感器。例如,在巡线的同时,用超声波传感器检测前方障碍物,实现“巡线避障”。这需要编写更复杂的状态机程序,在不同传感器触发时切换机器人的行为模式。
- 结构强化与轻量化:对经常受力的部件(如电机座),可以用ABS材料重新打印,其韧性比PLA更好。对于非承重的外壳,可以尝试降低填充率到10%,甚至使用“闪电”填充模式,能大幅减少打印时间和重量。
5.3 无限可能的功能扩展
SiRo 2.0的开放式架构意味着它的天花板很高。以下是一些扩展方向:
- 物联网平台集成:让ESP32连接到MQTT服务器(如EMQX),将机器人姿态、传感器数据发布到云端,并可以从云端订阅控制指令。你可以在办公室用手机App控制家里的机器人巡逻。
- 计算机视觉:为ESP32搭配一个OV2640摄像头模块,使用ESP32-CAM开发板更方便。虽然算力有限,但可以运行一些轻量级模型,实现颜色追踪、简单的人脸检测或二维码识别。
- 语音交互:接入一个简单的语音识别模块(如LD3320),或者利用ESP32的蓝牙连接手机,通过手机语音助手间接控制机器人。
- 机械臂扩展:在机器人顶部安装一个3D打印的小型舵机机械臂(通常由2-3个舵机组成),通过Micro:bit的额外IO口控制,让机器人具备抓取和搬运小物体的能力。
- 多机协作:制作两个或更多的SiRo机器人,让它们通过ESP32的Wi-Fi或蓝牙相互通信,实现简单的编队行驶或任务分配,这是探索多智能体系统的绝佳起点。
从一块小小的Micro:bit开始,到整合3D打印、电机驱动、传感器网络和无线通信,最终构建出一个功能丰富的智能移动平台,SiRo 2.0项目的全过程本身就是一堂生动的项目制学习课程。它教会你的远不止如何让一个小车跑起来,更是如何系统性地思考问题、拆解模块、调试故障和迭代优化。最棒的是,整个项目的所有设计文件、代码都是开源的,你可以在社区找到无数灵感,也可以将自己的修改和改进分享出去。这就是开源硬件和创客文化的魅力所在——站在巨人的肩膀上,然后成为新的巨人。
