<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Gaugette</title>
    <link>//guy.carpenter.id.au/gaugette/categories/beaglebone/index.xml</link>
    <description>Recent content on Gaugette</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <atom:link href="//guy.carpenter.id.au/gaugette/categories/beaglebone/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Controlling an Adafruit SSD1306 SPI OLED With a Beaglebone Black</title>
      <link>//guy.carpenter.id.au/gaugette/2014/01/28/controlling-an-adafruit-spi-oled-with-a-beaglebone-black/</link>
      <pubDate>Tue, 28 Jan 2014 12:49:00 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/2014/01/28/controlling-an-adafruit-spi-oled-with-a-beaglebone-black/</guid>
      <description>&lt;h2 id=&#34;what-are-we-doing-here&#34;&gt;What Are We Doing Here?&lt;/h2&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2014-01-28/BeagleBoneBlackSSD1306_proto_400x.jpg&#34;  class=&#34;right&#34;   /&gt;


&lt;p&gt;In an &lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/2012/11/08/controlling-an-adafruit-spi-oled-with-a-raspberry-pi/&#34; target=&#34;_blank&#34;&gt;earlier post&lt;/a&gt; I described how to use the py-gaugette library to drive an &lt;a href=&#34;http://www.adafruit.com/products/661&#34; target=&#34;_blank&#34;&gt;Adafruit 128x32 monochrome OLED display&lt;/a&gt; from a Raspberry Pi, and &lt;a href=&#34;//guy.carpenter.id.au/gaugette/2012/11/11/font-support-for-ssd1306/&#34;&gt;a followup article&lt;/a&gt; added high-quality fonts.&lt;/p&gt;

&lt;p&gt;I’ve now updated the library to run on the &lt;a href=&#34;http://beagleboard.org/Products/BeagleBone%20Black&#34; target=&#34;_blank&#34;&gt;BeagleBone Black&lt;/a&gt; and to support &lt;a href=&#34;http://www.adafruit.com/products/326&#34; target=&#34;_blank&#34;&gt;Adafruit’s larger 128x64 display&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On the BBB py-gaugette uses &lt;a href=&#34;https://github.com/adafruit/adafruit-beaglebone-io-python&#34; target=&#34;_blank&#34;&gt;Adafruit’s BBIO library&lt;/a&gt; for SPI and GPIO access.
&lt;/p&gt;

&lt;h2 id=&#34;preparing-the-beaglebone-black&#34;&gt;Preparing the BeagleBone Black&lt;/h2&gt;

