• VD6283TX环境光传感器驱动开发(2)----获取光强和色温


    概述

    为了更好地利用VD6283TX传感器的特点和功能,本章专门用于捕获光强度和相关色温值。VD6283TX,作为ST的高级色感器,具有并行感测多个通道的能力,这使得它成为光强和色温测量的理想选择。
    最近在弄ST的课程,需要样片的可以加群申请:615061293 。
    在这里插入图片描述

    硬件准备

    首先需要准备一个开发板,这里我准备的是自己绘制的开发板:
    在这里插入图片描述

    视频教学

    https://www.bilibili.com/video/BV1xu4y1t75n/

    VD6283TX环境光传感器驱动开发(2)----获取光强和色温

    样品申请

    https://www.wjx.top/vm/OhcKxJk.aspx#

    源码下载

    https://download.csdn.net/download/qq_24312945/88391797

    参考源码

    这里使用的参考为STM32CUBEMX配置的X-CUBE-ALS软件包。

    在这里插入图片描述

    设置增益

    增益是用来调整传感器对光的敏感度。高的增益值意味着传感器对光更敏感,而低的增益值则相反。
    CH1 到 CH6 代表六个不同的通道或色道,所以需要设置六个通道的增益,地址为0x25到0x2A。
    在这里插入图片描述
    在这里插入图片描述

    每个通道都可以设置16种增益,如下所示。

    在这里插入图片描述
    这里设置增益为1,配置如下。

    	//通道增益设置
    	//0000: reserved
    	//0001: AGAIN = 66.6x
    	//0010: AGAIN = 50x
    	//0011: AGAIN = 33x
    	//0100: AGAIN = 25x
    	//0101: AGAIN = 16x
    	//0110: AGAIN = 10x
    	//0111: AGAIN = 7.1x
    	//1000: AGAIN = 5x
    	//1001: AGAIN = 3.33x
    	//1010: AGAIN = 2.5x
    	//1011: AGAIN = 1.67x
    	//1100: AGAIN = 1.25x
    	//1101: AGAIN = 1x
    	//1110: AGAIN = 0.83x
    	//1111: AGAIN = 0.71x
    	VD6283TX_setALSGainCH1(VD6283TX_ID, 0x0D);
    	VD6283TX_setALSGainCH2(VD6283TX_ID, 0x0D);	
    	VD6283TX_setALSGainCH3(VD6283TX_ID, 0x0D);	
    	VD6283TX_setALSGainCH4(VD6283TX_ID, 0x0D);
    	VD6283TX_setALSGainCH5(VD6283TX_ID, 0x0D);	
    	VD6283TX_setALSGainCH6(VD6283TX_ID, 0x0D);		
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    设置VD6283TX传感器中不同通道的模拟增益值函数如下。

    // ALS Gain Registers for Channels
    #define VD6283TX_ALS_GAIN_CH1                   0x25
    #define VD6283TX_ALS_GAIN_CH2                   0x26
    #define VD6283TX_ALS_GAIN_CH3                   0x27
    #define VD6283TX_ALS_GAIN_CH4                   0x28
    #define VD6283TX_ALS_GAIN_CH5    								0x29
    #define VD6283TX_ALS_GAIN_CH6    								0x2A
    
    /**
      * @brief  设置VD6283的ALS通道2模拟增益
      * 
      * @param  add      设备地址
      * @param  gain     模拟增益值,对应于上述描述中的AGAIN[4:0]
      * @retval          操作的返回状态
      */
    uint8_t VD6283TX_setALSGainCH2(uint8_t add, uint8_t gain)
    {
        if (gain > 0x0F || gain == 0x00) {
            // 输入的增益值无效或保留,返回错误码
            return 0xFF;  
        }
    
        // 如果用I2C等其他通信协议,可以调用相应的写入函数。
        // 假设VD6283TX_write_reg是一个函数,它写入一个字节到指定的寄存器。
        return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH2, &gain, 1);
    }
    
    /**
      * @brief  设置VD6283的ALS通道3模拟增益
      * 
      * @param  add      设备地址
      * @param  gain     模拟增益值,对应于上述描述中的AGAIN[4:0]
      * @retval          操作的返回状态
      */
    uint8_t VD6283TX_setALSGainCH3(uint8_t add, uint8_t gain)
    {
        if (gain > 0x0F || gain == 0x00) {
            // 输入的增益值无效或保留,返回错误码
            return 0xFF;  
        }
    
        // 如果用I2C等其他通信协议,可以调用相应的写入函数。
        // 假设VD6283TX_write_reg是一个函数,它写入一个字节到指定的寄存器。
        return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH3, &gain, 1);
    }
    
    
    /**
      * @brief  设置VD6283的ALS通道4模拟增益
      * 
      * @param  add      设备地址
      * @param  gain     模拟增益值,对应于上述描述中的AGAIN[4:0]
      * @retval          操作的返回状态
      */
    uint8_t VD6283TX_setALSGainCH4(uint8_t add, uint8_t gain)
    {
        if (gain > 0x0F || gain == 0x00) {
            // 输入的增益值无效或保留,返回错误码
            return 0xFF;  
        }
    
        // 如果用I2C等其他通信协议,可以调用相应的写入函数。
        // 假设VD6283TX_write_reg是一个函数,它写入一个字节到指定的寄存器。
        return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH4, &gain, 1);
    }
    
    /**
      * @brief  设置VD6283的ALS通道5模拟增益
      * 
      * @param  add      设备地址
      * @param  gain     模拟增益值,对应于上述描述中的AGAIN[4:0]
      * @retval          操作的返回状态
      */
    uint8_t VD6283TX_setALSGainCH5(uint8_t add, uint8_t gain)
    {
        if (gain > 0x0F || gain == 0x00) {
            // 输入的增益值无效或保留,返回错误码
            return 0xFF;  
        }
    
        // 如果用I2C等其他通信协议,可以调用相应的写入函数。
        // 假设VD6283TX_write_reg是一个函数,它写入一个字节到指定的寄存器。
        return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH5, &gain, 1);
    }
    
    
    /**
      * @brief  设置VD6283的ALS通道6模拟增益
      * 
      * @param  add      设备地址
      * @param  gain     模拟增益值,对应于上述描述中的AGAIN[4:0]
      * @retval          操作的返回状态
      */
    uint8_t VD6283TX_setALSGainCH6(uint8_t add, uint8_t gain)
    {
        if (gain > 0x0F || gain == 0x00) {
            // 输入的增益值无效或保留,返回错误码
            return 0xFF;  
        }
    
        // 如果用I2C等其他通信协议,可以调用相应的写入函数。
        // 假设VD6283TX_write_reg是一个函数,它写入一个字节到指定的寄存器。
        return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH6, &gain, 1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104

    基准配置

    寄存配置可以通过寄存器0x32进行配置。
    在这里插入图片描述

    这里配置为默认值。

    	//光源的闪烁 默认为3
    	VD6283TX_setPedestalValue(VD6283TX_ID,0x03);
    
    • 1
    • 2

    具体操作如下所示。

    // Pedestal Value Register
    #define VD6283TX_PEDESTAL_VALUE  								0x32
    
    /**
      * @brief  设置VD6283的pedestal值
      * 
      * @param  add          设备的I2C地址
      * @param  pdst_val     要设置的pedestal值 (位于[2:0]范围内)
      * @retval              操作的返回状态(例如:成功或失败)
      */
    uint8_t VD6283TX_setPedestalValue(uint8_t add, uint8_t pdst_val)
    {
        // 验证输入参数的有效性
        if (pdst_val > 0x07) {
            return 0xFF;  // 错误码,表示无效的参数
        }
    
        // 假设有一个函数VD6283TX_write_reg,用于向给定的地址写入一个字节
        return VD6283TX_write_reg(add, VD6283TX_PEDESTAL_VALUE, &pdst_val, 1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    设置ALS曝光时间

    VD6283给出了曝光时间的配置,寄存器位0x1d-0x1e。

    在这里插入图片描述

    配置100ms为0x003f(63),时间为(63+ 1) x 16384/10.24M=102.4ms。

    	//设置VD6283的ALS曝光时间
    	//EXTIME: exposure time = (EXTIME[9:0] + 1) x 16384/Fosc
    	//Fosc = 10.24 MHz
    	//Default value = 80 ms (min. = 1.6 ms and max. = 1.6 s)
    	//0x003f,设置为100ms
    	VD6283TX_setALSExposureTime(VD6283TX_ID, 0x003f)	;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    具体操作如下所示。

    // ALS Exposure Registers
    #define VD6283TX_ALS_EXPOSURE_M                 0x1D
    #define VD6283TX_ALS_EXPOSURE_L                 0x1E
    /**
      * @brief  设置VD6283的ALS曝光时间
      *
      * @param  add       设备地址
      * @param  exTime    曝光时间计数值(EXTIME[9:0],不是实际的时间单位)
      * @retval           操作的返回状态
      *
      * 该函数用于控制VD6283的ALS曝光时间。寄存器地址从0x1D到0x1E。
      * 寄存器的[9:0]位表示ALS的曝光时间。
      * 默认值对应的曝光时间是80毫秒,最小值是1.6毫秒,最大值是1.6秒。
      */
    uint8_t VD6283TX_setALSExposureTime(uint8_t add, uint16_t exTime)
    {
        uint8_t data[2];
    		uint8_t ret;
        data[0] = exTime & 0xFF;        // 低字节
        data[1] = (exTime >> 8) & 0xFF; // 高字节
    		ret = VD6283TX_write_reg(add, VD6283TX_ALS_EXPOSURE_L, &data[0], 1);
    
    		if(ret)
    			return ret;
    		else
    			ret = VD6283TX_write_reg(add, VD6283TX_ALS_EXPOSURE_M, &data[1], 1);
        return ret;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    通道使能

    由于VD6283TX有六个,所以进行使能时候需要根据所需要的通道进行使能,主要寄存器为0x2d和0x2e。

    在这里插入图片描述

    在这里插入图片描述

    这里将6个通道都开启。

    	//设置VD6283的ALS通道使能状态(1-5)		0x1F->11111
    	VD6283TX_setALSChannelEnable(VD6283TX_ID, 0x1F);		
    	//设置VD6283的ALS通道6使能状态	
    	VD6283TX_setChannel6Enable(VD6283TX_ID, 0x01);	
    
    • 1
    • 2
    • 3
    • 4

    函数如下所示。

    // Channel 6 Enable Register
    #define VD6283TX_CHANNEL6_ENABLE 								0x2D
    
    // ALS Channel Enable Register
    #define VD6283TX_ALS_CHANNEL_ENABLE 						0x2E
    
    /**
      * @brief  设置VD6283的通道6使能
      * 
      * @param  add      设备地址
      * @param  enable   1表示启用通道6,0表示禁用通道6
      * @retval          操作的返回状态
      */
    uint8_t VD6283TX_setChannel6Enable(uint8_t add, uint8_t enable)
    {
    		uint8_t data;
        if (enable > 1) {
            // 输入的使能值无效,返回错误码
            return 0xFF;  
        }
    
    
    
    
        // 根据enable参数来设置或清除CH6_EN位
        if (enable) {
            data |= 0x01;  // 设置第0位
        } else {
            data &= ~0x01; // 清除第0位
        }
    
        // 使用I2C或其他通信协议写回更改后的值。
        // 假设VD6283TX_write_reg是一个函数,用于向指定的寄存器写入一个字节。
        return VD6283TX_write_reg(add, VD6283TX_CHANNEL6_ENABLE, &data, 1);
    }
    
    
    /**
      * @brief  设置VD6283的ALS通道使能状态
      * 
      * @param  add         设备的I2C地址
      * @param  channels    一个字节,其中位[4:0]表示要启用的ALS通道
      * @retval             操作的返回状态(例如:成功或失败)
      */
    uint8_t VD6283TX_setALSChannelEnable(uint8_t add, uint8_t channels)
    {
        // 检查channels的位[7:5]是否为0,因为这些位是保留的
        if (channels & 0xE0) {
            return 0xFF;  // 错误码,表示无效的参数
        }
    
        // 假设有一个函数VD6283TX_write_reg,用于向给定的地址写入一个字节
        return VD6283TX_write_reg(add, VD6283TX_ALS_CHANNEL_ENABLE, &channels,1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    启用ALS操作

    寄存器0x03是选择ALS的工作模式(单次测量或连续测量)并启动或停止ALS操作。
    在这里插入图片描述

    这里启动单次测量模式。

    	//启用VD6283的ALS操作,使用ALS_CONT模式启动ALS操作。
    	VD6283TX_enableALSOperation(VD6283TX_ID, 0x01);		
    
    • 1
    • 2

    具体函数如下所示。

    #define VD6283TX_ALS_CTRL                       0x03
    /**
      * @brief  启用或禁用VD6283的ALS操作
      *
      * @param  add      设备地址
      * @param  enable   1启用ALS操作,0禁用
      * @retval          操作的返回状态
      *[0] ALS_EN (Enable ALS Operation): 启用或禁用ALS操作。
      *0: ALS操作已停止(即,空闲)。
      *1: 使用ALS_CONT模式启动ALS操作。
      */
    uint8_t VD6283TX_enableALSOperation(uint8_t add, uint8_t enable)
    {
        uint8_t data[1] = {(enable & 0x01)};
        return VD6283TX_write_reg(add, VD6283TX_ALS_CTRL, data, 1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    中断查询及清除

    当信号准备好时候可以查询寄存器0x02进行查询。

    在这里插入图片描述

    可以通过查询中断方式判断数据是否获取完毕。

    	//获取VD6283的中断状态,等待INTR_ST为0
    	timeout = 0xffff;//溢出时间
    	while(1)
    	{
    		data=VD6283TX_getInterruptStatus(VD6283TX_ID);	
    		timeout--;
    		if(data==0 || timeout==0)
    			break;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    具体函数如下所示。

    #define VD6283TX_INTERRUPT_CTRL                 0x02
    /**
      * @brief  获取VD6283的中断状态
      *[1] INTR_ST (Interrupt Status): 该位表示中断状态。当值为1时,表示没有触发中断或上一个中断尚未清除。
      *[0] CLR_INTR (Clear Interrupt): 该位用于清除中断标志。INTR_ST中断标志可以通过将CLR_INTR设置为'1',随后设置为'0'来清除。
      * @param  add      设备地址
      * @retval          中断状态:1 表示没有触发中断或上一个中断尚未清除,0 则表示已清除或未设置。
      *
      */
    uint8_t VD6283TX_getInterruptStatus(uint8_t add)
    {
        uint8_t intStatus[1] = {0};
        VD6283TX_read_reg(add, VD6283TX_INTERRUPT_CTRL, intStatus, 1);
        return (intStatus[0] >> 1) & 0x01;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    获取中断如下所示。

    	//清除VD6283的中断标志
    	VD6283TX_clearInterruptFlag(VD6283TX_ID);	
    
    • 1
    • 2

    具体函数如下所示。

    /**
      * @brief  清除VD6283的中断标志
      *
      * @param  add      设备地址
      * @retval          操作的返回状态
      *
      */
    uint8_t VD6283TX_clearInterruptFlag(uint8_t add)
    {
        uint8_t cmd[1] = {0x01};  // Set CLR_INTR to '1'
        uint8_t ret = VD6283TX_write_reg(add, VD6283TX_INTERRUPT_CTRL, cmd, 1);
        cmd[0] = 0x00;  // Set CLR_INTR to '0'
        ret |= VD6283TX_write_reg(add, VD6283TX_INTERRUPT_CTRL, cmd, 1);
        return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    获取ALS数据

    读取环境光传感器通1的数据值。数据值由三个字节组成,包括高、中和低字节,共计24位。这可能意味着该通道可以提供非常高的测量精度,因为它使用24位来表示一个单一的测量值。

    在这里插入图片描述

    获取方式如下所示。

    	//读取VD6283的ALS通道数据
    	AlsResults[LIGHT_SENSOR_RED_CHANNEL]=VD6283TX_getALSCH1Data(VD6283TX_ID);
    	ALS_CH2_DATA=VD6283TX_getALSCH2Data(VD6283TX_ID);	
    	AlsResults[LIGHT_SENSOR_BLUE_CHANNEL]=VD6283TX_getALSCH3Data(VD6283TX_ID);	
    	AlsResults[LIGHT_SENSOR_GREEN_CHANNEL]=VD6283TX_getALSCH4Data(VD6283TX_ID);	
    	ALS_CH5_DATA=VD6283TX_getALSCH5Data(VD6283TX_ID);	
    	ALS_CH6_DATA=VD6283TX_getALSCH6Data(VD6283TX_ID);	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    具体操作如下所示。

    /**
      * @brief  读取VD6283的ALS通道1数据
      *
      * @param  add      设备地址
      * @retval          返回数值
      *ALS channel 1 data register (ALS_CH1_DATA)
      *
      *这是一个只读寄存器,用于读取ALS通道1的数据。寄存器地址范围是0x06到0x08,默认值都是0x00。
      *
      *[23:16] ALS_CH1_DATA_H:ALS通道1的高字节数据。
      *
      *[15:8] ALS_CH1_DATA_M:ALS通道1的中字节数据。
      *
      *[7:0] ALS_CH1_DATA_L:ALS通道1的低字节数据
      */
    uint32_t VD6283TX_getALSCH1Data(uint8_t add)
    {
    		uint8_t data1[3];
    		uint32_t ALSCHData=0;
    		VD6283TX_read_reg(add, VD6283TX_ALS_CH1_DATA_H, data1, 3);
    		ALSCHData = data1[0];
    		ALSCHData = ALSCHData<<8;
    		ALSCHData|= data1[1];
    		ALSCHData = ALSCHData<<8;
    		ALSCHData|= data1[2];	
    		return ALSCHData;
    }
    
    
    
    
    
    
    /**
      * @brief  读取VD6283的ALS通道2数据
      *
      * @param  add      设备地址
      * @param  data     存储读取数据的数组,大小至少为3字节
      * @retval          操作的返回状态
      *用于读取ALS通道2的数据。寄存器地址范围是0x0A到0x0C,默认值都是0x00。
      *
      *[23:16] ALS_CH2_DATA_H:ALS通道2的高字节数据。
      *
      *[15:8] ALS_CH2_DATA_M:ALS通道2的中字节数据。
      *
      *[7:0] ALS_CH2_DATA_L:ALS通道2的低字节数据。
      */
    uint32_t VD6283TX_getALSCH2Data(uint8_t add)
    {
    		uint8_t data1[3];
    		uint32_t ALSCHData=0;
    		VD6283TX_read_reg(add, VD6283TX_ALS_CH2_DATA_H, data1, 3);
    		ALSCHData = data1[0];
    		ALSCHData = ALSCHData<<8;
    		ALSCHData|= data1[1];
    		ALSCHData = ALSCHData<<8;
    		ALSCHData|= data1[2];	
    		return ALSCHData;	
    
    }
    
    
    
    /**
      * @brief  读取VD6283的ALS通道3数据
      *
      * @param  add      设备地址
      * @param  data     存储读取数据的数组,大小至少为3字节
      * @retval          操作的返回状态
      *用于读取ALS通道3的数据。寄存器地址范围是0x0E到0x10,默认值都是0x00。
      *
      *[23:16] ALS_CH3_DATA_H:ALS通道3的高字节数据。
      *
      *[15:8] ALS_CH3_DATA_M:ALS通道3的中字节数据。
      *
      *[7:0] ALS_CH3_DATA_L:ALS通道3的低字节数据。
      */
    uint32_t VD6283TX_getALSCH3Data(uint8_t add)
    {
    		uint8_t data1[3];
    		uint32_t ALSCHData=0;
    		VD6283TX_read_reg(add, VD6283TX_ALS_CH3_DATA_H, data1, 3);
    		ALSCHData = data1[0];
    		ALSCHData = ALSCHData<<8;
    		ALSCHData|= data1[1];
    		ALSCHData = ALSCHData<<8;
    		ALSCHData|= data1[2];	
    		return ALSCHData;		
    
    }
    
    
    
    /**
      * @brief  读取VD6283的ALS通道4数据
      *
      * @param  add      设备地址
      * @param  data     存储读取数据的数组,大小至少为3字节
      * @retval          操作的返回状态
      *用于读取ALS通道4的数据。寄存器地址范围是0x12到0x14,默认值都是0x00。
      *
      *[23:16] ALS_CH4_DATA_H:ALS通道4的高字节数据。
      *
      *[15:8] ALS_CH4_DATA_M:ALS通道4的中字节数据。
      *
      *[7:0] ALS_CH4_DATA_L:ALS通道4的低字节数据。
      */
    uint32_t VD6283TX_getALSCH4Data(uint8_t add)
    {
    		uint8_t data1[3];
    		uint32_t ALSCHData=0;
    		VD6283TX_read_reg(add, VD6283TX_ALS_CH4_DATA_H, data1, 3);
    		ALSCHData = data1[0];
    		ALSCHData = ALSCHData<<8;
    		ALSCHData|= data1[1];
    		ALSCHData = ALSCHData<<8;
    		ALSCHData|= data1[2];	
    		return ALSCHData;		
    
    }
    
    
    
    
    /**
      * @brief  读取VD6283的ALS通道5数据
      *
      * @param  add      设备地址
      * @param  data     存储读取数据的数组,大小至少为3字节
      * @retval          操作的返回状态
      *用于读取ALS通道5的数据。寄存器地址范围是0x16到0x18,默认值都是0x00。
      *
      *[23:16] ALS_CH5_DATA_H:ALS通道5的高字节数据。
      *
      *[15:8] ALS_CH5_DATA_M:ALS通道5的中字节数据。
      *
      *[7:0] ALS_CH5_DATA_L:ALS通道5的低字节数据。
      */
    uint32_t VD6283TX_getALSCH5Data(uint8_t add)
    {
    		uint8_t data1[3];
    		uint32_t ALSCHData=0;
    		VD6283TX_read_reg(add, VD6283TX_ALS_CH5_DATA_H, data1, 3);
    		ALSCHData = data1[0];
    		ALSCHData = ALSCHData<<8;
    		ALSCHData|= data1[1];
    		ALSCHData = ALSCHData<<8;
    		ALSCHData|= data1[2];	
    		return ALSCHData;		
    
    }
    
    
    
    /**
      * @brief  读取VD6283的ALS通道6数据
      *
      * @param  add      设备地址
      * @param  data     存储读取数据的数组,大小至少为3字节
      * @retval          操作的返回状态
      *用于读取ALS通道6的数据。寄存器地址范围是0x1A到0x1C,默认值都是0x00。
      *
      *[23:16] ALS_CH6_DATA_H:ALS通道6的高字节数据。
      *
      *[15:8] ALS_CH6_DATA_M:ALS通道6的中字节数据。
      *
      *[7:0] ALS_CH6_DATA_L:ALS通道6的低字节数据。
      */
    uint32_t VD6283TX_getALSCH6Data(uint8_t add)
    {
    		uint8_t data1[3];
    		uint32_t ALSCHData=0;
    		VD6283TX_read_reg(add, VD6283TX_ALS_CH6_DATA_H, data1, 3);
    		ALSCHData = data1[0];
    		ALSCHData = ALSCHData<<8;
    		ALSCHData|= data1[1];
    		ALSCHData = ALSCHData<<8;
    		ALSCHData|= data1[2];	
    		return ALSCHData;	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180

    计算光强及色温

    计算色温(Correlated Color Temperature, CCT)的方法基于颜色科学和人类对颜色的感知。
    这里移植了ST提供代码,左边为ST提供代码,右边为本项目代码。

    在这里插入图片描述
    从RGB到XYZ:
    RGB色彩空间是基于显示设备(如电视和计算机屏幕)的颜色表示。然而,为了更广泛、更精确地描述颜色(特别是在与人的视觉感知有关的情况下),科学家们使用了CIE 1931 XYZ色彩空间。
    RGB到XYZ的转换通常使用一个线性转换矩阵。这是因为RGB和XYZ都是线性色彩空间,所以可以通过一个线性关系(即矩阵乘法)从一个空间转换到另一个空间。

    为什么要使用XYZ空间:
    XYZ色彩空间是一个设备无关的色彩空间,这意味着它不依赖于特定的显示设备或光源。这使得它成为一个非常适合描述色彩和进行色彩科学研究的空间。
    其中,Y值与亮度或明度有关,而X和Z与色彩有关。从XYZ值,我们可以计算出xy色度坐标,这些坐标在CIE色度图上描述了颜色的色调和饱和度。

    计算CCT:
    通过将XYZ转换为xy色度坐标,我们可以在CIE色度图上定位颜色。然后,我们可以使用McCamy的公式(或其他方法)来近似CCT。CCT基本上表示该颜色与哪种"色温"的黑体辐射器最接近。例如,一个CCT值为6500K的光可能看起来与中午的阳光相似。
    McCamy的公式是一个经验公式,基于xy色度坐标为输入,并提供一个近似的CCT值。它是通过对多个实际样本进

    在CIE 1931 XYZ色彩空间中,Y值通常与亮度或明度有关,这也可以与光的强度或光照量(lux)联系起来。
    具体来说:
    X, Y, Z 在XYZ色彩空间中分别代表三个维度的色彩信息。
    Y 组件直接与感知亮度有关。在光学和颜色科学中,它经常被用来代表一个光源或反射物的明度或亮度,因此,它可以与光照量(用lux度量)直接关联。
    当我们在测量光源或环境光时,这个Y 值可以被视为对于该光源的总亮度或光强的表示。

    *
     * @brief compute cct value from RGB channels values
     */
    static void compute_cct(uint32_t TimeExposure, ResultCCT_t *Result)
    {
      /* correlation matrix used in order to convert RBG values to XYZ space */
    
      /*
       * (X)   (G)   (Cx1 Cx2 Cx3)
       * (Y) = (B) * (Cy1 Cy2 Cy3)
       * (Z)   (R)   (Cz1 Cz2 Cz3)
       *
       * X = G * Cx1 + B * Cx2 + R * Cx3
       * Y = G * Cy1 + B * Cy2 + R * Cy3
       * Z = G * Cz1 + B * Cz2 + R * Cz3
       *
       * */
    
      static const double_t Cx[] = {0.416700, -0.143816, 0.205570};
      static const double_t Cy[] = {0.506372, -0.120614, -0.028752};
      static const double_t Cz[] = {0.335866, 0.494781, -0.552625};
    
      uint8_t i;
    
      double_t data[CCT_COEFF_NB];
      double_t X_tmp = 0, Y_tmp = 0, Z_tmp = 0;
      double_t xyNormFactor;
      double_t m_xNormCoeff;
      double_t m_yNormCoeff;
      double_t nCoeff;
      double_t expo_scale = 100800.0 / TimeExposure;
    
      /* normalize and prepare RGB channels values for cct computation */
      data[0] = (double_t)AlsResults[LIGHT_SENSOR_GREEN_CHANNEL] / (float_t)VD6283TX_DEFAULT_GAIN;
      data[1] = (double_t)AlsResults[LIGHT_SENSOR_BLUE_CHANNEL] / (float_t)VD6283TX_DEFAULT_GAIN;
      data[2] = (double_t)AlsResults[LIGHT_SENSOR_RED_CHANNEL] / (float_t)VD6283TX_DEFAULT_GAIN;
    
      /* apply correlation matrix to RGB channels to obtain (X,Y,Z) */
      for (i = 0; i < CCT_COEFF_NB; i++)
      {
        X_tmp += Cx[i] * data[i];
        Y_tmp += Cy[i] * data[i];
        Z_tmp += Cz[i] * data[i];
      }
    
      /* transform (X,Y,Z) to (x,y) */
      xyNormFactor = X_tmp + Y_tmp + Z_tmp;
      m_xNormCoeff = X_tmp / xyNormFactor;
      m_yNormCoeff = Y_tmp / xyNormFactor;
    
      /* rescale X, Y, Z according to expo. Reference is G1x and 100.8ms */
      Result->X = expo_scale * X_tmp;
      Result->Y = expo_scale * Y_tmp;
      Result->Z = expo_scale * Z_tmp;
    
      /* apply McCamy's formula to obtain CCT value (expressed in °K) */
      nCoeff = (m_xNormCoeff - 0.3320) / (0.1858 - m_yNormCoeff);
      Result->cct = (449 * pow(nCoeff, 3) + 3525 * pow(nCoeff, 2) + 6823.3 * nCoeff + 5520.33);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    打印信息如下所示。

    static void print_cct(ResultCCT_t *Result)
    {
      /* clip the result in order to avoid negative values */
      if (Result->Y < 0) Result->Y = 0;
    
      printf("%6ld.%01ld Lux ", (long)Result->Y, (long)decimal_partlux(Result->Y));
      printf("\tCCT: %5ld K\r", (long)Result->cct);
      fflush(stdout);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果演示

    在这里插入图片描述

  • 相关阅读:
    传智杯第二届javaB组例题
    vue中的生命周期有什么,怎么用
    WEB安全 HTML基础
    SQL中的数据类型和规范化,助力数据存储优化
    Nginx七层负载均衡之动静分离
    项目二---04.基于Nginx、keepalived的高可用集群之Apache Bench测试
    新手如何用Airtest实现在图片范围内随机点击?
    Swagger概述
    ORB-SLAM2_RGBD_DENSE_MAP编译、问题解决、离线加载TUM数据和在线加载D435i相机数据生成稠密地图
    一、【Photoshop如何根据不同类型图像抠图】
  • 原文地址:https://blog.csdn.net/qq_24312945/article/details/133519763