A library for the Avago ADJD-S311-CR999 Color Light Sensor

Dependents:   ADJD-S311_HelloWorld

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ADJDs311.cpp Source File

ADJDs311.cpp

00001 #include "ADJDs311.h"
00002 #include "mbed.h"
00003 #include <algorithm>
00004 
00005 ADJDs311::ADJDs311(PinName sda, PinName scl, PinName led):
00006         _i2c(sda, scl), _led(led) {
00007     // hard coded value for number of capacitors
00008     colorCap.red = 12;
00009     colorCap.green = 9;
00010     colorCap.blue = 2;
00011     colorCap.clear = 9;
00012     
00013     // hard coded value for number of integration time slot
00014     colorInt.red = 16;
00015     colorInt.green = 16;
00016     colorInt.blue = 16;
00017     colorInt.clear = 16; 
00018     
00019     colorOffset.red = readRegister(OFFSET_RED);
00020     colorOffset.green = readRegister(OFFSET_GREEN);
00021     colorOffset.blue = readRegister(OFFSET_BLUE);
00022     colorOffset.clear = readRegister(OFFSET_CLEAR);
00023     
00024     // write number of capacitors to registers
00025     writeRegister(colorCap.red & 0xF, CAP_RED);    
00026     writeRegister(colorCap.green & 0xF, CAP_GREEN); 
00027     writeRegister(colorCap.blue & 0xF, CAP_BLUE); 
00028     writeRegister(colorCap.clear & 0xF, CAP_CLEAR);
00029     
00030     // write number of integration time slot to registers
00031     writeInt(colorInt.red & 0xFFF, INT_RED_LO);
00032     writeInt(colorInt.green & 0xFFF, INT_GREEN_LO); 
00033     writeInt(colorInt.blue & 0xFFF, INT_BLUE_LO); 
00034     writeInt(colorInt.clear & 0xFFF, INT_CLEAR_LO);     
00035 }
00036 
00037 // Read data regeisters and return a RGBC var
00038 RGBC ADJDs311::read(){
00039     RGBC color = RGBC();
00040     
00041     performMeasurement();
00042     
00043     color.red = readInt(DATA_RED_LO);
00044     color.green = readInt(DATA_GREEN_LO);
00045     color.blue = readInt(DATA_BLUE_LO);
00046     color.clear = readInt(DATA_CLEAR_LO);
00047     
00048     return color;        
00049 }
00050 
00051 // get number of capacitor
00052 RGBC ADJDs311::getColorCap()
00053 {
00054     return colorCap;   
00055 }
00056 
00057 // get number of intetgration time slot
00058 RGBC ADJDs311::getColorInt()
00059 {
00060     return colorInt;   
00061 }
00062 
00063 // set number of capacitor
00064 void ADJDs311::setColorCap(int red, int green, int blue, int clear) {
00065     colorCap.red = red;
00066     colorCap.green = green;
00067     colorCap.blue = blue;
00068     colorCap.clear = clear;
00069     
00070     // write number of capacitors to registers
00071     writeRegister(colorCap.red & 0xF, CAP_RED);    
00072     writeRegister(colorCap.green & 0xF, CAP_GREEN); 
00073     writeRegister(colorCap.blue & 0xF, CAP_BLUE); 
00074     writeRegister(colorCap.clear & 0xF, CAP_CLEAR);
00075 }
00076 
00077 // set number of integration time slot
00078 void ADJDs311::setColorInt(int red, int green, int blue, int clear) { 
00079     colorInt.red = red;
00080     colorInt.green = green;
00081     colorInt.blue = blue;
00082     colorInt.clear = clear; 
00083     
00084     // write number of integration time slot to registers
00085     writeInt(colorInt.red & 0xFFF, INT_RED_LO);
00086     writeInt(colorInt.green & 0xFFF, INT_GREEN_LO); 
00087     writeInt(colorInt.blue & 0xFFF, INT_BLUE_LO); 
00088     writeInt(colorInt.clear & 0xFFF, INT_CLEAR_LO); 
00089 }
00090 
00091 // Perform measurement and save the result to registers
00092 void ADJDs311::performMeasurement(){ 
00093  writeRegister(0x01, 0x00); // start sensing
00094  while(readRegister(0x00) != 0)
00095   ; // waiting for a result
00096 }
00097 
00098 // Write a byte of data to a specific ADJD-S311 address
00099 void ADJDs311::writeRegister(char data, char regAddr){
00100     char temp[2];
00101     temp[0] = regAddr;  // register addresss
00102     temp[1] = data;
00103     
00104     _i2c.write(WRITE_ADDRESS, temp, 2, false);
00105 }
00106 
00107 // Read a byte of data from ADJD-S311 address
00108 char ADJDs311::readRegister(char regAddr){
00109     char data;
00110     
00111     _i2c.write(WRITE_ADDRESS, &regAddr, 1, true);
00112     _i2c.read(READ_ADDRESS, &data, 1, false);
00113     return data;
00114 }
00115 
00116 // Read two bytes of data from ADJD-S311 address and addres+1
00117 int ADJDs311::readInt(char loRegAddr)
00118 {
00119     return (unsigned char)readRegister(loRegAddr) + (((unsigned char)readRegister(loRegAddr+1))<<8);
00120 }
00121 
00122 // Write two bytes of data to ADJD-S311 address and addres+1
00123 void ADJDs311::writeInt(int data, char loRegAddr)
00124 {
00125     char lobyte = data;
00126     char hibyte = data >> 8;
00127     
00128     writeRegister(lobyte, loRegAddr);
00129     writeRegister(hibyte, loRegAddr+1);   
00130 }
00131 
00132 /* calibrateClear() - This function calibrates the clear integration registers
00133 of the ADJD-S311.
00134 */
00135 void ADJDs311::calibrateClearInt(){
00136     bool gainFound = false;
00137     int upperBox=4096;
00138     int lowerBox = 0;
00139     int half;
00140     
00141     while (!gainFound){
00142         half = ((upperBox-lowerBox)/2)+lowerBox;
00143         //no further halfing possbile
00144         
00145         if (half==lowerBox){
00146             gainFound=true;
00147         }else{
00148             colorInt.clear = half;
00149             writeInt(colorInt.clear & 0xFFF, INT_CLEAR_LO);
00150             performMeasurement();
00151             int halfValue = readInt(DATA_CLEAR_LO);
00152         
00153             if (halfValue>800){
00154                 upperBox=half;
00155             }else if (halfValue<800){
00156                 lowerBox=half;
00157             }else{
00158                 gainFound=true;
00159             } 
00160         }
00161     }
00162 }
00163 
00164 /* calibrateColor() - This function clalibrates the RG and B 
00165 integration registers.
00166 */
00167 void ADJDs311::calibrateColorInt(){
00168  bool gainFound = false;
00169  int upperBox=4096;
00170  int lowerBox = 0;
00171  int half;
00172  int halfValue;
00173  
00174  while (!gainFound)
00175  {
00176   half = ((upperBox-lowerBox)/2)+lowerBox;
00177   //no further halfing possbile
00178   if (half==lowerBox)
00179   {
00180    gainFound=true;
00181   }
00182   else {
00183     colorInt.red = half;
00184     colorInt.green = half;
00185     colorInt.blue = half;
00186     
00187     // write number of integration time slot to registers
00188     writeInt(colorInt.red & 0xFFF, INT_RED_LO);
00189     writeInt(colorInt.green & 0xFFF, INT_GREEN_LO); 
00190     writeInt(colorInt.blue & 0xFFF, INT_BLUE_LO); 
00191 
00192    performMeasurement();
00193    halfValue = 0;
00194 
00195    halfValue=std::max(halfValue, readInt(DATA_RED_LO));
00196    halfValue=std::max(halfValue, readInt(DATA_GREEN_LO));
00197    halfValue=std::max(halfValue, readInt(DATA_BLUE_LO));
00198 
00199    if (halfValue>800) {
00200     upperBox=half;
00201    }
00202    else if (halfValue<800) {
00203     lowerBox=half;
00204    }
00205    else {
00206     gainFound=true;
00207    }
00208   }
00209  }
00210 }
00211 
00212 
00213 /* calibrateCapacitors() - This function calibrates each of the RGB and C
00214 capacitor registers.
00215 */
00216 void ADJDs311::calibrateCapacitors(){
00217 
00218  bool calibrated = false;
00219 
00220  //need to store detect better calibration
00221  int diff;
00222  int oldDiff = 1024;
00223 
00224  while (!calibrated){
00225   // sensor gain setting (Avago app note 5330)
00226   // CAPs are 4bit (higher value will result in lower output)
00227     writeRegister(colorCap.red & 0xF, CAP_RED);    
00228     writeRegister(colorCap.green & 0xF, CAP_GREEN); 
00229     writeRegister(colorCap.blue & 0xF, CAP_BLUE); 
00230 
00231   int maxRead = 0;
00232   int minRead = 1024;
00233   int red  = 0;
00234   int green = 0;
00235   int blue = 0;
00236   
00237   for (int i=0; i<4 ;i ++)
00238   {
00239    performMeasurement();
00240    red  += readInt(DATA_RED_LO);
00241    green += readInt(DATA_GREEN_LO);
00242    blue += readInt(DATA_BLUE_LO);
00243   }
00244   red  /= 4;
00245   green /= 4;
00246   blue /= 4;
00247 
00248   maxRead = std::max(maxRead, red);
00249   maxRead = std::max(maxRead, green);
00250   maxRead = std::max(maxRead, blue);
00251 
00252   minRead = std::min(minRead, red);
00253   minRead = std::min(minRead, green);
00254   minRead = std::min(minRead, blue);
00255 
00256   diff = maxRead - minRead;
00257 
00258   if (oldDiff != diff)
00259   {
00260    if ((maxRead==red) && (colorCap.red<15))
00261     colorCap.red++;
00262    else if ((maxRead == green) && (colorCap.green<15))
00263     colorCap.green++;
00264    else if ((maxRead == blue) && (colorCap.blue<15))
00265     colorCap.blue++;
00266   }
00267   else
00268    calibrated = true;
00269    
00270   oldDiff=diff;
00271 
00272  }
00273  
00274 }
00275 
00276 void ADJDs311::calibrate(){
00277     setColorCap(0, 0, 0, 8);
00278     calibrateColorInt(); // This calibrates R, G, and B int registers
00279     calibrateClearInt(); // This calibrates the C int registers
00280     calibrateCapacitors(); // This calibrates the RGB, and C cap registers
00281     calibrateColorInt();
00282 }
00283 
00284 
00285 void ADJDs311::ledMode(bool ledOn)
00286 {
00287     _led = ledOn;
00288 }
00289 
00290 void ADJDs311::offsetMode(bool useOffset)
00291 {
00292     if (useOffset)
00293     {
00294         writeRegister(0x01, CONFIG);   
00295     } else
00296     {
00297         writeRegister(0x00, CONFIG); 
00298     }
00299 }
00300 
00301 RGBC ADJDs311::getOffset()
00302 {
00303     return colorOffset;   
00304 }
00305 
00306 RGBC ADJDs311::setOffset(bool useOffset)
00307 {
00308     _led = 0;
00309     
00310     writeRegister(0x02, CTRL);
00311     while(readRegister(CTRL));
00312     colorOffset.red = readRegister(OFFSET_RED);
00313     colorOffset.green = readRegister(OFFSET_GREEN);
00314     colorOffset.blue = readRegister(OFFSET_BLUE);
00315     colorOffset.clear = readRegister(OFFSET_CLEAR);
00316     
00317     offsetMode(useOffset);
00318     
00319     return colorOffset;
00320 }