Class which provides functions to control a TAOS TCS3472 Color Light-to-Digital Converter with IR Filter via I2C. (Tidied up)

Dependents:   openwear-lifelogger-example

Fork of TCS3472_I2C by Karl Maxwell

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TCS3472_I2C.cpp Source File

TCS3472_I2C.cpp

00001 #include "TCS3472_I2C.h"
00002 
00003 TCS3472_I2C::TCS3472_I2C( I2C *i2c, uint8_t deviceAddress ) : _i2c( i2c ){  
00004     _slaveAddress = deviceAddress; 
00005     
00006     enablePowerAndRGBC();
00007 }
00008 
00009 TCS3472_I2C::~TCS3472_I2C(){
00010     
00011 }
00012 
00013 int TCS3472_I2C::writeSingleRegister( char address, char data ){
00014     char tx[2] = { address | 160, data }; //0d160 = 0b10100000
00015     int ack = _i2c->write( _slaveAddress << 1, tx, 2 );
00016     return ack;
00017 }
00018 
00019 int TCS3472_I2C::writeMultipleRegisters( char address, char* data, int quantity ){
00020     char tx[ quantity + 1 ];
00021     tx[0] = address | 160;
00022     for ( int i = 1; i <= quantity; i++ ){
00023         tx[ i ] = data[ i - 1 ];
00024     }
00025     int ack = _i2c->write( _slaveAddress << 1, tx, quantity + 1 );
00026     return ack;
00027 }
00028 
00029 char TCS3472_I2C::readSingleRegister( char address ){
00030     char output = 255;
00031     char command = address | 160; //0d160 = 0b10100000
00032     _i2c->write( _slaveAddress << 1, &command, 1, true );
00033     _i2c->read( _slaveAddress << 1, &output, 1 );
00034     return output;
00035 }
00036 
00037 int TCS3472_I2C::readMultipleRegisters( char address, char* output, int quantity ){
00038     char command = address | 160; //0d160 = 0b10100000
00039     _i2c->write( _slaveAddress << 1, &command, 1, true );
00040     int ack = _i2c->read( _slaveAddress << 1, output, quantity );
00041     return ack;
00042 }
00043 
00044 void TCS3472_I2C::getAllColors( int* readings ){
00045     char buffer[8] = { 0 };
00046 
00047     readMultipleRegisters( CDATA, buffer, 8 );
00048 
00049     readings[0] = (int)buffer[1] << 8 | (int)buffer[0];
00050     readings[1] = (int)buffer[3] << 8 | (int)buffer[2];
00051     readings[2] = (int)buffer[5] << 8 | (int)buffer[4];
00052     readings[3] = (int)buffer[7] << 8 | (int)buffer[6];
00053 }
00054 
00055 int TCS3472_I2C::getClearData(){
00056     char buffer[2] = { 0 };
00057     readMultipleRegisters( CDATA, buffer, 2 );
00058     int reading = (int)buffer[1] << 8 | (int)buffer[0];
00059     return reading;
00060 }
00061 
00062 int TCS3472_I2C::getRedData(){
00063     char buffer[2] = { 0 };
00064     readMultipleRegisters( RDATA, buffer, 2 );
00065     int reading = (int)buffer[1] << 8 | (int)buffer[0];
00066     return reading;
00067 }
00068 
00069 int TCS3472_I2C::getGreenData(){
00070     char buffer[2] = { 0 };
00071     readMultipleRegisters( GDATA, buffer, 2 );
00072     int reading = (int)buffer[1] << 8 | (int)buffer[0];
00073     return reading;
00074 }
00075 
00076 int TCS3472_I2C::getBlueData(){
00077     char buffer[2] = { 0 };
00078     readMultipleRegisters( BDATA, buffer, 2 );
00079     int reading = (int)buffer[1] << 8 | (int)buffer[0];
00080     return reading;
00081 }
00082 
00083 int TCS3472_I2C::enablePower(){
00084     char enable_old = readSingleRegister( ENABLE );
00085     char enable_new = enable_old | 1; // sets PON (bit 0) to 1
00086     int ack = writeSingleRegister( ENABLE, enable_new );
00087     return ack;
00088 }
00089 
00090 int TCS3472_I2C::disablePower(){
00091     char enable_old = readSingleRegister( ENABLE );
00092     char enable_new = enable_old & 254; // sets PON (bit 0) to 0
00093     int ack = writeSingleRegister( ENABLE, enable_new );
00094     return ack;
00095 }
00096 
00097 bool TCS3472_I2C::isPowerEnabled(){
00098     char enable = readSingleRegister( ENABLE );
00099     char pon = enable << 7;
00100     pon = pon >> 7; // gets PON (bit 0) from ENABLE register byte
00101     return (bool)pon;
00102 }
00103 
00104 int TCS3472_I2C::enableRGBC(){
00105     char enable_old = readSingleRegister( ENABLE );
00106     char enable_new = enable_old | 2; // sets AEN (bit 1) to 1
00107     int ack = writeSingleRegister( ENABLE, enable_new );
00108     return ack;
00109 }
00110 
00111 int TCS3472_I2C::disableRGBC(){
00112     char enable_old = readSingleRegister( ENABLE );
00113     char enable_new = enable_old & 253; // sets AEN (bit 1) to 0
00114     int ack = writeSingleRegister( ENABLE, enable_new );
00115     return ack;
00116 }
00117 
00118 bool TCS3472_I2C::isRGBCEnabled(){
00119     char enable = readSingleRegister( ENABLE );
00120     char aen = enable << 6;
00121     aen = aen >> 7; // gets AEN (bit 1) from ENABLE register byte
00122     return (bool)aen;
00123 }
00124 
00125 int TCS3472_I2C::enablePowerAndRGBC(){
00126     char enable_old = readSingleRegister( ENABLE );
00127     char enable_new = enable_old | 3; // sets PON (bit 0) and AEN (bit 1) to 1
00128     int ack = writeSingleRegister( ENABLE, enable_new );
00129     return ack;
00130 }
00131 
00132 int TCS3472_I2C::disablePowerAndRGBC(){
00133     char enable_old = readSingleRegister( ENABLE );
00134     char enable_new = enable_old & 252; // sets PON (bit 0) and AEN (bit 1) to 0
00135     int ack = writeSingleRegister( ENABLE, enable_new );
00136     return ack;
00137 }
00138 
00139 int TCS3472_I2C::enableWait(){
00140     char enable_old = readSingleRegister( ENABLE );
00141     char enable_new = enable_old | 8; // sets WEN (bit 3) to 1
00142     int ack = writeSingleRegister( ENABLE, enable_new );
00143     return ack;
00144 }
00145 
00146 int TCS3472_I2C::disableWait(){
00147     char enable_old = readSingleRegister( ENABLE );
00148     char enable_new = enable_old & 247; // sets WEN (bit 3) to 0
00149     int ack = writeSingleRegister( ENABLE, enable_new );
00150     return ack;
00151 }
00152 
00153 bool TCS3472_I2C::isWaitEnabled(){ 
00154     char enable = readSingleRegister( ENABLE );
00155     char wen = enable << 4;
00156     wen = wen >> 7; // gets WEN (bit 3) from ENABLE register byte
00157     return (bool)wen;
00158 }
00159 
00160 int TCS3472_I2C::enableInterrupt(){
00161     char enable_old = readSingleRegister( ENABLE );
00162     char enable_new = enable_old | 16; // sets AIEN (bit 4) to 1
00163     int ack = writeSingleRegister( ENABLE, enable_new );
00164     return ack;
00165 }
00166 
00167 int TCS3472_I2C::disableInterrupt(){
00168     char enable_old = readSingleRegister( ENABLE );
00169     char enable_new = enable_old & 239; // sets AIEN (bit 4) to 0
00170     int ack = writeSingleRegister( ENABLE, enable_new );
00171     return ack;
00172 }
00173 
00174 bool TCS3472_I2C::isInterruptEnabled(){
00175     char enable = readSingleRegister( ENABLE );
00176     char aien = enable << 3;
00177     aien = aien >> 7; // gets AIEN (bit 4) from ENABLE register byte
00178     return (bool)aien;
00179 }
00180 
00181 int TCS3472_I2C::setIntegrationTime( const float itime ){
00182     char atime = 256 - roundTowardsZero( itime / 2.4 ); // rounding ensures nearest value of atime is used
00183     int ack = writeSingleRegister( ATIME, atime );
00184     return ack;
00185 }
00186 
00187 float TCS3472_I2C::readIntegrationTime(){
00188     float itime = 0;
00189     char atime = readSingleRegister( ATIME );
00190     itime = 2.4 * ( 256 - atime );
00191     return itime;
00192 }
00193 
00194 int TCS3472_I2C::setWaitTime( const float time ){
00195     int ack = 1;
00196     char wtime = 0;
00197     if ( time >= 2.39 && time <= 614.4 ){ // 2.39 instead of 2.4 to allow for float accuracy errors
00198         ack = writeSingleRegister( TCS_CONFIG, 0 ); // sets WLONG to 0
00199         wtime = 256 - roundTowardsZero( time / 2.4 );
00200     }
00201     else if ( time > 614.4 && time <= 7400.1 ){ // 7400.1 instead of 7400 to allow for float accuracy errors
00202         ack = writeSingleRegister( TCS_CONFIG, 2 ); // sets WLONG to 1
00203         wtime = 256 - roundTowardsZero( time / 28.8 );
00204     } 
00205     ack = ack || writeSingleRegister( WTIME, wtime );
00206     return ack;
00207 }
00208 
00209 float TCS3472_I2C::readWaitTime(){
00210     float time = 0;
00211     char wtime = readSingleRegister( WTIME );
00212     char config = readSingleRegister( TCS_CONFIG );
00213     int wlong = ( config << 6 ) >> 7; // gets WLONG (bit 1) from CONFIG register byte
00214     if ( wlong == 0 ){
00215         time = 2.4 * ( 256 - wtime );
00216     }
00217     else if ( wlong == 1 ){
00218         time = 28.8 * ( 256 - wtime ); // 28.8 = 2.4 * 12
00219     }
00220     return time;
00221 }
00222 
00223 char TCS3472_I2C::readEnableRegister(){
00224     return readSingleRegister( ENABLE );
00225 }
00226 
00227 int TCS3472_I2C::readLowInterruptThreshold(){
00228     char buffer[2] = { 0 };
00229     readMultipleRegisters( AILTL, buffer, 2 );
00230     int reading = (int)buffer[1] << 8 | (int)buffer[0];
00231     return reading;
00232 }
00233 
00234 int TCS3472_I2C::readHighInterruptThreshold(){
00235     char buffer[2] = { 0 };
00236     readMultipleRegisters( AIHTL, buffer, 2 );
00237     int reading = (int)buffer[1] << 8 | (int)buffer[0];
00238     return reading;
00239 }
00240 
00241 int TCS3472_I2C::setLowInterruptThreshold( const int threshold ){
00242     char threshold_bytes[2];
00243     threshold_bytes[0] = threshold; // take lowest 8 bits of threshold
00244     threshold_bytes[1] = threshold >> 8; // take highest 8 bits of threshold
00245     int ack = writeMultipleRegisters( AILTL, threshold_bytes, 2 );
00246     return ack;
00247 }
00248 
00249 int TCS3472_I2C::setHighInterruptThreshold( const int threshold ){
00250     char threshold_bytes[2];
00251     threshold_bytes[0] = threshold;
00252     threshold_bytes[1] = threshold >> 8;
00253     int ack = writeMultipleRegisters( AIHTL, threshold_bytes, 2 );
00254     return ack;
00255 }
00256 
00257 int TCS3472_I2C::readInterruptPersistence(){
00258     char pers = readSingleRegister( PERS );
00259     char persistence_bits = ( pers << 4 ) >> 4; // discard bits 4 to 7, keep only bits 0 to 3
00260     int persistence = -1;
00261     switch (persistence_bits){
00262         case 0:
00263             persistence = 0;
00264             break;
00265         case 1:
00266             persistence = 1;
00267             break;
00268         case 2:
00269             persistence = 2;
00270             break;
00271         case 3:
00272             persistence = 3;
00273             break;
00274         case 4:
00275             persistence = 5;
00276             break;
00277         case 5:
00278             persistence = 10;
00279             break;
00280         case 6:
00281             persistence = 15;
00282             break;
00283         case 7:
00284             persistence = 20;
00285             break;
00286         case 8:
00287             persistence = 25;
00288             break;
00289         case 9:
00290             persistence = 30;
00291             break;
00292         case 10:
00293             persistence = 35;
00294             break;
00295         case 11:
00296             persistence = 40;
00297             break;
00298         case 12:
00299             persistence = 45;
00300             break;
00301         case 13:
00302             persistence = 50;
00303             break;
00304         case 14:
00305             persistence = 55;
00306             break;
00307         case 15:
00308             persistence = 60;
00309             break;
00310         default:
00311             break;
00312     }
00313     return persistence;
00314 }
00315 
00316 int TCS3472_I2C::setInterruptPersistence( const int persistence ){
00317     char pers_byte;
00318     int ack = 0;
00319     switch (persistence){
00320         case 0:
00321             pers_byte = 0;
00322             break;
00323         case 1:
00324             pers_byte = 1;
00325             break;
00326         case 2:
00327             pers_byte = 2;
00328             break;
00329         case 3:
00330             pers_byte = 3;
00331             break;
00332         case 5:
00333             pers_byte = 4;
00334             break;
00335         case 10:
00336             pers_byte = 5;
00337             break;
00338         case 15:
00339             pers_byte = 6;
00340             break;
00341         case 20:
00342             pers_byte = 7;
00343             break;
00344         case 25:
00345             pers_byte = 8;
00346             break;
00347         case 30:
00348             pers_byte = 9;
00349             break;
00350         case 35:
00351             pers_byte = 10;
00352             break;
00353         case 40:
00354             pers_byte = 11;
00355             break;
00356         case 45:
00357             pers_byte = 12;
00358             break;
00359         case 50:
00360             pers_byte = 13;
00361             break;
00362         case 55:
00363             pers_byte = 14;
00364             break;
00365         case 60:
00366             pers_byte = 15;
00367             break;
00368         default:
00369             ack = 2; // 2 used to indicate invalid entry
00370             break;
00371     }
00372     if ( ack != 2 ){
00373         ack = writeSingleRegister( PERS, pers_byte );
00374     }
00375     return ack;
00376 }
00377 
00378 int TCS3472_I2C::clearInterrupt(){
00379     char tx = 230;
00380     int ack = _i2c->write( _slaveAddress << 1, &tx, 1 );
00381     return ack;
00382 }
00383 
00384 int TCS3472_I2C::readRGBCGain(){
00385     char control = readSingleRegister( CONTROL );
00386     char gain_bits = ( control << 6 ) >> 6; // discard  bits 2 to 7, keep only bits 0 & 1
00387     int gain;
00388     switch (gain_bits) {
00389         case 0:
00390             gain = 1;
00391             break;
00392         case 1:
00393             gain = 4;
00394             break;
00395         case 2:
00396             gain = 16;
00397             break;
00398         case 3:
00399             gain = 60;
00400             break;
00401         default:
00402             gain = 0;
00403             break;
00404     }
00405     return gain;
00406 }
00407 
00408 int TCS3472_I2C::setRGBCGain( const int gain ){
00409     char control;
00410     int ack = 0;
00411     switch (gain){
00412         case 1:
00413             control = 0;
00414             break;
00415         case 4:
00416             control = 1;
00417             break;
00418         case 16:
00419             control = 2;
00420             break;
00421         case 60:
00422             control = 3;
00423             break;
00424         default:
00425             ack = 2; // 2 used to indicate invalid entry
00426             break;
00427     }
00428     if ( ack != 2 ){
00429         ack = writeSingleRegister( CONTROL, control );
00430     }
00431     return ack;
00432 }
00433 
00434 char TCS3472_I2C::getDeviceID(){
00435     return readSingleRegister( ID );
00436 }
00437 
00438 char TCS3472_I2C::readStatusRegister(){
00439     return readSingleRegister( STATUS );
00440 }
00441 
00442 float TCS3472_I2C::roundTowardsZero( const float value ){
00443     float result = 0;
00444     if ( ( value >= 0 && ( value - (int)value ) < 0.5 ) || ( value < 0 && ( abs(value) - (int)abs(value) ) >= 0.5 ) ){
00445         result = floor(value);
00446     }
00447     else{
00448         result = ceil(value);
00449     }
00450     return result;
00451 }