基于CW32的GY-33颜色识别模块的应用

cathy的头像
cathy 发布于:周一, 09/18/2023 - 17:39 ,关键词:

例程资料链接如下:

BD网盘链接:

https://pan.baidu.com/s/1B1Fa4GhmScSGR6VQNDsE3w 

提取码:855c

一、简介

1.GY-33是一种基于TCS34725颜色传感器的颜色识别模块。TCS34725是一种高精度光学传感器,能够检测红、绿、蓝三个基本色的光谱信息,从而实现对物体颜色的准确识别,该模块的具体应用场景包括以下几个方面:

(1)电子设备颜色校准:在电子设备制造过程中,颜色一致性非常重要。使用GY-33模块可以帮助制造商检测和校准电子设备的颜色,确保不同设备之间的颜色表现一致。

(2)色彩分析和精确匹配:GY-33模块在颜色分析和匹配方面有广泛应用。例如,在印刷行业中,可以使用该模块来检测和匹配颜色样本,从而确保印刷品的准确颜色表现。

(3)机器人视觉系统:GY-33模块可以用于机器人视觉系统,帮助机器人在环境中对不同颜色的物体进行识别和分类。这在物流、仓储和自动导航系统中非常有用,机器人可以根据物体的颜色属性执行相应的任务。

二、所需物料

本实验使用到了CW32F030C8小蓝板、GY-33颜色识别模块、0.96寸OLED显示屏,RGB全彩LED模块、轻触开关模块及Keil5开发环境。

1.jpg

CW32F030C8小蓝板

2.png

GY-33颜色识别模块

3.png   

RGB全彩LED模块

4.png

实物展示

【GY-33与单片机连线】:VCC<-->+3.3V

   GND<-->GND

   DR<-->PA5

   CT<-->PA4

【LED与单片机连线】:V<-->+3.3V

        R<-->PA0

    G<-->PA1

    B<-->PA2

【轻触开关与单片机连线】:VCC<-->+3.3V

GND<-->GND

OUT<-->PB9

此模块有两种方式读取数据,即串口UART或者 MCU_IIC,本次实验采用MCU_IIC的方式。

5.png

6.png

7.png

有简单的7种颜色识别,单片机不参与数据处理工作,不需要计算RGB值,直接读取吧 数据即可。需要特别注意的是:

8.png

三、核心代码

main.c:
#include "main.h"
#include "RGB.h"
#include "GTIM.h"
#include "Delay.h"
#include "GY_33.h"
#include "OLED.h"
#include "Key.h"
#include "BTIM.h"

#define LENGTH 3   //读取数据的长度
uint8_t press_flag=0; //按键按下标识
uint8_t data[LENGTH]={0}; //存放读取到的RGB数据
uint8_t color[1]={0};  //存放模块识别到的颜色数据
char *str[]={"blue","dblue","green","black","white","pink","yellow","red"};//模块可以识别到的颜色

int main()
{    
    uint8_t i;    
    OLED_Init();      //OLED显示  
    RGB_GPIO_Init();  //RGB灯GPIO初始化  
    GTIM2_Init();     //GTIM2初始化配置为PWM输出模式  
    I2C_GPIO_Init();  //GY-33模块GPIO初始化  
    Key_GPIO_Init();  //按键GPIO初始化  
    BTIM_Init();      //BTIM定时器初始化,定时控制按键扫描周期
    //  WriteData(GY33_ADDR,Config,0x51);  //启动白平衡,等级亮度为5
  
  while(1)  
  {    
      if(press_flag==1)  //若按键标识已打开,代表有按键按下,执行按键功能    
      {      
          OLED_Clear(); //清屏      
          if(ReadData(GY33_ADDR,R,data,LENGTH)) //读取模块检测颜色并进行处理后返回的RGB值      
          {        
              OLED_ShowString(1,1,"RGB:");        
              OLED_ShowNum(1,5,data[0],3);  //R值        
              OLED_ShowNum(2,5,data[1],3);  //G值        
              OLED_ShowNum(3,5,data[2],3);  //B值      
          }      
          RGB_Running(data);  //RGB全彩LED灯根据读取到的RGB进行显示      
          Delay_ms(100);      //数据读取间隔应不小于100ms      
          if(ReadData(GY33_ADDR,Color,color,1))//读取模块检测颜色并进行处理后的颜色信息返回值      
          {        
              for(i=0;i<8;i++) //8-bits数据,逐位判断        
              {          
                  if((color[0]>>i)==1) //判断哪一位为1          
                  {            
                      OLED_ShowString(4,1,"Color:");            
                      OLED_ShowString(4,7,str[7-i]); //显示对应颜色            
                      break;          
                  }        
              }      
          }      
          press_flag=0; //执行完关闭按键标识    
      }    
  }
}

void BTIM1_IRQHandler(void)  //BTIM1中断服务函数
{  
    static unsigned int cnt = 0;   
    
    if(BTIM_GetITStatus(CW_BTIM1,BTIM_IT_OV))    
    {    
        if(++cnt>=20)  //20ms定时,执行一次按键扫描    
        {      
            cnt = 0;      
            if(Key_Scan()==1)  //返回值不为0时        
            press_flag=1;    //打开按键标识    
        }    
        BTIM_ClearITPendingBit(CW_BTIM1,BTIM_IT_OV); //清除标志位  
    }
}

GY-33.c:
#include "main.h"
#include "Delay.h"
#include "GY_33.h"

void I2C_GPIO_Init(void)   //GY-33颜色识别模块GPIO初始化
{  
    __RCC_GPIOA_CLK_ENABLE();   
    
    GPIO_InitTypeDef GPIO_InitStruct;   
    GPIO_InitStruct.IT=GPIO_IT_NONE;  
    GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_OD;      //开漏输出  
    GPIO_InitStruct.Pins=GPIO_PIN_4|GPIO_PIN_5;  
    GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;  
    GPIO_Init(CW_GPIOA, &GPIO_InitStruct);  
     
    SCL(1);  
    SDA(1);
}

void I2C_Delay() //I2C延时函数
{  
    Delay_us(time);
}

uint8_t I2C_Start(void)  //发送起始信号
{  
    SDA(1);  
    SCL(1);  
    I2C_Delay();  
    if(ReadSDA==0) return 0;  
    SDA(0);  
    I2C_Delay();  
    if(ReadSDA==1) return 0;  
    SCL(0);  
    I2C_Delay();   
    
    return 1;
}

void I2C_Stop(void)  //发送停止信号
{  
    SDA(0);  
    SCL(0);  
    I2C_Delay();  
    SCL(1);  
    I2C_Delay();  
    SDA(1);
}

void I2C_SendACK(uint8_t ackbit)  //发送应答
{  
    SDA(ackbit);  
    SCL(1);  
    I2C_Delay();  
    SCL(0);  
    I2C_Delay();
}

void I2C_SendByte(uint8_t Byte)  //发送1字节(8-bit)的数据
{  
    uint8_t i;  
    SCL(0);  
    for (i = 0; i < 8; i++)  
    {    
        if(Byte&0x80) SDA(1);    
        else SDA(0);    
        SCL(1);    
        I2C_Delay();    
        SCL(0);    
        Byte<<=1;    
        I2C_Delay();  
    }
}

uint8_t I2C_ReceiveByte(void)  //接收1字节(8-bit)的数据
{  
    uint8_t data,i;  
    SDA(1);  
    Delay_us(1);  
    for(i=0;i<8;i++)  
    {    
        SCL(1);    
        data<<=1;    
        if(ReadSDA==1) data|=0x01;    
        I2C_Delay();    
        SCL(0);    
        I2C_Delay();  
    }   
    
    return data;
}

uint8_t I2C_WaitAck(void) //等待应答
{  
    uint16_t i;  
    SDA(1);  
    SCL(1);  
    while(ReadSDA==1)  
    {    
        if(++i==500)      
        break;  
    }  
    if(ReadSDA==1)  
    {    
        SCL(0);    
        return 0;  
    }  
    I2C_Delay();  
    SCL(0);  
    I2C_Delay();   
    return 1; 
}

uint8_t WriteData(uint8_t Slave_Addr,uint8_t REG_Addr,uint8_t data)  //写操作
{  
    if(I2C_Start()==0) RETURN   
    
    I2C_SendByte(Slave_Addr);    
    if(I2C_WaitAck()==0) RETURN  
     
    I2C_SendByte(REG_Addr);          
    if(I2C_WaitAck()==0) RETURN                   
    
    I2C_SendByte(data);  
    if(I2C_WaitAck()==0) RETURN                 
    
    I2C_Stop();              //发送停止信号   
    
    return 1;
}

uint8_t ReadData(uint8_t Slave_Addr,uint8_t REG_Addr,uint8_t *data,uint8_t length) //读操作
{    
    if(I2C_Start()==0) RETURN  
             
    I2C_SendByte(Slave_Addr);      
    if(I2C_WaitAck()==0) RETURN           
    
    I2C_SendByte(REG_Addr);              
    if(I2C_WaitAck()==0) RETURN   
    
    if(I2C_Start()==0) RETURN  
     
    I2C_SendByte(Slave_Addr+1);   
    if(I2C_WaitAck()==0) RETURN                   
    
    while(--length)
    {    
        *data++=I2C_ReceiveByte();    
        I2C_SendACK(0);    
        Delay_ms(110);  
    }  
    *data=I2C_ReceiveByte();  
    I2C_SendACK(1);  
    I2C_Stop();  
                      //发送停止信号   
    return 1;              
}

四、实物展示+效果演示

10.png

11.png

12.png

13.png

来源: CW32生态社区

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 81