unless otherwise stated

博客内容主要是将英文短语‘unless stated stated’翻译成中文,其对应的中文表述为‘除非有特殊说明’。

翻译成中文就是:“除非有特殊说明”

/** * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause */ #include <stdio.h> #include "pico/stdlib.h" #include "pico/binary_info.h" #include "OPT4048.h" int main() { stdio_init_all(); sleep_ms(5000); printf("boot......\r\n"); rtrobot_i2c_init(); if (OPT4048_Init() == false) printf("OPT4048 initialize error.\r\n"); else printf("OPT4048 initialize register finished.\r\n"); OPT4048_Setting_Configure( OPT4048_RANGE_AUTO | OPT4048_CONV_TIME_100MS | OPT4048_MODE_CONTINUOUS | OPT4048_LATCH_ON | OPT4048_POL_LOW | OPT4048_FAULT_COUNT_1, // Cconfigure for 0x0A OPT4048_INT_Dir_OUTPUT | OPT4048_INT_SMBUS | OPT4048_I2C_BURST_ENABLE // Cconfigure for 0x0B ); while (true) { if (OPT4048_Get_Ready() == OPT4048_INT_CONV_READY_FLAG) { OPT4048_Data_t data; OPT4048_Read_Data(&data); printf("CIEX:%f;CIEY:%f;LUX:%f;CCT:%f\r\n", data.cie_x, data.cie_y, data.lux, data.cct); } sleep_ms(10); } return 0; } /********************************************************* * OPT4048.c * Copyright (c) 2012 - 2025 RTrobot Inc. * * Unless otherwise stated, the use of this software is subject to the following conditions: * 1. Any form of redistribution must include the original copyright notice and the following disclaimer. * 2. Not for commercial use without explicit written permission, including but not limited to sales, licensing, or commercial support. * 3. Any modifications to this software must be clearly marked with attribution and documented in the modified files. * 4. If modifications are made, they must be clearly indicated in the modified files. * 5. Without explicit written permission, the names of the authors or original contributors may not be used to endorse or promote derived products. * * This software is provided "as is," without any warranties of any kind, express or implied, including but not limited to the warranties of merchantability or fitness for a particular purpose. * The authors are not liable for any direct, indirect, incidental, special, exemplary, or consequential damages arising in any way out of the use of this software. *********************************************************/ #include "OPT4048.h" #include <stdbool.h> #include <stdio.h> #include "hardware/i2c.h" #include "pico/stdlib.h" #include "pico/binary_info.h" #include <malloc.h> const double cieMatrix[4][4] = { { 2.34892992e-04, -1.89652390e-05, 1.20811684e-05, 0.0 }, { 4.07467441e-05, 1.98958202e-04, -1.58848115e-05, 2.15e-3 }, { 9.28619404e-05, -1.69739553e-05, 6.74021520e-04, 0.0 }, { 0.0, 0.0, 0.0, 0.0 } }; /*************************************************************************************************************** i2c master initialization ****************************************************************************************************************/ void rtrobot_i2c_init(void) { i2c_init(i2c_default, 50 * 1000); gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C); gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C); gpio_pull_up(PICO_DEFAULT_I2C_SDA_PIN); gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN); bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C)); } /*************************************************************************************************************** tmf8806 Read Command ****************************************************************************************************************/ int8_t rtrobot_i2c_read_command(uint8_t reg_addr, uint8_t* rev_data, uint8_t length) { i2c_write_blocking(i2c_default, OPT4048_I2CADDR, &reg_addr, 1, true); // sleep_ms(15); return i2c_read_blocking(i2c_default, OPT4048_I2CADDR, rev_data, length, false); } /*************************************************************************************************************** tmf8806 Write Command ****************************************************************************************************************/ int8_t rtrobot_i2c_write_command(uint8_t reg_addr, uint8_t* send_data, uint16_t length) { int8_t status; uint8_t *reg = malloc(length + 2); reg[0] = reg_addr; for (int i = 0; i < length; i++) reg[i + 1] = send_data[i]; status = i2c_write_blocking(i2c_default, OPT4048_I2CADDR, reg, length + 1, false); free(reg); } void rtrobot_delay_ms(uint32_t ms) { sleep_ms(ms); } int8_t OPT4048_i2c_read(uint8_t reg_addr, uint16_t* rev_data) { uint8_t tmp[2] = { 0 }; int8_t status = 0; status = rtrobot_i2c_read_command(reg_addr, tmp, 2); *rev_data = (tmp[0] << 8) | tmp[1]; return status; } int8_t OPT4048_i2c_write(uint8_t reg_addr, const uint16_t* send_data) { uint8_t tmp[2] = { *send_data >> 8, *send_data & 0xff }; int8_t status = 0; status = rtrobot_i2c_write_command(reg_addr, tmp, 2); return status; } /*************************************************************************************************************** OPT4048 Setting Configure ****************************************************************************************************************/ void OPT4048_Setting_Configure(uint16_t config_msb, uint16_t config_lsb) { OPT4048_i2c_write(OPT4048_REG_CONFIG_MSB, &config_msb); config_lsb = config_lsb | 0x8000; OPT4048_i2c_write(OPT4048_REG_CONFIG_LSB, &config_lsb); } /*************************************************************************************************************** OPT4048 Get Ready ****************************************************************************************************************/ OPT4048_INTStatus_t OPT4048_Get_Ready(void) { uint16_t status; OPT4048_i2c_read(OPT4048_REG_INT_FLAG, &status); return (OPT4048_INTStatus_t)status; } /*************************************************************************************************************** OPT4048 Read Raw Data ****************************************************************************************************************/ void OPT4048_Read_Raw_Data(OPT4048_RawData_t* raw_data) { uint16_t reg_msb, reg_lsb; for (int i = 0; i < 4; ++i) { OPT4048_i2c_read(OPT4048_REG_RESULT_CH0_MSB + (i * 2), &reg_msb); OPT4048_i2c_read(OPT4048_REG_RESULT_CH0_LSB + (i * 2), &reg_lsb); raw_data->exponent[i] = (reg_msb >> 12) & 0x0F; raw_data->mantissa[i] = ((uint32_t)(reg_msb & 0x0FFF) << 8) | ((reg_lsb >> 8) & 0xFF); raw_data->counter[i] = (reg_lsb >> 4) & 0x0F; raw_data->crc[i] = reg_lsb & 0x0F; } } /*************************************************************************************************************** OPT4048 Calculate Linear ADC ADC_CODES_CHx = MANTISSA_CHx * 2^EXPONENT_CHx ****************************************************************************************************************/ double OPT4048_Calculate_Linear_ADC(uint8_t exponent, uint32_t mantissa) { //why do this? not use pow. because you don't need to use the math library --RTrobot return (double)mantissa * exponent * exponent; } /*************************************************************************************************************** OPT4048 Calculate Lux Lux can be simply calculated using the following equation lux = adc_codes_ch1 x 2.15e-3 from database 8.3.4.5 ****************************************************************************************************************/ double OPT4048_Calculate_Lux(double ch1_adc) { return ch1_adc * 2.15e-3; } /*************************************************************************************************************** OPT4048 Calculate CIE from database 8.3.4.5 ****************************************************************************************************************/ void OPT4048_Calculate_CIE(OPT4048_Data_t* data) { double X = 0.0, Y = 0.0, Z = 0.0; X = data->adc_code_ch[0] * cieMatrix[0][0] + data->adc_code_ch[1] * cieMatrix[1][0] + data->adc_code_ch[2] * cieMatrix[2][0] + data->adc_code_ch[3] * cieMatrix[3][0]; Y = data->adc_code_ch[0] * cieMatrix[0][1] + data->adc_code_ch[1] * cieMatrix[1][1] + data->adc_code_ch[2] * cieMatrix[2][1] + data->adc_code_ch[3] * cieMatrix[3][1]; Z = data->adc_code_ch[0] * cieMatrix[0][2] + data->adc_code_ch[1] * cieMatrix[1][2] + data->adc_code_ch[2] * cieMatrix[2][2] + data->adc_code_ch[3] * cieMatrix[3][2]; double sum = X + Y + Z; if (sum > 1e-9) { data->cie_x = X / sum; data->cie_y = Y / sum; } else { data->cie_x = 0.0; data->cie_y = 0.0; } } /*************************************************************************************************************** OPT4048 Calculate CIE from database 8.3.4.5 ****************************************************************************************************************/ void OPT4048_Calculate_CCT(OPT4048_Data_t* data) { double n = (data->cie_x - 0.3320) / (0.1858 - data->cie_y); //why do this? not use pow. because you don't need to use the math library --RTrobot data->cct = 437 * n * n * n + 3601 * n * n + 6861 * n + 5517; } /*************************************************************************************************************** OPT4048 Read_Data ****************************************************************************************************************/ void OPT4048_Read_Data(OPT4048_Data_t* data) { OPT4048_RawData_t raw; OPT4048_Read_Raw_Data(&raw); // Calculate linearized ADC codes for all channels data->adc_code_ch[0] = OPT4048_Calculate_Linear_ADC(raw.exponent[0], raw.mantissa[0]); // Ch0 = X data->adc_code_ch[1] = OPT4048_Calculate_Linear_ADC(raw.exponent[1], raw.mantissa[1]); // Ch1 = Y data->adc_code_ch[2] = OPT4048_Calculate_Linear_ADC(raw.exponent[2], raw.mantissa[2]); // Ch2 = Z data->adc_code_ch[3] = OPT4048_Calculate_Linear_ADC(raw.exponent[3], raw.mantissa[3]); // Ch3 = W // Calculate Lux data->lux = OPT4048_Calculate_Lux(data->adc_code_ch[1]); // Calculate CIE X, Y OPT4048_Calculate_CIE(data); // Calculate CCT OPT4048_Calculate_CCT(data); if (data->lux < 0.0) data->lux = 0.0; if (data->cct < 0.0) data->cct = 0.0; if (data->cie_x < 0.0) data->cie_x = 0.0; if (data->cie_y < 0.0) data->cie_y = 0.0; } /*************************************************************************************************************** OPT4048 Init Command ****************************************************************************************************************/ bool OPT4048_Init(void) { uint16_t device_id; OPT4048_i2c_read(OPT4048_REG_DEVICE_ID, &device_id); if (device_id != 0x821) return false; return true; } /********************************************************* * OPT4048.h * Copyright (c) 2012 - 2025 RTrobot Inc. * * Unless otherwise stated, the use of this software is subject to the following conditions: * 1. Any form of redistribution must include the original copyright notice and the following disclaimer. * 2. Not for commercial use without explicit written permission, including but not limited to sales, licensing, or commercial support. * 3. Any modifications to this software must be clearly marked with attribution and documented in the modified files. * 4. If modifications are made, they must be clearly indicated in the modified files. * 5. Without explicit written permission, the names of the authors or original contributors may not be used to endorse or promote derived products. * * This software is provided "as is," without any warranties of any kind, express or implied, including but not limited to the warranties of merchantability or fitness for a particular purpose. * The authors are not liable for any direct, indirect, incidental, special, exemplary, or consequential damages arising in any way out of the use of this software. *********************************************************/ #ifndef OPT4048_H #define OPT4048_H #include <stdbool.h> #include "pico/stdlib.h" #define OPT4048_I2CADDR 0x44 #define OPT4048_REG_RESULT_CH0_MSB 0x00 #define OPT4048_REG_RESULT_CH0_LSB 0x01 #define OPT4048_REG_RESULT_CH1_MSB 0x02 #define OPT4048_REG_RESULT_CH1_LSB 0x03 #define OPT4048_REG_RESULT_CH2_MSB 0x04 #define OPT4048_REG_RESULT_CH2_LSB 0x05 #define OPT4048_REG_RESULT_CH3_MSB 0x06 #define OPT4048_REG_RESULT_CH3_LSB 0x07 #define OPT4048_REG_THRESH_LOW_LSB 0x08 #define OPT4048_REG_THRESH_LOW_MSB 0x09 #define OPT4048_REG_CONFIG_MSB 0x0A #define OPT4048_REG_CONFIG_LSB 0x0B #define OPT4048_REG_INT_FLAG 0x0C #define OPT4048_REG_DEVICE_ID 0x11 typedef enum { OPT4048_RANGE_2_25K = 0x0000, // 2.25 klux OPT4048_RANGE_4_5K = 0x0400, // 4.51 klux OPT4048_RANGE_9K = 0x0800, // 9.02 klux OPT4048_RANGE_18K = 0x0C00, // 18.0 klux OPT4048_RANGE_36K = 0x1000, // 36.1 klux OPT4048_RANGE_72K = 0x1400, // 72.1 klux OPT4048_RANGE_144K = 0x1800, // 144 klux OPT4048_RANGE_AUTO = 0x3000 // AUTO Range } OPT4048_Range_t; typedef enum { OPT4048_CONV_TIME_600US = 0x0000, OPT4048_CONV_TIME_1MS = 0x0040, OPT4048_CONV_TIME_1_8MS = 0x0080, OPT4048_CONV_TIME_3_4MS = 0x00C0, OPT4048_CONV_TIME_6_5MS = 0x0100, OPT4048_CONV_TIME_12_7MS = 0x0140, OPT4048_CONV_TIME_25MS = 0x0180, OPT4048_CONV_TIME_50MS = 0x01C0, OPT4048_CONV_TIME_100MS = 0x0200, OPT4048_CONV_TIME_200MS = 0x0240, OPT4048_CONV_TIME_400MS = 0x0280, OPT4048_CONV_TIME_800MS = 0x02C0 } OPT4048_ConversionTime_t; typedef enum { OPT4048_MODE_POWERDOWN = 0x0000, OPT4048_MODE_FORCED_ONESHOT = 0x0010, OPT4048_MODE_ONESHOT = 0x0020, OPT4048_MODE_CONTINUOUS = 0x0030 } OPT4048_OperatingMode_t; typedef enum { OPT4048_LATCH_OFF = 0x0000, OPT4048_LATCH_ON = 0x0008 } OPT4048_LatchMode_t; typedef enum { OPT4048_POL_LOW = 0x0000, OPT4048_POL_HIGH = 0x0004 } OPT4048_IntPolarity_t; typedef enum { OPT4048_FAULT_COUNT_1 = 0x0, OPT4048_FAULT_COUNT_2 = 0x1, OPT4048_FAULT_COUNT_4 = 0x2, OPT4048_FAULT_COUNT_8 = 0x3 } OPT4048_FaultCount_t; typedef enum { OPT4048_INT_Dir_INPUT = 0x0000, OPT4048_INT_Dir_OUTPUT = 0x0010 } OPT4048_INTDirection_t; typedef enum { OPT4048_INT_SMBUS = 0x0000, OPT4048_INT_RDY_NEXT = 0x0004, OPT4048_INT_RDY_ALL = 0x000C, } OPT4048_INTConfig_t; typedef enum { OPT4048_I2C_BURST_DISABLE = 0x0000, OPT4048_I2C_BURST_ENABLE = 0x0001 } OPT4048_I2CBurst_t; typedef enum { OPT4048_INT_OVERLOAD_FLAG = 0x0008, OPT4048_INT_CONV_READY_FLAG = 0x0004, OPT4048_INT_THRESHOLD_HIGH_FLAG = 0x0002, OPT4048_INT_THRESHOLD_LOW_FLAG = 0x0001, } OPT4048_INTStatus_t; typedef struct { uint8_t exponent[4]; // Exponent for Ch0 (X), Ch1 (Y), Ch2 (Z), Ch3 (W) uint32_t mantissa[4]; // Mantissa (20-bit) for Ch0, Ch1, Ch2, Ch3 uint8_t counter[4]; // Sample counter (4-bit) for each channel uint8_t crc[4]; // CRC (4-bit) for each channel (Optional usage) } OPT4048_RawData_t; typedef struct { double lux; // Ambient Light Intensity in Lux (calculated from Ch1/Y) double cie_x; // CIE X coordinate double cie_y; // CIE Y coordinate double adc_code_ch[4]; double cct; //Correlated Color Temperature } OPT4048_Data_t; void rtrobot_i2c_init(void); bool OPT4048_Init(void); void OPT4048_Setting_Configure(uint16_t config_msb, uint16_t config_lsb); OPT4048_INTStatus_t OPT4048_Get_Ready(void); void OPT4048_Read_Data(OPT4048_Data_t* data); #endif //OPT4048_H 1、0x0A和0x0B寄存器的值是多少;2、用数学表达式表达cie_x和cie_y
07-25
/* sfe_opt4048.h SparkFun Tristimulus Color Sensor - OPT4048 Qwiic 1x1 * https://www.sparkfun.com/products/ Qwiic Mini * https://www.sparkfun.com/products/ Repository: * https://github.com/sparkfun/SparkFun_OPT4048_Arduino_Library The MIT License (MIT) Copyright (c) 2022 SparkFun Electronics Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. License(http://opensource.org/licenses/MIT). The following QwOpt4048 class defines the main main functionality for the OPT4048 IC. This file also includes the type definitions for function parameters as well as data types for the color data. */ #pragma once #include "OPT4048_Registers.h" #include "sfe_bus.h" #include <Wire.h> /// @brief Struct used to store the color data from the OPT4048. typedef struct { uint32_t red; uint32_t green; uint32_t blue; uint32_t white; uint8_t counterR; // Sample counter uint8_t counterG; uint8_t counterB; uint8_t counterW; uint8_t CRCR; uint8_t CRCG; uint8_t CRCB; uint8_t CRCW; } sfe_color_t; /// @brief Union used to re-calculate the CRC for optional double check. typedef union { struct { uint8_t bit0 : 1; uint8_t bit1 : 1; uint8_t bit2 : 1; uint8_t bit3 : 1; }; uint8_t byte; } crcBits; /// @brief Union used to re-calculate the CRC for optional double check. typedef union { struct { uint8_t bit0 : 1; uint8_t bit1 : 1; uint8_t bit2 : 1; uint8_t bit3 : 1; }; uint8_t byte; } exponBits; /// @brief Union used to re-calculate the CRC for optional double check. typedef union { struct { uint8_t bit0 : 1; uint8_t bit1 : 1; uint8_t bit2 : 1; uint8_t bit3 : 1; uint8_t bit4 : 1; uint8_t bit5 : 1; uint8_t bit6 : 1; uint8_t bit7 : 1; uint8_t bit8 : 1; uint8_t bit9 : 1; uint8_t bit10 : 1; uint8_t bit11 : 1; uint8_t bit12 : 1; uint8_t bit13 : 1; uint8_t bit14 : 1; uint8_t bit15 : 1; uint8_t bit16 : 1; uint8_t bit17 : 1; uint8_t bit18 : 1; uint8_t bit19 : 1; }; uint32_t word; } mantissaBits; class QwOpt4048 { public: QwOpt4048() : _sfeBus(nullptr), _i2cAddress(0) {}; /// @brief Sets the struct that interfaces with STMicroelectronic's C Library. /// @return true on successful execution. bool init(); /// @brief Checks that the bus is connected with the OPT4048 by checking /// it's unique ID. /// @return True on successful execution. bool isConnected(); /// @brief Retrieves the the device's ID: 0x24 for the OPT4048. /// @return Returns the unique ID. uint16_t getDeviceID(); /// @brief Sets the pointer to the data bus for read and writes. /// @param theBus This parameter sets the the I2C hardware bus. /// @param i2cAddress The I2C address for the device. void setCommunicationBus(sfe_OPT4048::QwDeviceBus &theBus, uint8_t i2cAddress); /// @brief Sets the pointer to the data bus for read and writes. /// @param theBus This parameter sets the hardware bus. void setCommunicationBus(sfe_OPT4048::QwDeviceBus &theBus); /// @brief Writes to the data to the given register using the hardware data bus. /// @param offset The register to write to. /// @param data The data to write to the register. /// @param length The number of writes /// @return The successful (0) or unsuccessful (-1) write to the given register. int32_t writeRegisterRegion(uint8_t offset, uint8_t *data, uint16_t length = 2); /// @brief Reads data from the specified register using the set data bas. /// @param offset The register to read from. /// @param data The pointer to the value to store the value. /// @param length The number of reads /// @return The successful (0) or unsuccessful (-1) read of the given register. int32_t readRegisterRegion(uint8_t offset, uint8_t *data, uint16_t numBytes = 2); ///////////////////////////////////////////////////////////////////Device Settings /// @brief Sets the minimum of settings to get the board running. void setBasicSetup(); /// @brief Sets the OPT4048's effective sensing range which will effect its resolution. /// @param range The range to set the device to. /// @return True on successful execution. bool setQwake(bool enable = true); /// @brief Retrieves the light range in lux of the OPT4048. /// @return The range of lux able to be measured. bool getQwake(); /// @brief Sets the OPT4048's effective sensing range which will effect its resolution. /// @param range The range to set the device to. /// RANGE_2KLUX2, /// RANGE_4KLUX5, /// RANGE_9LUX, /// RANGE_18LUX, /// RANGE_36LUX, /// RANGE_72LUX, /// RANGE_144LUX, /// RANGE_AUTO /// @return True on successful execution. bool setRange(opt4048_range_t range); /// @brief Retrieves the light range in lux of the OPT4048. /// @return The range of lux able to be measured. opt4048_range_t getRange(); /// @brief Sets the OPT4048's conversion time which will effect its resolution. Longer conversion time /// will result in higher resolution. /// @param time The conversion time to set the device to. Possible values: /// CONVERSION_TIME_600US, /// CONVERSION_TIME_1MS, /// CONVERSION_TIME_1MS8, /// CONVERSION_TIME_3MS4, /// CONVERSION_TIME_6MS5, /// CONVERSION_TIME_12MS7, /// CONVERSION_TIME_25MS, /// CONVERSION_TIME_50MS, /// CONVERSION_TIME_100MS, /// CONVERSION_TIME_200MS, /// CONVERSION_TIME_400MS, /// CONVERSION_TIME_800MS /// @return True on successful execution. bool setConversionTime(opt4048_conversion_time_t time); /// @brief Retrieves the conversion time used for the ADC. /// @return The OPT4048 conversion time. opt4048_conversion_time_t getConversionTime(); /// @brief Sets the OPT4048's operation mode. /// @param mode The mode to set the device to. Possible Values: /// OPERATION_MODE_POWER_DOWN, /// OPERATION_MODE_AUTO_ONE_SHOT, /// OPERATION_MODE_ONE_SHOT, /// OPERATION_MODE_CONTINUOUS /// @return bool setOperationMode(opt4048_operation_mode_t mode); /// @brief Retrieves the set operation mode. /// @return The OPT4048 conversion time. opt4048_operation_mode_t getOperationMode(); /// @brief Changes the behavior of the interrupt from pin to latch. /// @param set True to enable, false to disable. /// @return True on successful execution. bool setIntLatch(bool enable = true); /// @brief Checks if the interrupt is set to pulse or latch. /// @return True if set to latch, false if not. bool getIntLatch(); /// @brief Sets the OPT4048's interrupt polarity. /// @param set True to enable, false to disable. /// @return True on successful execution. bool setIntActiveHigh(bool enable = true); /// @brief Sets the OPT4048's interrupt polarity. /// @param set True to enable, false to disable. /// @return True on successful execution. bool getIntActiveHigh(); /// @brief Sets the number of faults (light values over or under) before an interrupt is triggered. /// @param count The number of faults to trigger an interrupt /// FAULT_COUNT_1, /// FAULT_COUNT_2, /// FAULT_COUNT_4, /// FAULT_COUNT_8 /// @return True on successful execution. bool setFaultCount(opt4048_fault_count_t count); /// @brief Retrieves the number of faults (light values over or under) before /// an interrupt is triggered. /// @return The fault count. opt4048_fault_count_t getFaultCount(); /// @brief Sets the channel for threshold logic /// @param channel The channel to set the threshold logic to. /// THRESH_CHANNEL_CH0, /// THRESH_CHANNEL_CH1, /// THRESH_CHANNEL_CH2, /// THRESH_CHANNEL_CH3 /// @return True on successful execution. bool setThresholdChannel(opt4048_threshold_channel_t channel); /// @brief Retrives the threshold channel. /// @return THe selected channel. opt4048_threshold_channel_t getThresholdChannel(); /// @brief Sets the Lux High Value threshold. /// @param thresh The value in float /// @return Returns the high threshold. bool setThresholdHigh(float thresh); /// @brief Retrieves the Lux High Value threshold. /// @return Returns the high threshold. uint16_t getThresholdHigh(); /// @brief Sets the Lux Low Value threshold. /// @param thresh The value in float /// @return Returns the high threshold. bool setThresholdLow(float thresh); /// @brief Retrieves the Lux Low Value threshold. /// @return Returns the low threshold. uint16_t getThresholdLow(); /// @brief Enable CRC for ADC calues /// @param set True to enable, false to disable. /// @return True on successful execution. void setCRC(bool enable = true); ///////////////////////////////////////////////////////////////////Interrupt Settings /// @brief Changes the behavior of the interrupt pin to be an INPUT to trigger single shot. /// @param set True to enable, false to disable. /// @return True on successful execution. bool setIntInput(bool enable = true); /// @brief Gets the interrupt input bit /// @return True if the interrupt is set to INPUT. bool getIntInputEnable(); /// @brief Changes the behavior interrupt mechanism after the end of conversion /// @param mechanism The mechanism to set /// @return True on successful execution. bool setIntMechanism(opt4048_int_cfg_t mechanism); /// @brief Gets the interrupt mechanism for the OPT4048 /// @return Returns the setd mechanism. opt4048_int_cfg_t getIntMechanism(); /// @brief Enable register auto increment . /// @param set True to enable, false to disable. /// @return True on successful execution. bool setI2CBurst(bool enable = true); /// @brief Retrieves the I2C burst bit. /// @return True if I2C burst is setd, false otherwise. bool getI2CBurst(); /// @brief Retrieves the flag register /// @return The contents of the flag register opt4048_reg_flags_t getAllFlags(); /// @brief Checks the overload flag bit. /// @return True if the overload flag bit is set, false otherwise bool getOverloadFlag(); /// @brief Checks the conversion ready flag bit. /// @return True if that flag bit is set, false otherwise bool getConvReadyFlag(); /// @brief Checks the too bright flag bit. /// @return True if that flag bit is set, false otherwise bool getTooBrightFlag(); /// @brief Checks the too dim flag bit. /// @return True if that flag bit is set, false otherwise bool getTooDimFlag(); ///////////////////////////////////////////////////////////////////Color Information /// @brief Reads Channel Zero (Red) /// @return Returns the ADC value of Channel Zero uint32_t getADCCh0(); /// @brief Reads Channel One (Green) /// @return Returns the ADC value of Channel One uint32_t getADCCh1(); /// @brief Reads Channel Two (Blue) /// @return Returns the ADC value of Channel Two uint32_t getADCCh2(); /// @brief Reads Channel Three (White) /// @return Returns the ADC value of Channel Three uint32_t getADCCh3(); /// @brief Retrieves all ADC values for all channels: Red, Green, Blue, and White. /// @return Returns the ADC values of the channels. sfe_color_t getAllADC(); /// @brief Retrieves all ADC values for all channels: Red, Green, Blue, and White, as well as the sample counter, /// and /// the CRC value. /// @param color Pointer to the color struct to be populated with the channels values. /// @return Returns true on successful execution, false otherwise. bool getAllChannelData(sfe_color_t *color); /// @brief Calculates the CRC for the OPT4048. Note that the OPT4048 does this already /// but this is a way to double check the value. /// @param mantissa The mantissa value of the ADC /// @param exponent The exponent value of the ADC /// @param crc The CRC value of the ADC /// @return Returns the calculated CRC value. bool calculateCRC(uint32_t manitssa, uint8_t expon, uint8_t crc); /// @brief Retrieves the Lux value. /// @return Returns the Lux value of the sensor uint32_t getLux(); /// @brief Retrieves the CIE X value of the sensor. /// @return Returns the CIE X value of the sensor double getCIEx(); /// @brief Retrieves the CIE Y value of the sensor. /// @return Returns the CIE Y value of the sensor double getCIEy(); /// @brief Retrieves the Correlated Color Temperature (CCT) of the sensor. /// @return Returns the CCT of the sensor in Kelvin double getCCT(); private: sfe_OPT4048::QwDeviceBus *_sfeBus; uint8_t _i2cAddress; bool crcEnabled = false; static constexpr uint8_t kOPTMatrixRows = 4; static constexpr uint8_t kOPTMatrixCols = 4; // Table in 9.2.4 of Datasheet for calculating CIE x and y, and Lux. const double cieMatrix[kOPTMatrixRows][kOPTMatrixCols] = {{.000234892992, -.0000189652390, .0000120811684, 0}, {.0000407467441, .000198958202, -.0000158848115, .00215}, {.0000928619404, -.0000169739553, .000674021520, 0}, {0, 0, 0, 0}}; }; /* sfe_bus.h SparkFun Tristimulus Color Sensor - OPT4048 Qwiic 1x1 * https://www.sparkfun.com/products/ Qwiic Mini * https://www.sparkfun.com/products/ Repository: * https://github.com/sparkfun/SparkFun_OPT4048_Arduino_Library The MIT License (MIT) Copyright (c) 2022 SparkFun Electronics Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. License(http://opensource.org/licenses/MIT). The following class specifies behavior for communicating over Inter-Integrated Circuit (I2C). */ #pragma once #include <Wire.h> #include <Arduino.h> #include <stdint.h> namespace sfe_OPT4048 { /// @brief This is an abstract interface for the I2C bus. class QwDeviceBus { public: virtual bool ping(uint8_t address) = 0; virtual int writeRegisterRegion(uint8_t address, uint8_t offset, uint8_t *data, uint16_t length) = 0; virtual int readRegisterRegion(uint8_t addr, uint8_t reg, uint8_t *data, uint16_t numBytes) = 0; }; /// @brief This class implements the I2C interface for the OPT4048 class QwI2C : public QwDeviceBus { public: QwI2C(void) : _i2cPort(nullptr) {}; bool init(); bool init(TwoWire &wirePort, bool bInit = false); bool ping(uint8_t address); int writeRegisterRegion(uint8_t address, uint8_t offset, uint8_t *data, uint16_t length); int readRegisterRegion(uint8_t addr, uint8_t reg, uint8_t *data, uint16_t numBytes); private: TwoWire *_i2cPort; }; } // namespace sfe_OPT4048 /********************************************************* * OPT4048.h * Copyright (c) 2012 - 2025 RTrobot Inc. * * Unless otherwise stated, the use of this software is subject to the following conditions: * 1. Any form of redistribution must include the original copyright notice and the following disclaimer. * 2. Not for commercial use without explicit written permission, including but not limited to sales, licensing, or commercial support. * 3. Any modifications to this software must be clearly marked with attribution and documented in the modified files. * 4. If modifications are made, they must be clearly indicated in the modified files. * 5. Without explicit written permission, the names of the authors or original contributors may not be used to endorse or promote derived products. * * This software is provided "as is," without any warranties of any kind, express or implied, including but not limited to the warranties of merchantability or fitness for a particular purpose. * The authors are not liable for any direct, indirect, incidental, special, exemplary, or consequential damages arising in any way out of the use of this software. *********************************************************/ #ifndef OPT4048_H #define OPT4048_H #include "main.h" #include <stdbool.h> #define OPT4048_I2CADDR 0x44 #define OPT4048_REG_RESULT_CH0_MSB 0x00 #define OPT4048_REG_RESULT_CH0_LSB 0x01 #define OPT4048_REG_RESULT_CH1_MSB 0x02 #define OPT4048_REG_RESULT_CH1_LSB 0x03 #define OPT4048_REG_RESULT_CH2_MSB 0x04 #define OPT4048_REG_RESULT_CH2_LSB 0x05 #define OPT4048_REG_RESULT_CH3_MSB 0x06 #define OPT4048_REG_RESULT_CH3_LSB 0x07 #define OPT4048_REG_THRESH_LOW_LSB 0x08 #define OPT4048_REG_THRESH_LOW_MSB 0x09 #define OPT4048_REG_CONFIG_MSB 0x0A #define OPT4048_REG_CONFIG_LSB 0x0B #define OPT4048_REG_INT_FLAG 0x0C #define OPT4048_REG_DEVICE_ID 0x11 typedef enum { OPT4048_RANGE_2_25K = 0x0000, // 2.25 klux OPT4048_RANGE_4_5K = 0x0400, // 4.51 klux OPT4048_RANGE_9K = 0x0800, // 9.02 klux OPT4048_RANGE_18K = 0x0C00, // 18.0 klux OPT4048_RANGE_36K = 0x1000, // 36.1 klux OPT4048_RANGE_72K = 0x1400, // 72.1 klux OPT4048_RANGE_144K = 0x1800, // 144 klux OPT4048_RANGE_AUTO = 0x3000 // AUTO Range } OPT4048_Range_t; typedef enum { OPT4048_CONV_TIME_600US = 0x0000, OPT4048_CONV_TIME_1MS = 0x0040, OPT4048_CONV_TIME_1_8MS = 0x0080, OPT4048_CONV_TIME_3_4MS = 0x00C0, OPT4048_CONV_TIME_6_5MS = 0x0100, OPT4048_CONV_TIME_12_7MS = 0x0140, OPT4048_CONV_TIME_25MS = 0x0180, OPT4048_CONV_TIME_50MS = 0x01C0, OPT4048_CONV_TIME_100MS = 0x0200, OPT4048_CONV_TIME_200MS = 0x0240, OPT4048_CONV_TIME_400MS = 0x0280, OPT4048_CONV_TIME_800MS = 0x02C0 } OPT4048_ConversionTime_t; typedef enum { OPT4048_MODE_POWERDOWN = 0x0000, OPT4048_MODE_FORCED_ONESHOT = 0x0010, OPT4048_MODE_ONESHOT = 0x0020, OPT4048_MODE_CONTINUOUS = 0x0030 } OPT4048_OperatingMode_t; typedef enum { OPT4048_LATCH_OFF = 0x0000, OPT4048_LATCH_ON = 0x0008 } OPT4048_LatchMode_t; typedef enum { OPT4048_POL_LOW = 0x0000, OPT4048_POL_HIGH = 0x0004 } OPT4048_IntPolarity_t; typedef enum { OPT4048_FAULT_COUNT_1 = 0x0, OPT4048_FAULT_COUNT_2 = 0x1, OPT4048_FAULT_COUNT_4 = 0x2, OPT4048_FAULT_COUNT_8 = 0x3 } OPT4048_FaultCount_t; typedef enum { OPT4048_INT_Dir_INPUT = 0x0000, OPT4048_INT_Dir_OUTPUT = 0x0010 } OPT4048_INTDirection_t; typedef enum { OPT4048_INT_SMBUS = 0x0000, OPT4048_INT_RDY_NEXT = 0x0004, OPT4048_INT_RDY_ALL = 0x000C, } OPT4048_INTConfig_t; typedef enum { OPT4048_I2C_BURST_DISABLE = 0x0000, OPT4048_I2C_BURST_ENABLE = 0x0001 } OPT4048_I2CBurst_t; typedef enum { OPT4048_INT_OVERLOAD_FLAG = 0x0008, OPT4048_INT_CONV_READY_FLAG = 0x0004, OPT4048_INT_THRESHOLD_HIGH_FLAG = 0x0002, OPT4048_INT_THRESHOLD_LOW_FLAG = 0x0001, } OPT4048_INTStatus_t; typedef struct { uint8_t exponent[4]; // Exponent for Ch0 (X), Ch1 (Y), Ch2 (Z), Ch3 (W) uint32_t mantissa[4]; // Mantissa (20-bit) for Ch0, Ch1, Ch2, Ch3 uint8_t counter[4]; // Sample counter (4-bit) for each channel uint8_t crc[4]; // CRC (4-bit) for each channel (Optional usage) } OPT4048_RawData_t; typedef struct { double lux; // Ambient Light Intensity in Lux (calculated from Ch1/Y) double cie_x; // CIE X coordinate double cie_y; // CIE Y coordinate double adc_code_ch[4]; double cct; //Correlated Color Temperature } OPT4048_Data_t; bool OPT4048_Init(void); void OPT4048_Setting_Configure(uint16_t config_msb, uint16_t config_lsb); OPT4048_INTStatus_t OPT4048_Get_Ready(void); void OPT4048_Read_Data(OPT4048_Data_t* data); #endif //OPT4048_H 总结以上代码,用数学方式得出CIE X和CIE Y的值
07-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值