概述
為了更好地利用VD6283TX傳感器的特點(diǎn)和功能,本章專門用于捕獲光強(qiáng)度和相關(guān)色溫值。VD6283TX,作為ST的高級色感器,具有并行感測多個(gè)通道的能力,這使得它成為光強(qiáng)和色溫測量的理想選擇。
最近在弄ST的課程,需要樣片的可以加群申請:615061293 。
硬件準(zhǔn)備
首先需要準(zhǔn)備一個(gè)開發(fā)板,這里我準(zhǔn)備的是自己繪制的開發(fā)板:
視頻教學(xué)
https://www.bilibili.com/video/BV1xu4y1t75n/
樣品申請
https://www.wjx.top/vm/OhcKxJk.aspx#](
源碼下載
https://download.csdn.net/download/qq_24312945/88391797
參考源碼
這里使用的參考為STM32CUBEMX配置的X-CUBE-ALS軟件包。
設(shè)置增益
增益是用來調(diào)整傳感器對光的敏感度。高的增益值意味著傳感器對光更敏感,而低的增益值則相反。
CH1 到 CH6 代表六個(gè)不同的通道或色道,所以需要設(shè)置六個(gè)通道的增益,地址為0x25到0x2A。
每個(gè)通道都可以設(shè)置16種增益,如下所示。
這里設(shè)置增益為1,配置如下。
//通道增益設(shè)置
//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);
設(shè)置VD6283TX傳感器中不同通道的模擬增益值函數(shù)如下。
// 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 設(shè)置VD6283的ALS通道2模擬增益
*
* @param add 設(shè)備地址
* @param gain 模擬增益值,對應(yīng)于上述描述中的AGAIN[4:0]
* @retval 操作的返回狀態(tài)
*/
uint8_t VD6283TX_setALSGainCH2(uint8_t add, uint8_t gain)
{
if (gain > 0x0F || gain == 0x00) {
// 輸入的增益值無效或保留,返回錯(cuò)誤碼
return 0xFF;
}
// 如果用I2C等其他通信協(xié)議,可以調(diào)用相應(yīng)的寫入函數(shù)。
// 假設(shè)VD6283TX_write_reg是一個(gè)函數(shù),它寫入一個(gè)字節(jié)到指定的寄存器。
return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH2, &gain, 1);
}
/**
* @brief 設(shè)置VD6283的ALS通道3模擬增益
*
* @param add 設(shè)備地址
* @param gain 模擬增益值,對應(yīng)于上述描述中的AGAIN[4:0]
* @retval 操作的返回狀態(tài)
*/
uint8_t VD6283TX_setALSGainCH3(uint8_t add, uint8_t gain)
{
if (gain > 0x0F || gain == 0x00) {
// 輸入的增益值無效或保留,返回錯(cuò)誤碼
return 0xFF;
}
// 如果用I2C等其他通信協(xié)議,可以調(diào)用相應(yīng)的寫入函數(shù)。
// 假設(shè)VD6283TX_write_reg是一個(gè)函數(shù),它寫入一個(gè)字節(jié)到指定的寄存器。
return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH3, &gain, 1);
}
/**
* @brief 設(shè)置VD6283的ALS通道4模擬增益
*
* @param add 設(shè)備地址
* @param gain 模擬增益值,對應(yīng)于上述描述中的AGAIN[4:0]
* @retval 操作的返回狀態(tài)
*/
uint8_t VD6283TX_setALSGainCH4(uint8_t add, uint8_t gain)
{
if (gain > 0x0F || gain == 0x00) {
// 輸入的增益值無效或保留,返回錯(cuò)誤碼
return 0xFF;
}
// 如果用I2C等其他通信協(xié)議,可以調(diào)用相應(yīng)的寫入函數(shù)。
// 假設(shè)VD6283TX_write_reg是一個(gè)函數(shù),它寫入一個(gè)字節(jié)到指定的寄存器。
return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH4, &gain, 1);
}
/**
* @brief 設(shè)置VD6283的ALS通道5模擬增益
*
* @param add 設(shè)備地址
* @param gain 模擬增益值,對應(yīng)于上述描述中的AGAIN[4:0]
* @retval 操作的返回狀態(tài)
*/
uint8_t VD6283TX_setALSGainCH5(uint8_t add, uint8_t gain)
{
if (gain > 0x0F || gain == 0x00) {
// 輸入的增益值無效或保留,返回錯(cuò)誤碼
return 0xFF;
}
// 如果用I2C等其他通信協(xié)議,可以調(diào)用相應(yīng)的寫入函數(shù)。
// 假設(shè)VD6283TX_write_reg是一個(gè)函數(shù),它寫入一個(gè)字節(jié)到指定的寄存器。
return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH5, &gain, 1);
}
/**
* @brief 設(shè)置VD6283的ALS通道6模擬增益
*
* @param add 設(shè)備地址
* @param gain 模擬增益值,對應(yīng)于上述描述中的AGAIN[4:0]
* @retval 操作的返回狀態(tài)
*/
uint8_t VD6283TX_setALSGainCH6(uint8_t add, uint8_t gain)
{
if (gain > 0x0F || gain == 0x00) {
// 輸入的增益值無效或保留,返回錯(cuò)誤碼
return 0xFF;
}
// 如果用I2C等其他通信協(xié)議,可以調(diào)用相應(yīng)的寫入函數(shù)。
// 假設(shè)VD6283TX_write_reg是一個(gè)函數(shù),它寫入一個(gè)字節(jié)到指定的寄存器。
return VD6283TX_write_reg(add, VD6283TX_ALS_GAIN_CH6, &gain, 1);
}
基準(zhǔn)配置
寄存配置可以通過寄存器0x32進(jìn)行配置。
這里配置為默認(rèn)值。
//光源的閃爍 默認(rèn)為3
VD6283TX_setPedestalValue(VD6283TX_ID,0x03);
具體操作如下所示。
// Pedestal Value Register
#define VD6283TX_PEDESTAL_VALUE 0x32
/**
* @brief 設(shè)置VD6283的pedestal值
*
* @param add 設(shè)備的I2C地址
* @param pdst_val 要設(shè)置的pedestal值 (位于[2:0]范圍內(nèi))
* @retval 操作的返回狀態(tài)(例如:成功或失?。? */
uint8_t VD6283TX_setPedestalValue(uint8_t add, uint8_t pdst_val)
{
// 驗(yàn)證輸入參數(shù)的有效性
if (pdst_val > 0x07) {
return 0xFF; // 錯(cuò)誤碼,表示無效的參數(shù)
}
// 假設(shè)有一個(gè)函數(shù)VD6283TX_write_reg,用于向給定的地址寫入一個(gè)字節(jié)
return VD6283TX_write_reg(add, VD6283TX_PEDESTAL_VALUE, &pdst_val, 1);
}
設(shè)置ALS曝光時(shí)間
VD6283給出了曝光時(shí)間的配置,寄存器位0x1d-0x1e。
配置100ms為0x003f(63),時(shí)間為(63+ 1) x 16384/10.24M=102.4ms。
//設(shè)置VD6283的ALS曝光時(shí)間
//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,設(shè)置為100ms
VD6283TX_setALSExposureTime(VD6283TX_ID, 0x003f) ;
具體操作如下所示。
// ALS Exposure Registers
#define VD6283TX_ALS_EXPOSURE_M 0x1D
#define VD6283TX_ALS_EXPOSURE_L 0x1E
/**
* @brief 設(shè)置VD6283的ALS曝光時(shí)間
*
* @param add 設(shè)備地址
* @param exTime 曝光時(shí)間計(jì)數(shù)值(EXTIME[9:0],不是實(shí)際的時(shí)間單位)
* @retval 操作的返回狀態(tài)
*
* 該函數(shù)用于控制VD6283的ALS曝光時(shí)間。寄存器地址從0x1D到0x1E。
* 寄存器的[9:0]位表示ALS的曝光時(shí)間。
* 默認(rèn)值對應(yīng)的曝光時(shí)間是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; // 低字節(jié)
data[1] = (exTime > > 8) & 0xFF; // 高字節(jié)
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有六個(gè),所以進(jìn)行使能時(shí)候需要根據(jù)所需要的通道進(jìn)行使能,主要寄存器為0x2d和0x2e。
這里將6個(gè)通道都開啟。
//設(shè)置VD6283的ALS通道使能狀態(tài)(1-5) 0x1F- >11111
VD6283TX_setALSChannelEnable(VD6283TX_ID, 0x1F);
//設(shè)置VD6283的ALS通道6使能狀態(tài)
VD6283TX_setChannel6Enable(VD6283TX_ID, 0x01);
函數(shù)如下所示。
// Channel 6 Enable Register
#define VD6283TX_CHANNEL6_ENABLE 0x2D
// ALS Channel Enable Register
#define VD6283TX_ALS_CHANNEL_ENABLE 0x2E
/**
* @brief 設(shè)置VD6283的通道6使能
*
* @param add 設(shè)備地址
* @param enable 1表示啟用通道6,0表示禁用通道6
* @retval 操作的返回狀態(tài)
*/
uint8_t VD6283TX_setChannel6Enable(uint8_t add, uint8_t enable)
{
uint8_t data;
if (enable > 1) {
// 輸入的使能值無效,返回錯(cuò)誤碼
return 0xFF;
}
// 根據(jù)enable參數(shù)來設(shè)置或清除CH6_EN位
if (enable) {
data |= 0x01; // 設(shè)置第0位
} else {
data &= ~0x01; // 清除第0位
}
// 使用I2C或其他通信協(xié)議寫回更改后的值。
// 假設(shè)VD6283TX_write_reg是一個(gè)函數(shù),用于向指定的寄存器寫入一個(gè)字節(jié)。
return VD6283TX_write_reg(add, VD6283TX_CHANNEL6_ENABLE, &data, 1);
}
/**
* @brief 設(shè)置VD6283的ALS通道使能狀態(tài)
*
* @param add 設(shè)備的I2C地址
* @param channels 一個(gè)字節(jié),其中位[4:0]表示要啟用的ALS通道
* @retval 操作的返回狀態(tài)(例如:成功或失敗)
*/
uint8_t VD6283TX_setALSChannelEnable(uint8_t add, uint8_t channels)
{
// 檢查channels的位[7:5]是否為0,因?yàn)檫@些位是保留的
if (channels & 0xE0) {
return 0xFF; // 錯(cuò)誤碼,表示無效的參數(shù)
}
// 假設(shè)有一個(gè)函數(shù)VD6283TX_write_reg,用于向給定的地址寫入一個(gè)字節(jié)
return VD6283TX_write_reg(add, VD6283TX_ALS_CHANNEL_ENABLE, &channels,1);
}
啟用ALS操作
寄存器0x03是選擇ALS的工作模式(單次測量或連續(xù)測量)并啟動(dòng)或停止ALS操作。
這里啟動(dòng)單次測量模式。
//啟用VD6283的ALS操作,使用ALS_CONT模式啟動(dòng)ALS操作。
VD6283TX_enableALSOperation(VD6283TX_ID, 0x01);
具體函數(shù)如下所示。
#define VD6283TX_ALS_CTRL 0x03
/**
* @brief 啟用或禁用VD6283的ALS操作
*
* @param add 設(shè)備地址
* @param enable 1啟用ALS操作,0禁用
* @retval 操作的返回狀態(tài)
*[0] ALS_EN (Enable ALS Operation): 啟用或禁用ALS操作。
*0: ALS操作已停止(即,空閑)。
*1: 使用ALS_CONT模式啟動(dòng)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);
}
中斷查詢及清除
當(dāng)信號(hào)準(zhǔn)備好時(shí)候可以查詢寄存器0x02進(jìn)行查詢。
可以通過查詢中斷方式判斷數(shù)據(jù)是否獲取完畢。
//獲取VD6283的中斷狀態(tài),等待INTR_ST為0
timeout = 0xffff;//溢出時(shí)間
while(1)
{
data=VD6283TX_getInterruptStatus(VD6283TX_ID);
timeout--;
if(data==0 || timeout==0)
break;
}
具體函數(shù)如下所示。
#define VD6283TX_INTERRUPT_CTRL 0x02
/**
* @brief 獲取VD6283的中斷狀態(tài)
*[1] INTR_ST (Interrupt Status): 該位表示中斷狀態(tài)。當(dāng)值為1時(shí),表示沒有觸發(fā)中斷或上一個(gè)中斷尚未清除。
*[0] CLR_INTR (Clear Interrupt): 該位用于清除中斷標(biāo)志。INTR_ST中斷標(biāo)志可以通過將CLR_INTR設(shè)置為'1',隨后設(shè)置為'0'來清除。
* @param add 設(shè)備地址
* @retval 中斷狀態(tài):1 表示沒有觸發(fā)中斷或上一個(gè)中斷尚未清除,0 則表示已清除或未設(shè)置。
*
*/
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的中斷標(biāo)志
VD6283TX_clearInterruptFlag(VD6283TX_ID);
具體函數(shù)如下所示。
/**
* @brief 清除VD6283的中斷標(biāo)志
*
* @param add 設(shè)備地址
* @retval 操作的返回狀態(tài)
*
*/
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數(shù)據(jù)
讀取環(huán)境光傳感器通1的數(shù)據(jù)值。數(shù)據(jù)值由三個(gè)字節(jié)組成,包括高、中和低字節(jié),共計(jì)24位。這可能意味著該通道可以提供非常高的測量精度,因?yàn)樗褂?4位來表示一個(gè)單一的測量值。
獲取方式如下所示。
//讀取VD6283的ALS通道數(shù)據(jù)
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數(shù)據(jù)
*
* @param add 設(shè)備地址
* @retval 返回?cái)?shù)值
*ALS channel 1 data register (ALS_CH1_DATA)
*
*這是一個(gè)只讀寄存器,用于讀取ALS通道1的數(shù)據(jù)。寄存器地址范圍是0x06到0x08,默認(rèn)值都是0x00。
*
*[23:16] ALS_CH1_DATA_H:ALS通道1的高字節(jié)數(shù)據(jù)。
*
*[15:8] ALS_CH1_DATA_M:ALS通道1的中字節(jié)數(shù)據(jù)。
*
*[7:0] ALS_CH1_DATA_L:ALS通道1的低字節(jié)數(shù)據(jù)
*/
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數(shù)據(jù)
*
* @param add 設(shè)備地址
* @param data 存儲(chǔ)讀取數(shù)據(jù)的數(shù)組,大小至少為3字節(jié)
* @retval 操作的返回狀態(tài)
*用于讀取ALS通道2的數(shù)據(jù)。寄存器地址范圍是0x0A到0x0C,默認(rèn)值都是0x00。
*
*[23:16] ALS_CH2_DATA_H:ALS通道2的高字節(jié)數(shù)據(jù)。
*
*[15:8] ALS_CH2_DATA_M:ALS通道2的中字節(jié)數(shù)據(jù)。
*
*[7:0] ALS_CH2_DATA_L:ALS通道2的低字節(jié)數(shù)據(jù)。
*/
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數(shù)據(jù)
*
* @param add 設(shè)備地址
* @param data 存儲(chǔ)讀取數(shù)據(jù)的數(shù)組,大小至少為3字節(jié)
* @retval 操作的返回狀態(tài)
*用于讀取ALS通道3的數(shù)據(jù)。寄存器地址范圍是0x0E到0x10,默認(rèn)值都是0x00。
*
*[23:16] ALS_CH3_DATA_H:ALS通道3的高字節(jié)數(shù)據(jù)。
*
*[15:8] ALS_CH3_DATA_M:ALS通道3的中字節(jié)數(shù)據(jù)。
*
*[7:0] ALS_CH3_DATA_L:ALS通道3的低字節(jié)數(shù)據(jù)。
*/
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數(shù)據(jù)
*
* @param add 設(shè)備地址
* @param data 存儲(chǔ)讀取數(shù)據(jù)的數(shù)組,大小至少為3字節(jié)
* @retval 操作的返回狀態(tài)
*用于讀取ALS通道4的數(shù)據(jù)。寄存器地址范圍是0x12到0x14,默認(rèn)值都是0x00。
*
*[23:16] ALS_CH4_DATA_H:ALS通道4的高字節(jié)數(shù)據(jù)。
*
*[15:8] ALS_CH4_DATA_M:ALS通道4的中字節(jié)數(shù)據(jù)。
*
*[7:0] ALS_CH4_DATA_L:ALS通道4的低字節(jié)數(shù)據(jù)。
*/
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數(shù)據(jù)
*
* @param add 設(shè)備地址
* @param data 存儲(chǔ)讀取數(shù)據(jù)的數(shù)組,大小至少為3字節(jié)
* @retval 操作的返回狀態(tài)
*用于讀取ALS通道5的數(shù)據(jù)。寄存器地址范圍是0x16到0x18,默認(rèn)值都是0x00。
*
*[23:16] ALS_CH5_DATA_H:ALS通道5的高字節(jié)數(shù)據(jù)。
*
*[15:8] ALS_CH5_DATA_M:ALS通道5的中字節(jié)數(shù)據(jù)。
*
*[7:0] ALS_CH5_DATA_L:ALS通道5的低字節(jié)數(shù)據(jù)。
*/
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數(shù)據(jù)
*
* @param add 設(shè)備地址
* @param data 存儲(chǔ)讀取數(shù)據(jù)的數(shù)組,大小至少為3字節(jié)
* @retval 操作的返回狀態(tài)
*用于讀取ALS通道6的數(shù)據(jù)。寄存器地址范圍是0x1A到0x1C,默認(rèn)值都是0x00。
*
*[23:16] ALS_CH6_DATA_H:ALS通道6的高字節(jié)數(shù)據(jù)。
*
*[15:8] ALS_CH6_DATA_M:ALS通道6的中字節(jié)數(shù)據(jù)。
*
*[7:0] ALS_CH6_DATA_L:ALS通道6的低字節(jié)數(shù)據(jù)。
*/
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;
}
計(jì)算光強(qiáng)及色溫
計(jì)算色溫(Correlated Color Temperature, CCT)的方法基于顏色科學(xué)和人類對顏色的感知。
這里移植了ST提供代碼,左邊為ST提供代碼,右邊為本項(xiàng)目代碼。
從RGB到XYZ:
RGB色彩空間是基于顯示設(shè)備(如電視和計(jì)算機(jī)屏幕)的顏色表示。然而,為了更廣泛、更精確地描述顏色(特別是在與人的視覺感知有關(guān)的情況下),科學(xué)家們使用了CIE 1931 XYZ色彩空間。
RGB到XYZ的轉(zhuǎn)換通常使用一個(gè)線性轉(zhuǎn)換矩陣。這是因?yàn)镽GB和XYZ都是線性色彩空間,所以可以通過一個(gè)線性關(guān)系(即矩陣乘法)從一個(gè)空間轉(zhuǎn)換到另一個(gè)空間。
為什么要使用XYZ空間:
XYZ色彩空間是一個(gè)設(shè)備無關(guān)的色彩空間,這意味著它不依賴于特定的顯示設(shè)備或光源。這使得它成為一個(gè)非常適合描述色彩和進(jìn)行色彩科學(xué)研究的空間。
其中,Y值與亮度或明度有關(guān),而X和Z與色彩有關(guān)。從XYZ值,我們可以計(jì)算出xy色度坐標(biāo),這些坐標(biāo)在CIE色度圖上描述了顏色的色調(diào)和飽和度。
計(jì)算CCT:
通過將XYZ轉(zhuǎn)換為xy色度坐標(biāo),我們可以在CIE色度圖上定位顏色。然后,我們可以使用McCamy的公式(或其他方法)來近似CCT。CCT基本上表示該顏色與哪種"色溫"的黑體輻射器最接近。例如,一個(gè)CCT值為6500K的光可能看起來與中午的陽光相似。
McCamy的公式是一個(gè)經(jīng)驗(yàn)公式,基于xy色度坐標(biāo)為輸入,并提供一個(gè)近似的CCT值。它是通過對多個(gè)實(shí)際樣本進(jìn)
在CIE 1931 XYZ色彩空間中,Y值通常與亮度或明度有關(guān),這也可以與光的強(qiáng)度或光照量(lux)聯(lián)系起來。
具體來說:
X, Y, Z 在XYZ色彩空間中分別代表三個(gè)維度的色彩信息。
Y 組件直接與感知亮度有關(guān)。在光學(xué)和顏色科學(xué)中,它經(jīng)常被用來代表一個(gè)光源或反射物的明度或亮度,因此,它可以與光照量(用lux度量)直接關(guān)聯(lián)。
當(dāng)我們在測量光源或環(huán)境光時(shí),這個(gè)Y 值可以被視為對于該光源的總亮度或光強(qiáng)的表示。
*
* @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 Kr", (long)Result- >cct);
fflush(stdout);
}
結(jié)果演示
審核編輯:湯梓紅
-
驅(qū)動(dòng)
+關(guān)注
關(guān)注
12文章
1840瀏覽量
85289 -
光強(qiáng)傳感器
+關(guān)注
關(guān)注
0文章
6瀏覽量
12741 -
環(huán)境光傳感器
+關(guān)注
關(guān)注
3文章
108瀏覽量
21912 -
驅(qū)動(dòng)開發(fā)
+關(guān)注
關(guān)注
0文章
130瀏覽量
12077 -
stm32cubemx
+關(guān)注
關(guān)注
5文章
283瀏覽量
14807
發(fā)布評論請先 登錄
相關(guān)推薦
評論