&lt;p&gt;I started with a fresh Angstrom boot image (
&lt;a href=&#34;http://beagleboard.org/latest-images&#34; target=&#34;_blank&#34;&gt;the 2013-09-04 eMMC flasher image&lt;/a&gt;).
After booting from the SD and
flashing the eMMC (which takes about 30 minutes), I installed the
&lt;a href=&#34;https://github.com/adafruit/adafruit-beaglebone-io-python&#34; target=&#34;_blank&#34;&gt;Adafruit BBIO library&lt;/a&gt;
following
the
&lt;a href=&#34;http://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/installation&#34; target=&#34;_blank&#34;&gt;instructions in their tutorial&lt;/a&gt;,
which boil down to this:&lt;/p&gt;

&lt;pre&gt;
/usr/bin/ntpdate -b -s -u pool.ntp.org
opkg update &amp;&amp; opkg install python-pip python-setuptools python-smbus
pip install Adafruit_BBIO
&lt;/pre&gt;


&lt;p&gt;Make sure you have flashed your eMMC and rebooted into the eMMC image before you
run the above steps. If you are still running the eMMC flasher image when you
run opkg to install the library, things get weird. Yep, I did that, not proud.&lt;/p&gt;

&lt;p&gt;Once you have these packages installed, you might think to look for
&lt;code&gt;/dev/spidevX.Y&lt;/code&gt; to verify that the SPI drivers are installed. To my surprise
they don’t show up until you actually run code that loads the SPI library. The
Linux 3.8 kernel uses new and crafty
&lt;a href=&#34;http://elinux.org/BeagleBone_and_the_3.8_Kernel#Device_Tree_Overlays&#34; target=&#34;_blank&#34;&gt;device overlay trees&lt;/a&gt;
 to manage devices. The Adafruit library will automatically load the overlay
 that creates those devices as necessary, so only if you look at &lt;code&gt;/dev&lt;/code&gt; after
 running the sample code will you see the spidev device files.&lt;/p&gt;

&lt;p&gt;Confused? Let me illustrate.&lt;/p&gt;

&lt;p&gt;After a reboot there are no spidev devices:&lt;/p&gt;

&lt;pre&gt;
root@beaglebone:~# ls -l /dev/spidev*
ls: cannot access /dev/spidev*: No such file or directory
&lt;/pre&gt;


&lt;p&gt;Run an application that instantiates Adafruit_BBIO.SPI:&lt;/p&gt;

&lt;pre&gt;
python -c &#34;from Adafruit_BBIO.SPI import SPI; SPI(0,0)&#34;
&lt;/pre&gt;


&lt;p&gt;Look again, there they are, it’s magic:&lt;/p&gt;

&lt;pre&gt;
root@beaglebone:~# ls -l /dev/spidev*
crw------- 1 root root 153, 1 Jan 28 02:25 /dev/spidev1.0
crw------- 1 root root 153, 0 Jan 28 02:25 /dev/spidev1.1
&lt;/pre&gt;


&lt;h2 id=&#34;wire-it-up&#34;&gt;Wire It Up&lt;/h2&gt;

&lt;p&gt;The BBB has two SPI interfaces. I’m using SPI0. If you want to use SPI1 you will need to follow &lt;a href=&#34;http://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black/spi&#34; target=&#34;_blank&#34;&gt;these instructions&lt;/a&gt; to disable HDMI first.&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;BeagleBone Black&lt;/th&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Colour&lt;/th&gt;
&lt;th&gt;Adafruit OLED&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;P9_1&lt;/td&gt;
&lt;td&gt;GND&lt;/td&gt;
&lt;td&gt;black&lt;/td&gt;
&lt;td&gt;Gnd&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;P9_3&lt;/td&gt;
&lt;td&gt;Vcc&lt;/td&gt;
&lt;td&gt;red&lt;/td&gt;
&lt;td&gt;Vin&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;P9_13&lt;/td&gt;
&lt;td&gt;Data/Cmd&lt;/td&gt;
&lt;td&gt;purple&lt;/td&gt;
&lt;td&gt;DC&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;P9_15&lt;/td&gt;
&lt;td&gt;Reset&lt;/td&gt;
&lt;td&gt;white&lt;/td&gt;
&lt;td&gt;Rst&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;P9_17&lt;/td&gt;
&lt;td&gt;Slave Sel&lt;/td&gt;
&lt;td&gt;green&lt;/td&gt;
&lt;td&gt;CS&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;P9_18&lt;/td&gt;
&lt;td&gt;MOSI&lt;/td&gt;
&lt;td&gt;blue&lt;/td&gt;
&lt;td&gt;Data&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;P9_22&lt;/td&gt;
&lt;td&gt;Clock&lt;/td&gt;
&lt;td&gt;yellow&lt;/td&gt;
&lt;td&gt;Clk&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Pins P9_17, P9_18 and P9_22 are fixed by the SPI0 interface. Pins P9_13 and P9_15 are arbitrarily chosen GPIO pins, feel free to use any available pins and pass the appropriate pin name to the constructor.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2014-01-28/BeagleBoneBlackSSD1306_bb.png&#34;   /&gt;


&lt;h2 id=&#34;porting-the-code&#34;&gt;Porting the Code&lt;/h2&gt;

&lt;p&gt;Porting gaugette.SSD1306 was straight forward. You can see what was required in &lt;a href=&#34;https://github.com/guyc/py-gaugette/commit/1212554cee06c26d2a9da38aa23c78e040eaaf47&#34; target=&#34;_blank&#34;&gt;this commit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The only catch getting this running on the BBB was a small bug in &lt;a href=&#34;https://github.com/adafruit/adafruit-beaglebone-io-python/blob/master/source/spimodule.c#L112&#34; target=&#34;_blank&#34;&gt;SPI_writebytes&lt;/a&gt; in the Adafruit_BBIO.SPI module. To refresh the entire 128x64 display we need to transfer 1024 bytes of data. Conveniently Adafruit’s writebytes routine has a maximum transfer size of 1024 bytes. Unfortunately the C code uses an 8-bit counter to store the length, which effectively reduces the maximum transfer size to 255 bytes. For now I’ve worked around that by chunking transfers into 255-byte blocks, and I have &lt;a href=&#34;https://github.com/adafruit/adafruit-beaglebone-io-python/pull/56&#34; target=&#34;_blank&#34;&gt;filed a bugfix with Adafruit&lt;/a&gt; so hopefully we can remove that hack soon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update: Adafruit &lt;a href=&#34;https://github.com/adafruit/adafruit-beaglebone-io-python/commit/63b26ac0e9b12d2287083d370feac3f781528e24&#34; target=&#34;_blank&#34;&gt;accepted the fix&lt;/a&gt; but I will wait until they update the python package &lt;a href=&#34;https://pypi.python.org/pypi/Adafruit_BBIO&#34; target=&#34;_blank&#34;&gt;currently at 0.0.19&lt;/a&gt; before I remove the workaround.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I can see that maintaining separate branches of py-gaugette for the RPi and BBB is going to be burden, so I’ve now refactored the library to isolate all of the SPI and GPIO dependencies into abstraction classes that will automatically detect the current platform and delegate to the appropriate library. The new classes are &lt;a href=&#34;https://github.com/guyc/py-gaugette/blob/master/gaugette/spi.py&#34; target=&#34;_blank&#34;&gt;gaugette.spi.SPI&lt;/a&gt; and &lt;a href=&#34;https://github.com/guyc/py-gaugette/blob/master/gaugette/gpio.py&#34; target=&#34;_blank&#34;&gt;gaugette.gpio.GPIO&lt;/a&gt;. This change makes all of the gaugette device classes run cross-platform &lt;em&gt;except&lt;/em&gt; rgbled, which requires PWM support. I’ll write an abstraction layer for PWM later.&lt;/p&gt;

&lt;h2 id=&#34;testing-the-display&#34;&gt;Testing the Display&lt;/h2&gt;

&lt;p&gt;There are a couple of sample applications in py-gaugette that will let you see your display in action. Note the first line shown below works around an issue with git over https on the BBB, and is only required if you are checking out directly on your BBB.&lt;/p&gt;

&lt;p&gt;Install py-gaugette:&lt;/p&gt;

&lt;pre&gt;
git config --global http.sslVerify false  # workaround for https issue
git clone https://github.com/guyc/py-gaugette.git
ln -s ../gaugette py-gaugette/samples   # link library for samples
&lt;/pre&gt;


&lt;p&gt;This test shows the current date and time using a low-resolution font.&lt;/p&gt;

&lt;pre&gt;
python py-gaugette/samples/ssd1306_test.py
&lt;/pre&gt;


&lt;p&gt;This test cycles through some of the high-resolution fonts.&lt;/p&gt;

&lt;pre&gt;
python py-gaugette/samples/font_test.py
&lt;/pre&gt;


&lt;p&gt;The python code for creating an instance for a 128x64 display now looks like this:&lt;/p&gt;

&lt;pre&gt;
# This example is for the 128x64 pixel display on the BeagleBone Black
RESET_PIN = &#34;P9_15&#34;
DC_PIN    = &#34;P9_13&#34;
led = gaugette.ssd1306.SSD1306(reset_pin=RESET_PIN, dc_pin=DC_PIN, rows=64)
&lt;/pre&gt;


&lt;p&gt;Notice that pins are identified as strings like &lt;code&gt;&amp;quot;P9_15&amp;quot;&lt;/code&gt; on the BBB, which is great for clarity.&lt;/p&gt;

&lt;p&gt;The video shows the output of the font test script. This particular sample code was written for a 32-row display where the bottom half of the display memory is off-screen, and so it looks a bit odd on a 64-bit display, but it does illustrate the high-resolution fonts.&lt;/p&gt;

&lt;pre&gt;
python py-gaugette/samples/font_test.py
&lt;/pre&gt;



&lt;div style=&#34;position: relative; padding-bottom: 56.25%; padding-top: 30px; height: 0; overflow: hidden;&#34;&gt;
  &lt;iframe src=&#34;//www.youtube.com/embed/mJ5eYuDXhMY&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%;&#34; allowfullscreen frameborder=&#34;0&#34;&gt;&lt;/iframe&gt;
 &lt;/div&gt;</description>
    </item>
    
  </channel>
</rss>