Project Digora IOT

Dependencies:   libmDot-dev-mbed5

Lum_sensor.cpp

Committer:
Niiippoooo
Date:
2017-05-19
Revision:
0:522ad8e780f6

File content as of revision 0:522ad8e780f6:

#include "Lum_sensor.h"


Capt_Lum::Capt_Lum() : i2c(PC_9, PA_8)            //initialise la liaison I2C entre le capteur et les pins SDA et SCL du mDot                      
{      
    i2c.frequency(100000); //impose la fréquence de communication recommandée pour le capteur
    enablePower();
                         
}

int Capt_Lum::enablePower(){
    int ack = writeSingleRegister( TSL_CONTROL, 3 );    //écrit le mot permettant d'allumer le capteur dans le registre CONTROL du capteur
    wait(0.1);
    return ack;
}

int Capt_Lum::disablePower(){
    int ack = writeSingleRegister( TSL_CONTROL, 0 );    //écrit le mot permettant d'éteindre le capteur dans le registre CONTROLdu capteur
    wait(0.1);
    return ack;
}

int Capt_Lum::writeSingleRegister( char address, char data ){
    char tx[2] = { address | 160, data }; //0d160 = 0b10100000         //on stocke l'addresse du registre et le mot à écrire dans tx
    int ack = i2c.write( TSL_SLAVE_ADDRESS << 1, tx, 2 );              //on écrit le mot data dans le registre d'addresse address
    return ack;
}

char Capt_Lum::readSingleRegister( char address ){
    char output = 255;
    char command = address | 160; //0d160 = 0b10100000                 //on stocke address dans un registre
    i2c.write( TSL_SLAVE_ADDRESS << 1, &command, 1, true );            //on indique que l'on veut lire le registre à l'addresse address
    i2c.read( TSL_SLAVE_ADDRESS << 1, &output, 1 );                    //on lit un mot que l'on sotcke dans output
    
    return output;
}

int Capt_Lum::readMultipleRegisters( char address, char* output, int quantity ){
    char command = address | 160; //0d160 = 0b10100000                 //on stocke address dans un registre
    i2c.write( TSL_SLAVE_ADDRESS << 1, &command, 1, true );            //on indique que l'on veut lire le registre à l'addresse address
    int ack = i2c.read( TSL_SLAVE_ADDRESS << 1, output, quantity );    //on lit un mot que l'on sotcke dans output
    
    return ack;
}


int Capt_Lum::getVisibleAndIR(){
    char buffer[2] = { 0 };
    readMultipleRegisters( TSL_DATA0LOW, buffer, 2 );      //lecture du registre contenant la mesure de luminosité visible et IR
    int reading = (int)buffer[1] << 8 | (int)buffer[0];   
    
    return reading;
}

int Capt_Lum::getIROnly(){
    char buffer[2] = { 0 };
    readMultipleRegisters( TSL_DATA1LOW, buffer, 2 );      //lecture du registre contenant la mesure d'infrarouge
    int reading = (int)buffer[1] << 8 | (int)buffer[0];
    
    return reading;
}


float Capt_Lum::getLux(){
    int ch0 = getVisibleAndIR();       
    int ch1 = getIROnly();
    
    // on vérifie que le capteur n'a pas saturé (0xFFFF)
    // si c'est le cas on arrête (-1)
    if( (ch0 == 0xFFFF) || (ch1 == 0xFFFF) ){
        
        return -1;
    }
    
    // conversion en float
    float d0 = ch0;
    float d1 = ch1;

    // We will need the ratio for subsequent calculations
    double ratio = d1 / d0;
    
    // division par le temps d'intégration
    int itime = readIntegrationTime();
    d0 *= (402.0/itime);
    d1 *= (402.0/itime);
    
    // division par le gain du capteur
    int gain = readGain();
        d0 /= gain;
        d1 /= gain;
    
    // conversion en lux d'après les équations de la datasheet :
    if (ratio < 0.5)
    {
        lux = 0.0304 * d0 - 0.062 * d0 * pow(ratio,1.4);
        if (ratio<0.125)
        {
            lux = 0.0304*d0-0.0272*d1;
        }
        else if (ratio < 0.250)
        {   
            lux = 0.0325*d0-0.0440*d1;
        }
        else if (ratio < 0.375)
        {
            lux = 0.0351*d0 - 0.0544*d1;
        }
        else
        {
            lux = 0.0381*d0 - 0.0624*d1;
        }
    }
    else if (ratio < 0.61)
    {
        lux = 0.0224 * d0 - 0.031 * d1;
    }
    else if (ratio < 0.80)
    {
        lux = 0.0128 * d0 - 0.0153 * d1;
    }
    else if (ratio < 1.30)
    {
        lux = 0.00146 * d0 - 0.00112 * d1;
    }
    else if (ratio >= 1.30)
    {
        lux = 0;
    }
    return lux;
}

//calcule le temps d'inégration d'après les équations de la datasheet :
float Capt_Lum::readIntegrationTime(){
    char timing = readSingleRegister( TSL_TIMING );
    char integ = ( timing << 6 ) >> 6; // keep bits 0 & 1
    int itime;
    switch (integ) {
        case 0:
            itime = 13.7;
            break;
        case 1:
            itime = 101;
            break;
        case 2:
            itime = 402;
            break;
        default:
            itime = 0;
            break;
    }
    
    return itime;
}
//calcule le gain du capteur d'après les équations de la datasheet :
int Capt_Lum::readGain(){
    char timing = readSingleRegister( TSL_TIMING );
    char gain_bit = ( timing << 3 ) >> 7; // keep only bit 4
    //printf("gain_bit = %i\n\r", gain_bit);
    int gain;
    switch (gain_bit) {
        case 0:
            gain = 1;
            break;
        case 1:
            gain = 16;
            break;
        default:
            gain = 0;
            break;
    }
    
    return gain;
}

float Capt_Lum::obtenirLuminosite()
{
        float lux = getLux();                               //mesure et calcule la luminosité
        if (lux>0)
        {
            printf("\n\rLuminosité : %.2f lux\n\r", lux); //affiche la luminosité
        }
        else
        {
               printf("\n\rErreur lecture luminosité\n\r");
        }
        return lux;                                         //retourne la luminosité pour une utilisation ultérieure
}