{"id":48,"date":"2014-03-23T17:32:07","date_gmt":"2014-03-23T17:32:07","guid":{"rendered":"https:\/\/blogs.ncl.ac.uk\/francisfranklin\/?p=48"},"modified":"2014-03-28T10:50:17","modified_gmt":"2014-03-28T10:50:17","slug":"using-i2c-with-the-raspberry-pi-step-1-modules-and-packages","status":"publish","type":"post","link":"https:\/\/blogs.ncl.ac.uk\/francisfranklin\/2014\/03\/23\/using-i2c-with-the-raspberry-pi-step-1-modules-and-packages\/","title":{"rendered":"Using I2C with the Raspberry Pi, Step 1: Modules and Packages"},"content":{"rendered":"<p>The hardware I&#8217;m using here is a Raspberry Pi Type A, described in detail <a href=\"https:\/\/blogs.ncl.ac.uk\/francisfranklin\/2014\/03\/18\/the-starting-point\/\">here<\/a>. The aim in this post is to connect to the I2C interface.<\/p>\n<p><b>1. Configuring the Raspberry Pi to use I2C<\/b><\/p>\n<p>First things first, set up the Raspberry Pi to use I2C. Here&#8217;s a good guide: <a href=\"http:\/\/learn.adafruit.com\/adafruit-16-channel-servo-driver-with-raspberry-pi\/configuring-your-pi-for-i2c\">Configuring Your Pi for I2C<\/a>. (And <a href=\"http:\/\/marks-space.com\/2013\/04\/29\/guide-to-interfacing-a-gyro-and-accelerometer-with-a-raspberry-pi\/\">another<\/a>.)<\/p>\n<p>1. Start by installing some extra packages (developer page <a href=\"http:\/\/www.lm-sensors.org\/wiki\/I2CTools\">here<\/a>):<\/p>\n<pre style=\"margin-left: 20px;background-color: #cccccc\">sudo apt-get install python-smbus\r\nsudo apt-get install i2c-tools\r\nsudo apt-get install libi2c-dev<\/pre>\n<p>2. Check the blacklist:<\/p>\n<pre style=\"margin-left: 20px;background-color: #cccccc\">~ $ cat \/etc\/modprobe.d\/raspi-blacklist.conf \r\n# blacklist spi and i2c by default (many users don't need them)\r\n\r\nblacklist spi-bcm2708\r\nblacklist i2c-bcm2708<\/pre>\n<p>and disable those two last lines (edit with nano):<\/p>\n<pre style=\"margin-left: 20px;background-color: #cccccc\">~ $ cat \/etc\/modprobe.d\/raspi-blacklist.conf \r\n# blacklist spi and i2c by default (many users don't need them)\r\n\r\n#blacklist spi-bcm2708\r\n#blacklist i2c-bcm2708<\/pre>\n<p>3. Check the list of modules:<\/p>\n<pre style=\"margin-left: 20px;background-color: #cccccc\">~ $ cat \/etc\/modules\r\n# \/etc\/modules: kernel modules to load at boot time.\r\n#\r\n# This file contains the names of kernel modules that should be loaded\r\n# at boot time, one per line. Lines beginning with \"#\" are ignored.\r\n# Parameters can be specified after the module name.\r\n\r\nsnd-bcm2835<\/pre>\n<p>and add two more modules to the list there:<\/p>\n<pre style=\"margin-left: 20px;background-color: #cccccc\">~ $ cat \/etc\/modules\r\n# \/etc\/modules: kernel modules to load at boot time.\r\n#\r\n# This file contains the names of kernel modules that should be loaded\r\n# at boot time, one per line. Lines beginning with \"#\" are ignored.\r\n# Parameters can be specified after the module name.\r\n\r\nsnd-bcm2835\r\ni2c-dev \r\ni2c-bcm2708<\/pre>\n<p>4. (Optional) To allow non-administrator users to use I2C, you can use this handy trick (thanks here to <a href=\"http:\/\/richardstechnotes.wordpress.com\/2014\/03\/26\/raspberry-pi-i2c-udev-rules\/\">Raspberry Pi I2C udev rules<\/a>).<\/p>\n<p>Create a file \/etc\/udev\/rules.d\/90-i2c.rules and add the line:<\/p>\n<pre style=\"margin-left: 20px;background-color: #cccccc\">KERNEL==\"i2c-[0-7]\",MODE=\"0666\"<\/pre>\n<p>5. (Optional) To adjust the clock speed of the I2C (the default is 100kHz but many I2C devices can operates at 400kHz), then here&#8217;s another handy trick (thanks here to <a href=\"http:\/\/richardstechnotes.wordpress.com\/2014\/03\/27\/setting-the-raspberry-pi-i2c-ports-to-operate-at-400khz\/\">Setting the Raspberry Pi I2C ports to operate at 400kHz<\/a>). Create a file \/etc\/modprobe.d\/i2c.conf and add the line:<\/p>\n<pre style=\"margin-left: 20px;background-color: #cccccc\">options i2c_bcm2708 baudrate=400000<\/pre>\n<p>6. Reboot.<\/p>\n<p>7. One final step <em>if you skipped Step 4<\/em> and <em>if you don&#8217;t want to use I2C as an administrator<\/em> &#8211; give everyone read-write access to the devices:<\/p>\n<pre style=\"margin-left: 20px;background-color: #cccccc\">~ $ sudo chmod o+rw \/dev\/i2c-*<\/pre>\n<p>It will be necessary to do this after every reboot.<\/p>\n<p><b>2. Testing the I2C Connection<\/b><\/p>\n<p>Linux has I2C support in the kernel (see <a href=\"http:\/\/git.kernel.org\/cgit\/linux\/kernel\/git\/torvalds\/linux.git\/tree\/Documentation\/i2c\/dev-interface\">kernel documentation<\/a> for details of the interface), and <a href=\"http:\/\/elinux.org\/Interfacing_with_I2C_Devices\">here&#8217;s a nice tutorial<\/a> explaining the simplest way to use it.<\/p>\n<p>I&#8217;m going to cheat and use a test program &#8211; <a href=\"http:\/\/www.vincenzov.net\/tutorial\/RaspberryPi\/check_I2C.c\">check_I2C.c<\/a> by <a href=\"http:\/\/www.vincenzov.net\/tutorial\/RaspberryPi\/i2c_c.htm\">Vincenzo Villa<\/a>:<\/p>\n<pre style=\"margin-left: 20px;background-color: #cccccc;height: 200px;overflow: auto;padding: 8px\">\r\n\/\/ Rapsberry Pi: I2C in C - Versione 0.61 - Luglio 2013\r\n\/\/ Copyright (c) 2013, Vincenzo Villa (http:\/\/www.vincenzov.net)\r\n\/\/ Creative Commons | Attribuzione-Condividi allo stesso modo 3.0 Unported.\r\n\/\/ Creative Commons | Attribution-Share Alike 3.0 Unported\r\n\/\/ http:\/\/www.vincenzov.net\/tutorial\/elettronica-di-base\/RaspberryPi\/i2c-c.htm\r\n\r\n\/\/ Compile:  gcc check_I2C.c -std=c99 -o check_I2C\r\n\/\/ Run as user with R&amp;W right on \/dev\/i2c-* (NOT ROOT!)\r\n\/\/ vv@vvrpi ~ $ .\/check_I2C \r\n\/\/ Check whether some i2c functionality are present\r\n\r\n#include &lt;stdint.h&gt;\r\n#include &lt;unistd.h&gt;\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;getopt.h&gt;\r\n#include &lt;fcntl.h&gt;\r\n#include &lt;sys\/ioctl.h&gt;\r\n#include &lt;linux\/types.h&gt;\r\n#include &lt;linux\/i2c-dev.h&gt;\r\n\r\n#define I2C_ADDR 0x4B\t\t\t\t\/\/ Device adress\r\n\r\n#define LM92_TEMP 0                             \/\/ Temperature register (see data sheet)\r\n#define LM92_RES 0.0625                         \/\/ Resolution (see data sheet)\r\n\r\nstatic const char *device = \"\/dev\/i2c-1\";\t\/\/ I2C bus\r\n\r\nstatic void exit_on_error (const char *s)\t\/\/ Exit and print error code\r\n{ \tperror(s);\r\n  \tabort();\r\n} \r\n\r\nint main(int argc, char *argv[])\r\n{\r\n\tint fd;\r\n\t\r\n\tint32_t functionality;\r\n\tuint8_t  buffer[2];\r\n        int16_t  data;\r\n        double   temperature;\r\n        \r\n        printf(\"Rapsberry Pi: I2C in C - Versione 0.61 - Luglio 2013\\n\");\r\n        printf(\"Copyright (c) 2013, Vincenzo Villa (http:\/\/www.vincenzov.net)\\n\");\r\n        printf(\"Creative Commons | Attribuzione-Condividi allo stesso modo 3.0 Unported.\\n\");\r\n        printf(\"Creative Commons | Attribution-Share Alike 3.0 Unported\\n\");\r\n        printf(\"http:\/\/www.vincenzov.net\/tutorial\/elettronica-di-base\/RaspberryPi\/i2c-c.htm\\n\\n\");                                       \r\n\r\n       \t\/\/ Open I2C device\r\n       \tif ((fd = open(device, O_RDWR)) &lt; 0) exit_on_error (\"Can't open I2C device\");\r\n\r\n        if (ioctl(fd, I2C_FUNCS, &amp;functionality) &lt; 0)  exit_on_error (\"Can't use I2C_FUNCS ioctl\");\r\n        \r\n        printf(\"Raw data from driver (I2C_FUNCS): 0x%.8X\\n\", functionality);        \r\n        \r\n        printf(\"\\nI2C_FUNC_I2C \");\r\n        if ( I2C_FUNC_I2C &amp; functionality) printf(\"\\t\\t\\t\\tOK\");      \r\n\r\n        printf(\"\\nI2C_FUNC_10BIT_ADDR \");\r\n        if ( I2C_FUNC_10BIT_ADDR &amp; functionality)  printf(\"\\t\\t\\tOK\");\r\n                                                                                                        \r\n        printf(\"\\nI2C_FUNC_PROTOCOL_MANGLING \");                 \r\n        if ( I2C_FUNC_PROTOCOL_MANGLING &amp; functionality) printf(\"\\tOK\");                   \r\n\r\n\/\/        printf(\"\\nI2C_FUNC_NOSTART \");\r\n\/\/        if ( I2C_FUNC_NOSTART &amp; functionality) printf(\"\\tOK\");\r\n                \r\n        printf(\"\\nI2C_FUNC_SMBUS_QUICK \");\r\n        if ( I2C_FUNC_SMBUS_QUICK &amp; functionality) printf(\"\\t\\t\\tOK\");\r\n                \r\n        printf(\"\\nI2C_FUNC_SMBUS_READ_BYTE \");\r\n        if ( I2C_FUNC_SMBUS_READ_BYTE &amp; functionality) printf(\"\\t\\tOK\");\r\n                \r\n        printf(\"\\nI2C_FUNC_SMBUS_WRITE_BYTE \");\r\n        if ( I2C_FUNC_SMBUS_WRITE_BYTE &amp; functionality) printf(\"\\t\\tOK\");\r\n                                                               \r\n        printf(\"\\nI2C_FUNC_SMBUS_READ_BYTE_DATA \");\r\n        if ( I2C_FUNC_SMBUS_READ_BYTE_DATA &amp; functionality) printf(\"\\t\\tOK\");\r\n                \r\n        printf(\"\\nI2C_FUNC_SMBUS_WRITE_BYTE_DATA \");\r\n        if ( I2C_FUNC_SMBUS_WRITE_BYTE_DATA &amp; functionality) printf(\"\\t\\tOK\");\r\n                \r\n        printf(\"\\nI2C_FUNC_SMBUS_READ_WORD_DATA \");\r\n        if ( I2C_FUNC_SMBUS_READ_WORD_DATA &amp; functionality) printf(\"\\t\\tOK\");\r\n\r\n        printf(\"\\nI2C_FUNC_SMBUS_WRITE_WORD_DATA \");\r\n        if ( I2C_FUNC_SMBUS_WRITE_WORD_DATA &amp; functionality) printf(\"\\t\\tOK\");\r\n\r\n        printf(\"\\nI2C_FUNC_SMBUS_PROC_CALL \");  \r\n        if ( I2C_FUNC_SMBUS_PROC_CALL &amp; functionality) printf(\"\\t\\tOK\"); \r\n                \r\n        printf(\"\\nI2C_FUNC_SMBUS_READ_BLOCK_DATA \");  \r\n        if ( I2C_FUNC_SMBUS_READ_BLOCK_DATA &amp; functionality) printf(\"\\t\\tOK\");                                                                                                                 \r\n\r\n        printf(\"\\nI2C_FUNC_SMBUS_WRITE_BLOCK_DATA \");  \r\n        if ( I2C_FUNC_SMBUS_WRITE_BLOCK_DATA &amp; functionality) printf(\"\\tOK\");                                                \r\n \r\n        printf(\"\\nI2C_FUNC_SMBUS_READ_I2C_BLOCK \");  \r\n        if ( I2C_FUNC_SMBUS_READ_I2C_BLOCK &amp; functionality) printf(\"\\t\\tOK\"); \r\n \r\n        printf(\"\\nI2C_FUNC_SMBUS_WRITE_I2C_BLOCK \");  \r\n        if ( I2C_FUNC_SMBUS_WRITE_I2C_BLOCK &amp; functionality) printf(\"\\t\\tOK\");         \r\n        \r\n        printf(\"\\n\\n\");\r\n\r\n        if (ioctl( fd, I2C_PEC, 1) &lt; 0) printf(\"Failed to enable PEC\\n\");\r\n        else printf(\"PEC enabled\\n\\n\"); \r\n\r\n        data = i2c_smbus_read_byte_data ( fd , 0x0a );\r\n\r\n        close(fd);\r\n\r\n\treturn (0);\r\n}\r\n<\/pre>\n<p>Compile &amp; run:<\/p>\n<pre style=\"margin-left: 20px;background-color: #cccccc;height: 200px;overflow: auto;padding: 8px\">~ $ gcc check_I2C.c -std=c99 -o check_I2C\r\n~ $ .\/check_I2C \r\nRapsberry Pi: I2C in C - Versione 0.61 - Luglio 2013\r\nCopyright (c) 2013, Vincenzo Villa (http:\/\/www.vincenzov.net)\r\nCreative Commons | Attribuzione-Condividi allo stesso modo 3.0 Unported.\r\nCreative Commons | Attribution-Share Alike 3.0 Unported\r\nhttp:\/\/www.vincenzov.net\/tutorial\/elettronica-di-base\/RaspberryPi\/i2c-c.htm\r\n\r\nRaw data from driver (I2C_FUNCS): 0x0EFF0009\r\n\r\nI2C_FUNC_I2C \t\t\t\tOK\r\nI2C_FUNC_10BIT_ADDR \r\nI2C_FUNC_PROTOCOL_MANGLING \r\nI2C_FUNC_SMBUS_QUICK \t\t\tOK\r\nI2C_FUNC_SMBUS_READ_BYTE \t\tOK\r\nI2C_FUNC_SMBUS_WRITE_BYTE \t\tOK\r\nI2C_FUNC_SMBUS_READ_BYTE_DATA \t\tOK\r\nI2C_FUNC_SMBUS_WRITE_BYTE_DATA \t\tOK\r\nI2C_FUNC_SMBUS_READ_WORD_DATA \t\tOK\r\nI2C_FUNC_SMBUS_WRITE_WORD_DATA \t\tOK\r\nI2C_FUNC_SMBUS_PROC_CALL \t\tOK\r\nI2C_FUNC_SMBUS_READ_BLOCK_DATA \r\nI2C_FUNC_SMBUS_WRITE_BLOCK_DATA \tOK\r\nI2C_FUNC_SMBUS_READ_I2C_BLOCK \t\tOK\r\nI2C_FUNC_SMBUS_WRITE_I2C_BLOCK \t\tOK\r\n\r\nPEC enabled<\/pre>\n<p>All I need now are some I2C sensors to play with&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The hardware I&#8217;m using here is a Raspberry Pi Type A, described in detail here. The aim in this post is to connect to the I2C interface. 1. Configuring the Raspberry Pi to use I2C First things first, set up the Raspberry Pi to use I2C. Here&#8217;s a good guide: Configuring Your Pi for I2C. <a href='https:\/\/blogs.ncl.ac.uk\/francisfranklin\/2014\/03\/23\/using-i2c-with-the-raspberry-pi-step-1-modules-and-packages\/' class='excerpt-more'>[&#8230;]<\/a><\/p>\n","protected":false},"author":1692,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[10,18,19,3],"class_list":["post-48","post","type-post","status-publish","format-standard","hentry","category-raspberry-pi","tag-i2c","tag-modules","tag-packages","tag-type-a","category-2-id","post-seq-1","post-parity-odd","meta-position-corners","fix"],"_links":{"self":[{"href":"https:\/\/blogs.ncl.ac.uk\/francisfranklin\/wp-json\/wp\/v2\/posts\/48","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.ncl.ac.uk\/francisfranklin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.ncl.ac.uk\/francisfranklin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.ncl.ac.uk\/francisfranklin\/wp-json\/wp\/v2\/users\/1692"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.ncl.ac.uk\/francisfranklin\/wp-json\/wp\/v2\/comments?post=48"}],"version-history":[{"count":20,"href":"https:\/\/blogs.ncl.ac.uk\/francisfranklin\/wp-json\/wp\/v2\/posts\/48\/revisions"}],"predecessor-version":[{"id":69,"href":"https:\/\/blogs.ncl.ac.uk\/francisfranklin\/wp-json\/wp\/v2\/posts\/48\/revisions\/69"}],"wp:attachment":[{"href":"https:\/\/blogs.ncl.ac.uk\/francisfranklin\/wp-json\/wp\/v2\/media?parent=48"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.ncl.ac.uk\/francisfranklin\/wp-json\/wp\/v2\/categories?post=48"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.ncl.ac.uk\/francisfranklin\/wp-json\/wp\/v2\/tags?post=48"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}