From 8fa09ba4fd4cef1102a331cfc5d70f51d97f096c Mon Sep 17 00:00:00 2001 From: ladyada Date: Sun, 17 Aug 2025 12:59:30 -0400 Subject: [PATCH] Initial implementation of Adafruit VEML6046 RGBIR color sensor library MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Complete register definitions and I2C interface - Configuration functions for integration time, gain, photodiode size - Enable/disable and calibration controls - Raw RGBIR data reading with efficient 8-byte I2C transaction - Threshold and interrupt management functions - Working test example with continuous measurement mode 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .clang-format | 13 + .github/workflows/githubci.yml | 26 ++ .gitignore | 4 + Adafruit_VEML6046.cpp | 357 +++++++++++++++++++++++ Adafruit_VEML6046.h | 131 +++++++++ README.md | 33 +++ examples/test_veml6046/test_veml6046.ino | 127 ++++++++ 7 files changed, 691 insertions(+) create mode 100644 .clang-format create mode 100644 .github/workflows/githubci.yml create mode 100644 .gitignore create mode 100644 Adafruit_VEML6046.cpp create mode 100644 Adafruit_VEML6046.h create mode 100644 README.md create mode 100644 examples/test_veml6046/test_veml6046.ino diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..ed70f56 --- /dev/null +++ b/.clang-format @@ -0,0 +1,13 @@ +Language: Cpp +BasedOnStyle: Google +IndentWidth: 2 +ColumnLimit: 80 +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +BinPackArguments: true +BinPackParameters: true +BreakBeforeBraces: Attach +DerivePointerAlignment: false +PointerAlignment: Left +SpacesBeforeTrailingComments: 1 \ No newline at end of file diff --git a/.github/workflows/githubci.yml b/.github/workflows/githubci.yml new file mode 100644 index 0000000..29a0ce5 --- /dev/null +++ b/.github/workflows/githubci.yml @@ -0,0 +1,26 @@ +name: Arduino Library CI + +on: [pull_request, push, repository_dispatch] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.x' + - name: pre-install + run: bash ci/actions_install.sh + - name: test platforms + run: python3 ci/build_platform.py main_platforms + + - name: clang + run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . + + - name: doxygen + env: + GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }} + PRETTYNAME : "Adafruit VEML6046 Arduino Library" + run: bash ci/doxy_gen_and_deploy.sh \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5adbb1a --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.pdf +*.txt +output.txt +.claude/ \ No newline at end of file diff --git a/Adafruit_VEML6046.cpp b/Adafruit_VEML6046.cpp new file mode 100644 index 0000000..611383e --- /dev/null +++ b/Adafruit_VEML6046.cpp @@ -0,0 +1,357 @@ +/*! + * @file Adafruit_VEML6046.cpp + * + * @mainpage Adafruit VEML6046 RGBIR color sensor library + * + * @section intro_sec Introduction + * + * This is the documentation for Adafruit's VEML6046 driver for the + * Arduino platform. It is designed specifically to work with the + * Adafruit VEML6046 sensor: https://www.adafruit.com/product/xxxx + * + * These sensors use I2C to communicate, 2 pins are required to + * interface. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * @section author Author + * + * Written by Limor 'ladyada' Fried with assistance from Claude Code for + * Adafruit Industries. + * + * @section license License + * + * MIT license, all text here must be included in any redistribution. + */ + +#include "Adafruit_VEML6046.h" + +/*! + * @brief Instantiates a new VEML6046 class + */ +Adafruit_VEML6046::Adafruit_VEML6046() { i2c_dev = nullptr; } + +/*! + * @brief Cleans up the VEML6046 + */ +Adafruit_VEML6046::~Adafruit_VEML6046() { + if (i2c_dev) { + delete i2c_dev; + } +} + +/*! + * @brief Sets up the hardware and initializes I2C + * @param i2c_addr + * The I2C address to be used. + * @param wire + * The Wire object to be used for I2C connections. + * @return True if initialization was successful, otherwise false. + */ +bool Adafruit_VEML6046::begin(uint8_t i2c_addr, TwoWire *wire) { + if (i2c_dev) { + delete i2c_dev; + } + + i2c_dev = new Adafruit_I2CDevice(i2c_addr, wire); + + if (!i2c_dev->begin()) { + return false; + } + + // Check device ID + Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_ID_L, 2, LSBFIRST); + uint16_t chip_id = id_reg.read(); + + if (chip_id != 0x0001) { + return false; + } + + // Enable the sensor + if (!enable()) { + return false; + } + + // Enable RGB calibration + if (!setRGBCalibration(true)) { + return false; + } + + return true; +} + +/*! + * @brief Sets the integration time for RGB measurements + * @param it Integration time setting + * @return True if successful, false if I2C write failed + */ +bool Adafruit_VEML6046::setIntegrationTime(veml6046_integration_time_t it) { + Adafruit_BusIO_Register rgb_conf0_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_0, 1); + Adafruit_BusIO_RegisterBits rgb_it_bits = Adafruit_BusIO_RegisterBits(&rgb_conf0_reg, 3, 4); + + return rgb_it_bits.write(it); +} + +/*! + * @brief Gets the current integration time setting + * @return Current integration time setting + */ +veml6046_integration_time_t Adafruit_VEML6046::getIntegrationTime(void) { + Adafruit_BusIO_Register rgb_conf0_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_0, 1); + Adafruit_BusIO_RegisterBits rgb_it_bits = Adafruit_BusIO_RegisterBits(&rgb_conf0_reg, 3, 4); + + return (veml6046_integration_time_t)rgb_it_bits.read(); +} + +/*! + * @brief Sets the RGB measurement mode (auto vs forced) + * @param forced True for active force mode, false for auto mode + * @return True if successful, false if I2C write failed + */ +bool Adafruit_VEML6046::setRGBModeForced(bool forced) { + Adafruit_BusIO_Register rgb_conf0_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_0, 1); + Adafruit_BusIO_RegisterBits rgb_mode_bits = Adafruit_BusIO_RegisterBits(&rgb_conf0_reg, 1, 3); + + return rgb_mode_bits.write(forced ? 1 : 0); +} + +/*! + * @brief Gets the current RGB measurement mode + * @return True if in active force mode, false if in auto mode + */ +bool Adafruit_VEML6046::getRGBModeForced(void) { + Adafruit_BusIO_Register rgb_conf0_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_0, 1); + Adafruit_BusIO_RegisterBits rgb_mode_bits = Adafruit_BusIO_RegisterBits(&rgb_conf0_reg, 1, 3); + + return rgb_mode_bits.read() == 1; +} + +/*! + * @brief Triggers a measurement in active force mode + * @return True if successful, false if I2C write failed + */ +bool Adafruit_VEML6046::RGBTrigger(void) { + Adafruit_BusIO_Register rgb_conf0_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_0, 1); + Adafruit_BusIO_RegisterBits rgb_trig_bits = Adafruit_BusIO_RegisterBits(&rgb_conf0_reg, 1, 2); + + return rgb_trig_bits.write(1); +} + +/*! + * @brief Checks if measurement is still in progress (trigger bit set) + * @return True if measurement in progress, false if complete + */ +bool Adafruit_VEML6046::isTriggered(void) { + Adafruit_BusIO_Register rgb_conf0_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_0, 1); + Adafruit_BusIO_RegisterBits rgb_trig_bits = Adafruit_BusIO_RegisterBits(&rgb_conf0_reg, 1, 2); + + return rgb_trig_bits.read() == 1; +} + +/*! + * @brief Enables or disables green channel interrupt + * @param enabled True to enable interrupt, false to disable + * @return True if successful, false if I2C write failed + */ +bool Adafruit_VEML6046::setGreenIntEnabled(bool enabled) { + Adafruit_BusIO_Register rgb_conf0_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_0, 1); + Adafruit_BusIO_RegisterBits g_int_bits = Adafruit_BusIO_RegisterBits(&rgb_conf0_reg, 1, 1); + + return g_int_bits.write(enabled ? 1 : 0); +} + +/*! + * @brief Gets the green channel interrupt enable status + * @return True if interrupt enabled, false if disabled + */ +bool Adafruit_VEML6046::getGreenIntEnabled(void) { + Adafruit_BusIO_Register rgb_conf0_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_0, 1); + Adafruit_BusIO_RegisterBits g_int_bits = Adafruit_BusIO_RegisterBits(&rgb_conf0_reg, 1, 1); + + return g_int_bits.read() == 1; +} + +/*! + * @brief Enables the VEML6046 sensor by clearing both RGB_ON bits + * @return True if successful, false if I2C write failed + */ +bool Adafruit_VEML6046::enable(void) { + Adafruit_BusIO_Register rgb_conf_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_0, 2, MSBFIRST); + Adafruit_BusIO_RegisterBits rgb_on_bits = Adafruit_BusIO_RegisterBits(&rgb_conf_reg, 2, 7); + + return rgb_on_bits.write(0x00); +} + +/*! + * @brief Checks if the VEML6046 sensor is enabled + * @return True if enabled, false if in shutdown + */ +bool Adafruit_VEML6046::isEnabled(void) { + Adafruit_BusIO_Register rgb_conf_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_0, 2, MSBFIRST); + Adafruit_BusIO_RegisterBits rgb_on_bits = Adafruit_BusIO_RegisterBits(&rgb_conf_reg, 2, 7); + + return rgb_on_bits.read() == 0x00; +} + +/*! + * @brief Sets the photodiode size (1/2 PD or 2/2 PD) + * @param half_size True for 1/2 PD, false for 2/2 PD + * @return True if successful, false if I2C write failed + */ +bool Adafruit_VEML6046::setPhotoDiodeHalfSize(bool half_size) { + Adafruit_BusIO_Register rgb_conf1_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_1, 1); + Adafruit_BusIO_RegisterBits pddiv_bits = Adafruit_BusIO_RegisterBits(&rgb_conf1_reg, 1, 6); + + return pddiv_bits.write(half_size ? 1 : 0); +} + +/*! + * @brief Gets the current photodiode size setting + * @return True if 1/2 PD, false if 2/2 PD + */ +bool Adafruit_VEML6046::getPhotoDiodeHalfSize(void) { + Adafruit_BusIO_Register rgb_conf1_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_1, 1); + Adafruit_BusIO_RegisterBits pddiv_bits = Adafruit_BusIO_RegisterBits(&rgb_conf1_reg, 1, 6); + + return pddiv_bits.read() == 1; +} + +/*! + * @brief Sets the RGB gain + * @param gain RGB gain setting + * @return True if successful, false if I2C write failed + */ +bool Adafruit_VEML6046::setRGBGain(veml6046_gain_t gain) { + Adafruit_BusIO_Register rgb_conf1_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_1, 1); + Adafruit_BusIO_RegisterBits gain_bits = Adafruit_BusIO_RegisterBits(&rgb_conf1_reg, 2, 3); + + return gain_bits.write(gain); +} + +/*! + * @brief Gets the current RGB gain setting + * @return Current RGB gain setting + */ +veml6046_gain_t Adafruit_VEML6046::getRGBGain(void) { + Adafruit_BusIO_Register rgb_conf1_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_1, 1); + Adafruit_BusIO_RegisterBits gain_bits = Adafruit_BusIO_RegisterBits(&rgb_conf1_reg, 2, 3); + + return (veml6046_gain_t)gain_bits.read(); +} + +/*! + * @brief Sets the interrupt persistence + * @param pers Persistence setting + * @return True if successful, false if I2C write failed + */ +bool Adafruit_VEML6046::setIntPersistence(veml6046_persistence_t pers) { + Adafruit_BusIO_Register rgb_conf1_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_1, 1); + Adafruit_BusIO_RegisterBits pers_bits = Adafruit_BusIO_RegisterBits(&rgb_conf1_reg, 2, 1); + + return pers_bits.write(pers); +} + +/*! + * @brief Gets the current interrupt persistence setting + * @return Current persistence setting + */ +veml6046_persistence_t Adafruit_VEML6046::getIntPersistence(void) { + Adafruit_BusIO_Register rgb_conf1_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_1, 1); + Adafruit_BusIO_RegisterBits pers_bits = Adafruit_BusIO_RegisterBits(&rgb_conf1_reg, 2, 1); + + return (veml6046_persistence_t)pers_bits.read(); +} + +/*! + * @brief Sets the RGB calibration enable + * @param enabled True to enable calibration, false to disable + * @return True if successful, false if I2C write failed + */ +bool Adafruit_VEML6046::setRGBCalibration(bool enabled) { + Adafruit_BusIO_Register rgb_conf1_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_1, 1); + Adafruit_BusIO_RegisterBits cal_bits = Adafruit_BusIO_RegisterBits(&rgb_conf1_reg, 1, 0); + + return cal_bits.write(enabled ? 1 : 0); +} + +/*! + * @brief Gets the RGB calibration enable status + * @return True if calibration enabled, false if disabled + */ +bool Adafruit_VEML6046::getRGBCalibration(void) { + Adafruit_BusIO_Register rgb_conf1_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_RGB_CONF_1, 1); + Adafruit_BusIO_RegisterBits cal_bits = Adafruit_BusIO_RegisterBits(&rgb_conf1_reg, 1, 0); + + return cal_bits.read() == 1; +} + +/*! + * @brief Sets the green channel high threshold + * @param threshold 16-bit threshold value + * @return True if successful, false if I2C write failed + */ +bool Adafruit_VEML6046::setGreenThresholdHigh(uint16_t threshold) { + Adafruit_BusIO_Register thdh_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_G_THDH_L, 2, LSBFIRST); + + return thdh_reg.write(threshold); +} + +/*! + * @brief Gets the green channel high threshold + * @return Current high threshold value + */ +uint16_t Adafruit_VEML6046::getGreenThresholdHigh(void) { + Adafruit_BusIO_Register thdh_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_G_THDH_L, 2, LSBFIRST); + + return thdh_reg.read(); +} + +/*! + * @brief Sets the green channel low threshold + * @param threshold 16-bit threshold value + * @return True if successful, false if I2C write failed + */ +bool Adafruit_VEML6046::setGreenThresholdLow(uint16_t threshold) { + Adafruit_BusIO_Register thdl_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_G_THDL_L, 2, LSBFIRST); + + return thdl_reg.write(threshold); +} + +/*! + * @brief Gets the green channel low threshold + * @return Current low threshold value + */ +uint16_t Adafruit_VEML6046::getGreenThresholdLow(void) { + Adafruit_BusIO_Register thdl_reg = Adafruit_BusIO_Register(i2c_dev, VEML6046_REG_G_THDL_L, 2, LSBFIRST); + + return thdl_reg.read(); +} + +/*! + * @brief Reads all RGBIR channel data in one operation + * @param r Pointer to store red channel data + * @param g Pointer to store green channel data + * @param b Pointer to store blue channel data + * @param ir Pointer to store IR channel data + * @return True if successful, false if I2C read failed + */ +bool Adafruit_VEML6046::getData(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *ir) { + if (!r || !g || !b || !ir) { + return false; + } + + uint8_t buffer[8]; + uint8_t reg_addr = VEML6046_REG_R_DATA_L; + if (!i2c_dev->write_then_read(®_addr, 1, buffer, 8)) { + return false; + } + + *r = buffer[0] | (buffer[1] << 8); + *g = buffer[2] | (buffer[3] << 8); + *b = buffer[4] | (buffer[5] << 8); + *ir = buffer[6] | (buffer[7] << 8); + + return true; +} \ No newline at end of file diff --git a/Adafruit_VEML6046.h b/Adafruit_VEML6046.h new file mode 100644 index 0000000..8848426 --- /dev/null +++ b/Adafruit_VEML6046.h @@ -0,0 +1,131 @@ +/*! + * @file Adafruit_VEML6046.h + * + * This is part of Adafruit's VEML6046 driver for the Arduino platform. It is + * designed specifically to work with the Adafruit VEML6046 sensor: + * https://www.adafruit.com/product/xxxx + * + * These sensors use I2C to communicate, 2 pins are required to interface. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Written by Limor 'ladyada' Fried with assistance from Claude Code for + * Adafruit Industries. + * + * MIT license, all text here must be included in any redistribution. + */ + +#ifndef _ADAFRUIT_VEML6046_H +#define _ADAFRUIT_VEML6046_H + +#include "Arduino.h" +#include +#include + +/*! Default I2C address for VEML6046 */ +#define VEML6046_DEFAULT_ADDR 0x29 + +/*! VEML6046 register addresses */ +#define VEML6046_REG_RGB_CONF_0 0x00 ///< RGB configuration register 0 +#define VEML6046_REG_RGB_CONF_1 0x01 ///< RGB configuration register 1 +#define VEML6046_REG_G_THDH_L 0x04 ///< Green high threshold low byte +#define VEML6046_REG_G_THDH_H 0x05 ///< Green high threshold high byte +#define VEML6046_REG_G_THDL_L 0x06 ///< Green low threshold low byte +#define VEML6046_REG_G_THDL_H 0x07 ///< Green low threshold high byte +#define VEML6046_REG_R_DATA_L 0x10 ///< Red data low byte +#define VEML6046_REG_R_DATA_H 0x11 ///< Red data high byte +#define VEML6046_REG_G_DATA_L 0x12 ///< Green data low byte +#define VEML6046_REG_G_DATA_H 0x13 ///< Green data high byte +#define VEML6046_REG_B_DATA_L 0x14 ///< Blue data low byte +#define VEML6046_REG_B_DATA_H 0x15 ///< Blue data high byte +#define VEML6046_REG_IR_DATA_L 0x16 ///< IR data low byte +#define VEML6046_REG_IR_DATA_H 0x17 ///< IR data high byte +#define VEML6046_REG_ID_L 0x18 ///< Device ID low byte +#define VEML6046_REG_ID_H 0x19 ///< Device ID high byte +#define VEML6046_REG_INT_FLAG 0x1A ///< Interrupt flag register + +/*! + * @brief Integration time settings for VEML6046 + */ +typedef enum { + VEML6046_IT_3_125MS = 0x00, ///< 3.125 ms integration time (default) + VEML6046_IT_6_25MS = 0x01, ///< 6.25 ms integration time + VEML6046_IT_12_5MS = 0x02, ///< 12.5 ms integration time + VEML6046_IT_25MS = 0x03, ///< 25 ms integration time + VEML6046_IT_50MS = 0x04, ///< 50 ms integration time + VEML6046_IT_100MS = 0x05, ///< 100 ms integration time + VEML6046_IT_200MS = 0x06, ///< 200 ms integration time + VEML6046_IT_400MS = 0x07 ///< 400 ms integration time +} veml6046_integration_time_t; + +/*! + * @brief RGB gain settings for VEML6046 + */ +typedef enum { + VEML6046_GAIN_1X = 0x00, ///< Gain x1 (default) + VEML6046_GAIN_2X = 0x01, ///< Gain x2 + VEML6046_GAIN_0_66X = 0x02, ///< Gain x0.66 + VEML6046_GAIN_0_5X = 0x03 ///< Gain x0.5 +} veml6046_gain_t; + +/*! + * @brief Interrupt persistence settings for VEML6046 + */ +typedef enum { + VEML6046_PERS_1 = 0x00, ///< 1 time (default) + VEML6046_PERS_2 = 0x01, ///< 2 times + VEML6046_PERS_4 = 0x02, ///< 4 times + VEML6046_PERS_8 = 0x03 ///< 8 times +} veml6046_persistence_t; + +/*! + * @brief Main VEML6046 class for RGBIR color sensor + */ +class Adafruit_VEML6046 { +public: + Adafruit_VEML6046(); + ~Adafruit_VEML6046(); + bool begin(uint8_t i2c_addr = VEML6046_DEFAULT_ADDR, TwoWire *wire = &Wire); + + bool setIntegrationTime(veml6046_integration_time_t it); + veml6046_integration_time_t getIntegrationTime(void); + + bool setRGBModeForced(bool forced); + bool getRGBModeForced(void); + + bool RGBTrigger(void); + bool isTriggered(void); + + bool setGreenIntEnabled(bool enabled); + bool getGreenIntEnabled(void); + + bool enable(void); + bool isEnabled(void); + + bool setPhotoDiodeHalfSize(bool half_size); + bool getPhotoDiodeHalfSize(void); + + bool setRGBGain(veml6046_gain_t gain); + veml6046_gain_t getRGBGain(void); + + bool setIntPersistence(veml6046_persistence_t pers); + veml6046_persistence_t getIntPersistence(void); + + bool setRGBCalibration(bool enabled); + bool getRGBCalibration(void); + + bool setGreenThresholdHigh(uint16_t threshold); + uint16_t getGreenThresholdHigh(void); + + bool setGreenThresholdLow(uint16_t threshold); + uint16_t getGreenThresholdLow(void); + + bool getData(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *ir); + +private: + Adafruit_I2CDevice *i2c_dev; ///< Pointer to I2C bus interface +}; + +#endif \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..5fd3c7f --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# Adafruit VEML6046 Library [![Build Status](https://github.com/adafruit/Adafruit_VEML6046/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_VEML6046/actions)[![Documentation](https://github.com/adafruit/Adafruit_VEML6046/workflows/GitHub%20Pages/badge.svg)](http://adafruit.github.io/Adafruit_VEML6046) + +Arduino library for the VEML6046 high accuracy RGBIR color sensor. + +## About the VEML6046 + +The VEML6046 is a high accuracy color digital 16-bit resolution sensor with I2C interface. It features: + +- RGBIR color sensing with high sensitivity photodiodes +- 16-bit A/D converter resolution +- I2C interface (address 0x29) +- Programmable integration times from 3.125ms to 400ms +- Multiple gain settings (0.5x, 0.66x, 1x, 2x) +- Interrupt functionality +- Supply voltage: 2.5V to 3.6V +- Ambient light range: 0 to 176,000 lx + +## Installation + +Download and install the library using the Arduino Library Manager or by downloading the latest release from GitHub. + +### Dependencies + +This library requires: +- [Adafruit BusIO](https://github.com/adafruit/Adafruit_BusIO) + +## License + +MIT License. See LICENSE file for details. + +## Contributing + +Contributions are welcome! Please read the contributing guidelines and submit pull requests to the main repository. \ No newline at end of file diff --git a/examples/test_veml6046/test_veml6046.ino b/examples/test_veml6046/test_veml6046.ino new file mode 100644 index 0000000..4b8578d --- /dev/null +++ b/examples/test_veml6046/test_veml6046.ino @@ -0,0 +1,127 @@ +/* + * Test sketch for VEML6046 RGBIR color sensor + * + * Written by Limor 'ladyada' Fried with assistance from Claude Code for Adafruit Industries. + * MIT license, check license.txt for more information + */ + +#include "Adafruit_VEML6046.h" + +Adafruit_VEML6046 veml = Adafruit_VEML6046(); + +void setup() { + Serial.begin(115200); + while (!Serial) delay(10); + + Serial.println(F("VEML6046 test")); + + if (!veml.begin()) { + Serial.println(F("Couldn't find VEML6046 chip")); + while (1) delay(10); + } + Serial.println(F("Found VEML6046 chip")); + + // Print current status (set by begin()) + bool is_enabled = veml.isEnabled(); + Serial.print(F("Sensor enabled: ")); + Serial.println(is_enabled ? F("Yes") : F("No")); + + bool cal_enabled = veml.getRGBCalibration(); + Serial.print(F("RGB calibration enabled: ")); + Serial.println(cal_enabled ? F("Yes") : F("No")); + + // Test photodiode size + Serial.println(F("Setting photodiode to full size")); + if (veml.setPhotoDiodeHalfSize(false)) { + Serial.println(F("Photodiode full size set successfully")); + } else { + Serial.println(F("Failed to set photodiode full size")); + } + + // Read back photodiode size + bool is_half_size = veml.getPhotoDiodeHalfSize(); + Serial.print(F("Photodiode half size: ")); + Serial.println(is_half_size ? F("Yes") : F("No")); + + // Test integration time setter/getter + Serial.println(F("Setting integration time to 25ms")); + if (veml.setIntegrationTime(VEML6046_IT_25MS)) { + Serial.println(F("Integration time set successfully")); + } else { + Serial.println(F("Failed to set integration time")); + } + + // Read back and display current integration time + veml6046_integration_time_t current_it = veml.getIntegrationTime(); + Serial.print(F("Current integration time: ")); + switch (current_it) { + case VEML6046_IT_3_125MS: + Serial.println(F("3.125ms")); + break; + case VEML6046_IT_6_25MS: + Serial.println(F("6.25ms")); + break; + case VEML6046_IT_12_5MS: + Serial.println(F("12.5ms")); + break; + case VEML6046_IT_25MS: + Serial.println(F("25ms")); + break; + case VEML6046_IT_50MS: + Serial.println(F("50ms")); + break; + case VEML6046_IT_100MS: + Serial.println(F("100ms")); + break; + case VEML6046_IT_200MS: + Serial.println(F("200ms")); + break; + case VEML6046_IT_400MS: + Serial.println(F("400ms")); + break; + default: + Serial.println(F("Unknown")); + break; + } + + // Test RGB mode setter/getter + Serial.println(F("Setting RGB mode to auto")); + if (veml.setRGBModeForced(false)) { + Serial.println(F("RGB mode set successfully")); + } else { + Serial.println(F("Failed to set RGB mode")); + } + + // Read back and display current RGB mode + bool is_forced = veml.getRGBModeForced(); + Serial.print(F("Current RGB mode: ")); + Serial.println(is_forced ? F("Forced") : F("Auto")); + + // Test green interrupt enable + Serial.println(F("Enabling green interrupt")); + if (veml.setGreenIntEnabled(true)) { + Serial.println(F("Green interrupt enabled successfully")); + } else { + Serial.println(F("Failed to enable green interrupt")); + } + + // Read back green interrupt status + bool green_int_enabled = veml.getGreenIntEnabled(); + Serial.print(F("Green interrupt enabled: ")); + Serial.println(green_int_enabled ? F("Yes") : F("No")); +} + +void loop() { + // Read RGBIR data in continuous mode + uint16_t r, g, b, ir; + if (veml.getData(&r, &g, &b, &ir)) { + Serial.print(F("R: ")); Serial.print(r); + Serial.print(F(" G: ")); Serial.print(g); + Serial.print(F(" B: ")); Serial.print(b); + Serial.print(F(" IR: ")); Serial.println(ir); + } else { + Serial.println(F("Failed to read data")); + } + + delay(1000); +} \ No newline at end of file