Project Digora IOT
Dependencies: libmDot-dev-mbed5
Diff: Lum_sensor.cpp
- Revision:
- 0:522ad8e780f6
diff -r 000000000000 -r 522ad8e780f6 Lum_sensor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lum_sensor.cpp Fri May 19 09:26:49 2017 +0000 @@ -0,0 +1,187 @@ +#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 +} \ No newline at end of file