First, we use these functions all the time to talk to a variety of I2C devices in our ECE 3724 course and senior design course, with a variety of PIC24 CPUs.
A few questions:
a. What is the part number of your sensor?
b. What is the part number of your PIC24? (some PIC24F devices have errata concerning the I2C interface).
c. Why are you using the 'putNoAckCheckI2C1' function? If this is a normal I2C device, you should just use the 'putI2C1' function which checks to ensure that the device returned the expected ack bit. The 'putNoAckCheck' is somewhat special purpose for cases where the device uses the ack bit as ready bit, like the Microchip LC515 serial eeprom. If the 'putI2C1' function times out and a software reset is generated, then this means the device is not returning the expected ACK and either the address byte is wrong (which does not seem the case here), or the physical bus is messed up somehow (no pullups?).
d. You should not need the DELAY_MS(1) function calls unless the sensor data sheet explicitly calls for a delay between reading of the return bytes.
e. Are you absolutely sure that that CO2 sensor returns 7 BYTES of data and not 7-bits of data (i.e., only one byte?)? If it only returns one byte of data, this would explain why your program is stopping during the read transaction. It would be an unusual C02 sensor that would require 7-bytes of data to encode a CO2 reading.
Regards,
Bob R
On Monday, January 14, 2013 10:08:55 AM UTC-6, Andy Zehnder wrote:
Hello,
is there anybody out there having experiences with the I2C functions from the library?
I am using the I2C interface to communicate with a CO2 sensor.
In the datasheed, the following is written about the communication:
1) I2C Start Condition
2) Write Command(Slave Address + R/W Bit(0) = 0x62) Transmission and Check Acknowledge
3)..Write Command(ASCII ‘R’ : 0x52) Transmission and Check Acknowledge
4) I2C Stop Command
5) I2C Start Command
6) Read Command(Slave Address + R/W Bit(1) = 0x63) Transmission and Check Acknowledge
7) Read 7 Byte Receiving Data from Module and Send Acknowledge
A part of my main function looks like this (only for testing purposes):
int main (void) {
configBasic(HELLO_MSG);
initLGT_SENSOR();
configHeartbeat();
configI2C1(100);
value1 = 0x21;
value2 = 0x22;
value3 = 0x23;
value4 = 0x24;
value5 = 0x25;
value6 = 0x26;
while (1) {
doHeartbeat();
startI2C1();
value1 = putNoAckCheckI2C1(0x62);
value2 = putNoAckCheckI2C1(0x52);
rstartI2C1();
value3 = putNoAckCheckI2C1(0x63);
value4 = getI2C1(0);
DELAY_MS(1);
value5 = getI2C1(0);
DELAY_MS(1);
value6 = getI2C1(0);
DELAY_MS(1);
value7 = getI2C1(0);
DELAY_MS(1);
value8 = getI2C1(0);
DELAY_MS(1);
value9 = getI2C1(0);
DELAY_MS(1);
value10 = getI2C1(1);
stopI2C1();
}
I get acknowledges until value 3. If I do the function getI2C to get value 4
the program stops.
I figured out that if stops while waiting for the finish of
while (!I2C1STATbits.RBF); in the getI2C.
In the oscilator plot i can see, the sensor is transmitting his data. But at the
end, something goes wrong, I guess.
Anybody out there with an idea?
thx
Andy
![]()