Library for the ADJD-S371, Avago Colour Sensor
Diff: ADJDColourSensor.cpp
- Revision:
- 0:47465be3223d
--- /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