Library for the ADJD-S371, Avago Colour Sensor

Files at this revision

API Documentation at this revision

Comitter:
MichaelW
Date:
Fri Oct 01 13:39:51 2010 +0000
Commit message:
Supports reading from the sensors and writing to the configuration registers. Doesn\t have built in optimisation yet

Changed in this revision

ADJDColourSensor.cpp Show annotated file Show diff for this revision Revisions of this file
ADJDColourSensor.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 47465be3223d ADJDColourSensor.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ADJDColourSensor.cpp	Fri Oct 01 13:39:51 2010 +0000
@@ -0,0 +1,296 @@
+/**
+* @section LICENSE
+*Copyright (c) 2010 ARM Ltd.
+*
+*Permission is hereby granted, free of charge, to any person obtaining a copy
+*of this software and associated documentation files (the "Software"), to deal
+*in the Software without restriction, including without limitation the rights
+*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+*copies of the Software, and to permit persons to whom the Software is
+*furnished to do so, subject to the following conditions:
+* 
+*The above copyright notice and this permission notice shall be included in
+*all copies or substantial portions of the Software.
+* 
+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+*THE SOFTWARE.
+* 
+*
+* @section DESCRIPTION
+*
+*
+*/
+
+#include "ADJDColourSensor.h"
+
+ADJDColourSensor::ADJDColourSensor(PinName sda, PinName scl, PinName LED):
+        _sensor(sda, scl),
+        _LED(LED)
+{
+    _address = 0x74 << 1;
+    char cmd[2];
+    cmd[0] = 1;     //Config reg
+    cmd[1] = 0x01;     //setup
+    _sensor.write(_address, cmd, 2);
+    
+    setCapacitors(0x0E,0x0E,0x0E,0x0E);
+    //Good for 500 under office light
+    setIntegrationTimeSlot(900,1000,1800,600);
+    //1000, 1000, 1700, 600
+
+    
+    setIntegrationTimeSlot(1300,1400,2200,1000);
+    
+}
+
+void ADJDColourSensor::setCapacitors(int redCap, int greenCap, int blueCap, int clearCap){
+    //Values from 00H to 0FH
+    char cmd[2];
+    //Red
+    cmd[0] = 0x06;     //Cap Red
+    cmd[1] = redCap;     //
+    _sensor.write(_address, cmd, 2);
+    
+    //Green
+    cmd[0] = 0x07;     //Cap Green
+    cmd[1] = greenCap;     //
+    _sensor.write(_address, cmd, 2);
+    
+    //Blue
+    cmd[0] = 0x08;     //Cap Blue
+    cmd[1] = blueCap;     //
+    _sensor.write(_address, cmd, 2);
+    
+    //Clear
+    cmd[0] = 0x09;     //Cap clear
+    cmd[1] = clearCap;     //
+    _sensor.write(_address, cmd, 2);
+}   
+void ADJDColourSensor::setIntegrationTimeSlot(int redInt, int greenInt, int blueInt, int clearInt){
+    //values should be 0 to 4095
+    char cmd[2];
+    //Red
+    cmd[0] = 0x0A;     //int red low
+    cmd[1] = redInt & 0xFF;     //redInt low
+    _sensor.write(_address, cmd, 2);
+    
+    cmd[0] = 0x0B;     //int red high
+    cmd[1] = (redInt >> 8) & 0x0F;     //redInt high
+    _sensor.write(_address, cmd, 2);
+    
+    //Green
+    cmd[0] = 0x0C;     //int green low
+    cmd[1] = greenInt & 0xFF;     //greenInt low
+    _sensor.write(_address, cmd, 2);
+    
+    cmd[0] = 0x0D;     //int green high
+    cmd[1] = (greenInt >> 8) & 0x0F;     //greenInt high
+    _sensor.write(_address, cmd, 2);
+    
+    //Blue
+    cmd[0] = 0x0E;     //int blue low
+    cmd[1] = blueInt & 0xFF;     //blueInt low
+    _sensor.write(_address, cmd, 2);
+    
+    cmd[0] = 0x0F;     //int blue high
+    cmd[1] = (blueInt >> 8) & 0x0F;     //blueInt high
+    _sensor.write(_address, cmd, 2);
+    
+    //Clear
+    cmd[0] = 0x10;     //int clear low
+    cmd[1] = clearInt & 0xFF;     //clearInt low
+    _sensor.write(_address, cmd, 2);
+    
+    cmd[0] = 0x11;     //int clear high
+    cmd[1] = (clearInt >> 8) & 0x0F;     //clearInt high
+    _sensor.write(_address, cmd, 2);
+}
+float ADJDColourSensor::read(){
+
+    _LED = 1;
+    
+    char cmd[2];
+    char cmd2[2];
+    char Result[2];
+    cmd[0] = 0x00;     //CTRL reg
+    cmd[1] = 0x01;     //Get sensor
+    _sensor.write(_address, cmd, 2);
+    wait(0.1);
+   
+    do{
+        wait(0.1);
+        cmd[0] = 0;
+        _sensor.write(_address, cmd, 1);
+        _sensor.read(_address, cmd2, 1);
+        //printf("sensing %i\n", int(cmd2[0]));    
+    }while(cmd2[0] != 0);                       //Wait for CTRl register to be clear
+   
+    
+    //red
+    cmd[0] = 0x40;
+    _sensor.write(_address, cmd, 1);
+    _sensor.read(_address, Result, 1);
+    cmd[0] = 0x41;
+    _sensor.write(_address, cmd, 1);
+    _sensor.read(_address, cmd2, 1);
+    _red = Result[0] | ((cmd2[0] & 0x03) << 8);
+    
+    
+    //Green
+     cmd[0] = 0x42;
+    _sensor.write(_address, cmd, 1);
+    _sensor.read(_address, Result, 1);
+    cmd[0] = 0x43;
+    _sensor.write(_address, cmd, 1);
+    _sensor.read(_address, cmd2, 1);
+    _green = Result[0] | ((cmd2[0] & 0x03) << 8);
+    
+     //Blue
+     cmd[0] = 0x44;
+    _sensor.write(_address, cmd, 1);
+    _sensor.read(_address, Result, 1);
+    cmd[0] = 0x45;
+    _sensor.write(_address, cmd, 1);
+    _sensor.read(_address, cmd2, 1);
+    _blue = Result[0] | ((cmd2[0] & 0x03) << 8);
+    _LED = 0;
+
+     //Clear
+     float clear;
+     cmd[0] = 0x46;
+    _sensor.write(_address, cmd, 1);
+    _sensor.read(_address, Result, 1);
+    cmd[0] = 0x47;
+    _sensor.write(_address, cmd, 1);
+    _sensor.read(_address, cmd2, 1);
+    _clear = Result[0] | ((cmd2[0] & 0x03) << 8);
+
+
+    //Convert the private int values into the output float values
+    red = (float)_red;
+    green = (float)_green;
+    blue = (float)_blue;
+    clear = (float)_clear;
+
+    return(clear);
+}
+
+int ADJDColourSensor::readOffset(){
+    _LED = 1;
+    char cmd[2];
+    cmd[0] = 0;     //CTRL reg
+    cmd[1] = 2;     //Get sensor
+    _sensor.write(_address, cmd, 2);
+
+    wait(0.1); //Or wait till bit cleared
+    
+    //Red
+    cmd[0] = 0x48;
+    _sensor.write(_address, cmd, 1);
+    _sensor.read(_address, cmd, 1);
+    redOffset = cmd[0];
+    
+    //Green
+    cmd[0] = 0x49;
+    _sensor.write(_address, cmd, 1);
+    _sensor.read(_address, cmd, 1);
+    greenOffset = cmd[0];
+    
+    //Blue
+    cmd[0] = 0x4A;
+    _sensor.write(_address, cmd, 1);
+    _sensor.read(_address, cmd, 1);
+    blueOffset = cmd[0];
+    
+    //Clear
+    cmd[0] = 0x4B;
+    _sensor.write(_address, cmd, 1);
+    _sensor.read(_address, cmd, 1);
+    clearOffset = cmd[0];
+    
+    _LED = 0;
+    
+    return(clearOffset);
+     
+}
+void ADJDColourSensor::optimise(){
+    optimise(500,500,500,500);
+}
+void ADJDColourSensor::optimise(int optimum){
+    optimise(optimum,optimum,optimum,optimum);
+}
+void ADJDColourSensor::optimise(int redTarget, int blueTarget, int greenTarget ,int clearTarget){
+    //use capacitor as they are to begin with
+    
+    //Optimise all at once as reading 
+    int redInt = 1000;
+    int greenInt = 1000;
+    int blueInt = 1000;
+    int clearInt = 1000;
+    int range = 20;
+    bool Optimised = false;
+    read();
+    while(!Optimised){
+        
+    
+        //Optimise red
+        if(_red > (redTarget + range)){
+            //too big so decreae redInt
+            redInt = redInt - 50;
+        }else{
+            if(_red < (redTarget - range)){
+            //too low so increase redInt
+                redInt = redInt + 50;
+            }
+        }
+        //optimise blue
+        if(_blue > (blueTarget + range)){
+            blueInt = blueInt - 50;
+        }else{
+            if(_blue < (blueTarget - range)){
+                blueInt = blueInt + 50;
+            }
+        }
+        
+        //optimise green
+        if(_green > (greenTarget + range)){
+            greenInt = greenInt - 50;
+        }else{
+            if(_green < (greenTarget - range)){
+                greenInt = greenInt + 50;
+            }
+        }
+    
+        //Optimise Clear
+        if(_clear > (clearTarget + range)){
+            clearInt = clearInt - 50;
+        }else{
+            if(_clear < (clearTarget - range)){
+                clearInt = clearInt + 50;
+            }
+        }
+        
+        //Check if any of the integration values  have exceeded the max limits (0 to 4095) and if so try changing the capacitors 
+        if((redInt > 4095 || greenInt > 4095 || blueInt > 4095 || clearInt > 4095) || (redInt <= 0 || greenInt <= 0 || blueInt <= 0 || clearInt <= 0)){
+            printf("Also need to change the capacitor values\n");
+        }
+        //Send the new optimisation
+        setIntegrationTimeSlot(redInt, greenInt, blueInt, clearInt);
+        
+        //get new values
+        _clear = read();
+        
+        //Check if optimised
+        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;
+        
+    }
+    
+    
+    //Should check max condition (Outputs do not exceed 1000) - or is the above optimising for max condition
+
+}
\ No newline at end of file
diff -r 000000000000 -r 47465be3223d ADJDColourSensor.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ADJDColourSensor.h	Fri Oct 01 13:39:51 2010 +0000
@@ -0,0 +1,95 @@
+/**
+* @section LICENSE
+*Copyright (c) 2010 ARM Ltd.
+*
+*Permission is hereby granted, free of charge, to any person obtaining a copy
+*of this software and associated documentation files (the "Software"), to deal
+*in the Software without restriction, including without limitation the rights
+*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+*copies of the Software, and to permit persons to whom the Software is
+*furnished to do so, subject to the following conditions:
+* 
+*The above copyright notice and this permission notice shall be included in
+*all copies or substantial portions of the Software.
+* 
+*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+*THE SOFTWARE.
+* 
+*
+* @section DESCRIPTION
+*
+*
+*/
+
+#ifndef ADJDCOLOURSENS_H_
+#define ADJDCOLOURSENS_H_
+
+/**
+*
+* Includes
+*
+*/
+#include "mbed.h"
+/**
+* A class to interface with an Avago ADJD-S371-QR999. 
+* The class allows you to read the light levels setected by the sensor for each colour and to set the gain settings.
+*/
+class ADJDColourSensor{
+public:
+    ADJDColourSensor(PinName sda, PinName scl, PinName LED);
+
+    /**
+    * Read the colour sensor channels. 
+    * The red, green and blue values are
+    *
+    * @returns The clear result, ie the overall brightness
+    */
+    float read();
+    
+    /**
+    * Read the offsets from the device and into the corresponding members. 
+    * 
+    * @returns The value of the clear offset
+    */
+    int readOffset();
+    
+    float red, green, blue;
+    
+    signed int redOffset, greenOffset, blueOffset, clearOffset;
+    
+    /**
+    * Set the number of capacitors for each channel of the ADC.
+    *
+    * The values of the parameters must be between 0x00 and 0x0F
+    * @param redCap The number of capacitors for the red channel
+    */
+    void setCapacitors(int redCap, int greenCap, int blueCap, int clearCap);
+    
+    /**
+    * Set the integration time slot for each of the ADCs.
+    * 
+    * All the values are as a 12 bit number
+    * @param redInt The integration time slot for the red channel
+    * @param greenInt The integration time slot for the green channel
+    * @param blueInt The integration time slot for the blue channel
+    * @param clearInt The integration time slot for the clear channel
+    */
+    void setIntegrationTimeSlot(int redInt, int greenInt, int blueInt, int ClearInt);
+
+    void optimise();
+    void optimise(int optimum);
+    void optimise(int redTarget, int blueTarget, int greenTarget, int clearTarget);
+    
+    
+private:    
+    I2C _sensor;
+    DigitalOut _LED;
+    int _red, _green, _blue, _clear;
+    int _address;
+};
+#endif
\ No newline at end of file