; TCS34725 RGBW colour sensor. AllyCat, March 2024
; LED auto-controlled by interrupt pin. Code waits for updated ADC values.
#picaxe 14m2 ; Or any other M2
#no_data
#terminal 4800
#DEFINE ACTIVELED ; ) LED Activated only during the ADC conversion period
; #DEFINE LEDON ; }- If neither defined, then LED flashes briefly (not during the ADC conversion)
symbol I2CADDR = $52 ; 8-bit Slave address of TCS34725
symbol COMMAND = $A0 ; WO ; Auto Increment Register address = $A0, Register (sub-)Address 0
symbol ENABLE = $A0 ; R/W ; (Active Low) INTERRUPT = 16 , WAIT = 8 , ADC = 2 , POWER = 1
symbol ATIME = $A1 ; ADC Integration Time (256-ATIME) * 2.4ms ($D0=150ms, fs=65535)
symbol WTIME = $A3 ; Wait time (256 - WTIME) * 2.4ms ($AD=200ms)
symbol CONFIG = $AD ; 0= WAIT*1 , 2= WAIT*12 (28.8 ms units above)
symbol GAIN = $AF ; 0= GAIN*1, 1= GAIN*4, 2= GAIN*16, 3= GAIN*60 (CONTROL Register)
symbol DEVID = $B2 ; RO ; 68 ($44) or 77 ($4D)
symbol STATUS = $B3 ; INTERRUPT=16 , ADCDONE=1
symbol WDATAL = $B4 ; Low Byte of White Register (Datasheet uses CLEAR) .....
symbol BDATAH = $BB ; High Byte of Blue Register
symbol CLRINT = $E6 ; Clear the Interrupt Flag (Special Function)
symbol REGPTR = 6 ; White Low Byte address Pointer in RAM
symbol WhiteLo = b6
symbol White = w3 ; 16-bit "Clear Filter" register address (Low byte first)
symbol Red = w4 ; Red Filter register
symbol Green = w5 ; Green Filter
symbol Blue = w6 ; Blue Filter
pause 2000
call getvdd ; Report the Power Supply voltage (OPTIONAL)
init:
hi2csetup I2CMASTER,I2CADDR,I2CSLOW,I2CBYTE
call startup ; Report the Softstart or Hard Reset (Default) conditions (OPTIONAL)
sertxd(cr,lf,"Initialising.")
; hi2cin DEVID,(b1)
; sertxd(cr,lf,"ID(68/77)= ",#b1)
do
hi2cout ATIME,($EF) ; 40ms ADC Integration time
hi2cout GAIN,(2) ; * 16 (Named CONTROL register in Data Sheet)
hi2cout ENABLE,(%00000001) ; Power On
pause 2 ; 2.4 ms required for Oscillator to start
#IFDEF LEDON
hi2cout ENABLE,(%00000011) ; Interrupt Disabled (Idle High, so can turn LED ON), Run ADC
#ELSE
hi2cout ENABLE,(%00010011) ; Interrupt and ADC On
#ENDIF
#IFDEF ACTIVELED
hi2cout (CLRINT) ; Clear Interrupt (Idle High) to turn LED(s) ON
#ENDIF
sertxd(" Waiting") ; Around 25 ms to transmit this
do
sertxd(".") ; Approx 6ms for each subsequent dot
hi2cin STATUS,(b1)
loop until b1 > 16 ; Wait for Interrupt+ADC completion
bptr = REGPTR ; Generic RAM location
hi2cin WDATAL,(@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptr)
; hi2cin WDATAL,(b6,b7,b8,b9,b10,b11,b12,b13) ; Explicit variables
Green = Green ** 50000 ; Scale down to 75-80% mainly for Orange/Red discrimination
w7 = w4 + w5 + w6 / 100 min 1 ; RGB Sum to calculate percentages (avoiding 0 divisor)
w4 = w4 / w7 : w5 = w5 / w7 : w6 = w6 / w7 ; Calculate relative percentages
sertxd(cr,lf,"RGB%sW= ",#w4,",",#w5,",",#w6," s=",#w7," W=",#w3) ; Percentages, scaling and White channel
if Blue > 40 then : sertxd(" Blue") : goto done : endif
if Green > 40 then : sertxd(" Green") : goto done : endif
if Red > 50 then
if Blue < Green then : sertxd(" Orange") : goto done : endif ; The marginal one :-(
sertxd(" Red") : goto done
endif
if Blue < 27 then : sertxd(" Yellow") : goto done : endif
sertxd(" White")
done:
pause 3000
loop
startup:
sertxd(cr,lf,"Registers 0-$0F (R/W) | $10-$1B (RO):",cr,lf)
for b0 = COMMAND to BDATAH
hi2cin b0,(b1)
sertxd(#b1,",")
if b0 = GAIN then
sertxd(cr,lf)
endif
next b0
hi2cin ATIME,(b1)
w1 = 256 - b1 * 240 / 100 ; Time in ms
sertxd(cr,lf,"ADC Integration Time = ",#w1," ms")
return
getvdd: ; Test the power supply voltage
symbol CALVDD = 52429 ; 1024*1.024*1000/20 (ADC steps * Ref V / Resolution in mV)
calibadc10 w1 ; Measure FVR (nominal 1.024 v) relative to Vdd (1024 steps)
w2 = w1 / 2 + CALVDD ; Effectively round up CALVDD by half a (result) bit
w2 = w2 / w1 ; Take the reciprocal to calculate (half) Vdd (tens of mV)
calibadc10 w1 ; Read the value again because noise might be present :)
w1 = CALVDD / w1 + w2 ; Calculate Vdd/2 again and add in the first value
sertxd(cr,lf,"Vdd= ",#w1,"0 mV")
return
#rem SAMPLE RESULTS:
HARD RESET:
Vdd= 4980 mV
Registers 0-$0F (R/W) | $10-$1B (RO):
0,0,255,255,0,0,0,0,0,0,0,0,0,0,0,0,
0,1,77,0,0,0,0,0,0,0,0,0,
ADC Integration Time = 614 ms
Initialising. Waiting.....
RGB%sW= 32,31,36 s=190 W=17408 White Waiting.....
RGB%sW= 32,31,36 s=189 W=17408 White
SOFT RESET:
Vdd= 5000 mV
Registers 0-$0F (R/W) | $10-$1B (RO):
19,239,255,255,0,0,0,0,0,0,0,0,0,0,0,2,
0,1,77,17,57,25,223,9,162,10,0,11,
ADC Integration Time = 40 ms
Initialising. Waiting.....
RGB%sW= 32,31,36 s=187 W=17408 White Waiting.....
RGB%sW= 56,19,24 s=53 W=4169 Red Waiting.....
RGB%sW= 25,46,28 s=36 W=3919 Green Waiting.....
RGB%sW= 25,27,47 s=52 W=4247 Blue Waiting.....
RGB%sW= 58,21,20 s=77 W=7194 Orange Waiting.....
RGB%sW= 40,37,21 s=184 W=17408 Yellow Waiting.....