{"id":130,"date":"2013-02-15T00:19:32","date_gmt":"2013-02-15T00:19:32","guid":{"rendered":"http:\/\/richardalbritton.wordpress.com\/?p=130"},"modified":"2015-01-16T00:14:07","modified_gmt":"2015-01-16T00:14:07","slug":"130","status":"publish","type":"post","link":"https:\/\/www.richa1.com\/RichardAlbritton\/130\/","title":{"rendered":"I2C protocol for LED matrix"},"content":{"rendered":"<p>Wow this will come in handy when I get around to configuring the Imp to send I2C\u00a0commands\u00a0to the Adafruit 8&#215;8 LED matrix backpack. Hopefully I can map the LED addresses\u00a0easily\u00a0so I can make an icon library to drive the matrix.<!--more--><\/p>\n<p>From <a href=\"https:\/\/gist.github.com\/ChickenProp\" target=\"_blank\">Philip Hazelden<\/a>:<\/p>\n<p><a href=\"https:\/\/gist.github.com\/ChickenProp\/3231712\" target=\"_blank\">using an Adafruit LED Matrix with the Raspberry Pi<\/a><\/p>\n<blockquote><p>Adafruit sells an\u00a0<a href=\"https:\/\/www.adafruit.com\/products\/872\">8&#215;8 LED matrix<\/a>\u00a0which you can control from a Raspberry Pi using I2C. Unfortunately they only provide Arduino code; I&#8217;ve only used I2C through the programs\u00a0<code>i2cset<\/code>,\u00a0<code>i2cget<\/code>,\u00a0<code>i2cdump<\/code>\u00a0and\u00a0<code>i2cdetect<\/code>available from the\u00a0<code>i2c-tools<\/code>\u00a0package; and it wasn&#8217;t immediately obvious how to use Adafruit&#8217;s code to control the matrix from the Pi.<\/p>\n<p>Fortunately, it turns out to be quite simple.\u00a0<code>i2c-tools<\/code>\u00a0seems to assume a register-based model of I2C devices, where the target device has up to 256 pointers which can be read and written. This doesn&#8217;t seem to suit the HT16K33 chip (<a href=\"http:\/\/www.adafruit.com\/datasheets\/ht16K33v110.pdf\">datasheet<\/a>) that the matrix backpack uses. For example, when I ran\u00a0<code>i2cdump<\/code>, which gets the value of each register, it started to blink a picture at me. At least I knew it was working.<\/p>\n<p>Setting individual LEDs works much as you might expect. Every row has a single register, the eight bits of that register correspond to the eight LEDs on a row. (It&#8217;s not 100% intuitive. If you label the LEDs 0 through 7 from left to right, and the bits 0 through 7 from LSB to MSB, then bit n corresponds to LED n+1 mod 8.) The registers in question are\u00a0<code>0x00<\/code>,\u00a0<code>0x02<\/code>, &#8230;,\u00a0<code>0x0e<\/code>. Registers\u00a0<code>0x01<\/code>,\u00a0<code>0x03<\/code>, etc. seem to correspond to other LED rows that don&#8217;t exist on this matrix, but presumably do on the\u00a0<a href=\"https:\/\/www.adafruit.com\/products\/902\">bicolour version<\/a>.<\/p>\n<p>So to turn on the top-left pin for example, run\u00a0<code>i2cset -y 0 $ADDRESS 0x00 0x80<\/code>. (By default, the address of the device is\u00a0<code>0x70<\/code>. This can be set up to\u00a0<code>0x73<\/code>\u00a0using two address-set pins, but I&#8217;m not sure how to use these. Each pin seems to be a pair of conductive plates close to each other on the backpack. My guess is connecting these will turn the pin on, but I&#8217;m not sure if there&#8217;s a standard thing I&#8217;m meant to connect them with.)<\/p>\n<p>But you can also turn the whole matrix on\/off, set blink rate, and set brightness. Each of these commands also corresponds to a register, but not in the same way. Interacting with the register in any way will run a command. For example, register\u00a0<code>0xe0<\/code>\u00a0is &#8220;turn brightness all the way down&#8221;, so any of the following will do that:<\/p>\n<pre><code>i2cget -y 0 $ADDRESS 0xe0\r\ni2cset -y 0 $ADDRESS 0xe0\r\ni2cset -y 0 $ADDRESS 0xe0 $val # for any legal $val, e.g. 0x00, 0xff\r\n<\/code><\/pre>\n<p>Similarly,\u00a0<code>0x87<\/code>\u00a0is the &#8220;turn display on and blink at 0.5 Hz&#8221; register, and is the highest-address register of that nature. So running\u00a0<code>i2cdump<\/code>\u00a0will cycle through all combinations of on\/off and blink modes, and finish on that one.<\/p>\n<p>Here are the registers that I&#8217;ve found that I care about (except the LED registers):<\/p>\n<ul>\n<li>Display setup:\u00a0<code>0x80<\/code>\u00a0through\u00a0<code>0x87<\/code>. Binary\u00a0<code>10000cba<\/code>, where\u00a0<code>a<\/code>\u00a0is 1 to turn the display on or 0 to turn it off;\u00a0<code>cb<\/code>\u00a0sets blink mode to off (00), 2Hz (01), 1Hz (10) or 0.5Hz (11). (Actually, registers\u00a0<code>0x88<\/code>\u00a0through<code>0x8f<\/code>\u00a0do exactly the same, in the same order. So\u00a0<code>i2cdump<\/code>\u00a0cycles through blink modes twice.)<\/li>\n<li>Brightness:\u00a0<code>0xe0<\/code>\u00a0through\u00a0<code>0xef<\/code>. Higher registers are brighter.<\/li>\n<\/ul>\n<p>There also seem to be read-only registers corresponding to key input, which I assume is just a feature of the chip not used for the LED matrix; and write-only registers putting the chip in and out of standby mode (which I guess uses less power than simply turning the display off). More information is available in the\u00a0<a href=\"http:\/\/www.adafruit.com\/datasheets\/ht16K33v110.pdf\">datasheet<\/a>, which I&#8217;ve only skimmed.<\/p><\/blockquote>\n<div class=\"sharedaddy sd-sharing-enabled\"><div class=\"robots-nocontent sd-block sd-social sd-social-icon-text sd-sharing\"><h3 class=\"sd-title\">Share this:<\/h3><div class=\"sd-content\"><ul><li class=\"share-print\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-print sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/130\/\" target=\"_blank\" title=\"Click to print\"><span>Print<\/span><\/a><\/li><li class=\"share-email\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-email sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/130\/?share=email\" target=\"_blank\" title=\"Click to email this to a friend\"><span>Email<\/span><\/a><\/li><li class=\"share-facebook\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-facebook-130\" class=\"share-facebook sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/130\/?share=facebook\" target=\"_blank\" title=\"Click to share on Facebook\"><span>Facebook<\/span><\/a><\/li><li class=\"share-twitter\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-twitter-130\" class=\"share-twitter sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/130\/?share=twitter\" target=\"_blank\" title=\"Click to share on Twitter\"><span>Twitter<\/span><\/a><\/li><li class=\"share-end\"><\/li><\/ul><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>Wow this will come in handy when I get around to configuring the Imp to send I2C\u00a0commands\u00a0to the Adafruit 8&#215;8 LED matrix backpack. Hopefully I can map the LED addresses\u00a0easily\u00a0so I can make an icon library to drive the matrix.<\/p>\n<div class=\"sharedaddy sd-sharing-enabled\"><div class=\"robots-nocontent sd-block sd-social sd-social-icon-text sd-sharing\"><h3 class=\"sd-title\">Share this:<\/h3><div class=\"sd-content\"><ul><li class=\"share-print\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-print sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/130\/\" target=\"_blank\" title=\"Click to print\"><span>Print<\/span><\/a><\/li><li class=\"share-email\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"\" class=\"share-email sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/130\/?share=email\" target=\"_blank\" title=\"Click to email this to a friend\"><span>Email<\/span><\/a><\/li><li class=\"share-facebook\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-facebook-130\" class=\"share-facebook sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/130\/?share=facebook\" target=\"_blank\" title=\"Click to share on Facebook\"><span>Facebook<\/span><\/a><\/li><li class=\"share-twitter\"><a rel=\"nofollow noopener noreferrer\" data-shared=\"sharing-twitter-130\" class=\"share-twitter sd-button share-icon\" href=\"https:\/\/www.richa1.com\/RichardAlbritton\/130\/?share=twitter\" target=\"_blank\" title=\"Click to share on Twitter\"><span>Twitter<\/span><\/a><\/li><li class=\"share-end\"><\/li><\/ul><\/div><\/div><\/div>","protected":false},"author":1,"featured_media":726,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[62,64],"tags":[22,23,16,18,13,24,14,15,20],"jetpack_featured_media_url":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-content\/uploads\/2013\/02\/imgres.png","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/s5AhH6-130","_links":{"self":[{"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/posts\/130"}],"collection":[{"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/comments?post=130"}],"version-history":[{"count":2,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/posts\/130\/revisions"}],"predecessor-version":[{"id":689,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/posts\/130\/revisions\/689"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/media\/726"}],"wp:attachment":[{"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/media?parent=130"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/categories?post=130"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.richa1.com\/RichardAlbritton\/wp-json\/wp\/v2\/tags?post=130"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}