--TCS34725 Color Sensor Example using Lua on Esp8266 by Craig Scott cjscottcjscott@gmail.com
-- Based on work by zeroday & sancho among many other open source authors
id=0 -- need this to identify (software) IC2 bus?
io_pin= {[0]=3,[2]=4,[4]=2,[5]=1,[12]=6,[13]=7,[14]=5} -- this maps GPIO numbers to internal IO references
sda=io_pin[0]-- connect to pin GPIO0
scl=io_pin[2] -- connect to pin GPIO2
addr=0x29 -- the I2C address of our device
CDATAL=0x14 -- Clear channel data
CDATAH=0x15
RDATAL=0x16 -- Red channel data
RDATAH=0x17
GDATAL=0x18 -- Green channel data
GDATAH=0x19
BDATAL=0x1A -- Blue channel data
BDATAH=0x1B
ENABLE=0x00
ENABLE_AEN=0x02 --RGBC Enable - Writing 1 actives the ADC, 0 disables it
ENABLE_PON=0x01 -- Power on - Writing 1 activates the internal oscillator, 0 disables it
INTEGRATIONTIME_2MS=0xFF --< 2.4ms - 1 cycle - Max Count: 1024
INTEGRATIONTIME_24MS=0xF6 --< 24ms - 10 cycles - Max Count: 10240
INTEGRATIONTIME_50MS=0xEB --< 50ms - 20 cycles - Max Count: 20480
INTEGRATIONTIME_101MS=0xD5 --< 101ms - 42 cycles - Max Count: 43008
INTEGRATIONTIME_154MS=0xC0 --< 154ms - 64 cycles - Max Count: 65535
INTEGRATIONTIME_700MS=0x00 --< 700ms - 256 cycles - Max Count: 65535
GAIN_1X=0x00 --< No gain
GAIN_4X=0x01 --< 2x gain
GAIN_16X=0x02 --< 16x gain
GAIN_60X=0x03 --< 60x gain
ATIME=0x01 --< Set the Integration Time
CONTROL=0x0F --< Set the gain level
REGISTER_ID=0x12 -- register for Device ID 0x44 for TCS34725
COMMAND_BIT=0x80 -- Used for reads and writes
function initialise(addr)
-- initialize i2c with our id and pins in slow mode :-)
i2c.setup(id,sda,scl,i2c.SLOW)
result=read_reg(addr,REGISTER_ID)
if (string.byte(result)==0x44) then
print("Found TCS34725")
end
end
-- user defined function: read from reg_addr content of dev_addr
function read_reg(dev_addr, reg_addr)
reg_addr=bit.bor(COMMAND_BIT,reg_addr)
i2c.start(id)
i2c.address(id, dev_addr ,i2c.TRANSMITTER)
i2c.write(id,reg_addr)
i2c.stop(id)
i2c.start(id)
i2c.address(id, dev_addr,i2c.RECEIVER)
c=i2c.read(id,1)
i2c.stop(id)
return c
end
function write_reg(dev_addr, reg_addr, reg_val)
reg_addr=bit.bor(COMMAND_BIT,reg_addr)
i2c.start(id)
i2c.address(id, dev_addr, i2c.TRANSMITTER)
i2c.write(id, reg_addr)
i2c.write(id, reg_val)
i2c.stop(id)
end
function getRawData ()
clear_l = string.byte(read_reg(addr,CDATAL))
clear_h = string.byte(read_reg(addr,CDATAH))
red_l = string.byte(read_reg(addr,RDATAL))
red_h = string.byte(read_reg(addr,RDATAH))
green_l = string.byte(read_reg(addr,GDATAL))
green_h = string.byte(read_reg(addr,GDATAH))
blue_l = string.byte(read_reg(addr,BDATAL))
blue_h = string.byte(read_reg(addr,BDATAH))
clear =bit.bor(bit.lshift(clear_h,8),clear_l)
red=bit.bor(bit.lshift(red_h,8),red_l)
green=bit.bor(bit.lshift(green_h,8),green_l)
blue=bit.bor(bit.lshift(blue_h,8),blue_l)
-- Set a delay for the worst case integration time
tmr.delay(700)
return clear,red,green,blue
end
function enable()
write_reg(addr,ENABLE,ENABLE_PON)
tmr.delay(30)
write_reg(addr, ENABLE, bit.bor(ENABLE_PON,ENABLE_AEN))
end
function disable()
reg=0
reg=read_reg(addr,ENABLE)
tmr.delay(3)
write_reg(ENABLE, bit.band(reg, bit.bnot(bit.bor(ENABLE_PON,ENABLE_AEN))))
end
initialise(addr)
write_reg(addr,ATIME, INTEGRATIONTIME_50MS)
print("Integration Time Set",INTEGRATIONTIME_700MS)
write_reg(addr,CONTROL, GAIN_1X)
print("Gain Set",GAIN_1X)
enable()
for i=0,25 do
getRawData()
print(i,red,green,blue,clear)
tmr.delay(250000)
tmr.wdclr()
end
I've tested your script but it seems not working. I tried everything but the values that I get doesn't make any sense. Can you please explain how this works and if your tests have right results? Thank you.
It was tested using Esplorer
I have found after reseting the initial state can be quirky so you may have to reset again.
What the code does...
1) Initialization reads the Device ID.
2) Integration time is set
3) Gain is set
4) RGB and clear registers are read as separate high and low byte integers (8bit).
5) each color value is formed by combining the high and low register bytes using shift and "or" functions
6) values printed are 1-25 index, red green, blue, clear
Here is a sample run printing the first 3 values with a gain of one:
> dofile('TCS34725.lua')
Found TCS34725
Integration Time Set 0
Gain Set 0
0 33 26 19 56
1 34 26 20 57
2 34 26 20 57
Now a gain of 16X:
> dofile('TCS34725.lua')
Found TCS34725
Integration Time Set 0
Gain Set 2
0 580 456 352 964
1 587 463 359 974
2 590 465 356 974
Now with a red card over sensor:
> dofile('TCS34725.lua')
Found TCS34725
Integration Time Set 0
Gain Set 2
0 3911 972 801 5012
1 3912 972 801 5015
2 3903 971 801 5003
3 3879 964 794 4974
Note the red value increases significantly. Others increase slightly due to scattering
When debugging I placed several print statements to help me understand what was being read. You may want to verify by looking at the low and high bytes of a register and the color value for each hue.
Hope this helps
Thank you for your explanation, but what I didn't understand is the relation of these values with the standard RGB values. The RGB values has a maximum of 255 and these not. And the variation of the values with the distance of the object to sensor is very high. Just 1 or 2 mm distance affect the values read.
Thank you