Kevin Braun / bme280
Committer:
loopsva
Date:
Thu Apr 21 23:32:50 2016 +0000
Revision:
1:d8d62aee6d5b
Parent:
bme280.cpp@0:40b4ebf843c6
Library for Vishay VEML6040 RGBW and VEML6075 UVA & UVB opto sensors

Who changed what in which revision?

UserRevisionLine numberNew contents of line
loopsva 1:d8d62aee6d5b 1 // Vishay veml6040 RGBW and veml6075 UVA + UVB optical sensors
loopsva 0:40b4ebf843c6 2
loopsva 1:d8d62aee6d5b 3 #include "veml60xx.h"
loopsva 0:40b4ebf843c6 4
loopsva 0:40b4ebf843c6 5 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 1:d8d62aee6d5b 6 // Constructor, to allow for user to select i2c frequency
loopsva 0:40b4ebf843c6 7
loopsva 1:d8d62aee6d5b 8 veml60xx::veml60xx(PinName sda, PinName scl, int i2cFrequency) {
loopsva 1:d8d62aee6d5b 9 _i2c_ = new I2C(sda, scl);
loopsva 1:d8d62aee6d5b 10 _i2c_->frequency(i2cFrequency);
loopsva 0:40b4ebf843c6 11 }
loopsva 0:40b4ebf843c6 12
loopsva 0:40b4ebf843c6 13 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 14 // deconstructor
loopsva 0:40b4ebf843c6 15
loopsva 1:d8d62aee6d5b 16 veml60xx::~veml60xx() {
loopsva 0:40b4ebf843c6 17 }
loopsva 0:40b4ebf843c6 18
loopsva 0:40b4ebf843c6 19 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 1:d8d62aee6d5b 20 // Set/initialize the veml60xx config register.
loopsva 0:40b4ebf843c6 21
loopsva 1:d8d62aee6d5b 22 void veml60xx::setConfig(veml60xx_struct& Pntr, uint16_t val) {
loopsva 1:d8d62aee6d5b 23 vemlBuffer[0] = VEML60xx_CONF_REG;
loopsva 1:d8d62aee6d5b 24 vemlBuffer[1] = val;
loopsva 1:d8d62aee6d5b 25 //vemlBuffer[1] = VEML60xx_CONF_BITS_IT_400m320m | val;
loopsva 1:d8d62aee6d5b 26 //vemlBuffer[1] = VEML60xx_CONF_BITS_IT_400m320m | VEML6075_CONF_BITS_HD;
loopsva 1:d8d62aee6d5b 27 //vemlBuffer[1] = VEML60xx_CONF_BITS_IT_400m320m | VEML6075_CONF_BITS_HD | VEML60xx_CONF_BITS_AF;
loopsva 1:d8d62aee6d5b 28 vemlBuffer[2] = 0;
loopsva 1:d8d62aee6d5b 29 _i2c_->write(VEML60_WADDR, vemlBuffer, 3, false);
loopsva 1:d8d62aee6d5b 30 Pntr.conf_reg = (vemlBuffer[2] << 8) | vemlBuffer[1];
loopsva 0:40b4ebf843c6 31 }
loopsva 0:40b4ebf843c6 32
loopsva 0:40b4ebf843c6 33 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 1:d8d62aee6d5b 34 // Get veml60xx ID register. Returns register value
loopsva 1:d8d62aee6d5b 35 // Note: the veml6040 does hvae a device ID, but is not in datasheet
loopsva 0:40b4ebf843c6 36
loopsva 1:d8d62aee6d5b 37 uint16_t veml60xx::getID(veml60xx_struct& Pntr) {
loopsva 1:d8d62aee6d5b 38 vemlBuffer[0] = VEML6075_CHIP_ID_REG;
loopsva 1:d8d62aee6d5b 39 _i2c_->write(VEML60_WADDR, vemlBuffer, 1, true);
loopsva 1:d8d62aee6d5b 40 _i2c_->read(VEML60_RADDR, vemlBuffer, 2, false);
loopsva 1:d8d62aee6d5b 41 uint16_t rdata = (vemlBuffer[1] << 8) | vemlBuffer[0];
loopsva 1:d8d62aee6d5b 42 if((rdata & VEML6075_DEVICE_ID) == VEML6075_DEVICE_ID) {
loopsva 1:d8d62aee6d5b 43 Pntr.is6075 = true;
loopsva 1:d8d62aee6d5b 44 Pntr.is6040 = false;
loopsva 1:d8d62aee6d5b 45 } else
loopsva 1:d8d62aee6d5b 46 if((rdata & VEML6040_DEVICE_ID) == VEML6040_DEVICE_ID) {
loopsva 1:d8d62aee6d5b 47 Pntr.is6075 = false;
loopsva 1:d8d62aee6d5b 48 Pntr.is6040 = true;
loopsva 1:d8d62aee6d5b 49 } else {
loopsva 1:d8d62aee6d5b 50 Pntr.is6075 = false;
loopsva 1:d8d62aee6d5b 51 Pntr.is6040 = false;
loopsva 1:d8d62aee6d5b 52 }
loopsva 0:40b4ebf843c6 53 return(rdata);
loopsva 0:40b4ebf843c6 54 }
loopsva 0:40b4ebf843c6 55
loopsva 0:40b4ebf843c6 56 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 1:d8d62aee6d5b 57 // Get veml60xx config register. Returns register value
loopsva 0:40b4ebf843c6 58
loopsva 1:d8d62aee6d5b 59 uint16_t veml60xx::getConfig(veml60xx_struct& Pntr) {
loopsva 1:d8d62aee6d5b 60 vemlBuffer[0] = VEML60xx_CONF_REG;
loopsva 1:d8d62aee6d5b 61 _i2c_->write(VEML60_WADDR, vemlBuffer, 1, true);
loopsva 1:d8d62aee6d5b 62 _i2c_->read(VEML60_RADDR, vemlBuffer, 2, false);
loopsva 1:d8d62aee6d5b 63 uint16_t rdata = (vemlBuffer[1] << 8) | vemlBuffer[0];
loopsva 1:d8d62aee6d5b 64 if(Pntr.is6040) {
loopsva 1:d8d62aee6d5b 65 uint16_t c = rdata & VEML60xx_CONF_BITS_IT;
loopsva 1:d8d62aee6d5b 66 switch (c) {
loopsva 1:d8d62aee6d5b 67 case VEML60xx_CONF_BITS_IT_50m40m:
loopsva 1:d8d62aee6d5b 68 Pntr.lux_step = VEML6040_LUX_STEP_000;
loopsva 1:d8d62aee6d5b 69 break;
loopsva 1:d8d62aee6d5b 70 case VEML60xx_CONF_BITS_IT_100m80m:
loopsva 1:d8d62aee6d5b 71 Pntr.lux_step = VEML6040_LUX_STEP_001;
loopsva 1:d8d62aee6d5b 72 break;
loopsva 1:d8d62aee6d5b 73 case VEML60xx_CONF_BITS_IT_200m160m:
loopsva 1:d8d62aee6d5b 74 Pntr.lux_step = VEML6040_LUX_STEP_010;
loopsva 1:d8d62aee6d5b 75 break;
loopsva 1:d8d62aee6d5b 76 case VEML60xx_CONF_BITS_IT_400m320m:
loopsva 1:d8d62aee6d5b 77 Pntr.lux_step = VEML6040_LUX_STEP_011;
loopsva 1:d8d62aee6d5b 78 break;
loopsva 1:d8d62aee6d5b 79 case VEML60xx_CONF_BITS_IT_800m640m:
loopsva 1:d8d62aee6d5b 80 Pntr.lux_step = VEML6040_LUX_STEP_100;
loopsva 1:d8d62aee6d5b 81 break;
loopsva 1:d8d62aee6d5b 82 case VEML6040_CONF_BITS_IT_1280m:
loopsva 1:d8d62aee6d5b 83 Pntr.lux_step = VEML6040_LUX_STEP_101;
loopsva 1:d8d62aee6d5b 84 break;
loopsva 1:d8d62aee6d5b 85 default:
loopsva 1:d8d62aee6d5b 86 Pntr.lux_step = 0.0;
loopsva 1:d8d62aee6d5b 87 break;
loopsva 1:d8d62aee6d5b 88 }
loopsva 1:d8d62aee6d5b 89 }
loopsva 0:40b4ebf843c6 90 return(rdata);
loopsva 0:40b4ebf843c6 91 }
loopsva 0:40b4ebf843c6 92
loopsva 0:40b4ebf843c6 93 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 1:d8d62aee6d5b 94 // If AF set to trigger mode, start a conversion process trigger
loopsva 1:d8d62aee6d5b 95 // Returns: 0=trigger set, 1=already triggered, 2=no AF bit - cannot set trigger
loopsva 0:40b4ebf843c6 96
loopsva 1:d8d62aee6d5b 97 uint16_t veml60xx::startAccess(veml60xx_struct& Pntr) {
loopsva 1:d8d62aee6d5b 98 uint16_t val = getConfig(Pntr);
loopsva 1:d8d62aee6d5b 99 if((val & VEML60xx_CONF_BITS_AF) == VEML60xx_CONF_BITS_AF) {
loopsva 1:d8d62aee6d5b 100 if((val & VEML60xx_CONF_BITS_TRIG) == VEML60xx_CONF_BITS_TRIG) return(1);
loopsva 1:d8d62aee6d5b 101 val |= VEML60xx_CONF_BITS_TRIG;
loopsva 1:d8d62aee6d5b 102 setConfig(Pntr, val);
loopsva 1:d8d62aee6d5b 103 return(0);
loopsva 1:d8d62aee6d5b 104 }
loopsva 1:d8d62aee6d5b 105 return(2);
loopsva 1:d8d62aee6d5b 106 }
loopsva 1:d8d62aee6d5b 107
loopsva 1:d8d62aee6d5b 108 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 1:d8d62aee6d5b 109 // Get VEML60xx values. Saves raw data is data structure. Returns 0 if successful, !0 if status is (something else);
loopsva 1:d8d62aee6d5b 110 // mode: false = VEML6075, true = VEML6040
loopsva 0:40b4ebf843c6 111
loopsva 1:d8d62aee6d5b 112 uint16_t veml60xx::getRawData(veml60xx_struct& Pntr) {
loopsva 1:d8d62aee6d5b 113 Pntr.conf_reg = getConfig(Pntr);
loopsva 1:d8d62aee6d5b 114 Pntr.id = getID(Pntr);
loopsva 1:d8d62aee6d5b 115
loopsva 1:d8d62aee6d5b 116 if(Pntr.is6075) {
loopsva 1:d8d62aee6d5b 117 vemlBuffer[0] = VEML6075_UVA_DATA_REG;
loopsva 1:d8d62aee6d5b 118 _i2c_->write(VEML60_WADDR, vemlBuffer, 1, true);
loopsva 1:d8d62aee6d5b 119 _i2c_->read(VEML60_RADDR, vemlBuffer, 2, false);
loopsva 1:d8d62aee6d5b 120 Pntr.uva_d = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
loopsva 1:d8d62aee6d5b 121 }
loopsva 1:d8d62aee6d5b 122
loopsva 1:d8d62aee6d5b 123 vemlBuffer[0] = VEML6075_DUMMY_REG;
loopsva 1:d8d62aee6d5b 124 _i2c_->write(VEML60_WADDR, vemlBuffer, 1, true);
loopsva 1:d8d62aee6d5b 125 _i2c_->read(VEML60_RADDR, vemlBuffer, 2, false);
loopsva 1:d8d62aee6d5b 126 if(Pntr.is6075) {
loopsva 1:d8d62aee6d5b 127 Pntr.dummy_d = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
loopsva 1:d8d62aee6d5b 128 } else
loopsva 1:d8d62aee6d5b 129 if(Pntr.is6040) {
loopsva 1:d8d62aee6d5b 130 Pntr.r_d = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
loopsva 1:d8d62aee6d5b 131 }
loopsva 1:d8d62aee6d5b 132
loopsva 1:d8d62aee6d5b 133 vemlBuffer[0] = VEML6075_UVB_DATA_REG;
loopsva 1:d8d62aee6d5b 134 _i2c_->write(VEML60_WADDR, vemlBuffer, 1, true);
loopsva 1:d8d62aee6d5b 135 _i2c_->read(VEML60_RADDR, vemlBuffer, 2, false);
loopsva 1:d8d62aee6d5b 136 if(Pntr.is6075) {
loopsva 1:d8d62aee6d5b 137 Pntr.uvb_d = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
loopsva 1:d8d62aee6d5b 138 } else
loopsva 1:d8d62aee6d5b 139 if(Pntr.is6040) {
loopsva 1:d8d62aee6d5b 140 Pntr.g_d = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
loopsva 1:d8d62aee6d5b 141 }
loopsva 1:d8d62aee6d5b 142
loopsva 1:d8d62aee6d5b 143 vemlBuffer[0] = VEML6075_UV_COMP1_REG;
loopsva 1:d8d62aee6d5b 144 _i2c_->write(VEML60_WADDR, vemlBuffer, 1, true);
loopsva 1:d8d62aee6d5b 145 _i2c_->read(VEML60_RADDR, vemlBuffer, 2, false);
loopsva 1:d8d62aee6d5b 146 if(Pntr.is6075) {
loopsva 1:d8d62aee6d5b 147 Pntr.uv_c1 = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
loopsva 1:d8d62aee6d5b 148 } else
loopsva 1:d8d62aee6d5b 149 if(Pntr.is6040) {
loopsva 1:d8d62aee6d5b 150 Pntr.b_d = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
loopsva 1:d8d62aee6d5b 151 }
loopsva 1:d8d62aee6d5b 152
loopsva 1:d8d62aee6d5b 153 vemlBuffer[0] = VEML6075_UV_COMP2_REG;
loopsva 1:d8d62aee6d5b 154 _i2c_->write(VEML60_WADDR, vemlBuffer, 1, true);
loopsva 1:d8d62aee6d5b 155 _i2c_->read(VEML60_RADDR, vemlBuffer, 2, false);
loopsva 1:d8d62aee6d5b 156 if(Pntr.is6075) {
loopsva 1:d8d62aee6d5b 157 Pntr.uv_c1 = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
loopsva 1:d8d62aee6d5b 158 } else
loopsva 1:d8d62aee6d5b 159 if(Pntr.is6040) {
loopsva 1:d8d62aee6d5b 160 Pntr.w_d = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
loopsva 1:d8d62aee6d5b 161 }
loopsva 1:d8d62aee6d5b 162
loopsva 0:40b4ebf843c6 163 return(0);
loopsva 0:40b4ebf843c6 164 }
loopsva 0:40b4ebf843c6 165
loopsva 0:40b4ebf843c6 166 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 1:d8d62aee6d5b 167 // Convert raw data into real UVA, UVB and UVI numbers
loopsva 0:40b4ebf843c6 168
loopsva 1:d8d62aee6d5b 169 void veml60xx::convertRawData(veml60xx_struct& Pntr) {
loopsva 1:d8d62aee6d5b 170 getRawData(Pntr);
loopsva 1:d8d62aee6d5b 171
loopsva 1:d8d62aee6d5b 172 //Eq (1)
loopsva 1:d8d62aee6d5b 173 Pntr.uva_comp = (double)(Pntr.uva_d - Pntr.dummy_d) -
loopsva 1:d8d62aee6d5b 174 VEML6075_UVA_COEF_A * (double)(Pntr.uv_c1 - Pntr.dummy_d) -
loopsva 1:d8d62aee6d5b 175 VEML6075_UVA_COEF_B * (double)(Pntr.uv_c2 - Pntr.dummy_d);
loopsva 1:d8d62aee6d5b 176
loopsva 1:d8d62aee6d5b 177 //Eq (2)
loopsva 1:d8d62aee6d5b 178 Pntr.uvb_comp = (double)(Pntr.uvb_d - Pntr.dummy_d) -
loopsva 1:d8d62aee6d5b 179 VEML6075_UVB_COEF_C * (double)(Pntr.uv_c1 - Pntr.dummy_d) -
loopsva 1:d8d62aee6d5b 180 VEML6075_UVB_COEF_D * (double)(Pntr.uv_c2 - Pntr.dummy_d);
loopsva 1:d8d62aee6d5b 181 //Eq (3)
loopsva 1:d8d62aee6d5b 182 Pntr.uv_index = ((Pntr.uva_comp * VEML6075_UVA_RESP) + (Pntr.uvb_comp * VEML6075_UVB_RESP))/2.0;
loopsva 0:40b4ebf843c6 183 }
loopsva 1:d8d62aee6d5b 184
loopsva 0:40b4ebf843c6 185
loopsva 0:40b4ebf843c6 186 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 1:d8d62aee6d5b 187 // If there is a lux over/underflow, automatically adjust the CONF_BITS_IT by +-1 to compensate accordingly
loopsva 1:d8d62aee6d5b 188 // if returns true, the Lux level was changed.
loopsva 0:40b4ebf843c6 189
loopsva 1:d8d62aee6d5b 190 bool veml60xx::autoAdjustLux(veml60xx_struct& Pntr) {
loopsva 1:d8d62aee6d5b 191 getRawData(Pntr);
loopsva 1:d8d62aee6d5b 192 uint16_t rdata = Pntr.conf_reg;
loopsva 1:d8d62aee6d5b 193 uint16_t lux = rdata & VEML60xx_CONF_BITS_IT;
loopsva 1:d8d62aee6d5b 194 if(Pntr.is6040) {
loopsva 1:d8d62aee6d5b 195 if((Pntr.r_d < 255) && (Pntr.g_d < 255) && (Pntr.b_d < 255) && (Pntr.w_d < 255)) {
loopsva 1:d8d62aee6d5b 196 if(lux == VEML6040_CONF_BITS_IT_1280m) return false;
loopsva 1:d8d62aee6d5b 197 lux += VEML60xx_CONF_BITS_IT_100m80m;
loopsva 1:d8d62aee6d5b 198 rdata = (rdata & ~VEML60xx_CONF_BITS_IT) | lux;
loopsva 1:d8d62aee6d5b 199 setConfig(Pntr, rdata);
loopsva 1:d8d62aee6d5b 200 return true;
loopsva 1:d8d62aee6d5b 201 } else
loopsva 1:d8d62aee6d5b 202 if((Pntr.r_d == 65535) || (Pntr.g_d == 65535) || (Pntr.b_d == 65535) || (Pntr.w_d == 65535)) {
loopsva 1:d8d62aee6d5b 203 if(lux == VEML60xx_CONF_BITS_IT_50m40m) return false;
loopsva 1:d8d62aee6d5b 204 lux -= VEML60xx_CONF_BITS_IT_100m80m;
loopsva 1:d8d62aee6d5b 205 rdata = (rdata & ~VEML60xx_CONF_BITS_IT) | lux;
loopsva 1:d8d62aee6d5b 206 setConfig(Pntr, rdata);
loopsva 1:d8d62aee6d5b 207 return true;
loopsva 1:d8d62aee6d5b 208 }
loopsva 1:d8d62aee6d5b 209 } else
loopsva 1:d8d62aee6d5b 210 if(Pntr.is6075) {
loopsva 1:d8d62aee6d5b 211 if((Pntr.uva_d < 255) && (Pntr.uvb_d < 255)) {
loopsva 1:d8d62aee6d5b 212 if(lux == VEML60xx_CONF_BITS_IT_800m640m) return false;
loopsva 1:d8d62aee6d5b 213 lux += VEML60xx_CONF_BITS_IT_100m80m;
loopsva 1:d8d62aee6d5b 214 rdata = (rdata & ~VEML60xx_CONF_BITS_IT) | lux;
loopsva 1:d8d62aee6d5b 215 setConfig(Pntr, rdata);
loopsva 1:d8d62aee6d5b 216 return true;
loopsva 1:d8d62aee6d5b 217 } else
loopsva 1:d8d62aee6d5b 218 if((Pntr.uva_d == 65535) || (Pntr.uvb_d == 65535)) {
loopsva 1:d8d62aee6d5b 219 if(lux == VEML60xx_CONF_BITS_IT_50m40m) return false;
loopsva 1:d8d62aee6d5b 220 lux -= VEML60xx_CONF_BITS_IT_100m80m;
loopsva 1:d8d62aee6d5b 221 rdata = (rdata & ~VEML60xx_CONF_BITS_IT) | lux;
loopsva 1:d8d62aee6d5b 222 setConfig(Pntr, rdata);
loopsva 1:d8d62aee6d5b 223 return true;
loopsva 1:d8d62aee6d5b 224 }
loopsva 0:40b4ebf843c6 225 }
loopsva 1:d8d62aee6d5b 226 return false;
loopsva 0:40b4ebf843c6 227 }
loopsva 1:d8d62aee6d5b 228
loopsva 1:d8d62aee6d5b 229