Pages: [1]   Go Down
Author Topic: I2C Ambient light sensor  (Read 2100 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

I'm wondering if anyone has tried hooking there arduino up to an I2C ambient light sensor. The sensor I have is this one: http://www.avagotech.com/docs/AV02-2315EN.

Is it possible to interface this component with arduino?

I don't really understand the address select input pin on the component, any ideas?

Thanks in advance!
Logged

Brunsbüttel, SH, F.Rep.GERM
Offline Offline
God Member
*****
Karma: 4
Posts: 596
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

there is an I2C library:
http://www.arduino.cc/en/Reference/Wire

should work fine... if the device is I2C conformant...  smiley
Logged

-Arne

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Is it possible to interface this component with arduino?

Yes, I don't see a reason against it.

Quote
I don't really understand the address select input pin on the component, any ideas?

The address selection pin can have 3 states:

1. Connected to ground => address = 0x29
2. Connected to Vcc => address = 0x49
3. Not connected (floating) => address = 0x39

I would use one of the connected states because the floating is the most error prone (some dirt may make enough connection to switch to another state)
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the replies!

I've been learning about the I2C library and have written some code that I thought would work. However, on page 7 of the datasheet it seems as if I need to send: start bit - address byte - write bit - command code byte - repeated start condition bit - address byte - read bit, just to obtain a data byte. I don't understand what the command code byte and repeated start condition bit are.

I have this program which successfully connects to the component but doesn't receive any meaningful output. I currently receive first byte (a) = 0, and second byte (b) = 2 always.

Code:
#include "Wire.h"
#define address 0x29

void setup(){
  Wire.begin();
  Serial.begin(9600);
}

void getdata(byte *a, byte *b){
 
  Wire.beginTransmission(address);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(address, 2);
  *a = Wire.read();
  *b = Wire.read();
}

void showdata(){
  byte aa,bb;
  getdata(&aa,&bb);
 
  Serial.println(aa);
  Serial.println(bb);
  delay(1000);
}

void loop(){
  showdata();
}


My serial output after 3secs is:
0
2
0
2
0
2

Thanks again.
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
However, on page 7 of the datasheet it seems as if I need to send: start bit - address byte - write bit - command code byte - repeated start condition bit - address byte - read bit, just to obtain a data byte.

This explains the details of the I2C communication. With the Wire library it's quite easy. Figure 7 translates to

Code:
Wire.beginTransmission(Slave_Address);
Wire.write(Common_code);
Wire.write(Data_Byte);
Wire.endTransmission();

while Figure 8 (read) translates to:

Code:
Wire.beginTransmission(SlaveAddress);
Wire.write(Command_Code);
Wire.endTransmission();
Wire.requestFrom((SlaveAddress,1);
uint8_t value = Wire.read();

Get the current value (channel 0, for channel 1 the register is 0x0E) is then:

Code:
#define address 0x29
Wire.beginTransmission(address);
Wire.write(0x0C);
Wire.endTransmission();
Wire.requestFrom(address, 2);
uint16_t val_low = Wire.read();
uint16_t val = Wire.read();
val <<= 8;
val |= val_low;
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks pylon,

I understand it better now but still am not getting any good output.

Here's my code:

Code:
void getdata(byte *a){
 
  Wire.beginTransmission(address);
  Wire.write(0x0C);
  Wire.endTransmission();

  Wire.requestFrom(address, 1);
  *a = Wire.read();
}

I still just get constant values:
C: 12
D: 13
E: 14
F: 63

Do I have to send read and write bits or maybe send the slave address again as it shows in figure 8?

What is the full code I need to obtain the channel 0 low, channel 0 high, channel 1 low, channel 1 high.

Thanks!
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Excuse me, I guess I misunderstood the datasheet on the first reading. Seems like the command byte has to have bit 7 always set to store the register address.

So your function reads:

Code:
uint16_t getdata(uint8_t channel){
 
  Wire.beginTransmission(address);
  Wire.write(0x8C + channel << 1);
  Wire.endTransmission();

  Wire.requestFrom(address, 2);
  uint8_t lowbyte = Wire.read();
  uint16_t value = Wire.read();
  value <<= 8;
  value += lowbyte;
  return value;
}

where channel is 0 or 1 to select the channel you like to read.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I tried your suggestion but it still gives a meaningless output of:
520
522
520
522

Here's the code I used:

Code:
#include "Wire.h"
#define address 0x29

void setup(){
  Wire.begin();
  Serial.begin(9600);
}

uint16_t getdata(uint8_t channel){
 
  Wire.beginTransmission(address);
  Wire.write(0x8C + channel << 1);
  Wire.endTransmission();

  Wire.requestFrom(address, 2);
  uint8_t lowbyte = Wire.read();
  uint16_t value = Wire.read();
  value <<= 8;
  value += lowbyte;
  return value;
}

void loop(){
  Serial.println(getdata(0));
  Serial.println(getdata(1));
  delay(1000);
}

I'm running it on a mega2560 if that makes any difference. I've also tried it with two of these sensors but with the same output. Any ideas?
Logged

Brunsbüttel, SH, F.Rep.GERM
Offline Offline
God Member
*****
Karma: 4
Posts: 596
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

does it make a difference when u change the address to 0x28?  smiley
i mean: r u really talking to that thingy?

what if u put a paper bag over that sensor?
does the 520 change?
Logged

-Arne

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yeh, the address is correct, any other address gives a different output but the same as any other address other than 29 if that makes sense. ie. 26,27,28,30,31 give the same output but 29 is different.

No I've still not had any output that varies at all; once I achieve this then I can probably work the rest out.
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How have you wired the sensor to your Arduino?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've wired it as shown on the last page of the datasheet using 1k resistors. Although I've just realised that I've not connected interrupt (since I don't need it), so it has no pull-up resistor or connected to arduino so it is floating. I don't think this would cause a problem though.
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Tell exactly what pin on the Arduino you took for these signals: VDD, SCL, SDA. I also guess you wired pin 3 of the sensor to GND, didn't you?

I'm asking because the sensor is running on 3V3 I guess (max VDD is 3V8 on the datasheet). If pullups go to 3V3 the logical 1 of the sensor (3V3) is just at the limit of the Arduino to recognize (60-70% of Vcc => 3V to 3V5). If there is only the smallest change in the supply voltage the signal may drop below that and you have problems. Best would be to use a level converter (two way) like this: http://shop.boxtec.ch/logic-level-converter-p-40705.html, although I cannot guarantee that your problem go away with it.

1k is a bit too low, do you have 2k2 resistors to change?
Logged

Brunsbüttel, SH, F.Rep.GERM
Offline Offline
God Member
*****
Karma: 4
Posts: 596
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

1.
what is ur supply voltage?
it shall not be more that 3.6V...
so u use arduino's 3V3 pin?

2. @pylon
the IO pin is read high (according to the ATmega168 datasheet) when it is above 2.5V...
i dont think that the 3.3V rail has that much ripple/inaccuracy...

3.
what if u read the "ID register"?
it is command code: 0x8A - i guess  smiley-razz
read just 1 byte...
the response should be 0x5N... where N is the revision number...
Logged

-Arne

Pages: [1]   Go Up
Jump to: