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

news2025/1/15 6:24:13

VD6283TX环境光传感器驱动开发----1.获取光强和色温

  • 概述
  • 视频教学
  • 样品申请
  • 源码下载
  • 参考源码
  • 设置增益
  • 基准配置
  • 设置ALS曝光时间
  • 通道使能
  • 启用ALS操作
  • 中断查询及清除
  • 获取ALS数据
  • 计算光强及色温
  • 结果演示

概述

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

最近在弄ST的课程,需要样片的可以加群申请:615061293 。

视频教学

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

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

样品申请

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

源码下载

参考源码

这里使用的参考为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);		

设置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);
}

基准配置

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

这里配置为默认值。

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

具体操作如下所示。

// 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);
}

设置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)	;

具体操作如下所示。

// 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;
}

通道使能

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

在这里插入图片描述

在这里插入图片描述

这里将6个通道都开启。

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

函数如下所示。

// 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);
}

启用ALS操作

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

这里启动单次测量模式。

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

具体函数如下所示。

#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);
}

中断查询及清除

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

在这里插入图片描述

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

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

具体函数如下所示。

#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;
}

获取中断如下所示。

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

具体函数如下所示。

/**
  * @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;
}

获取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);	

具体操作如下所示。

/**
  * @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;	
}

计算光强及色温

计算色温(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);
}

打印信息如下所示。

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);
}

结果演示

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1057901.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用通俗易懂的方式讲解大模型分布式训练并行技术:张量并行

近年来&#xff0c;随着Transformer、MOE架构的提出&#xff0c;使得深度学习模型轻松突破上万亿规模参数&#xff0c;传统的单机单卡模式已经无法满足超大模型进行训练的要求。因此&#xff0c;我们需要基于单机多卡、甚至是多机多卡进行分布式大模型的训练。 而利用AI集群&a…

最近脑机接口突破性成果这么多,它到底走到哪一步了?

美国心脏协会(AHA)首席临床科学官、哥伦比亚大学神经病学和流行病学终身教授Mitchell Elkind在接受NeuroNews采访时概述了脑机接口(BCI)技术的巨大潜力:“恢复患者活动能力的可能性可能会带来巨大的好处。”“对于那些功能受限的人来说&#xff0c;即使是微小的进步也能改变他们…

【数仓精品理论分析】能不能学大数据?

【数仓精品理论分析】能不能学大数据&#xff1f; 还能不能学大数据datapulse官网&#xff1a; 自身情况数据行业发展情况 还能不能学大数据 首先看到这个话题的时候&#xff0c;我是这样想的&#xff0c;能不能学大数据需要参考本人的自身情况【学历、年龄、决心、有没有矿或者…

高層建築設計和建造:從避難層到設備間和防風防火防水的設計理念,酒店住宅辦公樓都有什麽房間(精簡)

樓層概覽 標準層居住、辦公、商業等功能的樓層。結構和裝修與其他樓層相同&#xff0c;可供人正常居住、工作和活動避難層專門用於人員避難的樓層&#xff0c;通常會相隔數十個標準層&#xff0c;樓梯通常和標準層是錯開的(非公用)&#xff0c;具有更多的通風口。牆體和樓板具…

黑豹程序员-架构师学习路线图-百科:CSS-网页三剑客

文章目录 1、为什么需要CSS2、发展历史3、什么是CSS4、什么是SASS、SCSS 1、为什么需要CSS 作为网页三剑客的第二&#xff0c;CSS为何需要它&#xff0c;非常简单HTML只能完成页面的展现&#xff0c;但其做出来的页面奇丑无比。 随着网络的普及&#xff0c;人们的要求更高&…

Ubantu 20.04 卸载与安装 MySQL 5.7 详细教程

文章目录 卸载 MySQL安装 MySQL 5.71.获取安装包2.解压并安装依赖包3.安装 MySQL4.启动 MySQL 扩展开启 gtid 与 binlog 卸载 MySQL 执行以下命令即可一键卸载&#xff0c;包括配置文件目录等。 # 安装sudo软件 apt-get install sudo -y # 卸载所有以"mysql-"开头的…

小病变检测:Gravity Network for end-to-end small lesion detection

论文作者&#xff1a;Ciro Russo,Alessandro Bria,Claudio Marrocco 作者单位&#xff1a;University of Cassino and L.M. 论文链接&#xff1a;http://arxiv.org/abs/2309.12876v1 内容简介&#xff1a; 1&#xff09;方向&#xff1a;医学影像中小病变检测 2&#xff0…

PyQt5+Qt设计师初探

在上一篇文章中我们搭建好了PyQt5的开发环境&#xff0c;打铁到趁热我们基于搭建好的环境来简单实战一把 一&#xff1a;PyQt5包模块简介 PyQt5包括的主要模块如下。 QtCore模块——涵盖了包的核心的非GUI功能&#xff0c;此模块被用于处理程序中涉及的时间、文件、目录、数…

代谢组学最常用到的数据分析方法(五)

代谢组学是一门对某一生物或细胞所有低分子质量代谢产物&#xff08;以相对分子质量<1000的有机和无机的代谢物为研究核心区&#xff09;进行分析的新兴学科。因此从复杂的代谢组学数据中确定与所研究的现象有关的代谢物&#xff0c;筛选出候选生物标记物成为代谢物组学研究…

秋招,网申测评,认知能力测试

随着秋季的到来&#xff0c;越来越多的企业开始进行职业招聘&#xff0c;在这些招聘中&#xff0c;我们总会看到“认知能力测试”的影子。说到这个测试&#xff0c;很多人可能还不太理解&#xff0c;不知道这种测试是什么。 1、什么是认知能力测试 认知能力是指大脑加工、…

【Diffusion】DDPM - (1)预备基础知识

预备基础知识 1、概率 - 条件独立 A 和 B 是两个独立事件    ⇒    P ( A ∣ B ) = P ( A ) \; \Rightarrow \; P(A|B) = P(A) ⇒P(A∣B)=P(A), P ( B ∣ A ) = P ( B ) \quad P(B|A) = P(B) P(B∣A)=P(B) ⇒ P ( A , B ∣ C ) = P ( A ∣ C ) P ( B ∣ C ) \quad\quad…

Java编码

Java编码问题 Unicode与码点 所谓Unicode就是全世界的字符字典&#xff0c;也就是把字符给一个编号&#xff0c;这个编码就是码点。比如 2. 编码 由于这种分配的编码无论从占用空间角度&#xff0c;还是读取速度&#xff0c;以及逻辑划分角度&#xff0c;都不是完善。所以出…

Ai4science学习、教育和更多

11 学习、教育和更多 人工智能的进步为加速科学发现、推动创新和解决各个领域的复杂问题提供了巨大的希望。然而&#xff0c;要充分利用人工智能为科学研究带来的潜力&#xff0c;我们需要面对教育、人才培养和公众参与方面的新挑战。在本节中&#xff0c;我们首先收集了关于每…

Java并发-满老师

Java并发 一级目录栈与栈帧线程上下文切换三级目录 一级目录 栈与栈帧 满老师视频链接 我们都知道 JVM 中由堆、栈、方法区所组成&#xff0c;其中栈内存是给谁用的呢&#xff1f;其实就是线程&#xff0c;每个线程启动后&#xff0c;虚拟机就会为其分配一块栈内存 每个栈由…

CSS基础语法之盒子模型

目录 一、 选择器 1.1 结构伪类选择器 1.1.1基本使用 1.1.2 :nth-child(公式) 1.2 伪元素选择器 二、 PxCook 三、盒子模型 3.1 盒子模型-组成 3.2 边框线 3.2.1四个方向 3.2.2 单方向边框线 3.3 内边距 3.4 尺寸计算 3.5 外边距+版心居中 3.6 清除默认样式 3.7…

简单丝的tab切换栏(html/CSS)

#html <!DOCTYPE html> <html lang"en" > <head><meta charset"UTF-8"><title>CSS实现左右滑动选项卡效果</title><link rel"stylesheet" href"https://cdnjs.cloudflare.com/ajax/libs/meyer-res…

查看虚拟机ip地址

前几天安装了docker&#xff0c;运行了一下以后发现自己的主机无论如何也访问不了虚拟机上运行的容器&#xff0c;老实说我大受打击&#xff0c;因为各种各样的方法我都试了个遍&#xff0c;重装&#xff0c;配私服&#xff0c;各种各样的方法&#xff0c;结果显示却是正常的&a…

紫光同创FPGA图像视频采集系统,提供2套PDS工程源码和技术支持

目录 1、前言免责声明 2、紫光同创FPGA相关方案推荐3、设计思路框架视频源选择OV7725摄像头配置及采集OV5640摄像头配置及采集动态彩条HDMA图像缓存输入输出视频HDMA缓冲FIFOHDMA控制模块 HDMI输出 4、PDS工程1详解&#xff1a;OV7725输入5、PDS工程2详解&#xff1a;OV5640输入…

想要精通算法和SQL的成长之路 - 恢复二叉搜索树和有序链表转换二叉搜索树

想要精通算法和SQL的成长之路 - 恢复二叉搜索树和有序链表转换二叉搜索树 前言一. 恢复二叉搜索树二. 有序链表转换二叉搜索树 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 恢复二叉搜索树 原题链接 首先&#xff0c;一个正常地二叉搜索树在中序遍历下&#xff0c;遍历…

win10 快捷键

WinD 回到桌面 WinE 文件资源管理器 WinI windows设置 WinL 锁屏 Wintab 显示所有已打开窗口的缩略图 Alttab 在所有已打开窗口的缩略图中快速切换 Win空格 输入法切换 WinshiftS 截图 windows10下有哪些必须掌握的快捷键&#xff1f; - …