![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
stoyanoff
Joined: 20 Jul 2011 Posts: 375
|
Problem with addressing sensor through I2C |
Posted: Thu Feb 07, 2013 5:52 am |
|
|
Hi, everyone! I`m trying to use a specific sensor. I have PIC18F2550 connected to the sensor.
PIN_B1 <-> sensor CLK
PIN_B0 <-> sensor SDA
PIN_B2 <-> sensor INT
I don`t have enough info for the sensor. Just an algorythm which is not explaind. Here is the algorythm:
1. Start i2c
2. Master sends sensor address
3. Read/write to 0(write)
4. Sensor returns ACK
5. Master sends register address
6. Sensor returns ACK
7. Start (again)
8. Read/write to 1(read)
9. Sensor sends data
10. Master sends ACK
I made a simple program in try to use the sensor:
Code: |
#include <18F2550.h>
#FUSES HS,NOWDT,CPUDIV1
#use delay(clock=20M)
#use I2C(MASTER,SCL=PIN_B1,SDA=PIN_B0)
#define CS PIN_B2
#define sensorAddress 0x68
#define registerAddress 0x80
int ACK,data;
void main()
{
delay_ms(100);
ACK=0;data=0;
output_drive(CS);
output_low(CS);// I`m setting INT to low which should be it`s active
//state because it have pull up
i2c_start(); // point 1
i2c_write(sensorAddress);//point 2
ACK=i2c_read();//read the ACk from the sensor
i2c_write(registerAddress);//point 5
ACK=i2c_read();//read the ACk from the sensor
i2c_start();//point 7
data=i2c_read(1);// points 9 and 10
while(1);
}
|
The ACK and data has always 0xFF value. I`m doing something wrong but I don`t know what. I don`t very much expirience with I2C. I don`t know if I have to send INT to the sensor or it has to send INT to the PIC. Or this is the read/write wire?
Can you help me?! |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Thu Feb 07, 2013 6:25 am |
|
|
some comments....
1st. Is the sensor a 3 volt device? If so you'll need level translation between it and the 5 volt PIC.
2nd. Go to the code library here and download PCM programmer's 'I2C scanner' program.It's a 'must have' tool ! Use it to find your sensor.It will tell you every I2C device on the buss.
3rd.You've got pin_B2 as an interrupt but then call it 'CS' and driving it ....wrong! I would redfine the pins and use RB0 as the interrupt from the I2C device.That way you can use INT_EXT for the interrupts from the device.A simple 3k3 pullup resistor is all you need on that pin.
4th Do you have 3k3 pullup resistors on the I2C data and clock lines? These are necessary though the values can be from 1k2 to 4k7 depending on speed,distance,# of devices,etc. 3k3 works fine for me though.
5th.Have you got a '1Hz blinking LED' program running yet? It is an easy program to confirm your PIC is wired up right, proper fuse selection, crystal, etc.
hth
jay |
|
![](templates/subSilver/images/spacer.gif) |
stoyanoff
Joined: 20 Jul 2011 Posts: 375
|
|
Posted: Thu Feb 07, 2013 6:43 am |
|
|
I have 10k resistors pull-ups on INT,SDA and CLK(sensor datasheet!). The controller is working just fine. The sensor is working on 5V. PIC18F2550 has 3 input interrupt sources - pins B0,B1 and B2. So if we assume the sensor sneds an interrupt to the controller I can use it. I can eaily change the direction of pin B2 and enable the interrupts.
I`m concern about this read/write signals. I know the I2C master controll the direction of the dataflow. So is it possible I have just to do this? And how to do it?
There is a function i2c_poll() which I can use to check for ACK from the sensor, but it can be used only in interrupt statement(I`m not sure about this). But I can`t wait for int from the sensor because the master must start the communication.....
I find this I2C scanner and it found the sensor on address D0...
I thought the I2C is using 7 bits for communication?! But this address is in 8 bit format?! May be I have problem with data format?! |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Thu Feb 07, 2013 8:27 am |
|
|
You should post the device information(part number, link to datasheet) as that will really speed up replies. Someone here may already have made a 'driver' for that device.Original I2C device have 7 bit address.They are left shifted 1 bit so that bit0 is either 'read' or 'write'.This allows the device address and command(R or W) to be sent as a byte.
When configured for interrupts a device will send a pulse to the PIC on it's INT pin.The PIC hardware 'sees' this and a flag is set inside the PIC. The Interrupt Service Routine(ISR) is where you put short,fast code to deal with the isr. Typically you'll set a flag(a variable that 'main' reads),maybe read 1 or 2 bytes, then exit the ISR.
There are two methods of reading data from devices.
Polling,where your main program loops around and around, testing a bit of a byte to see if action is to be taken.Fine for simple programs but not efficient.
Interrupts,are 'triggered' by a device doing 'something' allowing the main program to do lots of other tasks until the ISR is 'fired',When that happens, the PIC does a few quick things, then returns to the main program.
hth
jay |
|
![](templates/subSilver/images/spacer.gif) |
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Thu Feb 07, 2013 3:40 pm |
|
|
May not be of help in this case.
Often I2C sensors and EEProms can't do what is asked of them instantaneously. The PIC quickly moves from write to read but the I2C slave device may not yet be ready. Adding CCS delay_xx(nnn) statements between PIC I2C read writes will provide the extra time the slave device may need. If the data sheet for the device doesn't provide the timing then just start high say 20 ms and fine tune from there. |
|
![](templates/subSilver/images/spacer.gif) |
stoyanoff
Joined: 20 Jul 2011 Posts: 375
|
|
Posted: Fri Feb 08, 2013 5:09 am |
|
|
I think I did it! But there is one more thing! I put the sensor on room temperature an it returns values like 123,124,125(0x7A,0x7B,0x7C). When I grab it into my hand it start to return values like 130-135-140(0x82,0x87,0x8C). I tried to cool it down. I put it into a fridge and it retuned 22-23-24(0x16,0x17,0x18). In the fridge the temperature is 8-9 degree Celsius. I`m using int8 to contain the data. Any ideas how to transform this data to real value???
PP: The sensor doesn`t need calibration. It has 2-3 degree tolerance!(as for the datasheet) |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19359
|
|
Posted: Fri Feb 08, 2013 5:28 am |
|
|
No, not without you telling us the sensor, so we can look at the data sheet and say 'this is the curve fit function it uses, and values are relative to the following origin'. However if you make some guesses at the temperatures involved, so (say) room temperature 20C, hand temperature say 35C (a little below the 'core' temperature that is normally about 37C, and fridge 8C. then just draw a graph, and get the curve of best fit.
It looks very non linear. Possibly a curve like a thermocouple, rather than something easy to scale/use.
Why not use one of the easy to use sensors, that has a known response and nicely available data?. There are I2C sensors that give you nice easy numbers like 2 counts per degree.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|