项目介绍
JBR-001 是一个开源、可 3D 打印的桌面陪伴机器人,核心是一块 Arduino UNO Q。
我们做 JBR-001,是想给机器人、实体交互、边缘 AI 和计算机视觉提供一个上手就能折腾的小平台。它把摄像头、测距、声音、动画屏和三路舵机塞进了一个紧凑的外壳里——打印、组装、写程序、改造,全部由你自己完成。

它能摆动手臂和脑袋跟你打招呼,发出提示音,让屏幕播放动画,用测距传感器感知周围,还能靠摄像头在 UNO Q 上跑计算机视觉。
工作原理
整台机器人的中枢是 Arduino UNO Q。它驱动屏幕、传感器、蜂鸣器和舵机,同时提供计算机视觉这类进阶应用需要的算力。
动作全部来自三个舵机:一个管头部,另外两个分别管左右手臂。
藏在后脑勺的测距传感器让它能感知身后的物体;蜂鸣器负责简单的音频反馈;板载屏幕则给了它一张会动的脸和心跳动画。
摄像头是更进一步的那层交互——它不再只是"前面有东西",而是能看到那东西是什么。
三个舵机由外接电源供电,不从 UNO Q 取电。外接电源与 UNO Q 共地,这样板子发出的控制信号才能稳定驱动舵机。
摄像头通过 USB-C 扩展坞与 UNO Q 相连。

