Michael Walker / ADJD-S371_ColourSens
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ADJDColourSensor.cpp Source File

ADJDColourSensor.cpp

00001 /**
00002 * @section LICENSE
00003 *Copyright (c) 2010 ARM Ltd.
00004 *
00005 *Permission is hereby granted, free of charge, to any person obtaining a copy
00006 *of this software and associated documentation files (the "Software"), to deal
00007 *in the Software without restriction, including without limitation the rights
00008 *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009 *copies of the Software, and to permit persons to whom the Software is
00010 *furnished to do so, subject to the following conditions:
00011 * 
00012 *The above copyright notice and this permission notice shall be included in
00013 *all copies or substantial portions of the Software.
00014 * 
00015 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021 *THE SOFTWARE.
00022 * 
00023 *
00024 * @section DESCRIPTION
00025 *
00026 *
00027 */
00028 
00029 #include "ADJDColourSensor.h"
00030 
00031 ADJDColourSensor::ADJDColourSensor (PinName sda, PinName scl, PinName LED):
00032         _sensor(sda, scl),
00033         _LED(LED)
00034 {
00035     _address = 0x74 << 1;
00036     char cmd[2];
00037     cmd[0] = 1;     //Config reg
00038     cmd[1] = 0x01;     //setup
00039     _sensor.write(_address, cmd, 2);
00040     
00041     setCapacitors(0x0E,0x0E,0x0E,0x0E);
00042     //Good for 500 under office light
00043     setIntegrationTimeSlot(900,1000,1800,600);
00044     //1000, 1000, 1700, 600
00045 
00046     
00047     setIntegrationTimeSlot(1300,1400,2200,1000);
00048     
00049 }
00050 
00051 void ADJDColourSensor::setCapacitors(int redCap, int greenCap, int blueCap, int clearCap){
00052     //Values from 00H to 0FH
00053     char cmd[2];
00054     //Red
00055     cmd[0] = 0x06;     //Cap Red
00056     cmd[1] = redCap;     //
00057     _sensor.write(_address, cmd, 2);
00058     
00059     //Green
00060     cmd[0] = 0x07;     //Cap Green
00061     cmd[1] = greenCap;     //
00062     _sensor.write(_address, cmd, 2);
00063     
00064     //Blue
00065     cmd[0] = 0x08;     //Cap Blue
00066     cmd[1] = blueCap;     //
00067     _sensor.write(_address, cmd, 2);
00068     
00069     //Clear
00070     cmd[0] = 0x09;     //Cap clear
00071     cmd[1] = clearCap;     //
00072     _sensor.write(_address, cmd, 2);
00073 }   
00074 void ADJDColourSensor::setIntegrationTimeSlot(int redInt, int greenInt, int blueInt, int clearInt){
00075     //values should be 0 to 4095
00076     char cmd[2];
00077     //Red
00078     cmd[0] = 0x0A;     //int red low
00079     cmd[1] = redInt & 0xFF;     //redInt low
00080     _sensor.write(_address, cmd, 2);
00081     
00082     cmd[0] = 0x0B;     //int red high
00083     cmd[1] = (redInt >> 8) & 0x0F;     //redInt high
00084     _sensor.write(_address, cmd, 2);
00085     
00086     //Green
00087     cmd[0] = 0x0C;     //int green low
00088     cmd[1] = greenInt & 0xFF;     //greenInt low
00089     _sensor.write(_address, cmd, 2);
00090     
00091     cmd[0] = 0x0D;     //int green high
00092     cmd[1] = (greenInt >> 8) & 0x0F;     //greenInt high
00093     _sensor.write(_address, cmd, 2);
00094     
00095     //Blue
00096     cmd[0] = 0x0E;     //int blue low
00097     cmd[1] = blueInt & 0xFF;     //blueInt low
00098     _sensor.write(_address, cmd, 2);
00099     
00100     cmd[0] = 0x0F;     //int blue high
00101     cmd[1] = (blueInt >> 8) & 0x0F;     //blueInt high
00102     _sensor.write(_address, cmd, 2);
00103     
00104     //Clear
00105     cmd[0] = 0x10;     //int clear low
00106     cmd[1] = clearInt & 0xFF;     //clearInt low
00107     _sensor.write(_address, cmd, 2);
00108     
00109     cmd[0] = 0x11;     //int clear high
00110     cmd[1] = (clearInt >> 8) & 0x0F;     //clearInt high
00111     _sensor.write(_address, cmd, 2);
00112 }
00113 float ADJDColourSensor::read(){
00114 
00115     _LED = 1;
00116     
00117     char cmd[2];
00118     char cmd2[2];
00119     char Result[2];
00120     cmd[0] = 0x00;     //CTRL reg
00121     cmd[1] = 0x01;     //Get sensor
00122     _sensor.write(_address, cmd, 2);
00123     wait(0.1);
00124    
00125     do{
00126         wait(0.1);
00127         cmd[0] = 0;
00128         _sensor.write(_address, cmd, 1);
00129         _sensor.read(_address, cmd2, 1);
00130         //printf("sensing %i\n", int(cmd2[0]));    
00131     }while(cmd2[0] != 0);                       //Wait for CTRl register to be clear
00132    
00133     
00134     //red
00135     cmd[0] = 0x40;
00136     _sensor.write(_address, cmd, 1);
00137     _sensor.read(_address, Result, 1);
00138     cmd[0] = 0x41;
00139     _sensor.write(_address, cmd, 1);
00140     _sensor.read(_address, cmd2, 1);
00141     _red = Result[0] | ((cmd2[0] & 0x03) << 8);
00142     
00143     
00144     //Green
00145      cmd[0] = 0x42;
00146     _sensor.write(_address, cmd, 1);
00147     _sensor.read(_address, Result, 1);
00148     cmd[0] = 0x43;
00149     _sensor.write(_address, cmd, 1);
00150     _sensor.read(_address, cmd2, 1);
00151     _green = Result[0] | ((cmd2[0] & 0x03) << 8);
00152     
00153      //Blue
00154      cmd[0] = 0x44;
00155     _sensor.write(_address, cmd, 1);
00156     _sensor.read(_address, Result, 1);
00157     cmd[0] = 0x45;
00158     _sensor.write(_address, cmd, 1);
00159     _sensor.read(_address, cmd2, 1);
00160     _blue = Result[0] | ((cmd2[0] & 0x03) << 8);
00161     _LED = 0;
00162 
00163      //Clear
00164      float clear;
00165      cmd[0] = 0x46;
00166     _sensor.write(_address, cmd, 1);
00167     _sensor.read(_address, Result, 1);
00168     cmd[0] = 0x47;
00169     _sensor.write(_address, cmd, 1);
00170     _sensor.read(_address, cmd2, 1);
00171     _clear = Result[0] | ((cmd2[0] & 0x03) << 8);
00172 
00173 
00174     //Convert the private int values into the output float values
00175     red = (float)_red;
00176     green = (float)_green;
00177     blue = (float)_blue;
00178     clear = (float)_clear;
00179 
00180     return(clear);
00181 }
00182 
00183 int ADJDColourSensor::readOffset(){
00184     _LED = 1;
00185     char cmd[2];
00186     cmd[0] = 0;     //CTRL reg
00187     cmd[1] = 2;     //Get sensor
00188     _sensor.write(_address, cmd, 2);
00189 
00190     wait(0.1); //Or wait till bit cleared
00191     
00192     //Red
00193     cmd[0] = 0x48;
00194     _sensor.write(_address, cmd, 1);
00195     _sensor.read(_address, cmd, 1);
00196     redOffset = cmd[0];
00197     
00198     //Green
00199     cmd[0] = 0x49;
00200     _sensor.write(_address, cmd, 1);
00201     _sensor.read(_address, cmd, 1);
00202     greenOffset = cmd[0];
00203     
00204     //Blue
00205     cmd[0] = 0x4A;
00206     _sensor.write(_address, cmd, 1);
00207     _sensor.read(_address, cmd, 1);
00208     blueOffset = cmd[0];
00209     
00210     //Clear
00211     cmd[0] = 0x4B;
00212     _sensor.write(_address, cmd, 1);
00213     _sensor.read(_address, cmd, 1);
00214     clearOffset = cmd[0];
00215     
00216     _LED = 0;
00217     
00218     return(clearOffset);
00219      
00220 }
00221 void ADJDColourSensor::optimise(){
00222     optimise(500,500,500,500);
00223 }
00224 void ADJDColourSensor::optimise(int optimum){
00225     optimise(optimum,optimum,optimum,optimum);
00226 }
00227 void ADJDColourSensor::optimise(int redTarget, int blueTarget, int greenTarget ,int clearTarget){
00228     //use capacitor as they are to begin with
00229     
00230     //Optimise all at once as reading 
00231     int redInt = 1000;
00232     int greenInt = 1000;
00233     int blueInt = 1000;
00234     int clearInt = 1000;
00235     int range = 20;
00236     bool Optimised = false;
00237     read();
00238     while(!Optimised){
00239         
00240     
00241         //Optimise red
00242         if(_red > (redTarget + range)){
00243             //too big so decreae redInt
00244             redInt = redInt - 50;
00245         }else{
00246             if(_red < (redTarget - range)){
00247             //too low so increase redInt
00248                 redInt = redInt + 50;
00249             }
00250         }
00251         //optimise blue
00252         if(_blue > (blueTarget + range)){
00253             blueInt = blueInt - 50;
00254         }else{
00255             if(_blue < (blueTarget - range)){
00256                 blueInt = blueInt + 50;
00257             }
00258         }
00259         
00260         //optimise green
00261         if(_green > (greenTarget + range)){
00262             greenInt = greenInt - 50;
00263         }else{
00264             if(_green < (greenTarget - range)){
00265                 greenInt = greenInt + 50;
00266             }
00267         }
00268     
00269         //Optimise Clear
00270         if(_clear > (clearTarget + range)){
00271             clearInt = clearInt - 50;
00272         }else{
00273             if(_clear < (clearTarget - range)){
00274                 clearInt = clearInt + 50;
00275             }
00276         }
00277         
00278         //Check if any of the integration values  have exceeded the max limits (0 to 4095) and if so try changing the capacitors 
00279         if((redInt > 4095 || greenInt > 4095 || blueInt > 4095 || clearInt > 4095) || (redInt <= 0 || greenInt <= 0 || blueInt <= 0 || clearInt <= 0)){
00280             printf("Also need to change the capacitor values\n");
00281         }
00282         //Send the new optimisation
00283         setIntegrationTimeSlot(redInt, greenInt, blueInt, clearInt);
00284         
00285         //get new values
00286         _clear = read();
00287         
00288         //Check if optimised
00289         if((_red < (redTarget + range) && (_red > redTarget - range)) && (_green < (greenTarget + range) && (_green > greenTarget - range)) && (_blue < (blueTarget + range) && (_blue > blueTarget - range)) && (_clear < (clearTarget + range) && (_clear > clearTarget - range)))Optimised = true;
00290         
00291     }
00292     
00293     
00294     //Should check max condition (Outputs do not exceed 1000) - or is the above optimising for max condition
00295 
00296 }