Spark fun have an RGB colour sensor http://www.sparkfun.com/commerce/product_info.php?products_id=8618. This has proven complicated to implement as the datasheet for this sensor is pretty shocking for a novice. The code below appears to work.
The theory is you calibrate the sensor to a surface or situation where the sensor will meet it's maximum reading so for paper I guess this is a white sheet of paper. This is done by setting 'cap values' and 'integration' times. Cap values is the amount of capacitors you will use to sense colour. The lower the value the higher the initial value. The Value must not exceed 1000. I still haven't found out what integration time is.
---+setting up+---
The integration values can be upto 4096 so take up two bytes. The cap values are from 0 to 15 so single byte
---+getting optimum value+---
Once again the aim of the calibration is to get a value of less than 1000 under normal conditions. B10 here is my cap value. Changing this value is to coarse an adjustment so I fix this to a value that gives me small enough changes when looping thru W13. W13 increases by one for each loop in the START: program. This is sent with the cap value to the sensor and the result is read back in. If the value read back in is greater than 900 a byte flag is set and the value is written to EEPROM for later.
The integration value is between 0 and 4095. I have found that a integration value of 256 gives the same sensor value as 0. This is also the case for 512. So I aim to get the optimum value before W13 reaches 256. If this is not the case I lower the CAP value, if the jumps in integration are too high I raise the CAP value.
---+setting up to read+---
This loads the values found in the first code into the sensor. The spec sheet says that the light source must be off when the values are loaded into the register hence the low led and high led. Later I used a more poweful light source which needed to be turned down with PWM.
---+reading the colour+---
This codes initiates a read when a push button is pushed, then writes it to pin 0.
This sensor seems to be able to tell differences between red green and blue. However wanted to measure differences in reflected colours like cyan, magenta and yellow. Cyan and Yellow gives me high values in blue,green and red,green respectivly but Magenta just gives me high values of red.
The results below are of a 12 step gradation from 100% magenta to 0%. The higher the value the higher amount of that colour is sensed. Or not refected depends how you interpret it.
The theory is you calibrate the sensor to a surface or situation where the sensor will meet it's maximum reading so for paper I guess this is a white sheet of paper. This is done by setting 'cap values' and 'integration' times. Cap values is the amount of capacitors you will use to sense colour. The lower the value the higher the initial value. The Value must not exceed 1000. I still haven't found out what integration time is.
---+setting up+---
Code:
WAIT 1
SYMBOL SENSOR_PWR = 2
SYMBOL LED = 1
SYMBOL ADJD = 0x74
SYMBOL CAP_RED = 0x06
SYMBOL CAP_GREEN = 0x07
SYMBOL CAP_BLUE = 0x08
SYMBOL CAP_CLEAR = 0x09
SYMBOL INT_RED_LO = 0x0A
SYMBOL INT_RED_HI = 0x0B
SYMBOL INT_GREEN_LO = 0x0C
SYMBOL INT_GREEN_HI = 0x0D
SYMBOL INT_BLUE_LO = 0x0E
SYMBOL INT_BLUE_HI = 0x0F
SYMBOL INT_CLEAR_LO = 0x10
SYMBOL INT_CLEAR_HI = 0x11
SYMBOL DATA_RED_LO = 0x40
SYMBOL DATA_RED_HI = 0x41
SYMBOL DATA_GREEN_LO = 0x42
SYMBOL DATA_GREEN_HI = 0x43
SYMBOL DATA_BLUE_LO = 0x44
SYMBOL DATA_BLUE_HI = 0x45
SYMBOL DATA_CLEAR_LO = 0x46
SYMBOL DATA_CLEAR_HI = 0x47
SYMBOL OFFSET_RED = 0x48
SYMBOL OFFSET_GREEN = 0x49
SYMBOL OFFSET_BLUE = 0x4A
SYMBOL OFFSET_CLEAR = 0x4B
i2cslave %11101001, i2cslow,i2cbyte
---+getting optimum value+---
Code:
B10=5
W13=1
START:
W13=W13+1
HIGH SENSOR_PWR
PAUSE 200
writei2c CAP_RED, (B10)
writei2c CAP_GREEN, (B10)
writei2c CAP_BLUE, (B10)
writei2c CAP_CLEAR, (B10)
writei2c INT_RED_LO,(B27)
writei2c INT_RED_HI,(B26)
writei2c INT_GREEN_LO,(B27)
writei2c INT_GREEN_HI,(B26)
writei2c INT_BLUE_LO,(B27)
writei2c INT_BLUE_HI,(B26)
writei2c INT_CLEAR_LO,(B27)
writei2c INT_CLEAR_HI,(B26)
HIGH LED
writei2c 0,(0x01) 'write 0x00 to to ctrl
PAUSE 200
readi2c 0,(b8)
readi2c DATA_RED_LO,(b0)
readi2c DATA_RED_HI,(b1)
readi2c DATA_GREEN_LO,(b2)
readi2c DATA_GREEN_HI,(b3)
readi2c DATA_BLUE_LO,(b4)
readi2c DATA_BLUE_HI,(b5)
readi2c DATA_CLEAR_LO,(b6)
readi2c DATA_CLEAR_HI,(b7)
serout 0,T2400,("INT: ",#W13,cr,lf)
serout 0,T2400,("CTRL: ",#B8,cr,lf)
serout 0,T2400,("RED : ",#W0,cr,lf)
serout 0,T2400,("GREEN: ",#W1,cr,lf)
serout 0,T2400,("BLUE: ",#W2,cr,lf)
serout 0,T2400,("B21: ",#B21,cr,lf)
serout 0,T2400,("CLEAR: ",#W3,cr,lf,cr,lf)
if W0 > 900 AND B22 != 1 THEN GOSUB SET_RED
IF W1 > 900 AND B23 != 1 THEN GOSUB SET_GREEN
IF W2 > 900 AND B24 != 1 THEN GOSUB SET_BLUE
IF W3 > 900 AND B25 != 1 THEN GOSUB SET_CLEAR
B21 = B22+B23+B24+B25
IF B21 = 4 THEN GOSUB FINISH
GOTO START
SET_RED:
serout 0,T2400,("RED SET ",cr,lf)
B22 = 1
WRITE 0,W13
RETURN
SET_GREEN:
serout 0,T2400,("GREEN SET ",cr,lf)
B23 = 1
WRITE 2,W13
RETURN
SET_BLUE:
serout 0,T2400,("BLUE SET ",cr,lf)
B24 = 1
WRITE 4,W13
RETURN
SET_CLEAR:
serout 0,T2400,("CLEAR SET ",cr,lf)
B25 = 1
WRITE 6,W13
RETURN
The integration value is between 0 and 4095. I have found that a integration value of 256 gives the same sensor value as 0. This is also the case for 512. So I aim to get the optimum value before W13 reaches 256. If this is not the case I lower the CAP value, if the jumps in integration are too high I raise the CAP value.
---+setting up to read+---
Code:
LOW SENSOR_PWR
WAIT 1
HIGH SENSOR_PWR
PAUSE 200
READ 0,W5
READ 2,W6
READ 4,W7
READ 6,W8
serout 0,T2400,(CR,LF,#B10," ",#B11," ",#B12," ",#B13," ",#B14," ",#B15," ",#B16," ",#B17)
writei2c CAP_RED, (0x04)
writei2c CAP_GREEN, (0x04)
writei2c CAP_BLUE, (0x04)
writei2c CAP_CLEAR, (0x04)
writei2c INT_RED_LO,(B11)
writei2c INT_RED_HI,(B10)
writei2c INT_GREEN_LO,(B13)
writei2c INT_GREEN_HI,(B12)
writei2c INT_BLUE_LO,(B15)
writei2c INT_BLUE_HI,(B14)
writei2c INT_CLEAR_LO,(B17)
writei2c INT_CLEAR_HI,(B16)
HIGH LED
writei2c 0,(0x01) 'write 0x00 to to ctrl
PAUSE 200
readi2c 0,(b8)
readi2c DATA_RED_LO,(b0)
readi2c DATA_RED_HI,(b1)
readi2c DATA_GREEN_LO,(b2)
readi2c DATA_GREEN_HI,(b3)
readi2c DATA_BLUE_LO,(b4)
readi2c DATA_BLUE_HI,(b5)
readi2c DATA_CLEAR_LO,(b6)
readi2c DATA_CLEAR_HI,(b7)
serout 0,T2400,(cr,lf,"RED : ",#W0,cr,lf)
serout 0,T2400,("GREEN: ",#W1,cr,lf)
serout 0,T2400,("BLUE: ",#W2,cr,lf)
serout 0,T2400,("CLEAR: ",#W3,cr,lf,cr,lf)
low led
writei2c 0x00,(0x02)
readi2c 0x00,(b8)
writei2c 0x01,(0x01)
readi2c 0x00,(b8)
high led
writei2c 0,(0x01) 'write 0x00 to to ctrl
pause 200
readi2c 0x00,(b8)
readi2c DATA_RED_LO,(b8)
readi2c DATA_RED_HI,(b9)
readi2c DATA_GREEN_LO,(b10)
readi2c DATA_GREEN_HI,(b11)
readi2c DATA_BLUE_LO,(b12)
readi2c DATA_BLUE_HI,(b13)
readi2c DATA_CLEAR_LO,(b14)
readi2c DATA_CLEAR_HI,(b15)
---+reading the colour+---
Code:
main2:
if pin2 = 1 then gosub read_col:
goto main2:
read_col:
writei2c 0,(0x01) 'write 0x00 to to ctrl
pause 200
readi2c 0x00,(b8)
readi2c DATA_RED_LO,(b0)
readi2c DATA_RED_HI,(b1)
readi2c DATA_GREEN_LO,(b2)
readi2c DATA_GREEN_HI,(b3)
readi2c DATA_BLUE_LO,(b4)
readi2c DATA_BLUE_HI,(b5)
readi2c DATA_CLEAR_LO,(b6)
readi2c DATA_CLEAR_HI,(b7)
serout 0,T2400,(cr,lf,"RED : ,",#W0,",")
serout 0,T2400,(" GREEN: ,",#W1,",")
serout 0,T2400,(" BLUE: ,",#W2,",")
serout 0,T2400,(" CLEAR: ,",#W3,",")
return
This sensor seems to be able to tell differences between red green and blue. However wanted to measure differences in reflected colours like cyan, magenta and yellow. Cyan and Yellow gives me high values in blue,green and red,green respectivly but Magenta just gives me high values of red.
The results below are of a 12 step gradation from 100% magenta to 0%. The higher the value the higher amount of that colour is sensed. Or not refected depends how you interpret it.
Code:
RED : 751 GREEN: 413 BLUE: 376 CLEAR: 517
RED : 792 GREEN: 449 BLUE: 428 CLEAR: 558
RED : 807 GREEN: 481 BLUE: 464 CLEAR: 588
RED : 823 GREEN: 512 BLUE: 509 CLEAR: 612
RED : 836 GREEN: 562 BLUE: 562 CLEAR: 652
RED : 864 GREEN: 616 BLUE: 618 CLEAR: 700
RED : 869 GREEN: 648 BLUE: 655 CLEAR: 721
RED : 894 GREEN: 718 BLUE: 724 CLEAR: 781
RED : 914 GREEN: 788 BLUE: 781 CLEAR: 842
RED : 923 GREEN: 834 BLUE: 820 CLEAR: 873
RED : 940 GREEN: 883 BLUE: 864 CLEAR: 912
RED : 955 GREEN: 937 BLUE: 921 CLEAR: 952