As the title says... Chat on...

User avatar
By gwizz
#6535 Hello everybody

I've been banging my head against this one for a few hours now! I'm going mad but I'm hoping someone can explain my stupid mistake.

I want to write a userland lua driver for this lux sensor - based on adafruit's arduino example here: https://github.com/adafruit/TSL2561-Arduino-Library

I've got the device to respond to an i2c scan, and the address is what I expect. However I can't get the first stage of initialisation to return a value as expected from her code.

Can anyone help?

My code:
Code: Select all-- This code is GPL v3 by gareth@l0l.org.uk
-- blah blah blah standard licence conditions apply blah blah blah
-- Special hat-tip to lady ada - hacker hero - amongst many others
-- Reads value of TSL2561 I2C Luminosity sensor
-- As used on breakout board by Adafruit

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[13] -- connect to pin GPIO13
scl=io_pin[14] -- connect to pin GPIO14
addr=0x39 -- the I2C address of our device
TSL2561_REGISTER_ID=0x0A -- part of the register table

function initialise(addr)
     -- initialize i2c with our id and pins in slow mode :-)
     i2c.setup(id,sda,scl,i2c.SLOW)
     result=read_reg(addr,TSL2561_REGISTER_ID)
     print(tonumber(result))
     --if bit.band(result, 0x0A)==true then
     --     print("Found TSL2561")
     --end
end

-- user defined function: read from reg_addr content of dev_addr

function read_reg(dev_addr, 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

initialise(addr)
User avatar
By whamzam
#6960
gwizz wrote:Ok - I got to work with my real grown-up computer scientist friend today :D

He helped find my error - tonumber doesn't work for some reason - but string.byte does.

So if I write instead
Code: Select allprint(tonumber(result))


Then I see the result I was hoping for!


Glad to see you got the help you needed. I just started working on a similar project using the Adafruit TCS34725 color sensor breakout board. The command structure is similar. If you change the device address and registers it should work for you. I was able to read the rgbc registers but that part of the code needs cleaning up before I can post it. This code initializes and sets the gain and integration time. Don't forget to “OR” the COMMAND_BIT with the register addresses for all writes and reads! Good luck!

Code: Select all--TCS34725 Color Sensor Initialization Example using Lua on Esp8266 by Craig Scott cjscottcjscott@gmail.com
--code to read rgb registers works but needs cleaning up
-- Based on work by zeroday & sancho among many other open source authors
-- This code is public domain, attribution to gareth@l0l.org.uk appreciated.


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
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

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)
     --print("read command", reg_addr,c)
     i2c.stop(id)
     return c
end

 function write_reg(dev_addr, reg_addr, reg_val)
      reg_addr=bit.bor(COMMAND_BIT,reg_addr)
      --print("write command", dev_addr,reg_addr,reg_val)
      i2c.start(id)
      i2c.address(id, dev_addr, i2c.TRANSMITTER)
      i2c.write(id, reg_addr)
      i2c.write(id, reg_val)
      i2c.stop(id)
    end

initialise(addr)
write_reg(addr,ATIME, INTEGRATIONTIME_50MS)
print("Integration Time Set",val)
write_reg(addr,CONTROL, GAIN_1X)
enable()
print("Gain Set",GAIN_1X)
User avatar
By gwizz
#6973 AH! Thanks for that! Of course - a read also starts with a write, so it needs the command bit setting!

In the datasheet it mentions:
Power up/power down. By writing a 03h to this register, the device is powered up. By writing a 00h to this register, the device is powered down.

NOTE: If a value of 03h is written, the value returned during a read cycle will be 03h. This feature can be used to verify that the device is communicating properly.


I'm struggling to understand if this is possible using the nodemcu i2c implementation. I can get the return value of that write but it contains the number of bytes written, not the value 3 I'm expecting??

Useful debugging prints as well - I'll have them too! :)

Many thanks again and good luck with your project - I can see a load of applications of that with the esp and then send the colour off over the network for something!