Shop OBEX P1 Docs P2 Docs Learn Events
Problem with an TSL61 I2C Device: Code or Circuit? — Parallax Forums

Problem with an TSL61 I2C Device: Code or Circuit?

varnonvarnon Posts: 184
edited 2012-08-22 21:37 in Propeller 1
So I'm taking my first swing at putting together an I2C method for the TSL2561 https://www.adafruit.com/products/439. Unfortunately I haven't gotten very far, and I'm really not sure why. As far as I can tell, I follow the instructions in the data sheet. My code is also pretty much identical to the arduino demo code, and the code my engineer friend used to test the sensor on his microcontroller.

First, I can very that the sensor is connected correctly (As far as I can tell) with Tim Moore's i2cscan object. The scan detects the sensor, and correctly returns the address.This sensor has three addresses, depending on if the address pin is high, floating or low. I2cscan always reports the correct address.

Next I try to turn on the device. I have been using James Burrows's i2cobject. From what I understand from the data sheet, and other codes, I should send the address, the control register ($80), then the power on command ($03).

This doesn't actually seem to change the value of the register. If I read back the value of the register, it is reported as 255. (Michael Greene's Basic_I2C_Driver reports -1 when Burrow's object reports 255).

Of course everything after this doesn't matter. The sensor is never turned on. The devicepresent method agrees.

I've looked over the code dozens of times. I am not sure where I am going wrong. I've also tried other i2cobjects. I've tried it with and without wait methods.

CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000

  SCL = 28
  SDA = 29

   Address = $39       
   ' Binary 0111001    
      


OBJ

  PST           : "Parallax Serial Terminal"
  i2c           : "i2cObject"
  i2cscan       : "i2cscan"


VAR

  long  CH0
  long  CH1


PUB main | data

  i2cscan.i2cScan(SCL)
  ' Correctly finds and reports sensor address.

  pst.start(115_200)
  pst.str(string(13,"Starting...",13))

  turnon

  repeat 20
    readsensor
    wait

  turnoff


PUB turnon | data

  i2c.init(SDA,SCL,false)

  ' Power on sequence
  i2c.writeLocation(Address, $80, $03, 8, 8)
  wait

  pst.str(string(13,"Power on sequence complete.",13))
  pst.str(string("Register $80 = "))

  data:=i2c.readLocation(Address, $80, 8, 8)
  pst.dec(data)
  pst.char(13)

  data:=i2c.devicePresent(Address)

  if data==true
    pst.str(string("Device found.",13,13))
  else
    pst.str(string("Device not found.",13,13))


PUB turnoff | data

  ' Power off sequence
  i2c.writeLocation(Address, $80, $00, 8, 8)
  wait

  pst.str(string(13,"Power off sequence complete.",13))
  pst.str(string("Register $80 = "))

  data:=i2c.readLocation(Address, $80, 8, 8)
  pst.dec(data)
  pst.char(13)

  data:=i2c.devicePresent(Address)

  if data==true
    pst.str(string("Device found.",13,13))
  else
    pst.str(string("Device not found.",13,13))


PUB readsensor

  CH0:=i2c.readLocation(Address, $AC, 8, 16)
  CH1:=i2c.readLocation(Address, $AE, 8, 16)

  pst.str(string("Channel 0: "))
  pst.dec(CH0)
  pst.str(string("    "))
  pst.str(string("Channel 1: "))
  pst.dec(CH1)
  pst.char(13)

PUB Wait
  waitcnt((clkfreq/1000*250)+ cnt)



Another possibility is obviously the circuit. The fact that the i2cscan object has no problem detecting the device makes me thing the circuit isn't an issue. I am using the gadget USB platform. I tried it on the I2C bus (SCL=28, SDA=29) and general IO pins. I've tried with and without pull up resistors (1k and 1.5k) between the pins on the propeller and the pins on the sensor. I've also tried on the I2C bus on a quickstart. The result is always the same.
Another potential concern is the surface mount resistors on the breakout board (10k). I'm not really sure what those indicate. Do these resistors mean I can't use the sensor with 3.3v signals? I've got some level shifters somewhere if I need them. If the resistors on the breakout board are the problem then I have no idea how the i2cscan object would be able to get the address.


As always, I'd really appreciate any thoughts. I feel like there is something simple I am overlooking.

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2012-08-22 03:10
    Your Address constant appears to end with LSB being 1 (editor seems to have eaten the % and possibly some high order bits). AFAICS this interferes with the direction bit in the driver you're using. HTH
  • kuronekokuroneko Posts: 3,623
    edited 2012-08-22 19:43
    Just saw your edit. After some digging I found the i2cscan object. What does it report for this particular device (my assumption is $72, if not what is it)? The issue here is that the i2cObject takes control over bit 0 (LSB) of the device address to add directional information. If you pass in $39 then this stops the driver from working. So can you try again with something like:
    i2c.writeLocation(Address [COLOR="orange"]<< 1[/COLOR], $80, $03, 8, 8)
    
    Or left-justify your address (%aaaa_aaa0) and use your code as-is.
  • varnonvarnon Posts: 184
    edited 2012-08-22 21:37
    Thanks for the response.

    I saw your response earlier, and I didn't have time to reply so I just edited the post. I wanted to have a chance to look at the driver and really consider what you were saying before responding.

    I did find some comments in the i2cobject that mentioned the LSB, but I didn't realize that $39 could be written in only 6 bits. Its my fault for not counting. The %aaaa_aaaa convention is a very useful one. I also completely misunderstood the use of the LSB.

    The I2C scan object reports
    %01110010($72) %00111001($39)
    I think this is the address it scanned, then the device's address.

    Reformatting the address as %0111_0010 completely took care if everything! I still have to adjust other parts of the code to get accurate readings, but at least now I am able to communicate with the device.

    Thanks a lot! I knew it had to be something simple, but I was really running out of ideas.
Sign In or Register to comment.