简介:GY-AS7262 7263 配套资料包面向嵌入式开发、电子制造与传感器应用学习者,围绕 AS7262/AS7263 光谱传感模块的 Arduino 上手与二次开发整理。资源包含15个文件,约1.5MB,以3份PDF数据手册与原理图、3个ino示例程序、2份md说明、1个cpp与1个h驱动源码为主,并附工程配置与辅助文本文件,便于按“手册—库—示例”的路径查阅。已有442人学习,适合需要快速验证模块通信、理解寄存器配置或移植驱动的读者。包内Arduino驱动库与示例可直接用于搭建采集环境,配合PDF中的引脚、时序和电路信息,能帮助读者减少接线与调试中的试错;源码结构也可作为制造现场传感器集成、课程实验与项目原型的参考,方便后续扩展数据读取与校准逻辑。
1. 一块六通道光谱模块能干什么:从 GY-AS7262 和 GY-AS7263 的两个波长窗口说起
前阵子帮一个做分选设备的小团队调板子,桌上摆着 GY-AS7262 和 GY-AS7263 各一块,都是六通道光谱模块,长得几乎一样,卖家给的资料只有一张引脚图。接上总线后只认出一个设备,读数还全是 0xFF。这两块板子的价值不在于"能测光",而在于把可见光 450–650 nm 和近红外 610–860 nm 各切成六段,用几十块钱的成本替代一台微型光谱仪,做小批量制造里的色差判定、材质初筛、透光率一致性检查。它不适合做实验室级光谱标定,但适合产线上"这款料和标准样是不是同一批"这种二分类问题。后面几章按接线、自检、参数、避坑、特征提取的顺序走一遍,都是我实际调试时留下的参数和脚本。
2. 选型先说清楚:AS7262 与 AS7263 的通道差异决定你能测什么
很多人在下单时只看"六通道",收到货才发现测不了自己想要的东西。这两块模块的差别不是灵敏度,而是六个滤光片的中心波长完全落在不同区间,选错了再怎么调增益都是白费。
2.1 六个通道落在哪几条波长上
AS7262 覆盖可见光,六个通道中心波长依次是 450 nm、500 nm、550 nm、570 nm、600 nm、650 nm,工程上习惯叫 V、B、G、Y、O、R。这套配置的设计意图是覆盖人眼明视觉响应最密集的一段,做颜色相关的判断时,六点采样足以拟合出粗略的光谱曲线,再换算到色度坐标上。做印刷品色差、液体透光色、塑料件批次色差这类活,用它比用三通道 RGB 传感器靠谱得多,因为 570 nm 和 600 nm 这两个点把黄橙段拆开了,RGB 传感器在黄区是糊的。
AS7263 覆盖近红外,六个通道是 610 nm、680 nm、730 nm、760 nm、810 nm、860 nm,同样叫 R、S、T、U、V、W。这段的价值在于很多物质在可见光下看起来一样,在 700 nm 以上就分开了——水分在 760 nm 和 810 nm 有吸收差异,叶绿素在 680 nm 附近有强吸收、在 860 nm 附近高反射,深色塑料和黑色橡胶在近红外下的反射率差别往往比可见光下大一个量级。做农产品分选、塑料材质分拣、水分快检的,选 7263;做颜色、油墨、涂层、液体色度的,选 7262。
两块板子用的芯片封装、寄存器映射、I2C 时序完全一致,唯一的区别是 DEVICE_TYPE 寄存器的返回值:7262 读回 0x3E,7263 读回 0x3F。这个设计带来一个必须提前知道的后果——它们的 7 位 I2C 地址都是 0x20,不能直接挂在同一条总线上同时工作,后面第 5 章会专门讲怎么绕过去。
2.2 模块板载电路:稳压、上拉、照明 LED 与中断脚
GY 系列的模块板不是裸芯片,板上至少有四样东西需要你确认清楚。第一是稳压,绝大多数版本带一颗 3.3V 低压差稳压,所以 VCC 引脚可以喂 5V,但如果你手上这块板丝印写的是 3V3 而不是 VIN,就别接 5V。
第二是 I2C 上拉。上拉电阻有的拉到 3.3V,有的拉到 VCC,这决定了你能不能直接接 5V 逻辑的主控。我一般拿到板子第一件事是用万用表量 SCL 和 SDA 对 GND 的空闲电压:读到 3.3V,说明上拉在 3.3V 侧,可以放心接任何主控;读到 5V,说明上拉被拉到了输入电源,接 3.3V 主控前要么改供电为 3.3V,要么确认主控引脚耐 5V。
第三是板载照明 LED。芯片本身带一路 LED 驱动,模块上通常焊了一颗白光或红外 LED,位置就在传感窗口旁边。这颗灯是双刃剑:它让测量不依赖环境光,但它的发光谱和老化特性会直接进到你的数据里,做长期一致性比对时必须固定驱动电流档位,并且记录使用小时数。
第四是 INT 引脚。芯片在单次转换完成时会拉低这个脚,模块把它引出来是为了让你用中断而不是靠延时去等数据。做低速采集无所谓,做高速分选(比如传送带上每秒几十个工件)时,靠延时等会浪费大量时间,用中断能把节拍压下来。
2.3 按被检物选型号:三个判断维度
| 判断维度 | 选 AS7262 | 选 AS7263 |
|---|---|---|
| 检测目标 | 颜色、色差、油墨浓度、液体色度 | 材质、含水量、深色件区分、植被状态 |
| 环境光干扰 | 可用白光 LED 主动照明压制 | 环境光近红外成分少,可用自然光 |
| 样品温度 | 温度对可见光谱影响小 | 温度影响水吸收峰,需记录工况 |
| 典型制造场景 | 印刷品批次比对、注塑件色差 | 塑料分拣、农产口分选、涂层厚度趋势 |
判断方法很简单:把待测样品和标准样各测十次,看六个通道里有没有至少两个通道的差值稳定超过噪声的三倍。如果差值只出现在 450 nm 和 650 nm 两个端点上、中间四个通道几乎一样,说明你要区分的东西在可见光波段没有特征,换 7263 试。反过来,如果六个通道在近红外下全是平的一条线,那说明样品在这个波段没有选择性,7262 更合适。这个"先测差值再看选型"的流程,比看 datasheet 上的光谱响应曲线有用得多。
3. 把模块接到总线上:接线、上电时序与最小自检
接线本身不难,难的是第一次上电那五分钟。我见过太多人卡在"i2cdetect 扫不到设备"这一步,然后开始怀疑模块坏了,实际上九成是供电或者上拉的问题。
3.1 六针引脚怎么接
GY-AS7262/7263 常见的引出是六针:VCC、GND、SCL、SDA、INT、LED。不同批次的丝印顺序可能不同,接之前一定按板上丝印对,不要按卖家图片对——图片经常是旧版。
| 引脚 | 接到主控 | 说明 |
|---|---|---|
| VCC | 3.3V 或 5V | 板载稳压,优先 3.3V,减少自热 |
| GND | GND | 与主控共地,线尽量短 |
| SCL | I2C 时钟 | 100 kHz 起步,确认稳定后再提到 400 kHz |
| SDA | I2C 数据 | 与 SCL 成对,长度控制在 20 cm 内 |
| INT | 任意 GPIO(可选) | 单次转换完成拉低,低速采集可不接 |
| LED | 悬空或接 GPIO(可选) | 板上已有照明灯,一般不用外接 |
供电这里有个容易忽略的点:如果用 5V 供电,板载稳压会把多余压差变成热量,芯片结温会比环境高 5–10℃,温度寄存器读出来的值不能当环境温度用。做长时间连续采集时我倾向用 3.3V 供电,并且把模块固定在金属支架上散热,读数漂移会明显小一些。
线材上,杜邦线在 100 kHz 下跑 20 cm 没问题,超过 30 cm 就开始出现偶发 NAK。真要做设备,把 SCL/SDA 绞在一起并加地线回流,或者直接上排线加屏蔽。这不是玄学,是 I2C 单端信号在长线上的老问题。
3.2 用 i2cdetect 和 DEVICE_TYPE 做三分钟自检
接线完成后的第一步不是写业务代码,是确认设备在总线上。在带 I2C 的 Linux 单板机上,装好工具后直接扫:
# 安装 i2c 工具(Debian 系) sudo apt install -y i2c-tools # 确认 I2C 总线已启用,一般板载是 1 号总线 ls /dev/i2c-* # 扫描 1 号总线上的所有地址 i2cdetect -y 1正常结果是在 0x20 位置出现20。如果整张表全是--,先查供电和接线;如果出现的是别的地址(比如 0x49),说明你手上这块不是 AS7262/7263 系列,或者是另一颗芯片的模块,别硬套本文的寄存器表。
扫到 0x20 之后,还要确认它到底是 7262 还是 7263。这两块板子外观太像,包装袋上的标签经常贴错,用一行命令读 DEVICE_TYPE 就能分辨:
# 通过 AT 命令层读 0x00 寄存器:先发 0x41(读1字节) + 寄存器地址,再读 1 字节 i2ctransfer -y 1 w2@0x20 0x41 0x00 r1返回0x3e是 AS7262,返回0x3f是 AS7263。返回0xff或者0x00说明 AT 命令层还没准备好,通常是上电后立刻就去读导致的,断电重来,中间等 200 ms 以上再试。
这里解释一下0x41这个字节的来龙去脉。AS7262/7263 不是那种"往寄存器地址写、再从寄存器地址读"的常规 I2C 器件,它在 I2C 之上套了一层命令协议,所有对内部寄存器的访问都要先发一个命令字节。读一个字节用 0x41,读两个字节用 0x42,写一个字节用 0x61,写两个字节用 0x62。命令字节后面跟目标寄存器地址,写操作再跟数据。这个协议不搞清楚,直接拿常规 I2C 库的"寄存器读"函数去访问,读回来永远是 0xFF,这是新手翻车率最高的一处。
3.3 一次读出六通道:完整可运行脚本
确认设备在线之后,用 Python 写一个最小可跑脚本。依赖只有 smbus2,主控侧不需要额外驱动。
#!/usr/bin/env python3 # gy_as72xx.py —— GY-AS7262 / GY-AS7263 六通道读取最小实现 import time from smbus2 import SMBus, i2c_msg ADDR = 0x20 # 7 位地址;8 位写法是写 0x40 / 读 0x41 AT_READ1 = 0x41 # 读 1 字节 AT_READ2 = 0x42 # 读 2 字节(16 位通道值) AT_WRITE1 = 0x61 # 写 1 字节 REG_DEV_TYPE = 0x00 REG_CTRL = 0x04 REG_INT_T = 0x05 REG_TEMP = 0x06 REG_LED = 0x07 REG_RAW_BASE = 0x08 # 6 通道原始值,每通道 2 字节,低字节在前 REG_CAL_BASE = 0x14 # 6 通道校准值,同上 # 波长标签,按 DEVICE_TYPE 区分 CH_TABLE = { 0x3E: ["450", "500", "550", "570", "600", "650"], 0x3F: ["610", "680", "730", "760", "810", "860"], } def vread(bus, reg): """读 1 个字节:先发命令+地址,再单独发起读事务""" bus.i2c_rdwr(i2c_msg.write(ADDR, [AT_READ1, reg])) time.sleep(0.002) # 给 AT 层留处理时间 m = i2c_msg.read(ADDR, 1) bus.i2c_rdwr(m) return list(m)[0] def vread16(bus, reg): """读 16 位:低字节在前,高字节在后""" bus.i2c_rdwr(i2c_msg.write(ADDR, [AT_READ2, reg])) time.sleep(0.002) m = i2c_msg.read(ADDR, 2) bus.i2c_rdwr(m) lo, hi = list(m) return (hi << 8) | lo def vwrite(bus, reg, val): """写 1 个字节""" bus.i2c_rdwr(i2c_msg.write(ADDR, [AT_WRITE1, reg, val & 0xFF])) time.sleep(0.002) def main(): bus = SMBus(1) time.sleep(0.2) # 上电稳定,别省这一步 dev = vread(bus, REG_DEV_TYPE) if dev not in CH_TABLE: raise SystemExit(f"DEVICE_TYPE=0x{dev:02X},不是 AS7262/7263") ch = CH_TABLE[dev] print(f"检测到 {'AS7262' if dev == 0x3E else 'AS7263'},通道 {ch}") vwrite(bus, REG_CTRL, 0x80) # bit7 软复位 time.sleep(0.1) vwrite(bus, REG_INT_T, 0x30) # 积分时间 (0x30+1)*2.8 = 137.2 ms vwrite(bus, REG_LED, 0x00) # 关闭板载照明,先测环境光 gain = 0b11 # 64x for n in range(5): # 单次模式触发:MODE=0b10 对应 bit3:2 写 0x08 vwrite(bus, REG_CTRL, (gain << 4) | 0x08) time.sleep(0.25) # > 积分时间,留出转换余量 raw = [vread16(bus, REG_RAW_BASE + 2 * i) for i in range(6)] cal = [vread16(bus, REG_CAL_BASE + 2 * i) for i in range(6)] print(f"[{n}] RAW", dict(zip(ch, raw))) print(f"[{n}] CAL", dict(zip(ch, cal)), "TEMP", vread(bus, REG_TEMP)) bus.close() if __name__ == "__main__": main()这段脚本有三个设计取舍要说清楚。第一,读写分成两个独立的 I2C 事务,中间插入 2 ms 延时,而不是用组合事务一次发完。原因是 AT 命令层是"收命令—内部执行—返回结果"的模型,命令字节发完到数据准备好之间有一个极短的处理窗口,把两个事务分开更接近芯片手册描述的时序,实测在 100 kHz 下比组合事务的稳定性高。
第二,用单次模式而不是连续模式。连续模式下 RAW 和 CAL 是两组不同时刻的快照,你读到六个 RAW 和六个 CAL 之间隔了一整轮转换,做比值计算时会引入不必要的误差。单次模式触发一次、等积分时间、一次性把两组值都读出来,虽然慢一点,但同一帧内的数据是自洽的。
第三,等待用的是固定延时 0.25 s 而不是轮询 DATA_RDY 位。DATA_RDY 在 CTRL 寄存器的低位,具体掩码在不同固件版本上有差异,靠固定延时更省事:积分时间 137.2 ms,加上转换开销,250 ms 是安全的。真要做高速采集,还是得把中断脚接上,用 INT 下降沿触发读取。
参数上,REG_INT_T写 0x30 得到的积分时间是 137 ms,这个值适合室内常光下的静态测量;gain=0b11是 64 倍增益,配合 137 ms 的积分时间,如果对着白纸测出来接近 65535,说明过曝了,把增益降到 0b10(16 倍)再来。反过来如果对着深色样品测出来只有几十,就往上加。
4. 参数怎么定:AT 虚拟寄存器、增益阶梯与积分时间的三角权衡
能读出数只是开始,读出来的数能不能用,全看这三个参数怎么配:增益、积分时间、照明电流。它们共同决定曝光量,而曝光量的可调范围有六万多倍,配错了不是饱和就是噪声淹没信号。
4.1 AT 命令层的读写模型
前面提过 0x41/0x42/0x61/0x62 四个命令字节,这里把完整的寄存器地图列出来,方便对照排查。地址空间不大,0x00 到 0x1F 一共 32 个字节,全部可以按单字节访问。
| 地址 | 名称 | 读/写 | 说明 |
|---|---|---|---|
| 0x00 | DEVICE_TYPE | R | 0x3E=AS7262,0x3F=AS7263 |
| 0x01 | HW_VERSION | R | 硬件版本,不同批次不同 |
| 0x02–0x03 | FW_VERSION | R | 固件版本高低字节 |
| 0x04 | CONTROL_SETUP | R/W | 复位、增益、模式、数据就绪 |
| 0x05 | INT_T | R/W | 积分时间,0–255 |
| 0x06 | DEVICE_TEMP | R | 芯片结温,8 位 |
| 0x07 | LED_CONTROL | R/W | 照明驱动方式与电流档 |
| 0x08–0x13 | RAW×6 | R | 六通道原始计数,各 2 字节 |
| 0x14–0x1F | CAL×6 | R | 六通道校准值,各 2 字节 |
需要注意的细节是:RAW 和 CAL 的数值范围都是 0–65535,但两者的含义不一样。RAW 是光电二极管加 ADC 的直接输出,用来判断有没有饱和、环境光够不够;CAL 是芯片内部做过多点校正后的结果,补偿了各通道之间的响应差异和暗电流偏移,做比值计算和色度换算时用 CAL,别用 RAW。很多人拿到数据直接用 RAW 算比值,结果换个模块数据就对不上,问题就出在这。
写寄存器时有一个顺序上的讲究:改 GAIN 或 MODE 之前先写一次软复位(CTRL 的 bit7 写 1),复位后等 100 ms 再配置。原因是芯片上电后的默认状态不一定是你想要的,而且如果上一次采集停在半途,不清状态直接改配置,新配置可能不生效。这个坑我在调试时踩过,改了增益读数一点变化都没有,复位之后才正常。
4.2 CONTROL_SETUP 的位域:GAIN、MODE 与 DATA_RDY
0x04 这一个字节塞了四组信息,位域划分如下。
| 位 | 名称 | 取值含义 |
|---|---|---|
| 7 | RST | 写 1 触发软复位,自动清零 |
| 6:4 | GAIN | 000=1x,001=3.7x,010=16x,011=64x |
| 3:2 | MODE | 00=连续转换,10=单次转换,11=待机 |
| 1:0 | DATA_RDY | 只读,转换完成标志 |
增益是四档固定值,不是线性可调的。1x 到 3.7x 的跳变比较大,从 3.7x 到 16x 是 4.3 倍,16x 到 64x 是 4 倍。这意味着你没法精细地"调亮一点",只能在四档里选最接近的,剩下的余量靠积分时间去补。实际调参的顺序我一般是:先把积分时间定在一个能接受的节拍上(比如产线要求每秒 5 个件,那就是 200 ms 一帧,积分时间最多给到 180 ms,取 INT_T=63),然后从低增益往高增益试,选第一个不饱和的档位。
单次模式和连续模式的切换就是改 bit3:2。连续模式下芯片不停转换,你随时读都能拿到最新值,但两次读之间可能跨帧;单次模式下要显式触发,读完数据后芯片待机,功耗低,数据帧边界清晰。做多通道比值、需要同一时刻快照的场景,用单次。
DATA_RDY 位在不同固件版本上位置有差异,有的是 bit1,有的是 bit1:0 两位组合。稳妥的做法是:先用单次模式加固定延时跑通,等系统稳定了再回头用逻辑分析仪抓一次 CTRL 寄存器的读回值,看数据就绪时哪一位翻转,把这个位写死到代码里。这属于典型的黑匣子问题——手册上写得清楚,实际固件不一定照做,实测一次比读十遍文档快。
4.3 积分时间与量程的配比表
积分时间的计算公式是:积分时间 = (INT_T + 1) × 2.8 ms。INT
本文还有配套的精品资源,点击获取