Color sensor reset at the end of calibration added. sensor id auto assignment was changed to be a fixed value assignment to avoid sensor id shift when some sensor is absent.
Dependencies: UniGraphic mbed vt100
Diff: sensors/VEML6040.cpp
- Revision:
- 0:ce97f6d34336
diff -r 000000000000 -r ce97f6d34336 sensors/VEML6040.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sensors/VEML6040.cpp Fri Feb 23 05:40:22 2018 +0000 @@ -0,0 +1,285 @@ +/* + * File description here + */ +#include "VEML6040.h" +#include "af_mgr.h" + +/* VEML6075 SLAVE ADDRESS AND FUNCTION DESCRIPTION */ +#define REG_COLOR_CONF 0x00 +#define REG_Reserved1 0x01 +#define REG_Reserved2 0x02 +#define REG_Reserved3 0x03 +#define REG_Reserved4 0x04 +#define REG_Reserved5 0x05 +#define REG_Reserved6 0x06 +#define REG_Reserved7 0x07 +#define REG_R_Data 0x08 +#define REG_G_Data 0x09 +#define REG_B_Data 0x0A +#define REG_W_Data 0x0B + +// Following magic numbers are from +// VISHAY VEML6040 Application Note 84331 +// Page 4 +#define LUX_RESOLUTION_0 (0.25168) +#define LUX_RESOLUTION_1 (0.12584) +#define LUX_RESOLUTION_2 (0.06292) +#define LUX_RESOLUTION_3 (0.03146) +#define LUX_RESOLUTION_4 (0.01573) +#define LUX_RESOLUTION_5 (0.007865) + +// Following magic numbers are from +// VISHAY VEML6040 Application Note 84331 +// Page 9 +#define CORR_COEFF_M0 (0.048403) +#define CORR_COEFF_M1 (0.183633) +#define CORR_COEFF_M2 (-0.253589) +#define CORR_COEFF_M3 (0.022916) +#define CORR_COEFF_M4 (0.176388) +#define CORR_COEFF_M5 (-0.183205) +#define CORR_COEFF_M6 (-0.077436) +#define CORR_COEFF_M7 (0.124541) +#define CORR_COEFF_M8 (0.032081) + +// Following magic numbers are from +// VISHAY VEML6040 Application Note 84331 +// Page 10 +#define CCT_CONST (4278.6) +#define OFFSET_OPEN_AIR (0.5) + +VEML6040::VEML6040(I2C *i2c, int addr) : m_addr(addr<<1) { + p_i2c = i2c ; + p_i2c->frequency(100000); /* 100kHz */ + // activate the peripheral +} + +VEML6040::~VEML6040() { } + +/** + * set COLOR Config + * @param colorconf uint8_t 8bit register value + * @returns 0: success non-0: failure + * @note Command Code 0x00 is used to access CONF register + * @note bit[7] (reserved) + * @note bit[6:4] = IT[2:0] Integration Time Selector + * @note bit[3] (reserved) + * @note bit[2] TRIG Proceed one detcting cycle at manual force mode + * @note bit[1] AF 0: Auto mode 1: manual force mode + * @note bit[0] SD 0: normal 1: chip shutdown setting + * + * @note IT[2:0] 0=40ms, 1=80ms, 2=160ms, 3=320ms, 4=640ms, 5=1280ms + * @note as our WatchDog is set to 1sec, 1280ms is invalid + * @note and 640ms may not be practical + */ +int VEML6040::setCOLORConf(uint8_t colorconf) +{ + int result ; + uint8_t data[3] ; + data[0] = REG_COLOR_CONF ; + data[1] = colorconf ; + data[2] = 0 ; + result = writeRegs(data, 3) ; + return( result ) ; +} + +/** + * get COLOR Config + * @param *colorconf uint8_t refer to setCOLORConf for the value + * @returns 0: success non-0: failure + */ +int VEML6040::getCOLORConf(uint8_t *colorconf) +{ + int result ; + uint8_t data[2] ; + result = readRegs(REG_COLOR_CONF, data, 2) ; + if (result == 0) { + *colorconf = data[0] ; + } + return( result ) ; +} + + + +int VEML6040::getRData(uint16_t *rdata) +{ + uint8_t data[2] ; + int result ; + result = readRegs(REG_R_Data, data, 2) ; + *rdata = (data[1]<<8) | data[0] ; + return( result ) ; +} + +int VEML6040::getGData(uint16_t *gdata) +{ + uint8_t data[2] ; + int result ; + result = readRegs(REG_G_Data, data, 2) ; + *gdata = (data[1]<<8) | data[0] ; + return( result ) ; +} + +int VEML6040::getBData(uint16_t *bdata) +{ + uint8_t data[2] ; + int result ; + result = readRegs(REG_B_Data, data, 2) ; + *bdata = (data[1]<<8) | data[0] ; + return( result ) ; +} + +int VEML6040::getWData(uint16_t *wdata) +{ + uint8_t data[2] ; + int result ; + result = readRegs(REG_W_Data, data, 2) ; + *wdata = (data[1]<<8) | data[0] ; + return( result ) ; +} + +// usage +// fvalue = veml->getUVA() ; +// printf("%f", fvalue) ; +float VEML6040::getR(void) +{ + uint16_t data ; + float value ; + getRData(&data) ; + value = (float)LUX_RESOLUTION_0 * (float)data ; + return( value ) ; +} + +float VEML6040::getG(void) +{ + uint16_t data ; + float value ; + getGData(&data) ; + value = (float)LUX_RESOLUTION_0 * (float)data ; + return( value ) ; +} + +float VEML6040::getB(void) +{ + uint16_t data ; + float value ; + getBData(&data) ; + value = (float)LUX_RESOLUTION_0 * (float)data ; + return( value ) ; +} + +float VEML6040::getW(void) +{ + uint16_t data ; + float value ; + getWData(&data) ; + value = (float)LUX_RESOLUTION_0 * (float)data ; + return( value ) ; +} + +float VEML6040::getX(void) +{ + uint16_t R ; + uint16_t G ; + uint16_t B ; + float value ; + getRData(&R) ; + getGData(&G) ; + getBData(&B) ; + value = (float)CORR_COEFF_M0 * (float)R + (float)CORR_COEFF_M1 * (float)G + (float)CORR_COEFF_M2 * (float)B ; + return( value ) ; +} + +float VEML6040::getY(void) +{ + uint16_t R ; + uint16_t G ; + uint16_t B ; + float value ; + getRData(&R) ; + getGData(&G) ; + getBData(&B) ; + value = (float)CORR_COEFF_M3 * (float)R + (float)CORR_COEFF_M4 * (float)G + (float)CORR_COEFF_M5 * (float)B ; + return( value ) ; +} + +float VEML6040::getZ(void) +{ + uint16_t R ; + uint16_t G ; + uint16_t B ; + float value ; + getRData(&R) ; + getGData(&G) ; + getBData(&B) ; + value = (float)CORR_COEFF_M6 * (float)R + (float)CORR_COEFF_M7 * (float)G + (float)CORR_COEFF_M8 * (float)B ; + return( value ) ; +} + +float VEML6040::getCCTiData(void) +{ + uint16_t rdata ; + uint16_t gdata ; + uint16_t bdata ; + float value ; + getRData(&rdata) ; + getGData(&gdata) ; + getBData(&bdata) ; + value = ((float)rdata - (float)bdata) / (float)gdata + (float)OFFSET_OPEN_AIR ; + return( value ) ; +} + +float VEML6040::getCCTData(void) +{ +// uint16_t cctidata ; + float cctidata ; + float value ; + cctidata = getCCTiData() ; +// getCCTiData(&cctidata) ; + value = (float)CCT_CONST * powf( cctidata, -1.2455 ) ; + return( value ) ; +} + +float VEML6040::getCIEX(void) +{ + float X ; + float Y ; + float Z ; + float value ; + X = getX() ; + Y = getY() ; + Z = getZ() ; + value = (float)X / ((float)X + (float)Y + (float)Z) ; + return( value ) ; +} + +float VEML6040::getCIEY(void) +{ + float X ; + float Y ; + float Z ; + float value ; + X = getX() ; + Y = getY() ; + Z = getZ() ; + value = (float)Y / ((float)X + (float)Y + (float)Z) ; + return( value ) ; +} + +int VEML6040::readRegs(int addr, uint8_t * data, int len) { + char t[1] = {addr}; + int result ; + __disable_irq() ; // Disable Interrupts + result = p_i2c->write(m_addr, t, 1, true); + if (result == 0) { // write success + result = p_i2c->read(m_addr, (char *)data, len, false); + } + __enable_irq() ; // Enable Interrupts + return(result) ; +} + +int VEML6040::writeRegs(uint8_t * data, int len) { + int result ; + __disable_irq() ; // Disable Interrupts + result = p_i2c->write(m_addr, (char *)data, len); + __enable_irq() ; // Enable Interrupts + return(result) ; +} \ No newline at end of file