Pro Mini, i2c and TAOS TSL26711 proximity sensor

Greetings. I'm trying to get the TSL26711 proximity sensor up and running with a 3.3v Pro Mini, and I'm not having any luck. This is my first foray in to the world of i2c communications, so that could be the root of my issue (plus I'm not much of a programmer). I've read through i2c examples and came across this post:

http://forum.arduino.cc/index.php/topic,243729.0.html

which seemed promising (the register addresses even match), but I cannot even get the incorrect output realized in that post.

Anyway, here is my code - apologies for how linear it is, I wanted to get it working first before building tidy functions:

#include <Wire.h>

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  
  Wire.beginTransmission(0x39);
  Wire.write(0x00); //move to enable register
  Wire.write(0x00); 
  Wire.endTransmission();
    
  Wire.beginTransmission(0x39);
  Wire.write(0x02); //move to time control register
  Wire.write(0xFF); 
  Wire.endTransmission();
  
  Wire.beginTransmission(0x39);
  Wire.write(0x03); //move to wait control register
  Wire.write(0xFF); 
  Wire.endTransmission();
  
  Wire.beginTransmission(0x39);
  Wire.write(0x0E); //move to prox pulse register
  Wire.write(0x10); //16 pulses
  Wire.endTransmission();
  
  Wire.beginTransmission(0x39);
  Wire.write(0x0F); //move to control register
  Wire.write(0x30); //00110000 - 100mA, use both diodes for prox
  Wire.endTransmission();
  
  Wire.beginTransmission(0x39);
  Wire.write(0x00); //move to enable register
  Wire.write(0x7); 
  Wire.endTransmission();
    
  Serial.begin(9600);  // start serial for output
}

void loop()
{
  
  Wire.beginTransmission(0x39);
  Wire.write(0x18); 
  Wire.endTransmission();
  
  Wire.requestFrom(0x39, 2);    
  while(Wire.available())    // slave may send less than requested
  { 
    byte c = Wire.read(); // receive a byte as character
    Serial.print("Low= ");
    Serial.println(c, HEX);
  } 
  
  Wire.beginTransmission(0x39);
  Wire.write(0x19); 
  Wire.endTransmission();
  
  Wire.requestFrom(0x39, 2);    
  while(Wire.available())    // slave may send less than requested
    { 
      byte c = Wire.read(); // receive a byte as character
      Serial.print("High= ");
      Serial.println(c, HEX);
    } 
  
  Wire.beginTransmission(0x39);
  Wire.write(0x13); 
  Wire.endTransmission();
  
  Wire.requestFrom(0x39, 2); 

  while(Wire.available())    // slave may send less than requested
    { 
      byte c = Wire.read(); // receive a byte as character
      Serial.print("Status= ");
      Serial.println(c, HEX);
    }  
    
    
  Wire.beginTransmission(0x39);
  Wire.write(0x00); 
  Wire.endTransmission();
  
  Wire.requestFrom(0x39, 2); 

  while(Wire.available())    // slave may send less than requested
    { 
      byte c = Wire.read(); // receive a byte as character
      Serial.print("Enable= ");
      Serial.println(c, HEX);
    }  

  delay(500);
}

I go through the process of setting up the various registers, then reading the low byte of the output, then the high byte, but the output I get is always the same, and it always is the register address for first byte, and nothing for the second byte. It appears that I am communicating, but even if I query one of the registers I allegedly set (enable, for instance), the response is the same - address for the first byte, nothing for the second. I'm using 1.5k pullups as per the datasheet and checked out the transmissions under a scope - the edges look pretty clean. Also, beyond the lack of output, I should be seeing 100mA blips on my power supply to drive the IR LED based on the setup configuration - I'm seeing no appreciable power draw at all. So, any ideas what I am doing wrong?

Thanks,

Chris

Ends up I wasn't addressing correctly - I wasn't formatting using the "command" register. All is well now.

-Chris

Hi;

It seems that I am also using the TSL26711 sensor for proximity sensing. I have spent the past few days sending I2C codes to the sensor but it never replies.

Would you be able to share how to hook up to the sensor?

Thanks in advance

Connection is a standard i2c connection, I'm using a 3.3v pro mini and a 3.3v external supply for the bus/sensor/LED drive. You might have issues running a 5v arduino with a 3.3v bus. Depending on the IR LED you are using, and the LED driver current setting, you might not be able to use the 3.3v output on whatever Arduino board you are using since some are limited to 50mA - and the driver can pull up to 100mA. I am also using 1.5k resistors as pullups on the i2c lines.

