View previous topic :: View next topic |
Author |
Message |
MotronixGS
Joined: 13 Jul 2011 Posts: 19
|
Problem with ISL29023 |
Posted: Thu Oct 18, 2012 2:09 am |
|
|
Hi,
I am trying to use a ISL29023 sensor, but I can't, the result is always 65535(count max to 16bits).
So, I paste an example (mode ALS continuous only), what am I doing wrong?
main:
Code: |
#define CMD_W_ADDR 0x88
#define CMD_R_ADDR 0x89
#define CMD_DATA_L 0x02
#define CMD_DATA_H 0x03
unsigned int16 luz_isl=0;
unsigned int16 ir_isl=0;
void main(){
write_ISL29023();
while(1)
{
luz_isl = read_ISL29023();
}
}
|
write:
Code: |
void write_ISL29023()
{
i2c_start();
i2c_write(0x88);
i2c_write(0x00);
i2c_write(0b10100000);
i2c_restart();
i2c_write(0x88);
i2c_write(0x01);
i2c_write(0b00000000);
i2c_stop();
}
|
read:
Code: |
unsigned int16 read_ISL29023()
{
unsigned int8 msb;
unsigned int8 lsb;
unsigned int16 valor;
unsigned int1 ack;
i2c_start();
i2c_write(CMD_W_ADDR);
i2c_write(0x02); //CMD_DATA_L
i2c_stop();
i2c_start();
i2c_write(CMD_R_ADDR);
lsb = i2c_read(1);
i2c_stop();
i2c_start();
i2c_write(CMD_W_ADDR);
i2c_write(0x03); //CMD_DATA_H
i2c_stop();
i2c_start();
i2c_write(CMD_R_ADDR);
msb = i2c_read(1);
i2c_stop();
valor = (msb << 8) | lsb;
return(valor);
}
|
Regards, |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Thu Oct 18, 2012 4:58 am |
|
|
What PIC are you using?.
Show your I2C setup.
What value pull-up resistors?.
You have the read and write address defined by name, then in the setup use numeric values. Messy, likely to go wrong....
At one point you show 'i2c_restart', yet this is just 'i2c_start', and 'restart' won't compile. Doesn't give us much confidence in the code. This is also basically wrong. The chip automatically increments to the next register address after a write. So to write the two registers you only need:
Code: |
void write_ISL29023()
{
i2c_start();
i2c_write(CMD_W_ADDR);
i2c_write(0x00);
i2c_write(0b10100000); //write to register 0
i2c_write(0b00000000); //write to register 1
i2c_stop();
}
|
I haven't checked to see if the values you are sending the registers make any sense.
Then, you are not using an I2C 'restart', where it is needed. Look at the data sheet pattern for a 16bit read. You need:
Code: |
i2c_write(CMD_W_ADDR);
i2c_write(0x02); //CMD_DATA_L - er. actually DATA_LSB
i2c_start();
i2c_write(CMD_R_ADDR);
lsb = i2c_read();
msb=i2c_read(1);
i2c_stop();
|
Look at figure 14. Note no stop, and the bytes are just read sequentially, just with the NACK on the last byte.
It takes 90mSec for the chip to perform a conversion. You need to wait for this time before reading.
Probably more, but I gave up.
Best Wishes |
|
|
MotronixGS
Joined: 13 Jul 2011 Posts: 19
|
|
Posted: Thu Oct 18, 2012 11:30 am |
|
|
Thank you very much for your reply and advice, but it still doesn't work. I use this instruction to init i2c:
Code: | #use i2c(master, sda=PIN_C4, scl=PIN_C3)) |
I use a 2k2 pull-ups, and 499k Rext. Any help?
Regards, |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 18, 2012 1:12 pm |
|
|
Questions regarding your board's hardware:
1. What is the Vdd voltage of your PIC ?
2. What is the Vdd voltage of the ISL29023 ?
With regard to the software, look at this desscription on page 7 of the
ISL29023 data sheet:
Quote: | BYTE READ
The master terminates the read operation by not responding with
an acknowledge and then issuing a stop condition.
|
This is commonly known as a "NACK" (not acknowledge) and is done
by the i2c Master after the last data byte is read from the slave, within
a read operation. CCS does a NACK if you give the i2c_read() function
a 0x00 parameter. None of the code posted so far in this thread is
doing this, and that's a problem.
The last byte read (before the i2c_stop) must do this:
Code: |
result = i2c_read(0); // NACK on last byte read
|
|
|
|
MotronixGS
Joined: 13 Jul 2011 Posts: 19
|
|
Posted: Thu Oct 18, 2012 1:34 pm |
|
|
I use a 5V PIC voltage, so I use a PCA9548AD to decrease the voltage to 3.3V. Thanks for the explanation, now I can't test it, but tomorrow I am going to try it and tell you.
Thanks again, regards |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Thu Oct 18, 2012 2:36 pm |
|
|
You do also realise that you need pull ups to 5v at the PIC side of the switch, and to 3.3v at the ISL29023 side. 2.2k, is about the maximum pull up you should use on 3.3v. Something like 1.2K is better here.
Best Wishes |
|
|
MotronixGS
Joined: 13 Jul 2011 Posts: 19
|
|
Posted: Fri Oct 19, 2012 2:16 am |
|
|
Still doesnt work, I keep trying it... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Fri Oct 19, 2012 2:43 am |
|
|
As a comment, pull the I2C bus scanner program that has been posted here in the past. This scans the bus, and lists every device it finds. If this can't find the target then you have a hardware problem.
It should obviously initially only find the PCA9548.
Add the code to initialise this and select the right channel, and then it should also find the ISL29023.
Best Wishes |
|
|
MotronixGS
Joined: 13 Jul 2011 Posts: 19
|
|
Posted: Fri Oct 19, 2012 3:08 am |
|
|
News: I can read and write registrers (0x00 and 0x01), but registers 0x02 and 0x03 are 0.
One thing, I conected INT pin to a pull-up(3.3), wrong? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Fri Oct 19, 2012 3:40 am |
|
|
No, perfectly OK.
Ideally you really want this to go back to the PIC, connecting to a TTL input, so you can detect when conversions have finished, levels alarms, etc..
Doesn't really matter if it is pulled up or not, if you are not using it.
Try just waiting a bit before programming the chip. A lot of chips do need some 'wake up' time, and it is also possible, if your 3.3v rail is using a regulator from the 5v (say), the rail may not actually go high for quite a time after the PIC wakes up. Just worth trying.
Best Wishes |
|
|
|