主要接线
- 头部舵机 → 9 号脚
- 左臂舵机 → 10 号脚
- 右臂舵机 → 11 号脚
- 三路舵机 → 外接电源
- 外接电源负极 → UNO Q 的 GND
- Modulino Distance → Modulino Buzzer
- Modulino Buzzer → Arduino UNO Q
- Arduino UNO Q → USB-C 扩展坞
- 摄像头 → USB-C 扩展坞
重点:不要让三个舵机都从 UNO Q 上取电。给舵机单独配一路合适的电源,并把外接电源的地和 UNO Q 的地接在一起。
组装 JBR-001
JBR-001 的目标之一,就是让你自己就能把它做出来。机身全部是 3D 打印件,电路和舵机直接装在打印结构内部。
你需要准备:
- Arduino UNO Q
- 摄像头
- Modulino Distance
- Modulino Buzzer
- 三个舵机
- 舵机专用外接电源
- USB-C 扩展坞
- JBR-001 3D 打印件
- 线材、螺丝与固定件
先打印零件、搭出主体结构。装头部和手臂时就把舵机一并装进去,保证舵机轴和活动件的对位是准的。
头部舵机负责水平转动,身体两侧各一个舵机分管一条手臂。
机械部分装好后,再装 UNO Q,并把舵机线、传感器线、摄像头线和电源线顺着机身走好。这一步把线理清楚,合盖会轻松很多。
摄像头装在头部,朝正前方取景。
测距传感器装在后方,让 JBR-001 能发现从背后靠近的人。
完整的机械组装过程可以看下面的视频,Goran 和 Nenad 会一步步演示。
让头部屏幕活起来
屏幕是给 JBR-001 添点性格最省事的办法。
待机时它显示一颗心,在两个尺寸之间来回切换,形成细微的心跳效果——即使什么都没发生,也能看出它在运行。
这个动画用两张小位图实现:一颗大心、一颗小心。
// Small heart - flipped to match display orientation
uint8_t heartSmall[8][13] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,0,0,0,0,0},
{0,0,0,0,1,1,1,1,1,0,0,0,0},
{0,0,0,1,1,1,1,1,1,1,0,0,0},
{0,0,1,1,1,1,1,1,1,1,1,0,0},
{0,0,1,1,1,1,0,1,1,1,1,0,0},
{0,0,0,1,1,0,0,0,1,1,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0}
};
// Large heart - flipped to match display orientation
uint8_t heartLarge[8][13] = {
{0,0,0,0,1,1,1,1,1,0,0,0,0},
{0,0,0,1,1,1,1,1,1,1,0,0,0},
{0,0,1,1,1,1,1,1,1,1,1,0,0},
{0,1,1,1,1,1,1,1,1,1,1,1,0},
{1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,1,1,1,1,1,0,1,1,1,1,1,0},
{0,0,1,1,1,0,0,0,1,1,1,0,0}
};心跳不要用长 delay 把整个程序卡住,而是按已过去的时间推进。这很关键:动画跑着的同时,JBR-001 还要盯着测距传感器、响应别的事件。
// Heartbeat animation
unsigned long heartbeatTimer = 0;
int heartbeatStep = 0;
void heartbeat() {
unsigned long now = millis();
switch (heartbeatStep) {
case 0:
matrix.renderBitmap(heartLarge, 8, 13);
heartbeatTimer = now;
heartbeatStep = 1;
break;
case 1:
if (now - heartbeatTimer >= 120) {
matrix.renderBitmap(heartSmall, 8, 13);
heartbeatTimer = now;
heartbeatStep = 2;
}
break;
case 2:
if (now - heartbeatTimer >= 100) {
matrix.renderBitmap(heartLarge, 8, 13);
heartbeatTimer = now;
heartbeatStep = 3;
}
break;
case 3:
if (now - heartbeatTimer >= 160) {
matrix.renderBitmap(heartSmall, 8, 13);
heartbeatTimer = now;
heartbeatStep = 4;
}
break;
case 4:
if (now - heartbeatTimer >= 700) {
heartbeatStep = 0;
}
break;
}
}屏幕很容易扩展成别的表情和状态。比如用不同图案表示"检测到物体""摄像头认出了东西""正在等待交互"。
用蜂鸣器加声音
JBR-001 用蜂鸣器做简单的音频反馈。比如发现有人靠近时,播一小段音符当作打招呼。
四个音就够拼出一句问候:
// Play JBR-001's friendly greeting
void playHello() {
buzzer.tone(523, 120); // C5
delay(150);
buzzer.tone(659, 120); // E5
delay(150);
buzzer.tone(784, 180); // G5
delay(210);
buzzer.tone(1047, 250); // C6
delay(270);
}这个上行音阶不需要喇叭,也不需要音频文件,就能给出一个短促好认的"你好"。
声音也能用来表达状态。在你自己的应用里,不同的音序可以对应识别成功、告警、开机等事件。
感知近处物体
后脑勺那颗测距传感器负责感知身后物体并测出距离,测量结果持续交给你的程序使用。
读取很简单:定一个距离阈值,用它触发转头、摆臂、发声或换动画。
这给了你一路很轻的输入,方便把物理感知和 JBR-001 的其他能力组合起来。
// React when someone approaches
if (distanceSensor.available()) {
float distance = distanceSensor.get();
if (distance < DETECTION_DISTANCE && !objectDetected) {
objectDetected = true;
playHello();
}
// Ready for the next greeting once they move away
if (distance > RESET_DISTANCE) {
objectDetected = false;
}
}控制舵机
动作由三个舵机提供。头部舵机接 9 号脚,两条手臂的舵机分别接 10 号和 11 号脚。
给舵机指定目标角度就能控制:
headServo.write(90);在此基础上,不要在大角度之间瞬跳,而是在若干中间位置之间过渡,动作会自然得多。
比如打招呼时,头微微转向来客,手臂配合着抬起再放下。
舵机需要的电流超过了 UNO Q 能直接提供的量,几个舵机同时动作时尤其明显,所以三路舵机统一走外接电源。
外接电源的地必须和 UNO Q 的地接在一起。少了这个共同参考,UNO Q 发给舵机的控制信号就可能不稳。
自己做动画时要记住机器的机械极限。舵机的行程应留在打印关节能承受的范围内,不要直接跑满理论上的 0° 到 180°。
小幅动作往往更适合 JBR-001。轻轻转个头、短促抬一下手臂,表现力够,又不会显得机械。
加入计算机视觉
摄像头的加入,是 JBR-001 从"传感器驱动的桌面玩具"变成别的东西的起点。
摄像头经 USB-C 扩展坞接上 UNO Q,为机器人上运行的视觉程序提供图像。

可能性一下打开了:认出摆在面前的物体、按看到的东西做不同反应、检测特定物件,或者把视觉信息和测距数据合起来做更复杂的交互。
举例来说,JBR-001 不再只知道"前面站着个什么东西",而是能知道那是什么。
合成数据在这里特别有用。我们可以针对特定物体和场景准备图像,训练出视觉模型,直接部署到 JBR-001,而不用先手动拍大量照片再标注。
JBR-001 上的视觉是怎么跑的
流程本身很直白:摄像头拍下前方画面,UNO Q 用训练好的模型处理这些图像,模型给出识别结果,JBR-001 据此决定下一步做什么。
完整链路是这样:

识别出物体之后,结果可以接到 JBR-001 的任意一路输出上:转头、摆臂、发声、换屏幕内容,或者把几个动作串成一个反应。
这种分离也让 JBR-001 很好做实验:视觉模型决定"能认出什么",你的程序决定"认出来之后怎么反应"。
识别什么
本例中,我们训练 JBR-001 识别 Arduino Modulino 系列的不同模块。
把某个 Modulino 放到摄像头前,模型分析画面并判断看到的是哪一款。识别结果再交给程序去触发动作、声音、屏幕动画或其他行为。
这个项目用的是 Arduino Modulino 数据集,在 VisionDatasets.com 上公开可用(见文末)。

数据集里是针对不同 Modulino 的合成图像,覆盖各种位置、朝向、背景、光照和其他视觉变化,目的是让模型在真实摄像头前也能认出来。
这套流程并不限于 Modulino。换一份数据集、重新训练,JBR-001 就能学会认完全不同的东西。
把数据集导入 Edge Impulse
视觉模型的训练和部署用的是 Edge Impulse。
Vision Datasets 与 Edge Impulse 直接打通,Arduino Modulino 数据集可以一步传进 Edge Impulse 项目,不用手动下载、整理、再上传。
在 VisionDatasets.com 上打开 Arduino Modulino 数据集,选 Upload to Edge Impulse。

填上你的 Edge Impulse 项目 API key,再选图像数量、分辨率和要包含的 Modulino 类别。
上传完成后,图像会出现在 Edge Impulse 的 Data Acquisition 里,标注已经做好了,可以直接用。
完整的对接步骤见文末的 Edge Impulse 官方文档。
用 Edge Impulse 训练模型
数据集进到 Edge Impulse 之后,就可以搭视觉流水线了。
先打开 Data Acquisition 过一遍导入的图像,确认各个 Modulino 类别都有正确样本,训练集和测试集的分布符合预期。
接着新建一个 impulse,配置图像处理和训练模块。Edge Impulse 会用从 Vision Datasets 导入的图像跑完训练流程,让模型学到区分不同 Modulino 的视觉特征。
目标不是只认训练用的那些合成图,而是让模型能泛化到 JBR-001 上那颗真实摄像头拍的画面。
这正是数据集里要有变化的原因。不同的位置、旋转、背景、光照等差异,能让模型在训练阶段见到足够多的外观形态。
训练完成后,用 Edge Impulse 的测试工具评估模型在未参与训练的图像上的表现。但最关键的测试,还是拿一个真的 Modulino 放到 JBR-001 面前,看它认不认得出。
对模型满意之后,就可以部署到机器人上了。
在 UNO Q 上跑模型
下一步,是把训练好的 Edge Impulse 模型放到 Arduino UNO Q 上跑。
输入图像由装在头部的摄像头提供,UNO Q 用训练好的模型做推理,把预测结果返回给应用层。

这个过程可以持续运行,JBR-001 会一直观察面前的东西,一旦认出模型里的某个 Modulino 就做出反应。
把视觉接到 JBR-001 的动作上
能识别出物体固然有用,但只有当识别结果带来物理反应时,这个项目才真正有意思。
JBR-001 已经给了我们几种回应摄像头所见的方式:
- 转头
- 抬左臂或右臂
- 发声
- 切换屏幕动画
把视觉模型返回的预测接到这些行为上就行。
比如认出某个 Modulino 时,它可以转头、抬臂、播一小段音,再换一张屏幕动画。不同 Modulino 也可以触发不同反应。
模型负责提供"物理世界里有什么"这个信息,Arduino 应用负责把它翻译成动作、声音和视觉反馈。
做你自己的视觉应用
Modulino 这个例子只是个起点。同一套流程可以用来教 JBR-001 认完全不同的东西——工具、电子元件、日用杂物,或者你自己项目里的专属物件。
VisionDatasets.com 上有可直接导入 Edge Impulse 的现成数据集,你也可以自己造训练数据。
换模型后,JBR-001 的硬件平台完全不用动。你只需要决定:让它认什么,认出来之后做什么。
还可以把多种识别结果配上不同的动作、声音和屏幕动画,组合出全新的行为。
结语
到这里,一台能用的 JBR-001 已经有底子了。
我们从一堆 3D 打印件和一块 Arduino UNO Q 开始,把它做成了一个会放动画、能测距、会发声、能转头摆臂的桌面机器人。
JBR-001 是开源的,你可以改、可以试、可以变成自己的东西:设计新的屏幕动画,做不同的声音和动作,加传感器,改打印件,甚至彻底换掉它的行为逻辑。
再借助 UNO Q 的摄像头和算力,你还可以开始构建基于"它看到了什么"的交互。
写在最后
下面是本文用到的项目文件、数据集和视频入口,照着做遇到问题可以直接去原项目翻源码。
- JBR-001 开源项目仓库(含全部 STL 文件):https://github.com/syntheticAIdata/JBR-001
- VisionDatasets.com:https://visiondatasets.com/
- Edge Impulse 官方对接文档:https://docs.edgeimpulse.com/tutorials/integrations/syntheticaIdata-vision-datasets
- 组装演示视频 1:https://youtu.be/WeVEVs1tk5E
- 组装演示视频 2:https://youtu.be/ZFH7z8PBQiA











