Library for the ADJD-S371, Avago Colour Sensor
ADJDColourSensor.cpp
- Committer:
- MichaelW
- Date:
- 2010-10-01
- Revision:
- 0:47465be3223d
File content as of revision 0:47465be3223d:
/** * @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 }