A Vishay library for devices VEML6040 R+G+B+W and VEML6075 UVA+UVB optical sensors. Data is stored in a dedicated data structure.

Dependents:   vmel60xx_hello_world

This device library is for use with the Vishay VEML6040 and VEML6075 optical sensors. Ambient light conditions are gathered and stored in a user accessible data structure veml60xx_struct. The library has enough intelligence to determine which device is connected and performs the appropriate functions.

The VEML6040 detects Red, Green, Blue and White light data, which is easily converted to relative Lux intensities.

The VEML6075 detects UVA and UVB light which is converted to a UV Index value.

Since both devices use the same I2C address, they cannot be on the same I2C bus at the same time.

Tested on a K64F

Committer:
loopsva
Date:
Mon Apr 25 22:35:08 2016 +0000
Revision:
2:c17b84879a2f
Parent:
1:f560bd61b3b3
Child:
3:dda770fa7228
Bug fixes. Updated and added to data structure.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
loopsva 0:92cb496cbbe1 1 #ifndef VEML60XX_H
loopsva 0:92cb496cbbe1 2 #define VEML60XX_H
loopsva 0:92cb496cbbe1 3
loopsva 2:c17b84879a2f 4 /**
loopsva 2:c17b84879a2f 5 * Library for Vishay VEML6040 R+G+B+W and VEML6075 UVA+UVB optical sensors that operate on the I2C bus. There are
loopsva 2:c17b84879a2f 6 * routines for detecting which VEML device is connected to the I2C bus and sets the appropriate resigter values
loopsva 2:c17b84879a2f 7 * in the data structure "veml60xx_struct".
loopsva 2:c17b84879a2f 8 *
loopsva 2:c17b84879a2f 9 * The code has all of the hooks for gathering raw data from the VEML60xx chip and performs the necessary compensation
loopsva 2:c17b84879a2f 10 * in order to get the corrected output readings. There is also an optional automatic scaling routine that
loopsva 2:c17b84879a2f 11 * modifies the dwell time (IT bits in the CONF register), should the raw register reading saturate (65535) or
loopsva 2:c17b84879a2f 12 * are too small (< 255). Adjustments are made + or - one IT count, each time the routine is called. If the light
loopsva 2:c17b84879a2f 13 * striking the sensor changes dramatically, you may have to run the automatic scaling routine a few times. After
loopsva 2:c17b84879a2f 14 * each change in dwell time (changing of IT bits), you must wait a maximum of 2 * 1280mSec before taking a new
loopsva 2:c17b84879a2f 15 * reading in order to get accurate results.
loopsva 2:c17b84879a2f 16 *
loopsva 2:c17b84879a2f 17 * NOTE: Both the VEML6040 and the VEML6075 have the same I2C address. You cannot have both devices on the same I2C
loopsva 2:c17b84879a2f 18 * bus at the same time!! Vishay does have an application note for using multiple devices in the same I2C bus.
loopsva 2:c17b84879a2f 19 * However, it does require additional hardware to do so.
loopsva 2:c17b84879a2f 20 *
loopsva 2:c17b84879a2f 21 * NOTE: Although no device ID is noted in the VEML6040 datasheet, it apprears to have an ID of 0x0123. This code
loopsva 2:c17b84879a2f 22 * does look at the 0x0123 ID signature to determine that a VEML6040 has been detected and sets
loopsva 2:c17b84879a2f 23 * the "is6040" flag in the "veml60xx_struct" data structure.
loopsva 2:c17b84879a2f 24 **/
loopsva 2:c17b84879a2f 25
loopsva 0:92cb496cbbe1 26 #include "mbed.h"
loopsva 0:92cb496cbbe1 27
loopsva 0:92cb496cbbe1 28 // I2C address
loopsva 0:92cb496cbbe1 29 #define VEML60_WADDR 0x20 //i2c address write mode
loopsva 0:92cb496cbbe1 30 #define VEML60_RADDR 0x21 //i2c address read mode
loopsva 0:92cb496cbbe1 31
loopsva 0:92cb496cbbe1 32
loopsva 1:f560bd61b3b3 33 // VEML6040 and VEML6075 common register set
loopsva 0:92cb496cbbe1 34 #define VEML60xx_CONF_REG 0x00 //rw Config Register
loopsva 0:92cb496cbbe1 35
loopsva 0:92cb496cbbe1 36 // VEML6075-only register set
loopsva 0:92cb496cbbe1 37 #define VEML6075_UVA_DATA_REG 0x07 //ro 16 bit UVA data Register
loopsva 0:92cb496cbbe1 38 #define VEML6075_DUMMY_REG 0x08 //ro 16 bit dummy Register
loopsva 0:92cb496cbbe1 39 #define VEML6075_UVB_DATA_REG 0x09 //ro 16 bit UVB data Register
loopsva 0:92cb496cbbe1 40 #define VEML6075_UV_COMP1_REG 0x0A //ro 16 bit UV compensation Register 1
loopsva 0:92cb496cbbe1 41 #define VEML6075_UV_COMP2_REG 0x0B //ro 16 bit UV compensation Register 2
loopsva 0:92cb496cbbe1 42 #define VEML6075_CHIP_ID_REG 0x0C //ro 16 bit Chip ID Register
loopsva 0:92cb496cbbe1 43
loopsva 0:92cb496cbbe1 44 // VEML6040-only register set
loopsva 0:92cb496cbbe1 45 #define VEML6040_R_DATA_REG 0x08 //ro 16 bit RED data
loopsva 0:92cb496cbbe1 46 #define VEML6040_G_DATA_REG 0x09 //ro 16 bit GREEN data
loopsva 0:92cb496cbbe1 47 #define VEML6040_B_DATA_REG 0x0A //ro 16 bit BLUE data
loopsva 0:92cb496cbbe1 48 #define VEML6040_W_DATA_REG 0x0B //ro 16 bit WHITE data
loopsva 0:92cb496cbbe1 49
loopsva 0:92cb496cbbe1 50 // VEML6040 and VEML6075 common config register bits
loopsva 0:92cb496cbbe1 51 #define VEML60xx_CONF_BITS_IT 0x70 //VEML6075 -> 0x00 = 50mS, 0x10 = 100mS, 0x20 = 200mS, 0x30 = 400mS, 0x40 = 800mS, 0x50-0x70 = reserved
loopsva 0:92cb496cbbe1 52 //VEML6040 -> 0x00 = 40mS, 0x10 = 80mS, 0x20 = 160mS, 0x30 = 320mS, 0x40 = 640mS, 0x50 = 1280mS, 0x60-0x70 = reserved
loopsva 0:92cb496cbbe1 53 #define VEML60xx_CONF_BITS_IT_50m40m 0x00
loopsva 0:92cb496cbbe1 54 #define VEML60xx_CONF_BITS_IT_100m80m 0x10
loopsva 0:92cb496cbbe1 55 #define VEML60xx_CONF_BITS_IT_200m160m 0x20
loopsva 0:92cb496cbbe1 56 #define VEML60xx_CONF_BITS_IT_400m320m 0x30
loopsva 0:92cb496cbbe1 57 #define VEML60xx_CONF_BITS_IT_800m640m 0x40
loopsva 0:92cb496cbbe1 58
loopsva 0:92cb496cbbe1 59 #define VEML60xx_CONF_BITS_TRIG 0x04 //0x00 = idle, 0x04 = trigger (measurement), auto returns to 0x00 note: AF == 1
loopsva 0:92cb496cbbe1 60 #define VEML60xx_CONF_BITS_AF 0x02 //0x00 = auto, 0x02 = force (mode)
loopsva 0:92cb496cbbe1 61 #define VEML60xx_CONF_BITS_SD 0x01 //0x00 = run, 0x01 = shut down
loopsva 0:92cb496cbbe1 62
loopsva 0:92cb496cbbe1 63 // VEML6075-only config register bits
loopsva 0:92cb496cbbe1 64 #define VEML6075_CONF_BITS_HD 0x08 //0x00 = normal, 0x08 = high (dynamic setting)
loopsva 0:92cb496cbbe1 65
loopsva 0:92cb496cbbe1 66 // VEML6040-only config register bits
loopsva 0:92cb496cbbe1 67 #define VEML6040_CONF_BITS_IT_1280m 0x50
loopsva 0:92cb496cbbe1 68
loopsva 0:92cb496cbbe1 69 // VEML6075-only ID contents
loopsva 0:92cb496cbbe1 70 #define VEML6075_DEVICE_ID 0x0026 //expected device ID
loopsva 0:92cb496cbbe1 71
loopsva 0:92cb496cbbe1 72 // VEML6040-only ID contents
loopsva 0:92cb496cbbe1 73 #define VEML6040_DEVICE_ID 0x0123 //expected device ID
loopsva 0:92cb496cbbe1 74
loopsva 0:92cb496cbbe1 75 // VEML6075-only conversion coefficients
loopsva 2:c17b84879a2f 76 #define VEML6075_UVA_RESP 0.0011
loopsva 2:c17b84879a2f 77 #define VEML6075_UVB_RESP 0.00125
loopsva 2:c17b84879a2f 78
loopsva 0:92cb496cbbe1 79 #define VEML6075_UVA_COEF_A 3.33
loopsva 0:92cb496cbbe1 80 #define VEML6075_UVA_COEF_B 2.50
loopsva 0:92cb496cbbe1 81 #define VEML6075_UVB_COEF_C 3.67
loopsva 0:92cb496cbbe1 82 #define VEML6075_UVB_COEF_D 2.75
loopsva 0:92cb496cbbe1 83
loopsva 0:92cb496cbbe1 84 // VEML6040-only conversion coefficients
loopsva 2:c17b84879a2f 85 #define VEML6040_LUX_STEP 0.005625
loopsva 0:92cb496cbbe1 86
loopsva 0:92cb496cbbe1 87 /**
loopsva 0:92cb496cbbe1 88 * Create VEML60 controller class
loopsva 0:92cb496cbbe1 89 *
loopsva 0:92cb496cbbe1 90 * @param VEML class
loopsva 0:92cb496cbbe1 91 *
loopsva 0:92cb496cbbe1 92 */
loopsva 0:92cb496cbbe1 93 class veml60xx {
loopsva 0:92cb496cbbe1 94
loopsva 0:92cb496cbbe1 95 public:
loopsva 0:92cb496cbbe1 96
loopsva 0:92cb496cbbe1 97 /**
loopsva 0:92cb496cbbe1 98 * Public data structure for VEML60xx data values.
loopsva 0:92cb496cbbe1 99 *
loopsva 0:92cb496cbbe1 100 **/
loopsva 0:92cb496cbbe1 101 typedef struct {
loopsva 2:c17b84879a2f 102 uint16_t id; /*!< VEML60xx Device ID*/
loopsva 0:92cb496cbbe1 103 uint16_t conf_reg; /*!< VEML60xx config register mirror */
loopsva 2:c17b84879a2f 104
loopsva 2:c17b84879a2f 105 bool is6075; /*!< connected device is a VEML6075 */
loopsva 2:c17b84879a2f 106 bool is6040; /*!< connected device is a VEML6040 */
loopsva 0:92cb496cbbe1 107
loopsva 2:c17b84879a2f 108 uint16_t uva_d; /*!< VEML6075 UVA data */
loopsva 0:92cb496cbbe1 109 uint16_t uvb_d; /*!< VEML6075 UVB data */
loopsva 2:c17b84879a2f 110 uint16_t dummy_d; /*!< VEML6075 Dummy data */
loopsva 0:92cb496cbbe1 111 uint16_t uv_c1; /*!< VEML6075 UV comp1 data */
loopsva 0:92cb496cbbe1 112 uint16_t uv_c2; /*!< VEML6075 UV comp2 data */
loopsva 2:c17b84879a2f 113 double uva_step; /*!< VEML6075 UVA value per step */
loopsva 2:c17b84879a2f 114 double uvb_step; /*!< VEML6075 UVB value per step */
loopsva 0:92cb496cbbe1 115 double uva_comp; /*!< VEML6075 UVA compensated data */
loopsva 0:92cb496cbbe1 116 double uvb_comp; /*!< VEML6075 UVB compensated data */
loopsva 0:92cb496cbbe1 117 double uv_index; /*!< VEML6075 UV Index */
loopsva 2:c17b84879a2f 118
loopsva 2:c17b84879a2f 119 double lux_step; /*!< VEML6040 Lux value per step */
loopsva 0:92cb496cbbe1 120 uint16_t r_d; /*!< VEML6040 RED data */
loopsva 0:92cb496cbbe1 121 uint16_t g_d; /*!< VEML6040 GREEN data */
loopsva 0:92cb496cbbe1 122 uint16_t b_d; /*!< VEML6040 BLUE data */
loopsva 0:92cb496cbbe1 123 uint16_t w_d; /*!< VEML6040 WHITE data */
loopsva 2:c17b84879a2f 124 double r_lux; /*!< VEML6040 RED Lux value */
loopsva 2:c17b84879a2f 125 double g_lux; /*!< VEML6040 GREEN Lux value */
loopsva 2:c17b84879a2f 126 double b_lux; /*!< VEML6040 BLUE Lux value */
loopsva 2:c17b84879a2f 127 double w_lux; /*!< VEML6040 WHITE Lux value */
loopsva 2:c17b84879a2f 128
loopsva 0:92cb496cbbe1 129 } veml60xx_struct;
loopsva 0:92cb496cbbe1 130
loopsva 0:92cb496cbbe1 131 /**
loopsva 0:92cb496cbbe1 132 * Create a VME60xx object using the specified I2C object
loopsva 0:92cb496cbbe1 133 *
loopsva 0:92cb496cbbe1 134 * @param sda - mbed I2C interface pin
loopsva 0:92cb496cbbe1 135 *
loopsva 0:92cb496cbbe1 136 * @param scl - mbed I2C interface pin
loopsva 0:92cb496cbbe1 137 *
loopsva 0:92cb496cbbe1 138 * @param set_I2C_frequency
loopsva 0:92cb496cbbe1 139 */
loopsva 0:92cb496cbbe1 140 veml60xx(PinName sda, PinName scl, int i2cFrequency);
loopsva 0:92cb496cbbe1 141
loopsva 0:92cb496cbbe1 142 /**
loopsva 0:92cb496cbbe1 143 * Destructor
loopsva 0:92cb496cbbe1 144 *
loopsva 0:92cb496cbbe1 145 * @param --none--
loopsva 0:92cb496cbbe1 146 */
loopsva 0:92cb496cbbe1 147 ~veml60xx();
loopsva 0:92cb496cbbe1 148
loopsva 0:92cb496cbbe1 149 /**
loopsva 1:f560bd61b3b3 150 * Get VEML60xx ID Register
loopsva 0:92cb496cbbe1 151 *
loopsva 1:f560bd61b3b3 152 * Note: the VEML6040 seems to have an ID register. However, it's not published
loopsva 0:92cb496cbbe1 153 *
loopsva 0:92cb496cbbe1 154 * @param pointer to struct veml60xx_struct
loopsva 0:92cb496cbbe1 155 *
loopsva 0:92cb496cbbe1 156 * @return ID Register value
loopsva 0:92cb496cbbe1 157 */
loopsva 0:92cb496cbbe1 158 uint16_t getID(veml60xx_struct& Pntr);
loopsva 0:92cb496cbbe1 159
loopsva 0:92cb496cbbe1 160 /**
loopsva 1:f560bd61b3b3 161 * Get VEMLxx Config Register
loopsva 0:92cb496cbbe1 162 *
loopsva 0:92cb496cbbe1 163 * @param pointer to struct veml60xx_struct
loopsva 0:92cb496cbbe1 164 *
loopsva 0:92cb496cbbe1 165 * @return Config Register value
loopsva 0:92cb496cbbe1 166 */
loopsva 0:92cb496cbbe1 167 uint16_t getConfig(veml60xx_struct& Pntr);
loopsva 0:92cb496cbbe1 168
loopsva 0:92cb496cbbe1 169 /**
loopsva 1:f560bd61b3b3 170 * Get VEML60xx Raw Data
loopsva 0:92cb496cbbe1 171 *
loopsva 0:92cb496cbbe1 172 * @param pointer to struct veml60xx_struct
loopsva 0:92cb496cbbe1 173 *
loopsva 1:f560bd61b3b3 174 * @return raw data put into struct VEML60xx_struct
loopsva 0:92cb496cbbe1 175 */
loopsva 0:92cb496cbbe1 176 uint16_t getRawData(veml60xx_struct& Pntr);
loopsva 0:92cb496cbbe1 177
loopsva 0:92cb496cbbe1 178 /**
loopsva 1:f560bd61b3b3 179 * Convert the VEML6075 Raw Data
loopsva 0:92cb496cbbe1 180 *
loopsva 0:92cb496cbbe1 181 * @param pointer to struct veml60xx_struct
loopsva 0:92cb496cbbe1 182 *
loopsva 1:f560bd61b3b3 183 * @return converted data put into struct VEML60xx_struct
loopsva 0:92cb496cbbe1 184 */
loopsva 0:92cb496cbbe1 185 void convertRawData(veml60xx_struct& Pntr);
loopsva 0:92cb496cbbe1 186
loopsva 0:92cb496cbbe1 187 /**
loopsva 1:f560bd61b3b3 188 * Initialize the VEML60xx
loopsva 0:92cb496cbbe1 189 *
loopsva 0:92cb496cbbe1 190 * Sets up the command register to proper operating mode
loopsva 0:92cb496cbbe1 191 *
loopsva 0:92cb496cbbe1 192 * @param pointer to struct veml60xx_struct
loopsva 0:92cb496cbbe1 193 *
loopsva 0:92cb496cbbe1 194 * @param val any value to be or'd into the config register
loopsva 0:92cb496cbbe1 195 *
loopsva 2:c17b84879a2f 196 * Typical val variable settings:
loopsva 2:c17b84879a2f 197 * - veml.setConfig(vemlSTR, 0);
loopsva 2:c17b84879a2f 198 * - veml.setConfig(vemlSTR, VEML60xx_CONF_BITS_IT_100m80m);
loopsva 2:c17b84879a2f 199 * - veml.setConfig(vemlSTR, VEML60xx_CONF_BITS_IT_400m320m);
loopsva 2:c17b84879a2f 200 * - veml.setConfig(vemlSTR, VEML60xx_CONF_BITS_IT_800m640m | VEML6075_CONF_BITS_HD | VEML60xx_CONF_BITS_AF);
loopsva 2:c17b84879a2f 201 *
loopsva 2:c17b84879a2f 202 * @return nothing
loopsva 0:92cb496cbbe1 203 */
loopsva 0:92cb496cbbe1 204 void setConfig(veml60xx_struct& Pntr, uint16_t val);
loopsva 0:92cb496cbbe1 205
loopsva 0:92cb496cbbe1 206 /**
loopsva 1:f560bd61b3b3 207 * Trigger a VEML60xx conversion cycle
loopsva 0:92cb496cbbe1 208 *
loopsva 0:92cb496cbbe1 209 * Must be in manual trigger mode (AF == 1)
loopsva 0:92cb496cbbe1 210 *
loopsva 2:c17b84879a2f 211 * Example: veml.setConfig(vemlSTR, VEML60xx_CONF_BITS_AF);
loopsva 0:92cb496cbbe1 212 *
loopsva 0:92cb496cbbe1 213 * @param pointer to struct veml60xx_struct
loopsva 0:92cb496cbbe1 214 *
loopsva 0:92cb496cbbe1 215 * @return 0 TRIG properly set
loopsva 0:92cb496cbbe1 216 * @return 1 TRIG has been previously set
loopsva 0:92cb496cbbe1 217 * @return 2 AF bit not set (in AUTO mode)
loopsva 0:92cb496cbbe1 218 */
loopsva 0:92cb496cbbe1 219 uint16_t startAccess(veml60xx_struct& Pntr);
loopsva 0:92cb496cbbe1 220
loopsva 0:92cb496cbbe1 221 /**
loopsva 0:92cb496cbbe1 222 * Automatically adjust Lux scaling level
loopsva 0:92cb496cbbe1 223 *
loopsva 0:92cb496cbbe1 224 * Change CONF_BITS_IT by +-1 if count bits saturated or too low
loopsva 0:92cb496cbbe1 225 *
loopsva 0:92cb496cbbe1 226 * @param pointer to struct veml60xx_struct
loopsva 0:92cb496cbbe1 227 *
loopsva 0:92cb496cbbe1 228 * @return true = IT scale value has changed
loopsva 0:92cb496cbbe1 229 * @return false = IT scale value not changed, could be at its limit
loopsva 0:92cb496cbbe1 230 */
loopsva 0:92cb496cbbe1 231 bool autoAdjustLux(veml60xx_struct& Pntr);
loopsva 0:92cb496cbbe1 232
loopsva 0:92cb496cbbe1 233 private:
loopsva 0:92cb496cbbe1 234 char vemlBuffer[4];
loopsva 0:92cb496cbbe1 235
loopsva 0:92cb496cbbe1 236 protected:
loopsva 0:92cb496cbbe1 237 I2C* _i2c_;
loopsva 0:92cb496cbbe1 238
loopsva 0:92cb496cbbe1 239 };
loopsva 0:92cb496cbbe1 240 #endif