What's wrong with my I2C code?
-
I hacked together some I2C code based on some things I found on the Interweb. I keep getting I2C read errors despite the fact I can see the I2C device with i2ctools.
root@Omega-1041:/# ./i2c HTU21D Test error reading i2c device : No such device or address error reading i2c device : No such device or address eror reading i2c device : No such device or address eror reading i2c device : No such device or address Temperature 0x66 0xfc 0x6c\nHumidity 0x3f 0xfc 0x6c
But the values that are returned for temperature seem legit. Anyone got any ideas where I'm going wrong here?
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <linux/i2c-dev.h> int main( int argc, char **argv ) { int i; int r; int fd; unsigned char command[2]; unsigned char value[3]; useconds_t delay = 5000; char *dev = "/dev/i2c-0"; int addr = 0x40; printf("HTU21D Test\n"); fd = open(dev, O_RDWR ); if(fd < 0) { perror("Opening i2c device node\n"); return 1; } r = ioctl(fd, I2C_SLAVE, addr); if(r < 0) { perror("Selecting i2c device\n"); } command[0] = 0xe3; r = write(fd, &command, 1); if(r != 1) { perror("error writing to i2c device\n"); } usleep(delay); for(i = 0; i < 3; i++) { // the read is always one step behind the selected input r = read(fd, &value[i], 1); if(r != 1) { perror("error reading i2c device\n"); } usleep(delay); } printf("Temperature 0x%02x 0x%02x 0x%02x\\n", value[0], value[1], value[2]); usleep(delay); command[0] = 0xe5; r = write(fd, &command, 1); usleep(delay); for(i = 0; i < 3; i++) { // the read is always one step behind the selected input r = read(fd, &value[i], 1); if(r != 1) { perror("eror reading i2c device\n"); } usleep(delay); } printf("Humidity 0x%02x 0x%02x 0x%02x\n", value[0], value[1], value[2]); close(fd); return(0); }
-
I busted out the logic analyzer and see the address (0x80 for write) and the byte (0xf3) for start conversion both get an ACK.
Reads get a NAK, however.
-
@Marc-Nicholas Did you run HTU21d?
-
@Przemyslaw-Downar I did. Although it doesn't seem 100% reliable on the Onion.
-
@Marc-Nicholas said in What's wrong with my I2C code?:
I busted out the logic analyzer and see the address (0x80 for write) and the byte (0xf3) for start conversion both get an ACK.
Reads get a NAK, however.
Is the direction bit being correctly set for a read, ie is 0x81 going down the wire?
Does the peripheral attempt to clock stretch?
-
May not have anything to do with your problem but I noticed this:
unsigned char command[2];
but later you only set the first command byte:command[0] = 0xe3;
Just thought I would point it out in case it helps.
-
@Doug-Petican said in What's wrong with my I2C code?:
May not have anything to do with your problem but I noticed this:
unsigned char command[2];
but later you only set the first command byte:command[0] = 0xe3;
Not an issue. The only use of that array is write() calls with a count of 1.