摘要:本文介绍颜色传感器模块GY33(TCS34725)的使用方法
前面已经介绍了GY-33模块的基本情况,接下来就来看一下,怎么用程序来驱动GY-33模块进行颜色的测量吧。
首先来看一下ESP32如何通过UART接口读取GY-33测量数据吧。在使用ESP32连接GY-33模块之前,先用厂家的调试软件连上GY-33模块,确保模块处于自动测量且输出RGB值的状态,如果不是,可以通过软件将其设置为该种状态,设置方法如下所示:
设置完成之后,就可以将GY-33模块与单片机相连接了。具体的连接方法如下:
GY-33模块 |
ESP32单片机 |
VCC |
VCC |
GND |
GND |
CT |
P18 |
DR |
P19 |
下面就通过程序,来把GY-33模块检测的颜色值输出到串口监视器中。程序代码如下所示:
/ /* GY33测试程序 VCC----VCC GND----GND CT-----P18 DR-----P19 @一起玩儿科技 2024-01-25 */ // unsigned char Re_buf[11], counter = 0; // 接收缓冲区 unsigned char sign = 0; // 接收完毕标识 byte rgb[3] = { 0 }; // 收到的颜色值 /** * 初始化函数 */ void setup() { Serial.begin(115200); Serial2.begin(9600, SERIAL_8N1, 18, 19); delay(1); Serial.println("Init OK......"); } void loop() { unsigned char i = 0, sum = 0; if (sign == 1) { sign = 0; for (i = 0; i < 7; i++) //计算校验和 sum += Re_buf[i]; if (sum == Re_buf[i]) //检查校验和 { rgb[0] = Re_buf[4]; rgb[1] = Re_buf[5]; rgb[2] = Re_buf[6]; Serial.print("r:"); Serial.print(rgb[0]); Serial.print(",g:"); Serial.print(rgb[1]); Serial.print(",b:"); Serial.println(rgb[2]); } } delay(50); } void serialEvent2() { while (Serial2.available()) { Re_buf[counter] = (unsigned char)Serial2.read(); if (counter == 0 && Re_buf[0] != 0x5A) return; // 检查帧头 counter++; if (counter == 8) //接收到数据 { counter = 0; //重新赋值,准备下一帧数据的接收 sign = 1; } } } |
在这个程序中,有两个地方需要解释一下。
Serial2.begin(9600, SERIAL_8N1, 18, 19);
接下来看一下如何使用IIC协议来读取GY-33模块的测量结果。GY-33模块默认的是UART通信,因此在使用IIC协议的时候,首先需要进行跳线的设置,需要将GY-33模块的S0引脚设置为低电平,也就是与旁边的GND引脚用跳线帽或者杜邦线短路到一起。如下图所示:
接下来,将GY-33模块与ESP32采集器相连接,连接的方法如下:
GY-33模块 |
ESP32单片机 |
VCC |
VCC |
GND |
GND |
CT |
P22 |
DR |
P21 |
当使用IIC通信时,GY-33的地址为0x5A,在这种模式下,GY-33会将测量数据保存到内部寄存器中,具体内寄存器的地址和内容如下表所示:
0x00(只读) |
RAW_RED_H |
原始 Red AD 值高 8 位 |
0x01(只读) |
RAW_RED_L |
原始 Red AD 值低 8 位 |
0x02(只读) |
RAW_GREEN_H |
原始 Green AD 值高 8 位 |
0x03(只读) |
RAW_GREEN_L |
原始 Green AD 值低 8 位 |
0x04(只读) |
RAW_BLUE_H |
原始 Blue AD 值高 8 位 |
0x05(只读) |
RAW_BLUE_L |
原始 Blue AD 值低 8 位 |
0x06(只读) |
RAW_CLEAR_H |
原始 Clear AD 值高 8 位 |
0x07(只读) |
RAW_CLEAR_L |
原始 Clear AD 值低 8 位 |
0x08(只读) |
Lux_H |
亮度高 8 位 |
0x09(只读) |
Lux_L |
亮度低 8 位 |
0x0a(只读) |
CT_H |
色温高 8 位 6 |
0x0b(只读) |
CT_L |
色温低 8 位 |
0x0c(只读) |
R |
处理后 8bit r 值 |
0x0d(只读) |
G |
处理后 8bit g 值 |
0x0e(只读) |
B |
处理后 8bit b 值 |
0x0f(只读) |
Color |
简单颜色状态 |
0x10(读写) |
Config |
配置寄存器 |
简单颜色状态寄存器0x0f中存储了计算后的简单颜色:
Color |
bit7 |
bit6 |
bit5 |
bit4 |
bit3 |
bit2 |
bit1 |
bit0 |
颜色 |
蓝色 |
深蓝色 |
绿色 |
黑色 |
白色 |
粉色 |
黄色 |
红色 |
注:Bit7-bit0:哪位置为1就表示检测的颜色为该位的颜色,例如Color=0x02表示当前物体为黄色。
配置寄存器0x10:
Config |
bit7 |
bit6 |
bit5 |
bit4 |
bit3 |
bit2 |
bit1 |
bit0 |
配置 |
D4 |
D3 |
D2 |
D1 |
NC |
NC |
NC |
白平衡 |
其中:
bit7-bit4:0-10,表示十一个等级调节LED的亮度,默认等级为3。
bit3-bit1:保留,值为0000,无意义
bit0 :1表示白平衡校准;0不进行白平衡校准。
下面就来通过一个Arduino程序,读取被检测物体的原始检测值,也就是寄存器0x00~07中的数据。程序代码如下所示:
#include #define GY33_ADDR 0x5A // GY-33模块IIC地址 #define RAW_REG 0x00 // 原始数据寄存器 void setup() { // put your setup code here, to run once: Serial.begin(115200); // 初始化串口 Wire.begin(); // 初始化IIC } void loop() { // put your main code here, to run repeatedly: // 读取IIC设备寄存器中的数据 Wire.beginTransmission(GY33_ADDR); Wire.write(RAW_REG); Wire.endTransmission(); Wire.requestFrom(GY33_ADDR, 8); while (Wire.available() < 8) ; Serial.print("Red:"); Serial.print(Wire.read()<<8|Wire.read()); Serial.print(",Green:"); Serial.print(Wire.read()<<8|Wire.read()); Serial.print(",Blue:"); Serial.print(Wire.read()<<8|Wire.read()); Serial.print(",Clear:"); Serial.println(Wire.read()<<8|Wire.read()); delay(100); } |
这个IIC协议读取数据的程序就不再解释了,如果不明白,请参考之前的文章。
接下来再尝试不适用GY-33的MCU处理器,直接使用IIC协议读取TCS34725寄存器内的检测数据。在直接读取TCS34725芯片的数据之前,需要先将S1引脚与旁边的GND相连接,这样就可以进入到仅使用TCS34725不使用MCU的工作模式。
在这种模式下的接线方法如下表所示:
GY-33模块 |
ESP32单片机 |
VCC |
VCC |
GND |
GND |
SCL |
P22 |
SDA |
P21 |
这个时候的IIC通信要使用模块上标注了SCL和SDA的引脚。TCS34725的默认地址为0x29,在使用这种模式的时候,就可以用别人开发好的库来直接操作这个模块了,不需要我们再去关注底层的协议。这次使用的库为:Adafruit TCS34725。先来安装一下这个库,如下图所示:
下面就来看一下直接访问TCS34725模块的测试程序,代码如下所示。在这个代码中,读取了原始测量数据,然后又计算了色温和照度值。
#include #include "Adafruit_TCS34725.h" // 初始化Adafruit_TCS34725对象的实例,指定测量的时间和增益 Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_614MS, TCS34725_GAIN_1X); void setup(void) { Serial.begin(115200); if (tcs.begin()) { Serial.println("Found sensor"); } else { Serial.println("No TCS34725 found ... check your connections"); while (1) ; } } void loop() { uint16_t r, g, b, c, colorTemp, lux; // 得到原始测量数据 tcs.getRawData(&r, &g, &b, &c); // 计算色温值 colorTemp = tcs.calculateColorTemperature_dn40(r, g, b, c); // 计算照度 lux = tcs.calculateLux(r, g, b); Serial.print("色温: "); Serial.print(colorTemp, DEC); Serial.print(" K - "); Serial.print("照度: "); Serial.print(lux, DEC); Serial.print(" - "); Serial.print("R: "); Serial.print(r, DEC); Serial.print(" "); Serial.print("G: "); Serial.print(g, DEC); Serial.print(" "); Serial.print("B: "); Serial.print(b, DEC); Serial.print(" "); Serial.print("C: "); Serial.print(c, DEC); Serial.print(" "); Serial.println(" "); } |
TCS34725这些方法具体是如何实现的,可以参考库文件的源代码。运行结果如下图所示:
好了,GY-33模块就介绍到这里了。