A library for the Avago ADJD-S311-CR999 Color Light Sensor
Dependents: ADJD-S311_HelloWorld
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, ®Addr, 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 }
Generated on Thu Jul 14 2022 17:07:11 by 1.7.2