Release candidate version. The pointer in GAS Pressure display is changed to a triangle.

Dependencies:   UniGraphic mbed vt100

Please note, at 2-Mar-2018 the current version of mbed-lib has a defect in Ticker.
https://os.mbed.com/forum/bugs-suggestions/topic/29287/

So, mbed lib version 157 is intentionally being used.
Please do not update mbed library until the problem in the above URL is fixed.

In this version, format of GAS Pressure Display has been changed.
/media/uploads/Rhyme/low.jpg

/media/uploads/Rhyme/good.jpg

/media/uploads/Rhyme/high.jpg

moto

sensors/VEML6040.cpp

Committer:
Rhyme
Date:
2018-03-02
Revision:
0:774324cbc5a6

File content as of revision 0:774324cbc5a6:

/*
 * 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) ;
}