Demonstration program for the VEML6040 and VEML6075 optical sensors

Dependencies:   VEML60xx mbed

main.cpp

Committer:
loopsva
Date:
2016-05-02
Revision:
5:be5c1d562334
Parent:
4:28b380ba35e4

File content as of revision 5:be5c1d562334:

#include "mbed.h"
#include "veml60xx.h"                       //Vishay VEML6075 UVA & UVB sensor

Serial pc(USBTX, USBRX);

#define SDA0                D14 //PTE25
#define SCL0                D15 //PTE24

veml60xx veml(SDA0, SCL0, 400000);                //UV sensor
veml60xx::veml60xx_struct vemlSTR = {};           //data structure for VEML60xx

//--------------------------------------------------------------------------------------------------------------------------------------//
// Print build date / time  Note: display is UTC, not local time

void printBuildDate() {
    pc.printf("FRDM-K64F + VEML6040 and VEML6075 ");
    pc.printf("   -> build: " __DATE__ " " __TIME__ "(UTC)  K Braun\n");
}

//--------------------------------------------------------------------------------------------------------------------------------------//
// initial splash display

void initSplash() {
    pc.printf("\r\n\r\n");
    pc.printf("--------------------------------------------------------------------------------\r\n");
    printBuildDate();
}

//--------------------------------------------------------------------------------------------------------------------------------------//
// Show VEML60xx contents

int cnts = 0;

void dispVeml60xxc() {
    uint16_t rdata = veml.getConfig(vemlSTR);
    if((rdata & VEML60xx_CONF_BITS_AF) == VEML60xx_CONF_BITS_AF) {
        rdata = veml.startAccess(vemlSTR);
        if(rdata == 0) {
            int rcnt = 0;
            while(1) {
                rdata = veml.getConfig(vemlSTR);
                if(!((rdata & VEML60xx_CONF_BITS_TRIG) == VEML60xx_CONF_BITS_TRIG)) break;
#ifdef RTOS_H
                Thread::wait(1);
#else
                wait_ms(1);
#endif
                rcnt++;
                if(rcnt > 2000) break;
            }
            pc.printf("VEML60xx count: %d\r\n", rcnt);
            if(rcnt > 2000) return; 
        } else {
            pc.printf("unexpected VEML60xx error : %d\r\n", rdata);
            return;
        }
    }
    
    cnts++;
//NOTE: 6040 is auto adjust, 6075 is manual with "opto 0" to "opto 4" cli command. 4 = highest resolution               
    if(vemlSTR.is6075) {
        veml.getRawData(vemlSTR);
        bool chgd = false;
        //bool chgd = veml.autoAdjustLux(vemlSTR);
        pc.printf("\r\nVEML6075 contents, count:  %6d\r\n", cnts);
        pc.printf("- id:        %04xh\r\n", vemlSTR.id);
        pc.printf("- conf:      %04xh\r\n", vemlSTR.conf_reg);
        pc.printf("- trig_dly:  %dmS\r\n", vemlSTR.trig_dly);
        pc.printf("- uva_step:  %.6f\r\n", vemlSTR.uva_step);
        pc.printf("- uvb_step:  %.6f\r\n\r\n", vemlSTR.uvb_step);
        if(chgd) {
            pc.printf("Adjusting Lux level, try again...\r\n");
            return;
        }
        veml.convertRawData(vemlSTR);
        pc.printf("- uva_d:     %04xh\r\n", vemlSTR.uva_d);
        pc.printf("- uvb_d:     %04xh\r\n", vemlSTR.uvb_d);
        pc.printf("- dummy_d:   %04xh\r\n", vemlSTR.dummy_d);
        pc.printf("- uv_c1:     %04xh\r\n", vemlSTR.uv_c1);
        pc.printf("- uv_c2:     %04xh\r\n", vemlSTR.uv_c2);
        pc.printf("- uva_comp:  %.2f\r\n", vemlSTR.uva_comp);
        pc.printf("- uvb_comp:  %.2f\r\n", vemlSTR.uvb_comp);
        pc.printf("- uv_index:  %.2f\r\n", vemlSTR.uv_index);
        if((vemlSTR.uva_d == 65535) || (vemlSTR.uvb_d == 65535)) pc.printf("*** UV overflow!!!\r\n");
    } else 
    if(vemlSTR.is6040) {
        //veml.getRawData(vemlSTR);
        bool chgd = veml.autoAdjustLux(vemlSTR);
        pc.printf("\r\nVEML6040 contents, count:  %6d\r\n", cnts);
        pc.printf("- id:        %04xh\r\n", vemlSTR.id);
        pc.printf("- conf:      %04xh\r\n", vemlSTR.conf_reg);
        pc.printf("- trig_dly:  %dmS\r\n", vemlSTR.trig_dly);
        pc.printf("- lux_step:  %.6f\r\n\r\n", vemlSTR.lux_step);
        if(chgd) {
            pc.printf("Adjusting Lux level, try again...\r\n");
            return;
        }
        veml.convertRawData(vemlSTR);
        pc.printf("- r_d:       %04xh   %5dd   %9.3f Lux\r\n", vemlSTR.r_d, vemlSTR.r_d, vemlSTR.r_lux);
        pc.printf("- g_d:       %04xh   %5dd   %9.3f Lux\r\n", vemlSTR.g_d, vemlSTR.g_d, vemlSTR.g_lux);
        pc.printf("- b_d:       %04xh   %5dd   %9.3f Lux\r\n", vemlSTR.b_d, vemlSTR.b_d, vemlSTR.b_lux);
        pc.printf("- w_d:       %04xh   %5dd   %9.3f Lux\r\n", vemlSTR.w_d, vemlSTR.w_d, vemlSTR.w_lux);
        double cct = 4278.8 * pow((vemlSTR.r_lux - vemlSTR.b_lux) / vemlSTR.g_lux + 0.5, -1.2455);
        pc.printf("- cct:       %5d K\r\n", (int)rint(cct));
        if((vemlSTR.r_d == 65535) || (vemlSTR.g_d == 65535) || (vemlSTR.b_d == 65535) || (vemlSTR.w_d == 65535)) pc.printf("*** RGBW overflow!!!\r\n");
    } else {
        pc.printf("No VEML60xx device detected...\r\n");
    }
}
    
