Library for the ADJD-S371, Avago Colour Sensor

Committer:
MichaelW
Date:
Fri Oct 01 13:39:51 2010 +0000
Revision:
0:47465be3223d
Supports reading from the sensors and writing to the configuration registers. Doesn\t have built in  optimisation yet

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MichaelW 0:47465be3223d 1 /**
MichaelW 0:47465be3223d 2 * @section LICENSE
MichaelW 0:47465be3223d 3 *Copyright (c) 2010 ARM Ltd.
MichaelW 0:47465be3223d 4 *
MichaelW 0:47465be3223d 5 *Permission is hereby granted, free of charge, to any person obtaining a copy
MichaelW 0:47465be3223d 6 *of this software and associated documentation files (the "Software"), to deal
MichaelW 0:47465be3223d 7 *in the Software without restriction, including without limitation the rights
MichaelW 0:47465be3223d 8 *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
MichaelW 0:47465be3223d 9 *copies of the Software, and to permit persons to whom the Software is
MichaelW 0:47465be3223d 10 *furnished to do so, subject to the following conditions:
MichaelW 0:47465be3223d 11 *
MichaelW 0:47465be3223d 12 *The above copyright notice and this permission notice shall be included in
MichaelW 0:47465be3223d 13 *all copies or substantial portions of the Software.
MichaelW 0:47465be3223d 14 *
MichaelW 0:47465be3223d 15 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
MichaelW 0:47465be3223d 16 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
MichaelW 0:47465be3223d 17 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
MichaelW 0:47465be3223d 18 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
MichaelW 0:47465be3223d 19 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
MichaelW 0:47465be3223d 20 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
MichaelW 0:47465be3223d 21 *THE SOFTWARE.
MichaelW 0:47465be3223d 22 *
MichaelW 0:47465be3223d 23 *
MichaelW 0:47465be3223d 24 * @section DESCRIPTION
MichaelW 0:47465be3223d 25 *
MichaelW 0:47465be3223d 26 *
MichaelW 0:47465be3223d 27 */
MichaelW 0:47465be3223d 28
MichaelW 0:47465be3223d 29 #include "ADJDColourSensor.h"
MichaelW 0:47465be3223d 30
MichaelW 0:47465be3223d 31 ADJDColourSensor::ADJDColourSensor(PinName sda, PinName scl, PinName LED):
MichaelW 0:47465be3223d 32 _sensor(sda, scl),
MichaelW 0:47465be3223d 33 _LED(LED)
MichaelW 0:47465be3223d 34 {
MichaelW 0:47465be3223d 35 _address = 0x74 << 1;
MichaelW 0:47465be3223d 36 char cmd[2];
MichaelW 0:47465be3223d 37 cmd[0] = 1; //Config reg
MichaelW 0:47465be3223d 38 cmd[1] = 0x01; //setup
MichaelW 0:47465be3223d 39 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 40
MichaelW 0:47465be3223d 41 setCapacitors(0x0E,0x0E,0x0E,0x0E);
MichaelW 0:47465be3223d 42 //Good for 500 under office light
MichaelW 0:47465be3223d 43 setIntegrationTimeSlot(900,1000,1800,600);
MichaelW 0:47465be3223d 44 //1000, 1000, 1700, 600
MichaelW 0:47465be3223d 45
MichaelW 0:47465be3223d 46
MichaelW 0:47465be3223d 47 setIntegrationTimeSlot(1300,1400,2200,1000);
MichaelW 0:47465be3223d 48
MichaelW 0:47465be3223d 49 }
MichaelW 0:47465be3223d 50
MichaelW 0:47465be3223d 51 void ADJDColourSensor::setCapacitors(int redCap, int greenCap, int blueCap, int clearCap){
MichaelW 0:47465be3223d 52 //Values from 00H to 0FH
MichaelW 0:47465be3223d 53 char cmd[2];
MichaelW 0:47465be3223d 54 //Red
MichaelW 0:47465be3223d 55 cmd[0] = 0x06; //Cap Red
MichaelW 0:47465be3223d 56 cmd[1] = redCap; //
MichaelW 0:47465be3223d 57 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 58
MichaelW 0:47465be3223d 59 //Green
MichaelW 0:47465be3223d 60 cmd[0] = 0x07; //Cap Green
MichaelW 0:47465be3223d 61 cmd[1] = greenCap; //
MichaelW 0:47465be3223d 62 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 63
MichaelW 0:47465be3223d 64 //Blue
MichaelW 0:47465be3223d 65 cmd[0] = 0x08; //Cap Blue
MichaelW 0:47465be3223d 66 cmd[1] = blueCap; //
MichaelW 0:47465be3223d 67 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 68
MichaelW 0:47465be3223d 69 //Clear
MichaelW 0:47465be3223d 70 cmd[0] = 0x09; //Cap clear
MichaelW 0:47465be3223d 71 cmd[1] = clearCap; //
MichaelW 0:47465be3223d 72 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 73 }
MichaelW 0:47465be3223d 74 void ADJDColourSensor::setIntegrationTimeSlot(int redInt, int greenInt, int blueInt, int clearInt){
MichaelW 0:47465be3223d 75 //values should be 0 to 4095
MichaelW 0:47465be3223d 76 char cmd[2];
MichaelW 0:47465be3223d 77 //Red
MichaelW 0:47465be3223d 78 cmd[0] = 0x0A; //int red low
MichaelW 0:47465be3223d 79 cmd[1] = redInt & 0xFF; //redInt low
MichaelW 0:47465be3223d 80 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 81
MichaelW 0:47465be3223d 82 cmd[0] = 0x0B; //int red high
MichaelW 0:47465be3223d 83 cmd[1] = (redInt >> 8) & 0x0F; //redInt high
MichaelW 0:47465be3223d 84 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 85
MichaelW 0:47465be3223d 86 //Green
MichaelW 0:47465be3223d 87 cmd[0] = 0x0C; //int green low
MichaelW 0:47465be3223d 88 cmd[1] = greenInt & 0xFF; //greenInt low
MichaelW 0:47465be3223d 89 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 90
MichaelW 0:47465be3223d 91 cmd[0] = 0x0D; //int green high
MichaelW 0:47465be3223d 92 cmd[1] = (greenInt >> 8) & 0x0F; //greenInt high
MichaelW 0:47465be3223d 93 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 94
MichaelW 0:47465be3223d 95 //Blue
MichaelW 0:47465be3223d 96 cmd[0] = 0x0E; //int blue low
MichaelW 0:47465be3223d 97 cmd[1] = blueInt & 0xFF; //blueInt low
MichaelW 0:47465be3223d 98 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 99
MichaelW 0:47465be3223d 100 cmd[0] = 0x0F; //int blue high
MichaelW 0:47465be3223d 101 cmd[1] = (blueInt >> 8) & 0x0F; //blueInt high
MichaelW 0:47465be3223d 102 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 103
MichaelW 0:47465be3223d 104 //Clear
MichaelW 0:47465be3223d 105 cmd[0] = 0x10; //int clear low
MichaelW 0:47465be3223d 106 cmd[1] = clearInt & 0xFF; //clearInt low
MichaelW 0:47465be3223d 107 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 108
MichaelW 0:47465be3223d 109 cmd[0] = 0x11; //int clear high
MichaelW 0:47465be3223d 110 cmd[1] = (clearInt >> 8) & 0x0F; //clearInt high
MichaelW 0:47465be3223d 111 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 112 }
MichaelW 0:47465be3223d 113 float ADJDColourSensor::read(){
MichaelW 0:47465be3223d 114
MichaelW 0:47465be3223d 115 _LED = 1;
MichaelW 0:47465be3223d 116
MichaelW 0:47465be3223d 117 char cmd[2];
MichaelW 0:47465be3223d 118 char cmd2[2];
MichaelW 0:47465be3223d 119 char Result[2];
MichaelW 0:47465be3223d 120 cmd[0] = 0x00; //CTRL reg
MichaelW 0:47465be3223d 121 cmd[1] = 0x01; //Get sensor
MichaelW 0:47465be3223d 122 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 123 wait(0.1);
MichaelW 0:47465be3223d 124
MichaelW 0:47465be3223d 125 do{
MichaelW 0:47465be3223d 126 wait(0.1);
MichaelW 0:47465be3223d 127 cmd[0] = 0;
MichaelW 0:47465be3223d 128 _sensor.write(_address, cmd, 1);
MichaelW 0:47465be3223d 129 _sensor.read(_address, cmd2, 1);
MichaelW 0:47465be3223d 130 //printf("sensing %i\n", int(cmd2[0]));
MichaelW 0:47465be3223d 131 }while(cmd2[0] != 0); //Wait for CTRl register to be clear
MichaelW 0:47465be3223d 132
MichaelW 0:47465be3223d 133
MichaelW 0:47465be3223d 134 //red
MichaelW 0:47465be3223d 135 cmd[0] = 0x40;
MichaelW 0:47465be3223d 136 _sensor.write(_address, cmd, 1);
MichaelW 0:47465be3223d 137 _sensor.read(_address, Result, 1);
MichaelW 0:47465be3223d 138 cmd[0] = 0x41;
MichaelW 0:47465be3223d 139 _sensor.write(_address, cmd, 1);
MichaelW 0:47465be3223d 140 _sensor.read(_address, cmd2, 1);
MichaelW 0:47465be3223d 141 _red = Result[0] | ((cmd2[0] & 0x03) << 8);
MichaelW 0:47465be3223d 142
MichaelW 0:47465be3223d 143
MichaelW 0:47465be3223d 144 //Green
MichaelW 0:47465be3223d 145 cmd[0] = 0x42;
MichaelW 0:47465be3223d 146 _sensor.write(_address, cmd, 1);
MichaelW 0:47465be3223d 147 _sensor.read(_address, Result, 1);
MichaelW 0:47465be3223d 148 cmd[0] = 0x43;
MichaelW 0:47465be3223d 149 _sensor.write(_address, cmd, 1);
MichaelW 0:47465be3223d 150 _sensor.read(_address, cmd2, 1);
MichaelW 0:47465be3223d 151 _green = Result[0] | ((cmd2[0] & 0x03) << 8);
MichaelW 0:47465be3223d 152
MichaelW 0:47465be3223d 153 //Blue
MichaelW 0:47465be3223d 154 cmd[0] = 0x44;
MichaelW 0:47465be3223d 155 _sensor.write(_address, cmd, 1);
MichaelW 0:47465be3223d 156 _sensor.read(_address, Result, 1);
MichaelW 0:47465be3223d 157 cmd[0] = 0x45;
MichaelW 0:47465be3223d 158 _sensor.write(_address, cmd, 1);
MichaelW 0:47465be3223d 159 _sensor.read(_address, cmd2, 1);
MichaelW 0:47465be3223d 160 _blue = Result[0] | ((cmd2[0] & 0x03) << 8);
MichaelW 0:47465be3223d 161 _LED = 0;
MichaelW 0:47465be3223d 162
MichaelW 0:47465be3223d 163 //Clear
MichaelW 0:47465be3223d 164 float clear;
MichaelW 0:47465be3223d 165 cmd[0] = 0x46;
MichaelW 0:47465be3223d 166 _sensor.write(_address, cmd, 1);
MichaelW 0:47465be3223d 167 _sensor.read(_address, Result, 1);
MichaelW 0:47465be3223d 168 cmd[0] = 0x47;
MichaelW 0:47465be3223d 169 _sensor.write(_address, cmd, 1);
MichaelW 0:47465be3223d 170 _sensor.read(_address, cmd2, 1);
MichaelW 0:47465be3223d 171 _clear = Result[0] | ((cmd2[0] & 0x03) << 8);
MichaelW 0:47465be3223d 172
MichaelW 0:47465be3223d 173
MichaelW 0:47465be3223d 174 //Convert the private int values into the output float values
MichaelW 0:47465be3223d 175 red = (float)_red;
MichaelW 0:47465be3223d 176 green = (float)_green;
MichaelW 0:47465be3223d 177 blue = (float)_blue;
MichaelW 0:47465be3223d 178 clear = (float)_clear;
MichaelW 0:47465be3223d 179
MichaelW 0:47465be3223d 180 return(clear);
MichaelW 0:47465be3223d 181 }
MichaelW 0:47465be3223d 182
MichaelW 0:47465be3223d 183 int ADJDColourSensor::readOffset(){
MichaelW 0:47465be3223d 184 _LED = 1;
MichaelW 0:47465be3223d 185 char cmd[2];
MichaelW 0:47465be3223d 186 cmd[0] = 0; //CTRL reg
MichaelW 0:47465be3223d 187 cmd[1] = 2; //Get sensor
MichaelW 0:47465be3223d 188 _sensor.write(_address, cmd, 2);
MichaelW 0:47465be3223d 189
MichaelW 0:47465be3223d 190 wait(0.1); //Or wait till bit cleared
MichaelW 0:47465be3223d 191
MichaelW 0:47465be3223d 192 //Red
MichaelW 0:47465be3223d 193 cmd[0] = 0x48;
MichaelW 0:47465be3223d 194 _sensor.write(_address, cmd, 1);
MichaelW 0:47465be3223d 195 _sensor.read(_address, cmd, 1);
MichaelW 0:47465be3223d 196 redOffset = cmd[0];
MichaelW 0:47465be3223d 197
MichaelW 0:47465be3223d 198 //Green
MichaelW 0:47465be3223d 199 cmd[0] = 0x49;
MichaelW 0:47465be3223d 200 _sensor.write(_address, cmd, 1);
MichaelW 0:47465be3223d 201 _sensor.read(_address, cmd, 1);
MichaelW 0:47465be3223d 202 greenOffset = cmd[0];
MichaelW 0:47465be3223d 203
MichaelW 0:47465be3223d 204 //Blue
MichaelW 0:47465be3223d 205 cmd[0] = 0x4A;
MichaelW 0:47465be3223d 206 _sensor.write(_address, cmd, 1);
MichaelW 0:47465be3223d 207 _sensor.read(_address, cmd, 1);
MichaelW 0:47465be3223d 208 blueOffset = cmd[0];
MichaelW 0:47465be3223d 209
MichaelW 0:47465be3223d 210 //Clear
MichaelW 0:47465be3223d 211 cmd[0] = 0x4B;
MichaelW 0:47465be3223d 212 _sensor.write(_address, cmd, 1);
MichaelW 0:47465be3223d 213 _sensor.read(_address, cmd, 1);
MichaelW 0:47465be3223d 214 clearOffset = cmd[0];
MichaelW 0:47465be3223d 215
MichaelW 0:47465be3223d 216 _LED = 0;
MichaelW 0:47465be3223d 217
MichaelW 0:47465be3223d 218 return(clearOffset);
MichaelW 0:47465be3223d 219
MichaelW 0:47465be3223d 220 }
MichaelW 0:47465be3223d 221 void ADJDColourSensor::optimise(){
MichaelW 0:47465be3223d 222 optimise(500,500,500,500);
MichaelW 0:47465be3223d 223 }
MichaelW 0:47465be3223d 224 void ADJDColourSensor::optimise(int optimum){
MichaelW 0:47465be3223d 225 optimise(optimum,optimum,optimum,optimum);
MichaelW 0:47465be3223d 226 }
MichaelW 0:47465be3223d 227 void ADJDColourSensor::optimise(int redTarget, int blueTarget, int greenTarget ,int clearTarget){
MichaelW 0:47465be3223d 228 //use capacitor as they are to begin with
MichaelW 0:47465be3223d 229
MichaelW 0:47465be3223d 230 //Optimise all at once as reading
MichaelW 0:47465be3223d 231 int redInt = 1000;
MichaelW 0:47465be3223d 232 int greenInt = 1000;
MichaelW 0:47465be3223d 233 int blueInt = 1000;
MichaelW 0:47465be3223d 234 int clearInt = 1000;
MichaelW 0:47465be3223d 235 int range = 20;
MichaelW 0:47465be3223d 236 bool Optimised = false;
MichaelW 0:47465be3223d 237 read();
MichaelW 0:47465be3223d 238 while(!Optimised){
MichaelW 0:47465be3223d 239
MichaelW 0:47465be3223d 240
MichaelW 0:47465be3223d 241 //Optimise red
MichaelW 0:47465be3223d 242 if(_red > (redTarget + range)){
MichaelW 0:47465be3223d 243 //too big so decreae redInt
MichaelW 0:47465be3223d 244 redInt = redInt - 50;
MichaelW 0:47465be3223d 245 }else{
MichaelW 0:47465be3223d 246 if(_red < (redTarget - range)){
MichaelW 0:47465be3223d 247 //too low so increase redInt
MichaelW 0:47465be3223d 248 redInt = redInt + 50;
MichaelW 0:47465be3223d 249 }
MichaelW 0:47465be3223d 250 }
MichaelW 0:47465be3223d 251 //optimise blue
MichaelW 0:47465be3223d 252 if(_blue > (blueTarget + range)){
MichaelW 0:47465be3223d 253 blueInt = blueInt - 50;
MichaelW 0:47465be3223d 254 }else{
MichaelW 0:47465be3223d 255 if(_blue < (blueTarget - range)){
MichaelW 0:47465be3223d 256 blueInt = blueInt + 50;
MichaelW 0:47465be3223d 257 }
MichaelW 0:47465be3223d 258 }
MichaelW 0:47465be3223d 259
MichaelW 0:47465be3223d 260 //optimise green
MichaelW 0:47465be3223d 261 if(_green > (greenTarget + range)){
MichaelW 0:47465be3223d 262 greenInt = greenInt - 50;
MichaelW 0:47465be3223d 263 }else{
MichaelW 0:47465be3223d 264 if(_green < (greenTarget - range)){
MichaelW 0:47465be3223d 265 greenInt = greenInt + 50;
MichaelW 0:47465be3223d 266 }
MichaelW 0:47465be3223d 267 }
MichaelW 0:47465be3223d 268
MichaelW 0:47465be3223d 269 //Optimise Clear
MichaelW 0:47465be3223d 270 if(_clear > (clearTarget + range)){
MichaelW 0:47465be3223d 271 clearInt = clearInt - 50;
MichaelW 0:47465be3223d 272 }else{
MichaelW 0:47465be3223d 273 if(_clear < (clearTarget - range)){
MichaelW 0:47465be3223d 274 clearInt = clearInt + 50;
MichaelW 0:47465be3223d 275 }
MichaelW 0:47465be3223d 276 }
MichaelW 0:47465be3223d 277
MichaelW 0:47465be3223d 278 //Check if any of the integration values have exceeded the max limits (0 to 4095) and if so try changing the capacitors
MichaelW 0:47465be3223d 279 if((redInt > 4095 || greenInt > 4095 || blueInt > 4095 || clearInt > 4095) || (redInt <= 0 || greenInt <= 0 || blueInt <= 0 || clearInt <= 0)){
MichaelW 0:47465be3223d 280 printf("Also need to change the capacitor values\n");
MichaelW 0:47465be3223d 281 }
MichaelW 0:47465be3223d 282 //Send the new optimisation
MichaelW 0:47465be3223d 283 setIntegrationTimeSlot(redInt, greenInt, blueInt, clearInt);
MichaelW 0:47465be3223d 284
MichaelW 0:47465be3223d 285 //get new values
MichaelW 0:47465be3223d 286 _clear = read();
MichaelW 0:47465be3223d 287
MichaelW 0:47465be3223d 288 //Check if optimised
MichaelW 0:47465be3223d 289 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;
MichaelW 0:47465be3223d 290
MichaelW 0:47465be3223d 291 }
MichaelW 0:47465be3223d 292
MichaelW 0:47465be3223d 293
MichaelW 0:47465be3223d 294 //Should check max condition (Outputs do not exceed 1000) - or is the above optimising for max condition
MichaelW 0:47465be3223d 295
MichaelW 0:47465be3223d 296 }