雷竞技注册
项目

Quark D2000 I2C Interfacing:添加颜色传感器和异步模式

2017年1月13日通过Raymond Genovese.

使用Quark D2000开发板上的I2C接口颜色传感器,熟悉异步模式的使用。

我们在Quark D2000开发板上使用I2C完成了我们的项目,添加了颜色传感器和对象颜色标识符程序。最后,我们使用异步模式I2C重新求解接口BH1750FVI环境光传感器。

在继续本文之前,请考虑通过第一个文章进行阅读:Quark D2000 I2C接口:添加光传感器和LCD

请参考下面的参考链接:

可以通过单击下面的链接栏来下载文章中所有程序的软件文件:

d2000_part_3p2_code.zip.zip.

添加颜色传感器

颜色传感器已经存在一段时间,我想尝试构建颜色标识符的手。也就是说,我想构建一个电路和程序,可以识别对象的颜色并在LCD屏幕上显示该颜色。

我选择了植物色彩传感器从阿布鲁特。下面说明的模块基于TCS34725颜色传感器芯片并包括I2C接口。

植物色彩传感器

Flora颜色传感器(左面板)和连接连接(右图)

传感器具有红外滤波器,该模块在船上具有白色照明LED,用于对象照明。该模块适用于可穿戴设备,它们也有一个选择模块这是更友好的面包板,让你控制照明LED。

与D2000的模块连接很简单,并在上面的图右侧示出。从模块的说明原理图它已经在I2C线路上包括10K上拉电阻,因此您应该在LCD显示屏上排除上拉电阻,如上所述。

在进一步之前,我想强调传感颜色的复杂性。这不是一个简单的事情,有些背景阅读是有序的。我特别建议来自芯片制造商的两个应用笔记:使用TAOS TCS3414CS数字颜色传感器计算色温和照度使用AMS颜色传感器的LUX和CCT计算

您可能还想查看主题上的两个项目:感受彩虹:感应颜色与Arduino通过RGB LED模块设计具有测量的颜色传感器

此外,这里有一个有趣的纸质详细说明机器人颜色分拣应用。简单的搜索将更加参考材料。

颜色识别方法

如下所示(左侧)是色度图。

原始色度图(左)提供AMS.(点击放大)。

简单地说,这个图是一个颜色空间的x y图。从这个图中,我们可以映射特定的颜色(即一组颜色的名称)。图的右边是我对这幅地图的再现。不可否认,它是粗糙的,我的意图只是提供一个可行的近似,有一些经验的有效性。

然而,TCS34725不直接向我们提供色度坐标(X,Y)。相反,我们必须基本上读取与红色,绿色,蓝色和清晰的光照二极管传感器相关联的ADC的输出。然后,我们可以从这些值生成x和y色度坐标。

附带的程序CS_TCS34725A.c将读取模块并在LCD屏幕上显示R,G,B,C传感器值,并显示X和Y色度值。该程序需要如前所述的LCD库。

在这些代码线中给出了计算的核心:

x =(-0.14282 * redc)+(1.54924 * greenc)+(-0.95641 * bluec);Y =(-0.32466 * REDC)+(1.57837 * Greenc)+(-0.73191 * bluec);Z =(-0.68202 * REDC)+(0.77073 * Greenc)+(0.56332 * Bluec);xcc = x /(x + y + z);YCC = Y /(X + Y + Z);

与每个光电二极管传感器的光谱响应分布相关的常数,直接来自先前引用的制造商应用笔记。尽管这些值基于TCS3414CS芯片,但是由于光电二极管的光谱响应度相似,因此它们也适用于TCS34725。

该程序可用于测试模块,调整增益和其他参数(参见数据表),并熟悉使用模块的工作。

颜色标识符

一旦我们有了色度坐标和标识颜色名称的映射,我们就可以生成一个查找表来将坐标映射到颜色名称。

附带的程序CS_Color_Namer.c将这些过程连接在一起,并尝试识别符合Flora颜色传感器的物体的颜色,然后在LCD上打印对象的颜色。

下面的视频演示了Action中的颜色标识符。请注意,我在传感器周围放置了一个黑色纸管,以防止模块的车载LED,这是非常明亮的,从压倒视频捕获。

我对这种有些粗糙的应用的准确性印象深刻,尽管找到一些可能会被错误识别的物体并不太难。如果任务仅仅是区分一些不同颜色的物体(例如,它是一个橙子还是一个香蕉?),那么这个方法很可能会被调整得非常精确——当然,这取决于物体之间的差异程度。

异步I2C通信