I suspect your issue may actually be the addressing, which I got wrong at first. In order to address one of the setup/configuration/status/output registers, you need to use the command register, and add in to the command register via bits 4:0 the address of the setup/configuration/status/output register of interest. For instance, if you wanted to change the control register - 0x0F - in order to do so, after beginning the transmission to the sensor (adress 0x39), when you send the command to move to the control register, using the address 0x0F won't work, you need to use the address 0X8F as per the command register notes. As per these notes, bit 7 needs to be a 1, bits 6:5 should be 00, and bits 4:0 should be 0x0F, yielding 0x8F. Also keep in mind that when you are querying the sensor for the proximity data, you need to use the auto-increment protocol transaction - bits 6:5 = 01 - as per the datasheet notes.

Once you are getting data back, keep an eye on your mechanical setup. I was using a giant IR LED and 16x 100mA pulse and my results made no sense. Backing the pulse off to 1 per cycle and placing the IR LED in the same plane as the sensor improved my results tremendously.

One issue I am still having is my proximity data is not coming back in full 16 bit resolution, I seem to max out at 10 bit. I might be doing something wrong with the proximity data retrieval. Let me know if you figure out how to correct this.

My updated code, for reference

#include <Wire.h>

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  
  Wire.beginTransmission(0x39);
  Wire.write(0x80); //move to enable register - 10000000
  Wire.write(0x00); //reset
  Wire.endTransmission();
    
  Wire.beginTransmission(0x39);
  Wire.write(0x82); //move to time control register - 10000010
  Wire.write(0xFF); //recommended by datasheet - 0xFF = 2.72ms integration cycle
  Wire.endTransmission();
  
  Wire.beginTransmission(0x39);
  Wire.write(0x83); //move to wait control register
  Wire.write(0xFF); //0xFF = 2.72ms wait
  Wire.endTransmission();
  
  Wire.beginTransmission(0x39);
  Wire.write(0x8E); //move to prox pulse register
  Wire.write(0x1); //16 pulses - 00010000
  Wire.endTransmission();
  
  Wire.beginTransmission(0x39);
  Wire.write(0x8F); //move to control register
  Wire.write(0x10); //00010000 (0x10) - 100mA, uses IR only, 00110000 (0x30) - 100mA, use both diodes for prox
  Wire.endTransmission();
  
  Wire.beginTransmission(0x39);
  Wire.write(0x80); //move to enable register
  Wire.write(0x7); //00000111 - power on, prox enable
  Wire.endTransmission();
    
  Serial.begin(9600);  // start serial for output
}

void loop()
{
  
  int low;
  int high;
  Wire.beginTransmission(0x39);
  Wire.write(0xB8); 
  Wire.endTransmission();
  
  Wire.requestFrom(0x39, 1);    
  while(Wire.available())    // slave may send less than requested
  { 
    low = Wire.read(); // receive a byte as character
    Serial.print("Low= ");
    Serial.println(low);
  } 
  
  Wire.beginTransmission(0x39);
  Wire.write(0x99); 
  Wire.endTransmission();
  
  Wire.requestFrom(0x39, 1);    
  while(Wire.available())    // slave may send less than requested
    { 
      high = Wire.read(); // receive a byte as character
      Serial.print("High= ");
      Serial.println(high);
    } 
  
  int prox = (low & 0x00FF) | (high << 8); //masks upper 8 bits of 16 bit low byte, ORs with bit shifted high byte - OR = if 1, return 1, otherwise 0
  Serial.print("Prox= ");
  Serial.println(prox);
    
  Wire.beginTransmission(0x39);
  Wire.write(0x80); 
  Wire.endTransmission();
  
  Wire.requestFrom(0x39, 1); 

  while(Wire.available())    // slave may send less than requested
    { 
      int c = Wire.read(); // receive a byte as character
      Serial.print("Enable= ");
      Serial.println(c);
    }  
    

  delay(500);
}

Thanks for the quick reply.

My device is still not responding on the I2C bus despite changing the PCB and the pull up resistors. All the lines seems correct and I am powering using 3V3 from an external source.

I will examine the sequence of the setup again. I suspect the problem is in there. Thanks!

Hi. I got it to work. :slight_smile: It was in the setup and I wrongly set the address. So thats all good now.

And also I am getting 10 bit resolution with 3FFh being the max. Did you manage to get past this?

I am trying to detect objects about 12in(30cm) away but so far it seems to be sensitive to only around 2 inches max with max current a1 100mA and max switching.