Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of TCS3472_I2C by
TCS3472_I2C.cpp
00001 #include "TCS3472_I2C.h" 00002 00003 TCS3472_I2C::TCS3472_I2C( PinName sda, PinName scl ) : i2c( sda, scl ){ 00004 i2c.frequency(100000); 00005 enablePowerAndRGBC(); 00006 } 00007 00008 TCS3472_I2C::~TCS3472_I2C(){ 00009 00010 } 00011 00012 bool TCS3472_I2C::verifyConnection(void) { 00013 uint8_t part_id = readSingleRegister(0x12);//ID 00014 if (part_id == 0x44) 00015 return true; 00016 return false; 00017 } 00018 int TCS3472_I2C::writeSingleRegister( char address, char data ){ 00019 char tx[2] = { address | 160, data }; //0d160 = 0b10100000 00020 int ack = i2c.write( SLAVE_ADDRESS << 1, tx, 2 ); 00021 return ack; 00022 } 00023 00024 int TCS3472_I2C::writeMultipleRegisters( char address, char* data, int quantity ){ 00025 char tx[ quantity + 1 ]; 00026 tx[0] = address | 160; 00027 for ( int i = 1; i <= quantity; i++ ){ 00028 tx[ i ] = data[ i - 1 ]; 00029 } 00030 int ack = i2c.write( SLAVE_ADDRESS << 1, tx, quantity + 1 ); 00031 return ack; 00032 } 00033 00034 char TCS3472_I2C::readSingleRegister( char address ){ 00035 char output = 255; 00036 char command = address | 160; //0d160 = 0b10100000 00037 i2c.write( SLAVE_ADDRESS << 1, &command, 1, true ); 00038 i2c.read( SLAVE_ADDRESS << 1, &output, 1 ); 00039 return output; 00040 } 00041 00042 int TCS3472_I2C::readMultipleRegisters( char address, char* output, int quantity ){ 00043 char command = address | 160; //0d160 = 0b10100000 00044 i2c.write( SLAVE_ADDRESS << 1, &command, 1, true ); 00045 int ack = i2c.read( SLAVE_ADDRESS << 1, output, quantity ); 00046 return ack; 00047 } 00048 00049 void TCS3472_I2C::getAllColors( int* readings ){ 00050 char buffer[8] = { 0 }; 00051 00052 if (readMultipleRegisters( CDATA, buffer, 8 ) ==0){ 00053 readings[0] = (int)buffer[1] << 8 | (int)buffer[0];//c 00054 readings[1] = (int)buffer[3] << 8 | (int)buffer[2];//r 00055 readings[2] = (int)buffer[5] << 8 | (int)buffer[4];//g 00056 readings[3] = (int)buffer[7] << 8 | (int)buffer[6];//b 00057 } 00058 else{ 00059 readings[0] = 0;readings[1] = 0;readings[2] = 0;readings[3] = 0; 00060 } 00061 } 00062 00063 int TCS3472_I2C::getClearData(){ 00064 char buffer[2] = { 0 }; 00065 readMultipleRegisters( CDATA, buffer, 2 ); 00066 int reading = (int)buffer[1] << 8 | (int)buffer[0]; 00067 return reading; 00068 } 00069 00070 int TCS3472_I2C::getRedData(){ 00071 char buffer[2] = { 0 }; 00072 readMultipleRegisters( RDATA, buffer, 2 ); 00073 int reading = (int)buffer[1] << 8 | (int)buffer[0]; 00074 return reading; 00075 } 00076 00077 int TCS3472_I2C::getGreenData(){ 00078 char buffer[2] = { 0 }; 00079 readMultipleRegisters( GDATA, buffer, 2 ); 00080 int reading = (int)buffer[1] << 8 | (int)buffer[0]; 00081 return reading; 00082 } 00083 00084 int TCS3472_I2C::getBlueData(){ 00085 char buffer[2] = { 0 }; 00086 readMultipleRegisters( BDATA, buffer, 2 ); 00087 int reading = (int)buffer[1] << 8 | (int)buffer[0]; 00088 return reading; 00089 } 00090 00091 int TCS3472_I2C::enablePower(){ 00092 char enable_old = readSingleRegister( ENABLE ); 00093 char enable_new = enable_old | 1; // sets PON (bit 0) to 1 00094 int ack = writeSingleRegister( ENABLE, enable_new ); 00095 return ack; 00096 } 00097 00098 int TCS3472_I2C::disablePower(){ 00099 char enable_old = readSingleRegister( ENABLE ); 00100 char enable_new = enable_old & 254; // sets PON (bit 0) to 0 00101 int ack = writeSingleRegister( ENABLE, enable_new ); 00102 return ack; 00103 } 00104 00105 bool TCS3472_I2C::isPowerEnabled(){ 00106 char enable = readSingleRegister( ENABLE ); 00107 char pon = enable << 7; 00108 pon = pon >> 7; // gets PON (bit 0) from ENABLE register byte 00109 return (bool)pon; 00110 } 00111 00112 int TCS3472_I2C::enableRGBC(){ 00113 char enable_old = readSingleRegister( ENABLE ); 00114 char enable_new = enable_old | 2; // sets AEN (bit 1) to 1 00115 int ack = writeSingleRegister( ENABLE, enable_new ); 00116 return ack; 00117 } 00118 00119 int TCS3472_I2C::disableRGBC(){ 00120 char enable_old = readSingleRegister( ENABLE ); 00121 char enable_new = enable_old & 253; // sets AEN (bit 1) to 0 00122 int ack = writeSingleRegister( ENABLE, enable_new ); 00123 return ack; 00124 } 00125 00126 bool TCS3472_I2C::isRGBCEnabled(){ 00127 char enable = readSingleRegister( ENABLE ); 00128 char aen = enable << 6; 00129 aen = aen >> 7; // gets AEN (bit 1) from ENABLE register byte 00130 return (bool)aen; 00131 } 00132 00133 int TCS3472_I2C::enablePowerAndRGBC(){ 00134 char enable_old = readSingleRegister( ENABLE ); 00135 char enable_new = enable_old | 3; // sets PON (bit 0) and AEN (bit 1) to 1 00136 int ack = writeSingleRegister( ENABLE, enable_new ); 00137 return ack; 00138 } 00139 00140 int TCS3472_I2C::disablePowerAndRGBC(){ 00141 char enable_old = readSingleRegister( ENABLE ); 00142 char enable_new = enable_old & 252; // sets PON (bit 0) and AEN (bit 1) to 0 00143 int ack = writeSingleRegister( ENABLE, enable_new ); 00144 return ack; 00145 } 00146 00147 int TCS3472_I2C::enableWait(){ 00148 char enable_old = readSingleRegister( ENABLE ); 00149 char enable_new = enable_old | 8; // sets WEN (bit 3) to 1 00150 int ack = writeSingleRegister( ENABLE, enable_new ); 00151 return ack; 00152 } 00153 00154 int TCS3472_I2C::disableWait(){ 00155 char enable_old = readSingleRegister( ENABLE ); 00156 char enable_new = enable_old & 247; // sets WEN (bit 3) to 0 00157 int ack = writeSingleRegister( ENABLE, enable_new ); 00158 return ack; 00159 } 00160 00161 bool TCS3472_I2C::isWaitEnabled(){ 00162 char enable = readSingleRegister( ENABLE ); 00163 char wen = enable << 4; 00164 wen = wen >> 7; // gets WEN (bit 3) from ENABLE register byte 00165 return (bool)wen; 00166 } 00167 00168 int TCS3472_I2C::enableInterrupt(){ 00169 char enable_old = readSingleRegister( ENABLE ); 00170 char enable_new = enable_old | 16; // sets AIEN (bit 4) to 1 00171 int ack = writeSingleRegister( ENABLE, enable_new ); 00172 return ack; 00173 } 00174 00175 int TCS3472_I2C::disableInterrupt(){ 00176 char enable_old = readSingleRegister( ENABLE ); 00177 char enable_new = enable_old & 239; // sets AIEN (bit 4) to 0 00178 int ack = writeSingleRegister( ENABLE, enable_new ); 00179 return ack; 00180 } 00181 00182 bool TCS3472_I2C::isInterruptEnabled(){ 00183 char enable = readSingleRegister( ENABLE ); 00184 char aien = enable << 3; 00185 aien = aien >> 7; // gets AIEN (bit 4) from ENABLE register byte 00186 return (bool)aien; 00187 } 00188 00189 int TCS3472_I2C::setIntegrationTime( const float itime ){ 00190 char atime = 256 - (int)roundTowardsZero( itime / 2.4 ); // rounding ensures nearest value of atime is used 00191 int ack = writeSingleRegister( ATIME, atime ); 00192 return ack; 00193 } 00194 00195 float TCS3472_I2C::readIntegrationTime(){ 00196 float itime = 0; 00197 char atime = readSingleRegister( ATIME ); 00198 itime = 2.4 * ( 256 - atime ); 00199 return itime; 00200 } 00201 00202 int TCS3472_I2C::setWaitTime( const float time ){ 00203 int ack = 1; 00204 char wtime = 0; 00205 if ( time >= 2.39 && time <= 614.4 ){ // 2.39 instead of 2.4 to allow for float accuracy errors 00206 ack = writeSingleRegister( CONFIG, 0 ); // sets WLONG to 0 00207 wtime = 256 - roundTowardsZero( time / 2.4 ); 00208 } 00209 else if ( time > 614.4 && time <= 7400.1 ){ // 7400.1 instead of 7400 to allow for float accuracy errors 00210 ack = writeSingleRegister( CONFIG, 2 ); // sets WLONG to 1 00211 wtime = 256 - roundTowardsZero( time / 28.8 ); 00212 } 00213 ack = ack || writeSingleRegister( WTIME, wtime ); 00214 return ack; 00215 } 00216 00217 float TCS3472_I2C::readWaitTime(){ 00218 float time = 0; 00219 char wtime = readSingleRegister( WTIME ); 00220 char config = readSingleRegister( CONFIG ); 00221 int wlong = ( config << 6 ) >> 7; // gets WLONG (bit 1) from CONFIG register byte 00222 if ( wlong == 0 ){ 00223 time = 2.4 * ( 256 - wtime ); 00224 } 00225 else if ( wlong == 1 ){ 00226 time = 28.8 * ( 256 - wtime ); // 28.8 = 2.4 * 12 00227 } 00228 return time; 00229 } 00230 00231 char TCS3472_I2C::readEnableRegister(){ 00232 return readSingleRegister( ENABLE ); 00233 } 00234 00235 int TCS3472_I2C::readLowInterruptThreshold(){ 00236 char buffer[2] = { 0 }; 00237 readMultipleRegisters( AILTL, buffer, 2 ); 00238 int reading = (int)buffer[1] << 8 | (int)buffer[0]; 00239 return reading; 00240 } 00241 00242 int TCS3472_I2C::readHighInterruptThreshold(){ 00243 char buffer[2] = { 0 }; 00244 readMultipleRegisters( AIHTL, buffer, 2 ); 00245 int reading = (int)buffer[1] << 8 | (int)buffer[0]; 00246 return reading; 00247 } 00248 00249 int TCS3472_I2C::setLowInterruptThreshold( const int threshold ){ 00250 char threshold_bytes[2]; 00251 threshold_bytes[0] = threshold; // take lowest 8 bits of threshold 00252 threshold_bytes[1] = threshold >> 8; // take highest 8 bits of threshold 00253 int ack = writeMultipleRegisters( AILTL, threshold_bytes, 2 ); 00254 return ack; 00255 } 00256 00257 int TCS3472_I2C::setHighInterruptThreshold( const int threshold ){ 00258 char threshold_bytes[2]; 00259 threshold_bytes[0] = threshold; 00260 threshold_bytes[1] = threshold >> 8; 00261 int ack = writeMultipleRegisters( AIHTL, threshold_bytes, 2 ); 00262 return ack; 00263 } 00264 00265 int TCS3472_I2C::readInterruptPersistence(){ 00266 char pers = readSingleRegister( PERS ); 00267 char persistence_bits = ( pers << 4 ) >> 4; // discard bits 4 to 7, keep only bits 0 to 3 00268 int persistence = -1; 00269 switch (persistence_bits){ 00270 case 0: 00271 persistence = 0; 00272 break; 00273 case 1: 00274 persistence = 1; 00275 break; 00276 case 2: 00277 persistence = 2; 00278 break; 00279 case 3: 00280 persistence = 3; 00281 break; 00282 case 4: 00283 persistence = 5; 00284 break; 00285 case 5: 00286 persistence = 10; 00287 break; 00288 case 6: 00289 persistence = 15; 00290 break; 00291 case 7: 00292 persistence = 20; 00293 break; 00294 case 8: 00295 persistence = 25; 00296 break; 00297 case 9: 00298 persistence = 30; 00299 break; 00300 case 10: 00301 persistence = 35; 00302 break; 00303 case 11: 00304 persistence = 40; 00305 break; 00306 case 12: 00307 persistence = 45; 00308 break; 00309 case 13: 00310 persistence = 50; 00311 break; 00312 case 14: 00313 persistence = 55; 00314 break; 00315 case 15: 00316 persistence = 60; 00317 break; 00318 default: 00319 break; 00320 } 00321 return persistence; 00322 } 00323 00324 int TCS3472_I2C::setInterruptPersistence( const int persistence ){ 00325 char pers_byte; 00326 int ack = 0; 00327 switch (persistence){ 00328 case 0: 00329 pers_byte = 0; 00330 break; 00331 case 1: 00332 pers_byte = 1; 00333 break; 00334 case 2: 00335 pers_byte = 2; 00336 break; 00337 case 3: 00338 pers_byte = 3; 00339 break; 00340 case 5: 00341 pers_byte = 4; 00342 break; 00343 case 10: 00344 pers_byte = 5; 00345 break; 00346 case 15: 00347 pers_byte = 6; 00348 break; 00349 case 20: 00350 pers_byte = 7; 00351 break; 00352 case 25: 00353 pers_byte = 8; 00354 break; 00355 case 30: 00356 pers_byte = 9; 00357 break; 00358 case 35: 00359 pers_byte = 10; 00360 break; 00361 case 40: 00362 pers_byte = 11; 00363 break; 00364 case 45: 00365 pers_byte = 12; 00366 break; 00367 case 50: 00368 pers_byte = 13; 00369 break; 00370 case 55: 00371 pers_byte = 14; 00372 break; 00373 case 60: 00374 pers_byte = 15; 00375 break; 00376 default: 00377 ack = 2; // 2 used to indicate invalid entry 00378 break; 00379 } 00380 if ( ack != 2 ){ 00381 ack = writeSingleRegister( PERS, pers_byte ); 00382 } 00383 return ack; 00384 } 00385 00386 int TCS3472_I2C::clearInterrupt(){ 00387 char tx = 230; 00388 int ack = i2c.write( SLAVE_ADDRESS << 1, &tx, 1 ); 00389 return ack; 00390 } 00391 00392 int TCS3472_I2C::readRGBCGain(){ 00393 char control = readSingleRegister( CONTROL ); 00394 char gain_bits = ( control << 6 ) >> 6; // discard bits 2 to 7, keep only bits 0 & 1 00395 int gain; 00396 switch (gain_bits) { 00397 case 0: 00398 gain = 1; 00399 break; 00400 case 1: 00401 gain = 4; 00402 break; 00403 case 2: 00404 gain = 16; 00405 break; 00406 case 3: 00407 gain = 60; 00408 break; 00409 default: 00410 gain = 0; 00411 break; 00412 } 00413 return gain; 00414 } 00415 00416 int TCS3472_I2C::setRGBCGain( const int gain ){ 00417 char control; 00418 int ack = 0; 00419 switch (gain){ 00420 case 1: 00421 control = 0; 00422 break; 00423 case 4: 00424 control = 1; 00425 break; 00426 case 16: 00427 control = 2; 00428 break; 00429 case 60: 00430 control = 3; 00431 break; 00432 default: 00433 ack = 2; // 2 used to indicate invalid entry 00434 break; 00435 } 00436 if ( ack != 2 ){ 00437 ack = writeSingleRegister( CONTROL, control ); 00438 } 00439 return ack; 00440 } 00441 00442 char TCS3472_I2C::getDeviceID(){ 00443 return readSingleRegister( ID ); 00444 } 00445 00446 char TCS3472_I2C::readStatusRegister(){ 00447 return readSingleRegister( STATUS ); 00448 } 00449 00450 float TCS3472_I2C::roundTowardsZero( const float value ){ 00451 float result = 0; 00452 if ( ( value >= 0 && ( value - (int)value ) < 0.5 ) || ( value < 0 && ( abs(value) - (int)abs(value) ) >= 0.5 ) ){ 00453 result = floor(value); 00454 } 00455 else{ 00456 result = ceil(value); 00457 } 00458 return result; 00459 } 00460 00461 int TCS3472_I2C::calculateColorTemperature(int r, int g, int b) 00462 { 00463 float X, Y, Z; /* RGB to XYZ correlation */ 00464 float xc, yc; /* Chromaticity co-ordinates */ 00465 float n; /* McCamy's formula */ 00466 float cct; 00467 00468 /* 1. Map RGB values to their XYZ counterparts. */ 00469 /* Based on 6500K fluorescent, 3000K fluorescent */ 00470 /* and 60W incandescent values for a wide range. */ 00471 /* Note: Y = Illuminance or lux */ 00472 X = (-0.14282F * r) + (1.54924F * g) + (-0.95641F * b); 00473 Y = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b); 00474 Z = (-0.68202F * r) + (0.77073F * g) + ( 0.56332F * b); 00475 00476 /* 2. Calculate the chromaticity co-ordinates */ 00477 xc = (X) / (X + Y + Z); 00478 yc = (Y) / (X + Y + Z); 00479 00480 /* 3. Use McCamy's formula to determine the CCT */ 00481 n = (xc - 0.3320F) / (0.1858F - yc); 00482 00483 /* Calculate the final CCT */ 00484 cct = -(449.0F * powf(n, 3)) + (3525.0F * powf(n, 2)) - (6823.3F * n) + 5520.33F; 00485 00486 /* Return the results in degrees Kelvin */ 00487 return (int)cct; 00488 } 00489 00490 float TCS3472_I2C::calculateChromaticityX(int r, int g, int b) 00491 { 00492 float X, Y, Z; /* RGB to XYZ correlation */ 00493 float xc, yc; /* Chromaticity co-ordinates */ 00494 00495 /* 1. Map RGB values to their XYZ counterparts. */ 00496 /* Based on 6500K fluorescent, 3000K fluorescent */ 00497 /* and 60W incandescent values for a wide range. */ 00498 /* Note: Y = Illuminance or lux */ 00499 X = (-0.14282F * r) + (1.54924F * g) + (-0.95641F * b); 00500 Y = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b); 00501 Z = (-0.68202F * r) + (0.77073F * g) + ( 0.56332F * b); 00502 00503 /* 2. Calculate the chromaticity co-ordinates */ 00504 xc = (X) / (X + Y + Z); 00505 yc = (Y) / (X + Y + Z); 00506 00507 /* Return the results in degrees Kelvin */ 00508 return (float)xc; 00509 } 00510 float TCS3472_I2C::calculateChromaticityY(int r, int g, int b) 00511 { 00512 float X, Y, Z; /* RGB to XYZ correlation */ 00513 float xc, yc; /* Chromaticity co-ordinates */ 00514 00515 /* 1. Map RGB values to their XYZ counterparts. */ 00516 /* Based on 6500K fluorescent, 3000K fluorescent */ 00517 /* and 60W incandescent values for a wide range. */ 00518 /* Note: Y = Illuminance or lux */ 00519 X = (-0.14282F * r) + (1.54924F * g) + (-0.95641F * b); 00520 Y = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b); 00521 Z = (-0.68202F * r) + (0.77073F * g) + ( 0.56332F * b); 00522 00523 /* 2. Calculate the chromaticity co-ordinates */ 00524 xc = (X) / (X + Y + Z); 00525 yc = (Y) / (X + Y + Z); 00526 00527 /* Return the results in degrees Kelvin */ 00528 return (float)yc; 00529 } 00530 00531 int TCS3472_I2C::calculateLux(int r, int g, int b) 00532 { 00533 float illuminance; 00534 00535 /* This only uses RGB ... how can we integrate clear or calculate lux */ 00536 /* based exclusively on clear since this might be more reliable? */ 00537 illuminance = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b); 00538 00539 return (int)illuminance; 00540 }
Generated on Thu Jul 14 2022 13:26:16 by
1.7.2
