{"id":1827,"date":"2014-02-04T22:26:07","date_gmt":"2014-02-05T03:26:07","guid":{"rendered":"http:\/\/protofusion.org\/wordpress\/?p=1827"},"modified":"2014-02-04T22:26:58","modified_gmt":"2014-02-05T03:26:58","slug":"ssd1306-and-python-with-the-beaglebone-black","status":"publish","type":"post","link":"http:\/\/protofusion.org\/wordpress\/2014\/02\/ssd1306-and-python-with-the-beaglebone-black\/","title":{"rendered":"SSD1306 and Python with the BeagleBone Black"},"content":{"rendered":"<p><a href=\"http:\/\/protofusion.org\/wordpress\/wp-content\/uploads\/2014\/02\/ssd1306-beaglebone.jpg\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-1838\" alt=\"SSD1306 with BeagleBone Black\" src=\"http:\/\/protofusion.org\/wordpress\/wp-content\/uploads\/2014\/02\/ssd1306-beaglebone-500x251.jpg\" width=\"500\" height=\"251\" srcset=\"http:\/\/protofusion.org\/wordpress\/wp-content\/uploads\/2014\/02\/ssd1306-beaglebone-500x251.jpg 500w, http:\/\/protofusion.org\/wordpress\/wp-content\/uploads\/2014\/02\/ssd1306-beaglebone-300x150.jpg 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/a><\/p>\n<p>The SSD1306 is an OLED display made with SPI and I2C interfaces. With a simple Python library I adapted (a modified version of <a href=\"http:\/\/guy.carpenter.id.au\/gaugette\/2012\/11\/08\/controlling-an-adafruit-spi-oled-with-a-raspberry-pi\/\">py-gaugette<\/a>), it is easy to render text, images (from bitmaps of pretty much any format), progress bars, etc. This guide is a bit on the long side, but should walk you through the whole process.<\/p>\n<p><!--more--><\/p>\n<h3>Unloading the capes<\/h3>\n<p>To use the SPI port, you first need to unload the HDMI virtual capes.&nbsp; Just echo a dash and the number of the virtual cape you want to remove to the slots file, as shown below:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n# cat \/sys\/devices\/bone_capemgr.9\/slots\r\n 0: 54:PF---\r\n 1: 55:PF---\r\n 2: 56:PF---\r\n 3: 57:PF---\r\n 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G\r\n 5: ff:P-O-- Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI\r\n 6: ff:P-O-- Bone-Black-HDMIN,00A0,Texas Instrument,BB-BONELT-HDMIN\r\n 7: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-UART5\r\n 8: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-UART2\r\n# echo -5&amp;gt; \/sys\/devices\/bone_capemgr.9\/slots\r\n# echo -6&amp;gt; \/sys\/devices\/bone_capemgr.9\/slots\r\n# cat \/sys\/devices\/bone_capemgr.9\/slots\r\n 0: 54:PF---\r\n 1: 55:PF---\r\n 2: 56:PF---\r\n 3: 57:PF---\r\n 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G\r\n 7: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-UART5\r\n 8: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-UART2\r\n<\/pre>\n<h3>Load SPI overlay<\/h3>\n<p>Download <a href=\"https:\/\/gist.github.com\/normaldotcom\/8816100\" target=\"_blank\">spimux.dts<\/a> and generate a dto file to load into the kernel overlay:<\/p>\n<ul>\n<li>Generate the code\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">dtc -O dtb -o BB-SPI1-01-00A0.dtbo -b 0 -@ spimux.dts<\/pre>\n<\/li>\n<\/ul>\n<ul>\n<li>Copy to firmware dir\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">cp BB-SPI1-01-00A0.dtbo \/lib\/firmware<\/pre>\n<\/li>\n<\/ul>\n<ul>\n<li>Load on demand\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">echo BB-SPI1-01 &amp;gt; \/sys\/devices\/bone_capemgr.*\/slots<\/pre>\n<\/li>\n<\/ul>\n<h3>Check results<\/h3>\n<p>You should now see the SPI cape loaded in the slots file and device nodes should be present at <em>\/dev\/spidev*<\/p>\n<p><\/em><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n# cat \/sys\/devices\/bone_capemgr.9\/slots\r\n 0: 54:PF---\r\n 1: 55:PF---\r\n 2: 56:PF---\r\n 3: 57:PF---\r\n 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G\r\n 7: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-UART5\r\n 8: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-UART2\r\n 9: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-SPI1-01\r\n<\/pre>\n<p>If you don&#8217;t see anything here, check the output of <em>dmesg<\/em> for any errors.<\/p>\n<p><a href=\"http:\/\/protofusion.org\/wordpress\/wp-content\/uploads\/2014\/02\/ssd1306.jpg\" data-rel=\"lightbox-image-1\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" alt=\"SSD1306 OLED Displays\" src=\"http:\/\/protofusion.org\/wordpress\/wp-content\/uploads\/2014\/02\/ssd1306-500x261.jpg\" width=\"500\" height=\"261\" \/><\/a><\/p>\n<h3>Wire stuff up<\/h3>\n<p>You can connect a SSD1306 to the BeagleBone Black with one of <a href=\"https:\/\/www.adafruit.com\/products\/661\" target=\"_blank\">Adafruit&#8217;s breakout board<\/a>, or with your own PCB design (you can use the footprint from Adafruit&#8217;s <a href=\"https:\/\/github.com\/adafruit\/Adafruit-128x32-SPI-OLED-breakout-board-PCB\" target=\"_blank\">open-hardware design files<\/a>).<\/p>\n<ul>\n<li>P9_1 &#8211; GND<\/li>\n<li>P9_3 &#8211; Vcc<\/li>\n<li>P9_13 &#8211; Data\/CMD<\/li>\n<li>P9_15 &#8211; Reset<\/li>\n<li>P9_17 &#8211; Chip select<\/li>\n<li>P9_18 &#8211; Master out \/ slave in<\/li>\n<li>P9_22 &#8211; Clock<\/li>\n<\/ul>\n<h3>Install Python Libraries<\/h3>\n<p>You&#8217;ll need a few supporting libraries to make everything work:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/doceme\/py-spidev\" target=\"_blank\">py-spidev<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/adafruit\/adafruit-beaglebone-io-python\" target=\"_blank\">adafruit-beaglebone-io-python<\/a><\/li>\n<li><a href=\"https:\/\/bitbucket.org\/normaldotcom\/python2-ssd1306-bb\" target=\"_blank\">python2-ssd1306-bb<\/a> (the actual OLED display library)<\/li>\n<\/ul>\n<p>If you&#8217;re running Arch Linux, just install python2-ssd-bb from the AUR with your favorite AUR helper like <em>packer,<\/em> and all dependencies will be pulled in automatically.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">packer -S python2-ssd1306-bb<\/pre>\n<p>On an Angstrom-based system, you can use <em>opkg<\/em> to install the dependencies:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">opkg update\r\nopkg install python-pip python-setuptools python-smbus\r\npip install Adafruit_BBIO\r\npip install spidev<\/pre>\n<h3>Run the Test Script<\/h3>\n<p>In the <em>python2-ssd1306-bb\/samples<\/em> folder, run <em>ssd1306.py<\/em>. This file will show some test patterns on the screen. If you installed from the AUR and don&#8217;t have the test script, you can download it <a href=\"https:\/\/bitbucket.org\/normaldotcom\/python2-ssd1306-bb\/src\/ac177ce7ede253ab248aa0bc37fd153a71c9c5c1\/samples\/ssd1306_test.py?at=default\" target=\"_blank\">here<\/a>.<\/p>\n<p>If you do not see the test patterns on your display, double-check all of your connections (make sure you don&#8217;t mix up power and ground!). Otherwise, you can move on to using the library from your own code!<\/p>\n<h3>Using the Library<\/h3>\n<h4>Want a progress bar?<\/h4>\n<p>Just call the <em>draw_progress<\/em> function with position, width, height, and the desired percent. Call the function again with a different percent value. to update the progress bar. Percent values are numbers 0-100. <strong>This function isn&#8217;t very well-tested yet, please comment if you encounter problems!<\/p>\n<p><\/strong><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ndraw_progress(self, percent, x, y, width=128, height=5):\r\nled.display()\r\n<\/pre>\n<h4>Want to render an image?<\/h4>\n<p>Make sure you scale your image and convert to black\/white first! All standard image formats are supported.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n    led.clear_display()\r\n    led.draw_image(&quot;\/home\/jsmith\/logo.png&quot;, x, y)\r\n<\/pre>\n<h4>Want to render some text?<\/h4>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n    led.draw_text2(x, y, 'Hello World', size)\r\n<\/pre>\n<p>Refer to the <strong><a href=\"https:\/\/bitbucket.org\/normaldotcom\/python2-ssd1306-bb\" target=\"_blank\">readme on BitBucket<\/a><\/strong> for an up-to-date overview of the library, or take a look at the test script code. If all goes well, you should be able to get results like this:<\/p>\n<p><iframe loading=\"lazy\" src=\"\/\/player.vimeo.com\/video\/85659585\" height=\"281\" width=\"500\" allowfullscreen=\"\" frameborder=\"0\"><\/iframe><\/p>\n<p>The person who wrote <em>py-gaugette<\/em> <a href=\"http:\/\/guy.carpenter.id.au\/gaugette\/2014\/01\/28\/controlling-an-adafruit-spi-oled-with-a-beaglebone-black\/\">also ported his library to BeagleBone Black<\/a>, although it uses a different approach for SPI communication and doesn&#8217;t have progress bars \/ image rendering (yet!).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The SSD1306 is an OLED display made with SPI and I2C interfaces. With a simple Python library I adapted (a modified version of py-gaugette), it is easy to render text, images (from bitmaps of pretty much any format), progress bars,<span class=\"ellipsis\">&hellip;<\/span><\/p>\n<div class=\"read-more\"><a href=\"http:\/\/protofusion.org\/wordpress\/2014\/02\/ssd1306-and-python-with-the-beaglebone-black\/\">Read more &#8250;<\/a><\/div>\n<p><!-- end of .read-more --><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kadence_starter_templates_imported_post":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[191,7,35,198],"tags":[],"class_list":["post-1827","post","type-post","status-publish","format-standard","hentry","category-beaglebone-black","category-linux","category-projects","category-python"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pNjAs-tt","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/protofusion.org\/wordpress\/wp-json\/wp\/v2\/posts\/1827","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/protofusion.org\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/protofusion.org\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/protofusion.org\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/protofusion.org\/wordpress\/wp-json\/wp\/v2\/comments?post=1827"}],"version-history":[{"count":44,"href":"http:\/\/protofusion.org\/wordpress\/wp-json\/wp\/v2\/posts\/1827\/revisions"}],"predecessor-version":[{"id":1888,"href":"http:\/\/protofusion.org\/wordpress\/wp-json\/wp\/v2\/posts\/1827\/revisions\/1888"}],"wp:attachment":[{"href":"http:\/\/protofusion.org\/wordpress\/wp-json\/wp\/v2\/media?parent=1827"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/protofusion.org\/wordpress\/wp-json\/wp\/v2\/categories?post=1827"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/protofusion.org\/wordpress\/wp-json\/wp\/v2\/tags?post=1827"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}