在结束之前,我必须补充一点,到目前为止,所有的I2C通信示例,包括第1部分中的Arduino示例,都使用了阻塞调用。也就是说,当执行对qm_i2c_master_write()的调用时,控制不会返回给调用函数,直到执行(即I2C传输)完成。

被调用的函数“阻塞”调用函数,直到被调用的函数完成。这种操作方式也称为同步。在许多情况下,阻塞调用绝对没有错。但是,如果您的代码正在等待传输完成,而在传输进行时,它可能正在做其他重要的事情,那么它们的效率可能会很低。

然而,D2000软件系统还具有异步I2C操作模式,其中进行了非阻塞呼叫。在这种情况下,调用启动传输,然后返回调用功能而不等待传输完成。

回想一下,在本项目的第1部分中,我们接口了一个BH1750环境光传感器。所包含的程序BH1750irq.c在功能上等同于前面第1部分中描述的BH1750.c,但这里我们使用的是非阻塞调用。传输是通过系统级的中断来处理的,这就是为什么您会看到一行qm_irq_request(QM_IRQ_I2C_0, qm_i2c_0_isr),它在使用这种模式之前为I2C“注册”中断服务。下面的代码片段说明了一些初始化的不同:

/ * I2C Asynch传输结构* /静态QM_I2C_TRANSFER_T IRQ_WRITE_XFER;静态qm_i2c_transfer_t irq_read_xfer;/ * I2C asynch结构vars * /静态uint8_t id_write = 0;静态UINT8_T ID_READ = 1;/ *回调函数* /静态void i2c_cb(void * data,int rc,qm_i2c_status_t状态,uint32_t len);/ *调用回来将此变量设置为true * / volatile bool i2cirq_complete = false;

全局变量部分的第一个区别是,我们定义了异步传输的两个结构。我们还声明了一个回调函数i2c_cb()。当I2C传输完成后,系统软件将调用此功能。

要检测传输请求完成后,我们将使用布尔变量I2CIRQ_COMPLETE。它被声明为易失性,因为它可以由多个线程操纵,该线程包括将执行回调函数的中断服务例程。

我们的程序将变量设置为“FALSE”,回调将其设置为“TRUE”,告诉我们转移已完成。此外,回调函数可以访问变量(ID_WRITE或ID_READ),因为在I2C传输请求中传递变量的地址。如果需要,该变量可以在回调函数中启用额外的处理。

下面的代码片段说明了基本的异步I2C读取请求。

irq_read_xfer.tx =零;irq_read_xfer.tx_len = 0;irq_read_xfer.callback = i2c_cb;irq_read_xfer.callback_data = &id_read;irq_read_xfer.rx = BHlxdata;irq_read_xfer.rx_len = BYTES2READ;irq_read_xfer.stop = true;i2cirq_complete = false;如果(qm_i2c_master_irq_transfer (QM_I2C_0 &irq_read_xfer BH1750addr)){返回(errno);} /*等待I2C完成,如果没有完成*/ while(! i2cirq_complete);

首先,我们填写转移结构。.tx和.tx_length元素分别为null和0,因为这是读取的。.callback元素设置为回调函数。.rx元素指向我们的读缓冲区,.rx_length元素包含我们想要读取的字节数。最后,.stop元素设置为true,在读取的末尾发送停止位。然后我们设置i2cirq_complete = false,并通过调用函数qm_i2c_master_irq_transfer(qm_i2c_0,&irq_read_xfer,bh1750addr)请求传输。

控制将传递到下一行而无需等待传输完成,说明了异步操作模式的优点。也就是说,当传输发生时,程序可以继续执行更多的代码。然而,在这个例子中,我们没有其他事情要做,所以我们只是通过检查i2cirq_complete的值来等待传输完成。

您可以通过程序代码来查看类似方法以执行I2C写入请求,并且还可以请求读取,然后用相同的请求写入。

同样,系统文件检查,QM_I2C.H和QM_I2C.c将提供一些文档以及在提供的系统工作室软件中的示例项目的检查,\ INTESWTOOLS \ ISSM_2016.1.067 \固件\ BSP \ 1.1 \示例\ I2C,它利用同步和异步操作模式,以及DMA异步模式(我尚未讨论过的)。

结束思想

在我看来,夸克D2000开发板继续留下深刻印象。I2C功能似乎是非常好的开发,提供高速通信和几种操作模式。系统工作室中的源代码的可用性特别有利。在一起,它的低价和大量的力量说服我,这是未来项目的一个非常好的候选人。

为自己提供这个项目!BOM。