Avago ADJD-S313-QR999 Reflective Color Sensor

Hello, I am new to forums, microcontrollers, and Arduino!
I am trying to interface the ADJD-S313-QR999 Reflective Color Sensor to an Arduino Duemilanove.
I want to output the contents of the registers of the Avago sensor to the serial terminal on the computer.
I believe I have powered the sensor properly and I have written the following code:

/*program for ADJD-S313-QR999 Reflective Color Sensor
Draft by Bradley J Piekie?ko
Start date: September 18, 2011
Corrections/Assistance by
*/

#include "Wire.h"

byte r = 0x00;//variable for storing data from ADJD-S313 RED register
byte g = 0x00;//variable for storing data from ADJD-S313 GREEN register
byte b = 0x00;//variable for storing data from ADJD-S313 BLUE register

void setup()
{
Wire.begin();
Serial.begin(9600);//allows computer terminal output

int xrset = 13;//sets pin 13 as ADJD-S313 reset
pinMode(xrset, OUTPUT);
digitalWrite(xrset, LOW);//a LOW will reset all registers on the ADJD-S313
delay(500);// ??necessary??
digitalWrite(xrset,HIGH);

/???set ADJD-S313 as slave???/
Wire.beginTransmission(0x58);
Wire.send(0);
Wire.endTransmission();

/at the start of the application, the following setup data must be written
to the setup registers:
/
Wire.beginTransmission(0x03);//address of ADJD-S313 SETUP0 register
Wire.send(0x01);
Wire.endTransmission();
Wire.beginTransmission(0x04);//address of ADJD-S313 SETUP1 register
Wire.send(0x01);
Wire.endTransmission();
Wire.beginTransmission(0x0C);//address of ADJD-S313 SETUP2 register
Wire.send(0x01);
Wire.endTransmission();
Wire.beginTransmission(0x0D);//address of ADJD-S313 SETUP3 register
Wire.send(0x01);
Wire.endTransmission();
Wire.beginTransmission(0x0E);//address of ADJD-S313 SETUP4 register
Wire.send(0x01);
Wire.endTransmission();

}

void loop()
{

/to obtain sensor ADC value, '02' Hex must be written to ACQ register
before reading the sensor ADC output registers
/
Wire.beginTransmission(0x02);//address of ACQ register
Wire.send(0x02);//sends '02' hex to the ACQ register
Wire.endTransmission();

Wire.requestFrom(0x44, 1);//address of the ADJD-S313 RED register
r = Wire.receive();
Wire.requestFrom(0x43, 1);//address of the ADJD-S313 GREEN register
g = Wire.receive();
Wire.requestFrom(0x42, 1);//address of the ADJD-S313 BLUE register
b = Wire.receive();

Serial.println(r);
Serial.println(g);
Serial.println(b);
delay(1000);//makes output readable

}

I get no output on the terminal. I think it is an addressing issue?
I am not sure when to use the "slave" address for the Avago sensor,
and when to use the addresses of the specific registers.
I have attached the datasheet for the Avago sensor.
So...
Any assistance would be appreciated.
Maybe my entire code is wrong.
If so, where is a good place to learn the I2C interface?

Thanks

ColorSensorDatasheet.pdf (1.12 MB)

In a nutshell, I2C communication consists of sending data from a master (Arduino) to a slave (color sensor) and requesting data be sent from a slave to a master.

Sending a byte to a slave device typically consists of 3 parts: Addressing the slave, setting a pointer to register address where the data should be sent and finally sending the data.

In your case, using the register SETUP0 as an example, the format would be as such:

Wire.beginTransmission(0x58);  //0x58 is the slave address of the sensor
Wire.send(0x03);  //pointer to register SETUP0
Wire.send(0x01);  //this is the data you want to send to the register
Wire.endTransmission(); // the previous commands only queue up the data in a buffer, this commands sends the data to the device

This is an example of sending a single byte to one register. Most devices support multibyte write which means if you have several consecutive registers that you need to write data to then you can send multiple bytes without having to repeat all the commands for each register. To use the above example to explain further, your setup requires sending 0x01 to several registers. Since SETUP0 and SETUP1 are consecutive (address 0x03 and address 0x04) the slave device will increase the pointer automatically after it receives data in the first register (this assumes it supports multibyte write which most devices do). So the data would be formatted as such:

Wire.beginTransmission(0x58);  //0x58 is the slave address of the sensor
Wire.send(0x03);  //pointer to register SETUP0
Wire.send(0x01);  //this is the data you want to send to the register SETUP0
Wire.send(0x01);  //this is the data you want to send to the register SETUP1
Wire.endTransmission(); // the previous commands only queue up the data in a buffer, this commands sends the data to the device

Using the above examples you should be able to figure out how to configure the rest of the registers.

As for requesting data the format is as follows: address the slave device, set the pointer to the starting address from where you want to request the data from, tell the slave how many bytes you are requesting and finally transfer the data into a local variable. Using your example of requesting data from blue, green and red registers, the format would look as such:

Wire.beginTransmission(0x58); //address of the slave device
Wire.send(0x42); //set the pointer to the BLUE register
Wire.endTransmission(); //sends data to slave device
Wire.requestFrom(0x58,3); //you are requesting 3 bytes from the slave device.  Since blue, green and red are consecutive registers you can request all 3 bytes at once
b = Wire.receive(); //first byte in memory, which is blue, is saved in b
g = Wire.receive(); //second byte in memory, which is green, is saved g
r = Wire.receive(); //final byte is saved in r

That's pretty much it. Good luck.

Hi!

The Avago ADJD-S371-Q999 / ADJD-S313-QR999 sensor is very powerful, so it requires careful settings.

Please have a look at the review I wrote and the library I've developed.

Enjoy :wink:

Wow, wayneft...
Your reply explains exactly what I was missing.
I was not using the slave address properly, and also not using the "Wire.beginTransmission()" and "Wire.endTransmission()" functions correctly.
Also, I did not know to "point" to the register location with Wire.send().

I am now getting data to the terminal.
However, the data is a bit nonsensical, but I believe the post after yours deals with my particular sensor settings in depth; I'll give it a read.

Again, thanks a lot for your detailed and accurate assistance.
This definitely made my day!

Brad