I2C write error


I use I2C(i2c-1) to get the sensor information.
I have tried the i2c-tool i2cget and read() system call to verify first. They are working correctly and have correct signal measured by LA.
However, when I use the write() system call for device register reading, It returns error and also not generate the signal.

Below are my partial program.
Appreciate for any suggestion.

#define ADDRESS_READ 0x0b
    unsigned char data_write[2];
    unsigned char data_read[2];
    if ((i2c_file = open(filename,O_RDONLY)) < 0) {
        printf("Failed to open the bus.");
        /* ERROR HANDLING; you can check errno to see what went wrong */
        return 1;

    if (ioctl(i2c_file,I2C_SLAVE,ADDRESS_READ) < 0) {
        printf("Failed to acquire bus access and/or talk to slave.\n");
        /* ERROR HANDLING; you can check errno to see what went wrong */
        return 2;
    data_write[0] = 0x0b;  //the device address
    data_write[1] = 0x09; //the register we went to read
    writereturn = write(i2c_file,data_write,2);
    if(2 != read(i2c_file,data_read,2))
      printf("Read error \n");
      return 0;
      printf("Data(%d,%d)  \n",data_read[0],data_read[1]);

You might want to check what error the read and write are returning. The value is contained in the variable errno.

Me guesses it’s a permission issue, but we shall see.

Hi Kangalow,

The error code return -1.

Are you using i2c-dev for your include file? The snippet is a little sparse as to what include files you use.

Here’s how people typically check for the error, something like:

if(ioctl() < 0)
int errsv = errno;
printf(“ioctl failed and returned errno %s \n”,strerror(errsv));

You need to save the errno before passing it to printf.

You should also check the file handle you get back on open to see if it’s valid. The smbus and read/write calls in i2c-dev use ioctl at the core.

Where you able to detect the device correctly? Something like:

sudo i2cdetect -y 1

When I execute i2cdetect I could not find the address.
Actually, the device interface is SMBus and I could use the API i2c_smbus_read_word_data to get the device info now.
In the beginning, I though the control method is the same between I2C and SMBus.
When we went to read the device register, we should write the address and command to the device(use write() system call), then read the data(use read() system call).
The i2c_smbus_read_word_data API work well, but the write( ) system call was executed, It return permission error.
I still confuse about this issue; Is there any difference when I use the i2c_smbus_read_word_data API and write() system call?

You have to run with sudo to have proper permissions to access the GPIO pins. If you plan on using the pins from user space, then you may want to add a udev rule to help.