传感器
在第 1 部分中,我们讨论了如何使用 DAC 和一些负反馈来控制红色、绿色和蓝色 LED 的强度。现在,我们可以使用 RGB LED 模块作为单像素显示器,即通过操纵红、绿和蓝光的混合,我们可以产生多种颜色。
我们想要使用这个 LED 模块来复制照亮 RGB 传感器的光的颜色。正如篇文章中提到的,我们使用的是罗姆公司生产的BH1745NUC颜色传感器IC(以下简称BH1745)。这实际上是一个相当令人印象深刻的设备。该封装很小(约 2 毫米 × 2 毫米),这就是我们在该项目中使用定制设计 PCB 的原因之一(也许您可以将跳线焊接到 8 个微小的 0.5 毫米间距焊盘上,但我做不到) t)。尽管尺寸很小,但该部件却具有广泛的功能,并且只需要很少的外部组件。这是数据表中的“典型应用电路”:

光学滤波器、四个光电二极管、四个独立的 16 位 ADC(具有所需的任何信号调节电路)、一个 I2C 接口以及一些中断逻辑(可用于在红色、绿色、蓝色或透明测量值超出范围时向微控制器发出警报)或低于可定制的阈值——我想说,对于如此微小且便宜的东西来说,这非常好(Digi-Key 的单个装置为 1.61 美元)。
这是原理图的相关部分:

收集数据
BH1745 的数字部分包括一组 21 个 8 位寄存器。微控制器和 BH1745 之间的所有交互(除了我们在本项目中不使用的中断功能)都是通过标准 I2C 事务写入或读取这些寄存器来完成的。有关 I2C 协议的大量一般信息和实用指南,请参阅“支持信息”下列出的文章。在这里,我们将重点关注 BH1745 的具体实现细节。
从 BH1745 控制和检索数据需要三种类型的 I2C 事务:写入、先写后读和读取。
写入:这些事务用于将数据加载到 BH1745 的寄存器组中。从机地址加 R/nW 字节之后的个字节指定寄存器地址,然后接下来的字节是要加载到寄存器中的数据。

先写后读:如果您熟悉 I2C 协议,您就会知道主设备无法在事务中写入和读取数据。每个事务都被定义为读取或写入。因此,我们不能使用单个事务来指示寄存器地址,然后从该寄存器读回数据。解决方案是两个单独的事务 - 首先我们将数据写入 BH1745 以告诉它我们要读取哪个寄存器,然后我们执行一个读取事务以从指定寄存器检索数据。这个过程中的个事务就是我所说的先写后读事务。
读取:这些事务允许主机从先写后读事务中传输的任何寄存器地址读取数据。

正如您所看到的,读事务并不限于一个指定的寄存器地址。如果继续从 BH1745 读取字节,它将自动递增寄存器地址并从新寄存器发送数据。实际上,您可以对写入事务执行相同的操作:

我通常避免使用自动递增功能,因为我重视保持简单的原则,这在这里特别重要,因为 BH1745 的寄存器不是连续排列的(即,无效的寄存器地址混合在有效的寄存器地址中)。然而,我在读取 RGBC 数据时确实利用了这个功能——所有 8 个字节都是连续的(从地址 0x50 开始),并且使用 16 个单独的单字节事务(8 个 write-before-)频繁收集 RGBC 数据的效率会非常低。读取和 8 次读取)。
另请注意,先写后读和读事务可以通过重复启动条件(如上图所示)来实现,而不是先停止条件后跟启动条件。如果 I2C 总线上有多个主控器,这将是更好的选择(有关更多信息,请参阅I2C 总线:固件实现详细信息中的“无停止启动”部分)。不过,在这个项目中,我们只有一个主控,因此我们将再次引用保持简单的原则并使用典型的先停后启动的方法。
处理数据
RGBC 数据以四个 16 位字形式从 BH1745 到达,如下所示:

我们可以忽略这个项目的明确数据;我们需要做的就是将 R、G 和 B 字转换为 8 位值,我们可以用它来控制 R、G 和 B LED 的强度。首先要认识到的是,BH1745 中的三个颜色检测器的灵敏度并不相同:
从该图中我们可以看到,当 G 为 1 时,R 约为 0.72,B 约为 0.56。因此,我们需要将 R 和 B 值乘以适当的校正因子:
\[CF_R=\frac{1}{0.72}=1.39,\ \ \ CF_B=\frac{1}{0.56}=1.79\]
现在我们需要以强调入射光颜色特征的方式修改数据。我们的目标是“测量”颜色,无论照射光电探测器的光的总体强度如何。

因此,我们需要以标准化测量同时保留相对值的方式缩放 RGB 值,换句话说,我们在保持入射光中红、绿、蓝比例的同时化整体强度。为了实现这一点,我们将三个测量值中的值乘以将该测量值增加到值的任何因子,然后将其他两个测量值乘以相同的因子。