//--------------------------------------------------------------------------------------------------------------------------------------//
// Show VEML60xx contents

int cnt = 0;

void dispVeml60xx() {
    uint16_t rdata = veml.getConfig(vemlSTR);
    bool chgd = false;
    //see if AF bit set.  If AF set, set TRIG then wait for access to complete
    if((rdata & VEML60xx_CONF_BITS_AF) == VEML60xx_CONF_BITS_AF) {
        pc.printf("Triggered mode...  ");
        rdata = veml.startAccess(vemlSTR);
        chgd = false;
        if(rdata) {
            pc.printf("unexpected VEML60xx error : %d\r\n", rdata);
            return;
        }
#ifdef RTOS_H
        for(int i = 0; i < 4; i++) {
            Thread::wait(vemlSTR.trig_dly >> 2);
            cli_t++;
            housek_t++;
            tftp_t++;
        }
#else
        wait_ms(vemlSTR.trig_dly);
#endif
        pc.printf("\r\n");
    }
    cnt++;
    
    //NOTE: 6040 is auto adjust, 6075 is manual with "opto 0" to "opto 4" cli command. 4 = highest resolution               
    if(vemlSTR.is6075) {
        veml.getRawData(vemlSTR);
        //if(!(chgd)) chgd = veml.autoAdjustLux(vemlSTR);
        pc.printf("\r\nVEML6075 contents, count:  %6d\r\n", cnt);
        pc.printf("- id:        %04xh\r\n", vemlSTR.id);
        pc.printf("- conf:      %04xh\r\n", vemlSTR.conf_reg);
        pc.printf("- trig_dly:  %dmS\r\n", vemlSTR.trig_dly);
        if(chgd) {
            pc.printf("Adjusting Lux level, try again...\r\n");
            chgd = false;
            return;
        }
        pc.printf("- uva_step:  %.6f\r\n", vemlSTR.uva_step);
        pc.printf("- uvb_step:  %.6f\r\n\r\n", vemlSTR.uvb_step);
        veml.convertRawData(vemlSTR);
        pc.printf("- uva_d:     %04xh\r\n", vemlSTR.uva_d);
        pc.printf("- uvb_d:     %04xh\r\n", vemlSTR.uvb_d);
        pc.printf("- dummy_d:   %04xh\r\n", vemlSTR.dummy_d);
        pc.printf("- uv_c1:     %04xh\r\n", vemlSTR.uv_c1);
        pc.printf("- uv_c2:     %04xh\r\n", vemlSTR.uv_c2);
        pc.printf("- uva_comp:  %.2f\r\n", vemlSTR.uva_comp);
        pc.printf("- uvb_comp:  %.2f\r\n", vemlSTR.uvb_comp);
        pc.printf("- uv_index:  %.2f   ", vemlSTR.uv_index);
        if(vemlSTR.uv_index >=  11.0) pc.printf("!!! EXTREME !!!\r\n");
        if((vemlSTR.uv_index < 11.0) && (vemlSTR.uv_index >= 8.0)) pc.printf(" !! VERY HIGH !!\r\n");
        if((vemlSTR.uv_index <  8.0) && (vemlSTR.uv_index >= 6.0)) pc.printf(" High\r\n");
        if((vemlSTR.uv_index <  6.0) && (vemlSTR.uv_index >= 3.0)) pc.printf(" Moderate\r\n");
        if((vemlSTR.uv_index <  3.0) && (vemlSTR.uv_index > 0.0)) pc.printf(" Low\r\n");
        if(vemlSTR.uv_index ==  0.0) pc.printf(" Safe for Vampires\r\n");
        
        if((vemlSTR.uva_d == 65535) || (vemlSTR.uvb_d == 65535)) pc.printf("*** UV overflow!!!\r\n");
    } else 
    if(vemlSTR.is6040) {
        //veml.getRawData(vemlSTR);
        if(!(chgd)) chgd = veml.autoAdjustLux(vemlSTR);
        pc.printf("\r\nVEML6040 contents, count:  %6d\r\n", cnt);
        pc.printf("- id:         %04xh\r\n", vemlSTR.id);
        pc.printf("- conf:       %04xh\r\n", vemlSTR.conf_reg);
        pc.printf("- trig_dly:   %dmS\r\n", vemlSTR.trig_dly);
        if(chgd) {
            pc.printf("Adjusting Lux level, try again...\r\n");
            chgd = false;
            return;
        }
        pc.printf("- lux_step:   %.6f\r\n\r\n", vemlSTR.lux_step);
        veml.convertRawData(vemlSTR);
        pc.printf("- red:");
        pc.printf("        %04xh   %5dd", vemlSTR.r_d, vemlSTR.r_d);
        pc.printf("   %9.3f Lux\r\n- grn:", vemlSTR.r_lux);
        pc.printf("        %04xh   %5dd", vemlSTR.g_d, vemlSTR.g_d);
        pc.printf("   %9.3f Lux\r\n- blu:", vemlSTR.g_lux);
        pc.printf("        %04xh   %5dd", vemlSTR.b_d, vemlSTR.b_d);
        pc.printf("   %9.3f Lux\r\n- wht:", vemlSTR.b_lux);
        pc.printf("        %04xh   %5dd", vemlSTR.w_d, vemlSTR.w_d);
        pc.printf("   %9.3f Lux\r\n- cct:", vemlSTR.w_lux);
        double cct = 4278.8 * pow((vemlSTR.r_lux - vemlSTR.b_lux) / vemlSTR.g_lux + 0.5, -1.2455);
        pc.printf("       %5d K     ", (int)rint(cct));
        
        if((int)rint(cct) >=  12000) pc.printf("???? Way Blue!!! \r\n");
        if(((int)rint(cct) < 12000) && ((int)rint(cct) >= 9000)) pc.printf("Blue Sky Poleward\r\n");
        if(((int)rint(cct) <  9000) && ((int)rint(cct) >= 7500)) pc.printf("Blue Sky\r\n");
        if(((int)rint(cct) <  7500) && ((int)rint(cct) >= 6500)) pc.printf("Overcast Sky\r\n");
        if(((int)rint(cct) <  6500) && ((int)rint(cct) >= 5500)) pc.printf("Daylight Vertical\r\n");
        if(((int)rint(cct) <  5500) && ((int)rint(cct) >= 5000)) pc.printf("Daylight Horizontal\r\n");
        if(((int)rint(cct) <  5000) && ((int)rint(cct) >= 4500)) pc.printf("Arc Light\r\n");
        if(((int)rint(cct) <  4500) && ((int)rint(cct) >= 4150)) pc.printf("undefined\r\n");
        if(((int)rint(cct) <  4150) && ((int)rint(cct) >= 4100)) pc.printf("Moonlight, Cool\r\n");
        if(((int)rint(cct) <  4100) && ((int)rint(cct) >= 3300)) pc.printf("Neutral\r\n");
        if(((int)rint(cct) <  3300) && ((int)rint(cct) >= 2700)) pc.printf("Soft White\r\n");
        if(((int)rint(cct) <  2700) && ((int)rint(cct) >= 2000)) pc.printf("Sunrise Sunset\r\n");
        if(((int)rint(cct) <  2000) && ((int)rint(cct) >= 1850)) pc.printf("Candle Light\r\n");
        if(((int)rint(cct) <  1850) && ((int)rint(cct) >= 1700)) pc.printf("Match Light\r\n");
        if((int)rint(cct) < 1700) pc.printf("???? Way Red!!! \r\n");
        
        if((vemlSTR.r_d == 65535) || (vemlSTR.g_d == 65535) || (vemlSTR.b_d == 65535) || (vemlSTR.w_d == 65535)) pc.printf("*** RGBW overflow!!!\r\n");
    } else {
        pc.printf("No VEML60xx device detected...\r\n");
    }
    chgd = false;
}   
    
