Enabling The I2C Port

The I2C port needs to be enabled in Rasbian before it can be used. See here.

Checking For Connected Devices

Install the I2C tools (i2c-tools is a set of I²C programs that make it easy to debug I²C devices without having to write any code):


sudo apt-get install i2c-tools
sudo apt-get update

At the command prompt type one of these depending on whether you are using the I2C0 or I2C1 port:


sudo i2cdetect -y 0
//or
sudo i2cdetect -y 1

The 7 bit I2C address of all found devices will be shown (ignoring the R/W bit, so I2C address 0000 0110 is displayed as hex 03).

Useful Resources

http://www.skpang.co.uk/blog/archives/575

http://www.hobbytronics.co.uk/raspberry-pi-raspbian-distro

Reading And Writing I2C


#include <unistd.h>				//Needed for I2C port
#include <fcntl.h>				//Needed for I2C port
#include <sys/ioctl.h>			//Needed for I2C port
#include <linux/i2c-dev.h>		//Needed for I2C port

	int file_i2c;
	int length;
	unsigned char buffer[60] = {0};

	
	//----- OPEN THE I2C BUS -----
	char *filename = (char*)"/dev/i2c-1";
	if ((file_i2c = open(filename, O_RDWR)) < 0)
	{
		//ERROR HANDLING: you can check errno to see what went wrong
		printf("Failed to open the i2c bus");
		return;
	}
	
	int addr = 0x5a;          //<<<<<The I2C address of the slave
	if (ioctl(file_i2c, I2C_SLAVE, addr) < 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;
	}
	
	
	//----- READ BYTES -----
	length = 4;			//<<< Number of bytes to read
	if (read(file_i2c, buffer, length) != length)		//read() returns the number of bytes actually read, if it doesn't match then an error occurred (e.g. no response from the device)
	{
		//ERROR HANDLING: i2c transaction failed
		printf("Failed to read from the i2c bus.\n");
	}
	else
	{
		printf("Data read: %s\n", buffer);
	}

	
	//----- WRITE BYTES -----
	buffer[0] = 0x01;
	buffer[1] = 0x02;
	length = 2;			//<<< Number of bytes to write
	if (write(file_i2c, buffer, length) != length)		//write() returns the number of bytes actually written, if it doesn't match then an error occurred (e.g. no response from the device)
	{
		/* ERROR HANDLING: i2c transaction failed */
		printf("Failed to write to the i2c bus.\n");
	}

 

USEFUL?
We benefit hugely from resources on the web so we decided we should try and give back some of our knowledge and resources to the community by opening up many of our company’s internal notes and libraries through mini sites like this. We hope you find the site helpful.
Please feel free to comment if you can add help to this page or point out issues and solutions you have found, but please note that we do not provide support on this site. If you need help with a problem please use one of the many online forums.

Comments

  1. spuduk

    6 years ago

    Shouldn’t Binary 0000 0110 be HEX 0x06. 0000 0011 would be HEX 0x03

    1. Adam

      6 years ago

      No the read write bit is located at bit 0 for I2C, so the binary value shown is the binary bits that appear in the byte transmitted, and the hex value shown is value of the 7 address bits 7:1. Its confusing as the address could be referred to as 0x06 or 0x03 depending on how an I2C driver is implemented which is why the binary is shown there to clarify it.

  2. Timothy M Johnson

    4 years ago

    When I compile the above i2c sample file, as is, the linker does link and while the file will compile, it won’t build or execute. I tried checking the four header files to see if they were were there were suppose to be. 3 files were but the isn’t there as there are no folders named “sys” in ~usr/include. I found similar name files in different folders under ~usr/include but still got the same problem. Any suggestions? Using a Rpi model 3, Jessian os
    Regards

    1. capri-sun

      1 month ago

      have you put it in a main func? maybe that will work

  3. Mehmet Suzer

    4 months ago

    It works great. Thank you very much! I really appreciate your work.

  4. Krishna Kumar Sah

    4 months ago

    How can i close the i2c bus ?

  5. Lukasz

    4 months ago

    I think you can just call close(file_i2c) when you are done. I think it should also release ioctl, but I’m not sure about that. Maybe someone can confirm?

  6. Veit

    4 months ago

    I think you are right. “close (file_i2c);” should work so. See “https://linux.die.net/man/3/close” or “https://man7.org/linux/man-pages/man2/ioctl.2.html”

Comments

Your email address will not be published.