Offline
Newbie
Karma: 0
Posts: 12
|
 |
« on: September 12, 2012, 05:24:13 am » |
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
God Member
Karma: 4
Posts: 596
|
 |
« Reply #1 on: September 12, 2012, 10:28:40 am » |
there is an I2C library: http://www.arduino.cc/en/Reference/Wireshould work fine... if the device is I2C conformant... 
|
|
|
|
|
Logged
|
-Arne
|
|
|
|
Switzerland
Offline
Faraday Member
Karma: 69
Posts: 3268
|
 |
« Reply #2 on: September 12, 2012, 01:15:19 pm » |
Is it possible to interface this component with arduino? Yes, I don't see a reason against it. 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
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #3 on: September 13, 2012, 06:43:38 am » |
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. #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
Faraday Member
Karma: 69
Posts: 3268
|
 |
« Reply #4 on: September 13, 2012, 07:14:53 am » |
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 Wire.beginTransmission(Slave_Address); Wire.write(Common_code); Wire.write(Data_Byte); Wire.endTransmission();
while Figure 8 (read) translates to: 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: #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
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #5 on: September 13, 2012, 08:04:20 am » |
Thanks pylon, I understand it better now but still am not getting any good output. Here's my 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
Faraday Member
Karma: 69
Posts: 3268
|
 |
« Reply #6 on: September 13, 2012, 11:51:13 am » |
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: 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
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #7 on: September 14, 2012, 04:39:53 am » |
Hi, I tried your suggestion but it still gives a meaningless output of: 520 522 520 522 Here's the code I used: #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
God Member
Karma: 4
Posts: 596
|
 |
« Reply #8 on: September 14, 2012, 05:07:25 am » |
does it make a difference when u change the address to 0x28?  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
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #9 on: September 14, 2012, 05:28:04 am » |
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
Faraday Member
Karma: 69
Posts: 3268
|
 |
« Reply #10 on: September 14, 2012, 10:18:45 am » |
How have you wired the sensor to your Arduino?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #11 on: September 14, 2012, 10:53:17 am » |
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
Faraday Member
Karma: 69
Posts: 3268
|
 |
« Reply #12 on: September 14, 2012, 11:39:15 am » |
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
God Member
Karma: 4
Posts: 596
|
 |
« Reply #13 on: September 14, 2012, 11:58:42 am » |
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  read just 1 byte... the response should be 0x5 N... where N is the revision number...
|
|
|
|
|
Logged
|
-Arne
|
|
|
|
|