//--------------------------------------------------------------------------------------------------------------------------------------//
//--------------------------------------------------------------------------------------------------------------------------------------//
    
int main() {
    pc.baud(230400);
    initSplash();
    
    //set up the light sensor - UV or RGBW
    pc.printf("Initializing the VEML60xx Opto Sensor...\r\n");
    veml.setConfig(vemlSTR, VEML60xx_CONF_BITS_IT_400m320m);
    //veml.setConfig(vemlSTR, VEML60xx_CONF_BITS_IT_400m320m | VEML60xx_CONF_BITS_AF);
    veml.getID(vemlSTR);
    if(vemlSTR.is6040) pc.printf("- VEML6040 device ID: 0x%04x   CONF: 0x%04x\r\n", vemlSTR.id, vemlSTR.conf_reg);
    if(vemlSTR.is6075) pc.printf("- VEML6075 device ID: 0x%04x   CONF: 0x%04x\r\n", vemlSTR.id, vemlSTR.conf_reg);
    if((!(vemlSTR.is6040)) && (!(vemlSTR.is6075))) pc.printf("- VEML60xx device ID: 0x%04x   CONF: 0x%04x\r\n", vemlSTR.id, vemlSTR.conf_reg);
    
    while(1) {
        wait(2.0);
        dispVeml60xx();
    }
}