
简介pixy2-master.zip 是一套面向 Arduino 开发者与机器视觉入门者的 Pixy2 视觉模块完整项目资源适合希望为机器人、自动化设备加入物体识别能力的爱好者与工程人员。压缩包共 490 个文件约 81.26MB以 h 头文件、cpp 源文件、m 实现文件、c 源码为主并包含 ino 示例程序、makefile 构建脚本、py 辅助脚本、hex 固件及 pdf 文档覆盖从底层驱动到上层应用的完整链路。资源中既有颜色签名设置、串口通信等示例代码也包含将识别数据实时显示于 LCD 的教程可帮助读者快速完成 Pixy2 与 Arduino 的集成。目前已有 903 人学习下载对于想涉足机器视觉领域的开发者而言是一份可直接上手实践、便于二次开发的参考资料。1. 拆开 pixy2-master.zip一块能跑视觉识别的嵌入式模块到底怎么落地如果你手头有一块 Pixy2 摄像头模块或者正在做嵌入式视觉相关的课程设计、竞赛项目大概率会搜到pixy2-master.zip这个资源包。它不是一个普通的示例压缩包而是围绕 Pixy2 机器视觉模块的一整套开发资料集合里面通常包含 Arduino 库、树莓派接口代码、通信协议文档以及若干演示程序。Pixy2 本身是一款集成图像传感器和处理器的小型视觉模块能直接输出目标物体的坐标、颜色标签和线段信息不需要你在主控上跑复杂的图像算法。这意味着什么意味着你用一个几十块钱的单片机就能做出巡线、追球、颜色分拣这类看起来挺唬人的功能。适合谁适合做嵌入式课程设计的学生、搞创客比赛的开发者以及想快速验证视觉方案但不想从 OpenCV 底层写起的工程师。但资源包拿到手只是第一步真正把它跑通、用稳中间还有不少细节要抠。2. Pixy2 的通信链路与数据格式从 UART 到 I2C 的选型逻辑2.1 为什么 Pixy2 不直接把图像传给你Pixy2 和普通 USB 摄像头最大的区别在于它内部已经跑完了图像处理流程。模块上的处理器会做颜色连通域分析、线段检测、二维码识别然后把结果打包成固定格式的数据帧通过 UART、I2C、SPI 或者 USB 发出去。你拿到的是“第 3 个色块在画面中的 x 坐标是 156y 坐标是 88宽度 42高度 35”这样的结构化数据而不是一帧 RGB 像素。这个设计的好处是主控压力极小Arduino Uno 这种只有 2KB RAM 的板子也能轻松接。代价是你没法拿到原始图像做二次处理Pixy2 只告诉你它“看到”了什么不告诉你它“长什么样”。常见做法是如果你需要同时做颜色识别和自定义形状判断那就得换方案如果只是追踪特定颜色的物体或者巡线Pixy2 的抽象层级刚刚好。2.2 UART 与 I2C 的接线差异和参数配置资源包里最常用的两种通信方式是 UART 和 I2C。UART 接线简单Pixy2 的 TX 接主控的 RXRX 接主控的 TX供电 5V地线共地。I2C 则只需要 SDA 和 SCL 两根线但需要上拉电阻Pixy2 模块内部已经带了 4.7k 上拉所以直接接就行。选哪个如果你主控的硬件串口已经被占用了比如用来烧录或接其他模块那就走 I2C如果对通信速度要求高UART 默认 19200 波特率可以改到 115200I2C 最高 400kHz实际吞吐量 UART 更稳。下面这段代码是 Arduino 下初始化 Pixy2 并读取色块数据的典型写法#include Pixy2.h Pixy2 pixy; void setup() { Serial.begin(115200); pixy.init(); // 默认走 SPI如果是 UART 或 I2C 需要改库配置 // 设置摄像头亮度、颜色特征等参数 pixy.setLamp(1, 1); // 打开补光灯参数为上下灯 } void loop() { pixy.ccc.getBlocks(); // 获取色块数据 if (pixy.ccc.numBlocks) { Serial.print(检测到 ); Serial.print(pixy.ccc.numBlocks); Serial.println( 个色块); for (int i 0; i pixy.ccc.numBlocks; i) { Serial.print( 色块 ); Serial.print(i); Serial.print(: 签名); Serial.print(pixy.ccc.blocks[i].m_signature); Serial.print( x); Serial.print(pixy.ccc.blocks[i].m_x); Serial.print( y); Serial.print(pixy.ccc.blocks[i].m_y); Serial.print( 宽); Serial.print(pixy.ccc.blocks[i].m_width); Serial.print( 高); Serial.println(pixy.ccc.blocks[i].m_height); } } delay(100); }这段代码的逻辑很直白pixy.init()完成模块初始化pixy.ccc.getBlocks()向模块请求当前画面中的色块信息返回的数据存在pixy.ccc.blocks[]数组里。m_signature是颜色签名编号对应你在 PixyMon 软件里训练的颜色标签m_x和m_y是色块中心坐标范围 0 到 315 和 0 到 207Pixy2 分辨率是 316x208m_width和m_height是外接矩形尺寸。参数怎么改pixy.setLamp()控制补光灯暗光环境下打开能显著提升识别率。pixy.setCameraBrightness()可以调曝光但一般自动曝光够用。注意pixy.init()默认参数是 SPI 模式如果你用 UART 或 I2C需要在库文件里改Pixy2.h中的PIXY2_DEFAULT_LINK宏或者调用pixy.init(linkType)指定。这个坑后面还会细说。2.3 数据帧结构为什么你读到的坐标偶尔会跳变Pixy2 输出的每个数据帧包含帧头、数据长度、有效载荷和校验和。以 CCCColor Connected Components协议为例一个色块报告包含 14 个字节2 字节签名、2 字节 x、2 字节 y、2 字节宽、2 字节高、2 字节角度、2 字节跟踪索引。坐标跳变通常不是模块坏了而是几个原因一是光照变化导致颜色阈值漂移模块重新分割连通域二是多个同色物体距离太近模块把它们合并成一个又分开三是通信丢包校验和没过主控拿到的是上一帧的缓存。排查方法先用 PixyMon 软件看实时画面如果软件里坐标稳定而你的代码里跳那就是通信问题如果软件里也跳那就是光照或颜色签名没训好。常见做法是给色块加跟踪索引过滤只取m_trackingIndex连续几帧不变的目标能滤掉大部分抖动。3. 从资源包到可运行工程编译、烧录与第一个巡线程序3.1 资源包目录结构与文件用途pixy2-master.zip解压后通常包含这几个目录arduino/下是 Arduino 库和示例raspberrypi/下是树莓派的 Python 接口docs/下是通信协议 PDF 和 API 说明src/下是底层固件源码一般用不到examples/下是巡线、追球、二维码识别等演示程序。你不需要全部看完重点看arduino/libraries/Pixy2/和examples/里的ccc_hello_world、line_following这两个。前者帮你验证通信链路后者直接给你一个巡线框架。文件数不多但每个都挺关键尤其是Pixy2.h和Pixy2CCC.h改通信方式、改分辨率、改默认签名都在这里。3.2 Arduino 环境下的库安装与编译验证把arduino/libraries/Pixy2整个文件夹复制到 Arduino 的libraries/目录下重启 IDE。然后打开文件 - 示例 - Pixy2 - ccc_hello_world。如果你用的是 UART 通信需要改两处一是Pixy2.h里把#define PIXY2_DEFAULT_LINK PIXY2_SPI改成PIXY2_UART二是确认波特率默认 19200如果你在 PixyMon 里改过这里也要同步。编译之前检查板子和端口选对上传后打开串口监视器波特率设 115200这是主控和电脑的通信速率不是主控和 Pixy2 的。如果看到“检测到 1 个色块”这样的输出说明链路通了。如果一直没输出先量 Pixy2 的 TX 引脚有没有电压跳动没有就是模块没启动或者接线反了。3.3 巡线程序的参数调优与现场调试巡线示例的核心逻辑是Pixy2 检测画面中的线段返回线段的主轴方向、起点终点坐标主控根据线段中心与画面中心的偏差调整舵机或电机。关键参数有三个m_x0、m_y0和m_x1、m_y1是线段两端点m_index是线段编号。调优步骤先把车放在线上打开 PixyMon 看线段检测是否稳定如果线断了或者交叉了模块可能返回多条线段你需要选最长的那条或者最靠近画面底部的那条。常见做法是加一个简单滤波只取m_y1大于画面高度一半的线段因为远处的线容易受干扰。速度控制上偏差乘以比例系数 Kp 直接给舵机转向Kp 太大会震荡太小会反应迟钝一般从 0.3 开始试。现场调试时把车架空用手左右移动线看舵机响应方向对不对再落地跑。4. 避坑与排查Pixy2 上手最容易翻车的五个地方4.1 现象串口有输出但坐标全是 0 或乱码原因通信协议不匹配。Pixy2 出厂默认可能是 SPI 模式而你的代码按 UART 解析帧头对不上解析出来的就是垃圾数据。解决用 PixyMon 连接模块在Configure - Pixy2 Parameters里把Data out port改成 UART波特率设 19200保存后重启模块。然后确认代码里Pixy2.h的PIXY2_DEFAULT_LINK也改成了PIXY2_UART。两边必须一致缺一不可。4.2 现象颜色签名训练后识别率仍然很低原因训练时的光照和实际运行时的光照差异太大。Pixy2 的颜色识别基于 HSV 阈值你在暖光下训的红色到冷光下可能偏紫阈值就不覆盖了。解决在最终运行的光照环境下重新训练签名。训练时把物体放在画面中央占画面 1/4 到 1/2 面积太远太小训不准。如果环境光变化大打开补光灯并固定亮度能大幅提升稳定性。另外签名编号 1 到 7 是留给用户训练的别用 00 是默认的“所有颜色”。4.3 现象I2C 通信时主控死机或读不到数据原因I2C 地址冲突或者上拉电阻不匹配。Pixy2 的 I2C 地址默认是 0x54如果你总线上还挂了其他 0x54 的设备就会冲突。另外虽然 Pixy2 内部有 4.7k 上拉但如果你的主控板子上已经有更强的上拉比如 2.2k并联后等效电阻变小上升沿太陡可能导致通信失败。解决先用 I2C 扫描工具确认能扫到 0x54如果扫不到检查 SDA 和 SCL 有没有接反如果能扫到但读数据死机试着去掉主控板上的外部上拉只靠 Pixy2 内部的。还有一点I2C 模式下 Pixy2 的供电必须稳定在 5V电压低于 4.8V 时内部逻辑会异常。4.4 现象巡线时车在直线段正常一到弯道就冲出原因线段检测的更新率跟不上车速或者转向比例系数太大。Pixy2 的帧率默认 60fps但如果你开了多个检测功能同时检测色块和线段帧率会降到 30fps 甚至更低。解决巡线时只开线段检测关掉色块和二维码。在Pixy2.h里把pixy.ccc.getBlocks()的调用去掉只保留pixy.line.getMainFeatures()。另外把 Kp 降到 0.15 到 0.2 之间试同时加一个微分项 Kd 抑制震荡。如果还不行那就是车速太快先降速跑通再提速。4.5 现象PixyMon 能识别但 Arduino 读不到原因USB 和 UART 同时输出时Pixy2 的 UART 数据可能被 USB 通信打断。Pixy2 允许同时通过 USB 和 UART 输出数据但如果你在 PixyMon 里改了参数没点“Save”就拔线参数没写入模块的 flash下次上电还是旧参数。解决每次在 PixyMon 里改完参数点Action - Save Parameters等模块重启后再拔线。另外Arduino 的串口监视器和 PixyMon 不能同时占用同一个串口如果你用 USB 转 TTL 接 Pixy2 的 UART那 PixyMon 就走 USB两者不冲突但如果你把 Pixy2 的 UART 直接接在 Arduino 的硬串口上那 Arduino 的串口监视器就看不到 Pixy2 的数据了因为硬串口被占用了。这时候要么用软串口要么换 I2C。5. 进阶技巧用 Python 在树莓派上做多目标跟踪与数据记录5.1 树莓派端的 Python 接口调用资源包里的raspberrypi/目录下有一个pixy2.py文件封装了 UART 和 I2C 的底层通信。树莓派上直接用 Python 调用比 Arduino 更灵活因为你可以把坐标数据存下来做分析或者推送到其他服务。下面这段代码演示了如何初始化 Pixy2 并持续读取色块数据同时把结果写入 CSV 文件import pixy2 import time import csv # 初始化 Pixy2使用 UART端口根据实际接线改 pixy pixy2.Pixy2UART(/dev/serial0, 19200) pixy.init() # 打开 CSV 文件准备记录 with open(pixy_log.csv, w, newline) as f: writer csv.writer(f) writer.writerow([timestamp, signature, x, y, width, height]) start time.time() while time.time() - start 30: # 记录 30 秒 blocks pixy.get_blocks(1) # 参数 1 表示只取第一个色块 if blocks: b blocks[0] writer.writerow([ round(time.time() - start, 3), b[signature], b[x], b[y], b[width], b[height] ]) time.sleep(0.05) # 20Hz 采样 pixy.close()这段代码的关键点pixy2.Pixy2UART的第一个参数是串口设备名树莓派 3B 及以上默认是/dev/serial0但如果你开了蓝牙串口可能被占用需要在/boot/config.txt里加dtoverlaydisable-bt关掉蓝牙。get_blocks(1)的参数是最大返回数量传 1 只取最靠前的那个色块减少数据量。time.sleep(0.05)控制采样率太快了没必要Pixy2 本身帧率就 60fps20Hz 足够记录运动轨迹。CSV 文件可以直接用 Excel 或 pandas 打开画个 x 坐标随时间变化的曲线就能看出目标移动的规律。5.2 多目标跟踪的索引过滤与数据后处理Pixy2 的色块数据里有一个m_trackingIndex字段模块内部会给每个连续出现的色块分配一个稳定的索引同一物体在连续帧里索引不变。利用这个特性可以做简单的多目标跟踪维护一个字典key 是 trackingIndexvalue 是最近几帧的坐标队列取队列平均值作为当前位置能有效平滑抖动。如果某个索引超过 10 帧没出现就从字典里删掉。这个逻辑在 Python 里十几行就能写完比在 Arduino 上省事得多。数据后处理方面把 CSV 导入 pandas 后用groupby(signature)分组再对每组做滑动平均就能得到每个颜色目标的运动轨迹。如果要做闭环控制把平滑后的坐标通过串口或网络发给主控比直接发原始坐标稳得多。5.3 一个我踩过的坑树莓派串口权限与波特率漂移树莓派默认的串口控制台是开着的如果你直接用/dev/serial0而不关控制台Pixy2 的数据会和登录提示混在一起解析全乱。解决办法运行sudo raspi-config在Interface Options - Serial Port里关掉 shell 访问保留硬件串口使能。另外树莓派的串口波特率受 CPU 频率影响如果开了动态调频低负载时波特率可能漂移导致丢包。我一般会在/boot/config.txt里加一行force_turbo1锁定频率或者至少把core_freq250固定住。从那以后我每次在树莓派上接串口设备都先跑一遍stty -F /dev/serial0 19200确认波特率再开程序读数据。希望帮到你。本文还有配套的精品资源点击获取