<?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/index.xml</link>
    <description>Recent content on Gaugette</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Sat, 29 Apr 2017 14:16:00 +1000</lastBuildDate>
    <atom:link href="//guy.carpenter.id.au/gaugette/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>SwitecX25 Quad Driver Tests</title>
      <link>//guy.carpenter.id.au/gaugette/2017/04/29/switecx25-quad-driver-tests/</link>
      <pubDate>Sat, 29 Apr 2017 14:16:00 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/2017/04/29/switecx25-quad-driver-tests/</guid>
      <description>&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2017-04-29/AX1201728SG-closeup.jpg&#34;  class=&#34;right&#34;   alt=&#34;AX1201728SG&#34;  /&gt;


&lt;p&gt;This article demonstrates a modification of the Arduino SwitecX25 driver library
to use a AX1201728SG quad driver chip (equivalent to the X12.017 or VID6606).
This chip offers some significant advantages over driving the motor directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it uses microstepping to provide smoother positioning - 12 steps per degree rather than 3.&lt;/li&gt;
&lt;li&gt;it requires only two GPIO pins per motor (plus one global reset pin)&lt;/li&gt;
&lt;li&gt;it protects the microprocessor from the inductive effects of the motor coils&lt;/li&gt;
&lt;li&gt;it places lower current requirements on the microprocessor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;In the past I&amp;rsquo;ve been unable to find a low-volume supplier for the &lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/2012/01/19/x12-quad-driver-chip/&#34;&gt;X12.017 Quad Driver Chip&lt;/a&gt;,
or any of the functionally identical chips from other manufacturers.  These are the ones I know about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The VID VID6606 Quad Driver &lt;a href=&#34;//guy.carpenter.id.au/gaugette/resources/vid/2009111391612_VID6606%20manual%20060927.pdf&#34;/&gt;(datasheet)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;a href=&#34;http://www.nostm.com&#34; target=&#34;_blank&#34;&gt;NOST Microelectronics&lt;/a&gt; BY8920 Quad Driver &lt;a href=&#34;//guy.carpenter.id.au/gaugette/resources/nost/1428412011616by8290datasheet.pdf&#34;/&gt;(datasheet, in Chinese)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The AX1201728SG (by EmMicroe maybe?)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Recently both the AX1201728SG and VID6606 have become readily available in small quantities.&lt;/p&gt;

&lt;h2 id=&#34;the-ax1201728sg&#34;&gt;The AX1201728SG&lt;/h2&gt;

&lt;p&gt;The AX1201728SG is available in single quantities from ebay for a few dollars apiece.
 The one complication is that they are SOP28 surface mount packages, which are
 a little harder to prototype with than DIP packages.
 I bought some drivers, and some SOP28 to DIP28 adaptors so I could mount the drivers on a breadboard
 for testing.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2017-04-29/SOP28-components.jpg&#34;   alt=&#34;AX1201728SG SOP28 Components&#34;  /&gt;


&lt;h2 id=&#34;mounting&#34;&gt;Mounting&lt;/h2&gt;

&lt;p&gt;I haven&amp;rsquo;t worked with SMD chips before, so I had a friend help me mount them.
We used tweezers to apply the paste, and a regular household oven for reflowing.
Very basic, but it worked fine.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2017-04-29/SOP28-mounting.jpg&#34;   alt=&#34;AX1201728SG SOP28 Mounting&#34;  /&gt;


&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2017-04-29/AX1201728SG-pinout.png&#34;  class=&#34;right&#34;   /&gt;


&lt;h2 id=&#34;wiring-it-up&#34;&gt;Wiring It Up&lt;/h2&gt;

&lt;p&gt;Initially I&amp;rsquo;m testing with a single motor on output A.  The wiring is as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VSS (chip pin 12) to GND&lt;/li&gt;
&lt;li&gt;VDD (chip pins 1 and 15) to 5V&lt;/li&gt;
&lt;li&gt;RESET (chip pin 26) to Arduino pin 10&lt;/li&gt;
&lt;li&gt;CW/CCW A (chip pin 27) to Arduino pin 9&lt;/li&gt;
&lt;li&gt;f(scx) A (chip pin 28) to Arduino pin 8&lt;/li&gt;
&lt;/ul&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2017-04-29/AX1201728SG_bb.png&#34;   alt=&#34;breadboard&#34;  /&gt;


&lt;p&gt;&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2017-04-29/X27.168-rear-contacts.png&#34;  class=&#34;right&#34;   /&gt;

The motor connections are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OUT1A (chip pin 7) to Motor pin 1&lt;/li&gt;
&lt;li&gt;OUT2A (chip pin 6) to Motor pin 2&lt;/li&gt;
&lt;li&gt;OUT3A (chip pin 4) to Motor pin 3&lt;/li&gt;
&lt;li&gt;OUT4A (chip pin 5) to Motor pin 4&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;software&#34;&gt;Software&lt;/h2&gt;

&lt;p&gt;I started with a basic hello-world program to run the motor forward and backwards
so I could work out any setup issues before switching to the more complicated driver software.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/*
  X12.017 Quad Driver Test
  Drive the motor forward and backwards through 270 degrees
  at constant speed.
 */

const int LED = 13;
const int DIR_A = 9; // pin for CW/CCW
const int STEP_A = 8; // pin for f(scx)
const int RESET = 10; // pin for RESET
const int DELAY = 250; // μs between steps
const int ANGLE = 270; // of 315 available
const int RANGE = ANGLE * 3 * 4;
int steps = 0;
bool forward = true;

// pull RESET low to reset, high for normal operation.

void setup() {
  pinMode(DIR_A, OUTPUT);
  pinMode(STEP_A, OUTPUT);
  pinMode(LED, OUTPUT);
  pinMode(RESET, OUTPUT);

  digitalWrite(RESET, LOW);
  digitalWrite(LED, HIGH);
  digitalWrite(STEP_A, LOW);
  digitalWrite(DIR_A, HIGH);
  delay(1);  // keep reset low min 1ms
  digitalWrite(RESET, HIGH);
}

// The motor steps on rising edge of STEP
// The step line must be held low for at least 450ns
// which is so fast we probably don&#39;t need a delay,
// put in a short delay for good measure.

void loop() {
  digitalWrite(STEP_A, LOW);
  delayMicroseconds(1);  // not required

  steps++;
  if (steps &amp;gt; RANGE) {
    forward = !forward;
    steps = 0;
    digitalWrite(DIR_A, forward ? LOW : HIGH);
    digitalWrite(LED, forward ? HIGH : LOW);
  }

  digitalWrite(STEP_A, HIGH);
  delayMicroseconds(DELAY);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This worked, mostly.  If I leave the motor running for a while I notice that
the needle position drifts, which indicates either missed steps, or
a counting problem.  Increasing the inter-step delay from 250ms to 500ms
resolved that problem, so most likely I&amp;rsquo;m exceeding the (low) torque limit
during the turnaround.  I&amp;rsquo;m not worried about that - once I port the SwitecX25
library I can find a safe set of acceleration parameters to keep it from dropping
steps.&lt;/p&gt;

&lt;h2 id=&#34;adapting-the-switecx25-library&#34;&gt;Adapting the SwitecX25 Library&lt;/h2&gt;

&lt;p&gt;The SwitecX25 library provides an acceleration/deceleration model,
and some higher-level control abstractions.  Importantly, it is asynchronous.
The caller sets a desired step position and then calls the &lt;code&gt;update()&lt;/code&gt; method
as frequently as possible and the library manages the scheduling of the steps.&lt;/p&gt;

&lt;p&gt;One concern I have about supporting the quad driver is the being able to
service the pin transitions quickly enough.
When driving the motor directly we need to update 4
outputs once per step.  With the quad driver we need to pulse the f(scx) line low then high
once per micro-step, which equates to 8 transitions per full step.  It may
turn out to be difficult hit all of the timing deadlines to drive 4 motors at full speed simultaneously.&lt;/p&gt;

&lt;p&gt;My first cut at this is to create an entirely new class &lt;a href=&#34;https://github.com/clearwater/SwitecX25/blob/X12/SwitecX12.h&#34; target=&#34;_blank&#34;&gt;SwitecX12&lt;/a&gt;
which duplicates the key timing code from SwitecX25, with new output logic
and an adjusted acceleration curve.&lt;/p&gt;

&lt;p&gt;The code below zeroes the needle, moves the needle to the centre of the sweep, then
cycles between &amp;frac14; range and &amp;frac34; range.&lt;/p&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/ygrRIWR8rmY&#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;


&lt;pre&gt;&lt;code&gt;#include &amp;lt;SwitecX12.h&amp;gt;

const int STEPS = 315 * 12;
const int A_STEP = 8;
const int A_DIR = 9;
const int RESET = 10;

SwitecX12 motor1(STEPS, A_STEP, A_DIR);


void setup() {
  digitalWrite(RESET, HIGH);
  Serial.begin(9600);
  motor1.zero();
  motor1.setPosition(STEPS/2);
}

void loop() {
  static bool forward = true;
  static int position1 = STEPS * 3/4;
  static int position2 = STEPS * 1/4;
  if (motor1.stopped) {
    motor1.setPosition(forward ? position1 : position2);
    forward = !forward;
  }
  motor1.update();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The AX1201728SG looks very promising.  It&amp;rsquo;s a bit of a nuisance to
deal with surface mount devices if you aren&amp;rsquo;t set up for it, but not insurmountable.&lt;/p&gt;

&lt;p&gt;The microstepping is really smooth. Below is a video showing how smooth.
I used a very exaggerated acceleration
table to keep the needle in the slow range for longer.&lt;/p&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/YJIwiru_kk4&#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>
    
    <item>
      <title>Google OAuth2 for Devices Revisited</title>
      <link>//guy.carpenter.id.au/gaugette/2017/01/01/google-oauth2-for-devices-revisited/</link>
      <pubDate>Sun, 01 Jan 2017 13:03:00 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/2017/01/01/google-oauth2-for-devices-revisited/</guid>
      <description>&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2012-11-06/oauth-2-sm.png&#34;  class=&#34;right&#34;   /&gt;


&lt;p&gt;I just dusted off an old project that uses
&lt;a href=&#34;https://developers.google.com/identity/protocols/OAuth2ForDevices&#34; target=&#34;_blank&#34;&gt;Google&amp;rsquo;s OAuth 2.0 for Devices&lt;/a&gt; API to
authenticate against Google Docs, and cleaned up my implementation.&lt;/p&gt;

&lt;p&gt;OAuth2ForDevices is really useful for IoT projects
that use Google APIs.  I&amp;rsquo;m using it for a device that records data directly a Google Sheet.&lt;/p&gt;

&lt;p&gt;While the API itself is pretty straight forward, getting the implementation 100%
battle-hardened takes a bit of work and iteration, so I&amp;rsquo;ll share here what I&amp;rsquo;ve learned.
If you are coding in Python, you might find the OAuth class in the
 &lt;a href=&#34;https://github.com/guyc/py-gaugette&#34; target=&#34;_blank&#34;&gt;py-gaugette&lt;/a&gt; library useful.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h2 id=&#34;theory-of-operation&#34;&gt;Theory of operation&lt;/h2&gt;

&lt;h3 id=&#34;first-boot-oauth2-flow&#34;&gt;First-Boot OAuth2 Flow&lt;/h3&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2017-01-01/deviceflow.png&#34;  class=&#34;right&#34;   /&gt;


&lt;p&gt;The first time a device boots, it needs to request permissions from the user to access
Google Docs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;call the OAuth2 API to specify the permissions required and request an authorisation code.&lt;/li&gt;
&lt;li&gt;show the auth code to the user&lt;/li&gt;
&lt;li&gt;poll the OAuth2 API waiting for confirmation that the user has granted access to the device.&lt;/li&gt;
&lt;li&gt;save the refresh token in persistent storage for next startup.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To confirm access, the user uses a web browser on a separate device, and navigates to
&lt;a href=&#34;https://www.google.com/device&#34; target=&#34;_blank&#34;&gt;https://www.google.com/device&lt;/a&gt; to enter the authorisation code.&lt;br /&gt;
The user must be logged in to a Google account when they confirm the permissions, and the
device will be granted access on behalf of that account.  The level of access is determined
by the scope parameters passed by the device, and the user will be shown which permissions
have been requested before they confirm.&lt;/p&gt;

&lt;h3 id=&#34;after-the-first-boot&#34;&gt;After the First Boot&lt;/h3&gt;

&lt;p&gt;On subsequent boots the device can use the saved refresh token to authenticate, so
no further user interaction is required.&lt;/p&gt;

&lt;h2 id=&#34;here-s-what-it-looks-like&#34;&gt;Here&amp;rsquo;s What It Looks Like&lt;/h2&gt;

&lt;h3 id=&#34;1-the-device-presents-a-code&#34;&gt;1. The Device Presents a Code&lt;/h3&gt;

&lt;p&gt;On my time clock, I display the code on the one-line OLED display.  The device code can be quite long - the API docs
recommend ensuring you can display 15 &amp;lsquo;W&amp;rsquo;-sized characters, although current codes are formatted as XXXX-XXXX.  The length of generated codes
has increased since I first started using this API and I now need to use horizontal scrolling to
display the entire code.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2017-01-01/device-auth.png&#34;   /&gt;


&lt;h3 id=&#34;2-the-user-enters-the-code&#34;&gt;2. The User Enters the Code&lt;/h3&gt;

&lt;p&gt;You need to communicate the URL (&lt;a href=&#34;https://www.google.com/device&#34; target=&#34;_blank&#34;&gt;https://www.google.com/device&lt;/a&gt;) to the user somehow.&lt;br /&gt;
This is the web page they will see.  They may first be prompted to log in to their
Google account or select from multiple logged in accounts.&lt;/p&gt;

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


&lt;h3 id=&#34;3-the-user-confirms-access&#34;&gt;3. The User Confirms Access&lt;/h3&gt;

&lt;p&gt;The permissions listed here are determined by the scope variables you have passed.  The list of
available scopes is &lt;a href=&#34;https://developers.google.com/identity/protocols/googlescopes&#34; target=&#34;_blank&#34;&gt;defined here&lt;/a&gt;.&lt;/p&gt;

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


&lt;h2 id=&#34;on-the-device&#34;&gt;On the Device&lt;/h2&gt;

&lt;p&gt;Here&amp;rsquo;s what it looks like on the device.&lt;/p&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/tZ6XZ1yhHJM&#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;


&lt;h2 id=&#34;making-api-calls-with-oauth2-tokens&#34;&gt;Making API Calls With OAuth2 tokens&lt;/h2&gt;

&lt;p&gt;The most complicated aspect of this API is passing the credentials and handling
exceptions, and a lot has changed since I wrote the earlier Feeds implementation.  Now
I&amp;rsquo;m using the &lt;a href=&#34;https://developers.google.com/api-client-library/python/start/installation&#34; target=&#34;_blank&#34;&gt;Google API Client Libraries for Python&lt;/a&gt;
and passing in the token via a  &lt;a href=&#34;http://oauth2client.readthedocs.io/en/latest/source/oauth2client.client.html#oauth2client.client.GoogleCredentials&#34; target=&#34;_blank&#34;&gt;oauth2client.client.GoogleCredientials&lt;/a&gt;
instance.&lt;/p&gt;

&lt;p&gt;One nasty little surprise I discovered with long-running applications
is that after the device has idled for a long time (say 24 hours without making an API call) I start getting
BadStatusLine exceptions on all API calls.  To handle this and other errors,
I use @wrap from functools to wrap all of the API calls in a retry function.  This keeps
the extra complexity of error recovery nicely abstracted away.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>py-gaugette Gets a Refresh</title>
      <link>//guy.carpenter.id.au/gaugette/2016/11/12/py-gaugette-gets-a-refresh/</link>
      <pubDate>Sat, 12 Nov 2016 14:39:00 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/2016/11/12/py-gaugette-gets-a-refresh/</guid>
      <description>

&lt;p&gt;I&amp;rsquo;ve made some major changes to the py-gaugette library to address
several issues that have accumulated over time, namely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;added interrupt-driven option to rotary encoder&lt;/li&gt;
&lt;li&gt;fully Python 3 compatible&lt;/li&gt;
&lt;li&gt;works with current version of Py-WiringPi&lt;/li&gt;
&lt;li&gt;uses dependency injection for GPIO and SPI interfaces&lt;/li&gt;
&lt;li&gt;updated Google Sheets code to use new API&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;dependency-injection-for-gpio-and-spi&#34;&gt;Dependency Injection for GPIO and SPI&lt;/h2&gt;

&lt;p&gt;Classes that interact with the GPIO or SPI interfaces now take
an instance of that interface as a parameter to the constructor.
This avoids the issue of having multiple classes trying to initialise
the GPIO library, and makes it easy to pass alternative interface
implementations.&lt;/p&gt;

&lt;h2 id=&#34;interrupts-for-rotary-encoders&#34;&gt;Interrupts for Rotary Encoders&lt;/h2&gt;

&lt;p&gt;The original implementation of the rotary encoder library used polling.
On the Raspberry Pi it now supports interrupts.  The previous polling
behaviour is still supported.&lt;/p&gt;

&lt;h2 id=&#34;fully-python-3-compatible&#34;&gt;Fully Python 3 Compatible&lt;/h2&gt;

&lt;p&gt;While the library has been mostly Python 3 compatible, there were a few
exceptions.  In particular the SSD1306 class depended heavily on the Python 2
behaviour of the division operator, which changed in Python 3.  I&amp;rsquo;ve rewritten
the calculations to mostly use bit shifts rather than division.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>About Gaugette</title>
      <link>//guy.carpenter.id.au/gaugette/about/</link>
      <pubDate>Tue, 01 Nov 2016 14:39:00 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/about/</guid>
      <description>

&lt;h2 id=&#34;what-is-gaugette&#34;&gt;What is Gaugette?&lt;/h2&gt;

&lt;p&gt;&lt;img src=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/thermo_backlit.png&#34; alt=&#34;&#34; title=&#34;LED Backlighting&#34; /&gt;&lt;/p&gt;

&lt;p&gt;Gaugette is a blog detailing the construction of custom gauges and gadgets using Arduino microcontrollers or Raspberry Pis.&lt;/p&gt;

&lt;p&gt;It was originally created to document the creation of analog gauges using Switec X25 stepper motors, but the focus is now broader; it turns out not every gadget needs an analog gauge. Go figure.&lt;/p&gt;

&lt;h2 id=&#34;what-is-a-switec-x25&#34;&gt;What is a Switec X25?&lt;/h2&gt;

&lt;p&gt;I’ve chosen Switec X25.168 miniature stepper motors to drive the gauges. These steppers were developed by Switec, the Swatch Company’s technology arm, for automobile instrument clusters. They are really cheap, readily available and require no external driver circuitry. Pretty cool huh?&lt;/p&gt;

&lt;p&gt;Because information about driving these motors with the Arduino is hard to find, I’ve gathered the datasheets and other &lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources&#34;&gt;resources here&lt;/a&gt;, and have published a &lt;a href=&#34;https://github.com/clearwater/SwitecX25&#34; target=&#34;_blank&#34;&gt;Arduino SwitecX25 driver library&lt;/a&gt; on GitHub.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/gauge_pair.jpg&#34; alt=&#34;&#34; title=&#34;Mounted Gauges&#34; /&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Resources</title>
      <link>//guy.carpenter.id.au/gaugette/resources/</link>
      <pubDate>Tue, 01 Nov 2016 14:39:00 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/resources/</guid>
      <description>

&lt;h2 id=&#34;source-code&#34;&gt;Source Code&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/clearwater/SwitecX25&#34; target=&#34;_blank&#34;&gt;SwitecX25 Driver Library for Arduino&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/clearwater/gaugette&#34; target=&#34;_blank&#34;&gt;Gaugette Source for Arduino&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;switec-x25-series-stepper-motors&#34;&gt;Switec X25 Series Stepper Motors&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/switec/X25_xxx_01_SP_E-1.pdf&#34;&gt;Switec X25 Series Data Sheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/switec/ISM_Buyers_Guide.pdf&#34;&gt;Switec X25 Series Buyers Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;vid29-series-motors&#34;&gt;VID29 Series Motors&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/vid/20091026113525_VID29_manual_EN-080606.pdf&#34;&gt;VID29 Series Data Sheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/vid/20090905105401VID29.pdf&#34;&gt;VID29 Mechanical Drawings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/vid/2009111395111_Acceleration_&amp;amp;_reset_calculation_example.pdf&#34;&gt;VID29 Acceleration and Reset Calculation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/vid/2009111395409_VID29_Precaution_of_Pointer_Assembly.pdf&#34;&gt;VID29 Pointer Assembly Precautions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/vid/2009111395504_VID29_reset_pulse_general_description.pdf&#34;&gt;VID29 Power-On Reset Procedure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/vid/2009111395537_VID29Electrical_and_Mechanical_Characteristic1.pdf&#34;&gt;VID29 Electrical and Mechanical Characteristics&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;vid23-series-motors&#34;&gt;VID23 Series Motors&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/vid/2009111390052_VID23 manual EN-081210.pdf&#34;&gt;VID23 Transparent Shaft Motor&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;mcr-motor-mr1107-mr1108&#34;&gt;MCR Motor MR1107/MR1108&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/mcr/2010410104720473.pdf&#34;&gt;MCR Motor MR1107/MR1108 Data Sheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/mcr/2009212115216347.pdf&#34;&gt;MCR Motor Mechanical Drawings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/mcr/201041010510949.pdf&#34;&gt;MCR PWM Driving Mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/mcr/2010410104915847.pdf&#34;&gt;MCR Acceleration Curve&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;driver-chips&#34;&gt;Driver Chips&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/switec/X12_017.pdf&#34;&gt;X12.017 Quad Driver Chip Data Sheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/nost/1428412011616by8290datasheet.pdf&#34;&gt;BY8290 Quad Driver Chip Data Sheet (in Chinese)&lt;/a&gt;, and here’s a link to a Google-generated &lt;a href=&#34;http://translate.google.com.au/translate?hl=en&amp;amp;sl=zh-CN&amp;amp;tl=en&amp;amp;u=http%3A%2F%2Fguy.carpenter.id.au%2Fgaugette%2Fresources%2Fnost%2F1428412011616by8290datasheet.pdf&#34; target=&#34;_blank&#34;&gt;English translation of the data sheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/resources/vid/2009111391612_VID6606%20manual%20060927.pdf&#34;&gt;VID6606 Quad Driver Chip Data Sheet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <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>
    
    <item>
      <title>Improved Test Code for Rotary Encoders</title>
      <link>//guy.carpenter.id.au/gaugette/2013/06/04/improved-test-code-for-rotary-encoders/</link>
      <pubDate>Tue, 04 Jun 2013 16:52:28 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/2013/06/04/improved-test-code-for-rotary-encoders/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-06-04/raspberry-pi-rotary-encoder.png&#34;  class=&#34;right&#34;   /&gt;

While working through a few queries about the &lt;a href=&#34;//guy.carpenter.id.au/gaugette/gaugette/2013/01/14/rotary-encoder-library-for-the-raspberry-pi/&#34;&gt;rotary encoder library&lt;/a&gt;,
it became evident that it would help to have a better test application to diagnose wiring issues.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve &lt;a href=&#34;https://github.com/guyc/py-gaugette/blob/19bf43f29fcc02d8865a7a2078447b2772a2af85/samples/rotary_test.py&#34; target=&#34;_blank&#34;&gt;committed&lt;/a&gt;
a better version of &lt;code&gt;rotary_test.py&lt;/code&gt; that writes out a
comprehensive table of state information, updated whenever anything changes.&lt;/p&gt;

&lt;p&gt;&lt;br clear=&#34;both&#34;/&gt;&lt;/p&gt;

&lt;p&gt;The output looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;A B STATE SEQ DELTA SWITCH
1 1   3    2    1    0
0 1   2    3    1    0
0 0   0    0    1    0
1 0   1    1    1    0
1 1   3    2    1    0
0 1   2    3    1    0
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The values in the table are defined as follows:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;Raw value of input A&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Raw value of input B&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;STATE&lt;/td&gt;
&lt;td&gt;Quadrature state 0,1,3,2&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;SEQ&lt;/td&gt;
&lt;td&gt;Ordinal sequence 0,1,2,3&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;DELTA&lt;/td&gt;
&lt;td&gt;Net change in position&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;SWITCH&lt;/td&gt;
&lt;td&gt;Push-button switch state&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;One small note on the implementation: although there are library calls to directly
fetch each of the values in the table, the test program only calls the library to
retrieve &lt;code&gt;STATE&lt;/code&gt; and &lt;code&gt;SWITCH&lt;/code&gt;, and then derives the other values from &lt;code&gt;STATE&lt;/code&gt;.  I did this to
make sure each column is generated from the same inputs.  If instead I made separate library calls
to fetch each column value, it is quite likely that the inputs would change while generating a row of this table,
producing inconsistent and confusing results.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Updating py-gaugette to wiringpi2</title>
      <link>//guy.carpenter.id.au/gaugette/2013/06/04/updating-to-wiringpi2-py/</link>
      <pubDate>Tue, 04 Jun 2013 16:14:51 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/2013/06/04/updating-to-wiringpi2-py/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://projects.drogon.net/wp-content/uploads/2013/05/adaLcd-1024x602.jpg&#34;   /&gt;

Phillip Howard and Gordon Henderson recently &lt;a href=&#34;http://pi.gadgetoid.com/post/039-wiringpi-version-2-with-extra-python&#34; target=&#34;_blank&#34;&gt;announced&lt;/a&gt;
the availability of &lt;a href=&#34;http://wiringpi.com/&#34; target=&#34;_blank&#34;&gt;WiringPi2&lt;/a&gt; along with a new python wrapper
&lt;a href=&#34;https://github.com/Gadgetoid/WiringPi2-Python&#34; target=&#34;_blank&#34;&gt;WiringPi2-Python&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The python library name has changed from &lt;code&gt;wiringpi&lt;/code&gt; to &lt;code&gt;wiringpi2&lt;/code&gt;, so any application
code referencing the module needs to be updated.
I&amp;rsquo;ve forked &lt;a href=&#34;https://github.com/guyc/py-gaugette&#34; target=&#34;_blank&#34;&gt;py-gaugette&lt;/a&gt; to create
a &lt;a href=&#34;https://github.com/guyc/py-gaugette/tree/wiringpi2&#34; target=&#34;_blank&#34;&gt;wiringpi2 branch&lt;/a&gt;.  I plan to roll
this into the master branch in the not-too-distant future.  When I do, wiringpi2 will
be a requirement for using py-gaugette.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s how I installed the wiringpi2 libraries on my boxes:&lt;/p&gt;

&lt;h3 id=&#34;install-wiringpi2&#34;&gt;Install WiringPi2&lt;/h3&gt;

&lt;p&gt;First install wiringPi.  At the time of writing, it does &lt;em&gt;not&lt;/em&gt; work to install
with &lt;code&gt;sudo pip install wiringpi2&lt;/code&gt;; the library builds and installs fine, but
the version installed is not compatible with current version of &lt;code&gt;WiringPi2-Python&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone git://git.drogon.net/wiringPi
cd wiringPi
./build
cd ..
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;install-wiringpi2-python&#34;&gt;Install WiringPi2-Python&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;git clone https://github.com/Gadgetoid/WiringPi2-Python.git
cd WiringPi2-Python/
sudo python setup.py install
cd ..
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;checkout-py-gaugette-for-wiringpi2&#34;&gt;Checkout py-gaugette for WiringPi2&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;git clone git://github.com/guyc/py-gaugette.git
cd py-gaugette
git checkout wiringpi2
cd ..
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>OpenXC - Hack Your Car</title>
      <link>//guy.carpenter.id.au/gaugette/2013/03/03/openxc-hack-your-car/</link>
      <pubDate>Sun, 03 Mar 2013 15:20:48 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/2013/03/03/openxc-hack-your-car/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-03-03/openxc-logo.png&#34;  class=&#34;left&#34;   /&gt;

&lt;a href=&#34;http://openxcplatform.com/&#34; target=&#34;_blank&#34;&gt;OpenXC&lt;/a&gt; is a very cool initiative involving Ford Motor Company
and Bug Labs aimed at creating an open development ecosystem for interfacing with in-car electronics.
Looks like a pretty great project.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h2 id=&#34;openxc-switec-x25-based-retro-gauge&#34;&gt;OpenXC Switec X25-based &amp;ldquo;Retro Gauge&amp;rdquo;&lt;/h2&gt;

&lt;p&gt;&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-03-03/overview.jpg&#34;  class=&#34;right&#34;   /&gt;

One of the OpenXC projects featured on their website is a
&lt;a href=&#34;http://openxcplatform.com/projects/retro-gauge.html&#34; target=&#34;_blank&#34;&gt;retro gauge&lt;/a&gt;
based around Switec X25 type micro-steppers.&lt;/p&gt;

&lt;p&gt;They have published Eagle schematics for a gorgeous little combination
analog/digital instrument gauge.  Their in-gauge PCB cleverly incorporates
an Arduino Pro Mini.  They have also published STL files for a 3D-printable housing.&lt;br /&gt;
This all looks very slick to me.&lt;/p&gt;

&lt;p&gt;Their firmware uses our very own &lt;a href=&#34;https://github.com/clearwater/SwitecX25&#34; target=&#34;_blank&#34;&gt;Switec X25 library&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can find detailed documentation and resources at
their &lt;a href=&#34;https://github.com/openxc/retro-gauge&#34; target=&#34;_blank&#34;&gt;github repository&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Raspberry Pi Time Clock</title>
      <link>//guy.carpenter.id.au/gaugette/2013/02/03/raspberry-pi-time-clock/</link>
      <pubDate>Sun, 03 Feb 2013 12:18:56 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/2013/02/03/raspberry-pi-time-clock/</guid>
      <description>&lt;h2 id=&#34;gaugette-time-clock&#34;&gt;Gaugette Time Clock&lt;/h2&gt;

&lt;p&gt;This build combines a Raspberry Pi with a rotary-encoder, an RGB LED and an OLED
character display to create a time clock that logs my time on tasks directly to
a Google Docs spreadsheet.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-02-03/imgp3555.jpg&#34;   /&gt;


&lt;p&gt;&lt;/p&gt;

&lt;h2 id=&#34;motivation&#34;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;Whenever I have to record time against projects, I find it really hard to
diligently keep my time records up to date. Maybe with a purpose-built time
clock I will keep better records? Hey, it could happen!&lt;/p&gt;

&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;

&lt;p&gt;The off-the-shelf components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Raspberry Pi model B Rev 1 - &lt;a href=&#34;http://www.adafruit.com/products/998&#34; target=&#34;_blank&#34;&gt;Adafruit has the Rev 2 board.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;128x32 SPI OLED display - &lt;a href=&#34;http://www.adafruit.com/products/661&#34; target=&#34;_blank&#34;&gt;Adafruit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Rotary Encoder - &lt;a href=&#34;https://www.adafruit.com/products/377&#34; target=&#34;_blank&#34;&gt;Adafruit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;5mm RGB LED - &lt;a href=&#34;https://www.sparkfun.com/products/105&#34; target=&#34;_blank&#34;&gt;Sparkfun&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Occidentalis 0.2 - &lt;a href=&#34;http://learn.adafruit.com/adafruit-raspberry-pi-educational-linux-distro/occidentalis-v0-dot-2&#34; target=&#34;_blank&#34;&gt;Adafruit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;6” Female/Female jumper wires - &lt;a href=&#34;https://www.adafruit.com/products/266&#34; target=&#34;_blank&#34;&gt;Adafruit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;3” Female/Female jumpers wires - &lt;a href=&#34;http://littlebirdelectronics.com/products/premium-jumper-wire-50-piece-rainbow-assortment-f-f-3&#34; target=&#34;_blank&#34;&gt;Little Bird Electronics&lt;/a&gt; or &lt;a href=&#34;https://www.adafruit.com/products/794&#34; target=&#34;_blank&#34;&gt;Adafruit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used a common cathode LED from Sparkfun. You could use Adafruit’s &lt;a href=&#34;http://www.adafruit.com/products/159&#34; target=&#34;_blank&#34;&gt;common
anode equivalent&lt;/a&gt; with minor code changes.&lt;/p&gt;

&lt;p&gt;The theory of operation is pretty simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;at start-up, it pulls a list of jobs from a Google Docs spreadsheet,&lt;/li&gt;
&lt;li&gt;rotating the knob scrolls through the list of jobs,&lt;/li&gt;
&lt;li&gt;clicking the knob logs a start time or end time in the spreadsheet.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;the-case&#34;&gt;The Case&lt;/h2&gt;

&lt;p&gt;The top of the case is made from a single block of wood.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-02-03/imgp3532.jpg&#34;   /&gt;


&lt;p&gt;The bottom of the block has been hollowed out to house the RPi board. The RPi
sits in a plastic carriage that screws to the bottom of the block. I have not
provided access to the HDMI, audio or video ports on the RPi since I’m not going
to use them.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-02-03/imgp3479.jpg&#34;   /&gt;


&lt;p&gt;The carriage for the Raspberry Pi was designed in
&lt;a href=&#34;http://openscad.org/&#34; target=&#34;_blank&#34;&gt;OpenSCAD&lt;/a&gt; and printed on a Makerbot Replicator. The RPi
board doesn’t have mounting holes, so the carriage has edge-clips to grasp the
board. The posts at the corners were originally intended to screw the carriage
to the block, but I found that to be impractical, so I added the two tabs at the
bottom and routed out matching recesses in the block. I left the posts there
because they make the carriage look a little more interesting. Or because I was
too lazy to remove them, I’ve heard it both ways.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-02-03/base_preview_featured.jpg&#34;   /&gt;


&lt;p&gt;The OpenScad sources and STL files for the base are available from
&lt;a href=&#34;http://www.thingiverse.com/thing:46892&#34; target=&#34;_blank&#34;&gt;Thingiverse&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&#34;the-circuit&#34;&gt;The Circuit&lt;/h2&gt;

&lt;p&gt;I’m using two of the ground pins originally documented as Do Not Connect (DNC).
The extra grounds are really convenient, and Eben &lt;a href=&#34;http://www.raspberrypi.org/archives/2233&#34; target=&#34;_blank&#34;&gt;has publicly committed&lt;/a&gt; to keeping these available
in future board revisions.&lt;/p&gt;

&lt;p&gt;It’s worth pointing out that I deliberately selected GPIO pin 5 for the push
button because of the &lt;a href=&#34;http://www.raspberrypi.org/phpBB3/viewtopic.php?f=29&amp;amp;t=12007&#34; target=&#34;_blank&#34;&gt;Raspberry Pi Safe
Mode&lt;/a&gt; feature. If
you have a recent &lt;a href=&#34;https://github.com/Hexxeh/rpi-update&#34; target=&#34;_blank&#34;&gt;firmware release&lt;/a&gt;, you
can boot your RPi in safe mode by holding the knob down (shorting pin 5 to
ground) when you power up. In truth my intention here is not so much to make
safe mode available (I’ve never needed it) but to make sure that pin 5 is not
&lt;em&gt;unintentionally&lt;/em&gt; shorted to ground at boot time, as it could be if you used it
for one of the quadrature encoder inputs. Yep, that happened. After I upgraded
to the version of firmware that supports safe mode my box stopped booting.
Lesson learned; be careful with pin 5, or &lt;a href=&#34;http://elinux.org/images/c/ca/Raspi_documented_config.txt&#34; target=&#34;_blank&#34;&gt;disable safe
mode&lt;/a&gt; by adding
&lt;code&gt;avoid_safe_mode=1&lt;/code&gt; to &lt;code&gt;/boot/config.txt&lt;/code&gt;.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-02-03/timeclock2_bb.jpg&#34;   /&gt;


&lt;p&gt;For most of the GPIO connections I cut pre-terminated &lt;a href=&#34;https://www.adafruit.com/products/266&#34; target=&#34;_blank&#34;&gt;Female Female jumper
wires&lt;/a&gt; in half and soldered the cut end
to the component. I already had header pins on the SSD1306 OLED module, so I
used &lt;a href=&#34;http://littlebirdelectronics.com/products/premium-jumper-wire-50-piece-rainbow-assortment-f-f-3&#34; target=&#34;_blank&#34;&gt;3” pre-made cables from Little Bird
Electronics&lt;/a&gt;.
It is crucial to keep wiring short and well insulated so that it will all pack
in neatly and without shorts when the case is closed up.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-02-03/imgp3481.jpg&#34;   /&gt;


&lt;h2 id=&#34;rgb-led-indicator&#34;&gt;RGB LED Indicator&lt;/h2&gt;

&lt;p&gt;For this device I wanted a large, diffuse and interesting state indicator built
around an RGB LED. I use the WiringPi
&lt;a href=&#34;https://projects.drogon.net/raspberry-pi/wiringpi/software-pwm-library/&#34; target=&#34;_blank&#34;&gt;soft PWM&lt;/a&gt;
library to drive the LED, and the
&lt;a href=&#34;https://github.com/guyc/py-gaugette/blob/master/gaugette/rgbled.py&#34; target=&#34;_blank&#34;&gt;py-gaugette RgbLed&lt;/a&gt;
class makes it easy to do animated colour transition loops. My first prototype
was made from the back of a GU10 light bulb. The bulb glass is thick and
diffuses the light nicely, and I thought the terminals would make cool
capacitive switches.&lt;/p&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/tRBiQ0ZXFZM&#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;


&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-02-03/imgp3560.jpg&#34;  class=&#34;right&#34;   /&gt;


&lt;p&gt;I liked that a lot, but ultimately settled on a long oven light which had a more
compact footprint. It gives elegant curving internal reflections which look
quite nice.&lt;/p&gt;

&lt;p&gt;When I cut the metal tip of the bulb off with a Dremel I expected to be able to
remove the burned-out filament, but discovered this bulb (like most others I
would guess) is made with an inner glass plug that encases the filament wires
and seals the bulb. It isn’t easily removed, but has a hollow neck just big
enough to receive an LED. So the filament stays. Maybe I should have used a new
bulb!&lt;/p&gt;

&lt;p&gt;I trimmed the red, green and blue leads on the LED quite short and soldered a
270Ω current-limiting resistor to each one. This keeps the resistors tucked up
away from the board. I then added connector wires to each lead, pushed the LED
up into the bulb neck and pumped some hot glue in to keep it all in place.&lt;/p&gt;

&lt;p&gt;I’ve seen advice suggesting I should have selected different values for the
resistors to to get optimal white balance. I didn’t bother. Colour balance is
fine. &lt;a href=&#34;http://www.youtube.com/watch?v=vFWkJuPhApc&#34; target=&#34;_blank&#34;&gt;I aint bovvered&lt;/a&gt;.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-02-03/imgp3444.jpg&#34;   /&gt;


&lt;h2 id=&#34;rotary-encoder&#34;&gt;Rotary Encoder&lt;/h2&gt;

&lt;p&gt;I documented the encoder library &lt;a href=&#34;//guy.carpenter.id.au/gaugette/blog/2013/01/14/rotary-encoder-library-for-the-raspberry-pi/&#34;&gt;in a previous post&lt;/a&gt;.
I’m using the
&lt;a href=&#34;https://github.com/guyc/py-gaugette/blob/master/gaugette/rotary_encoder.py&#34; target=&#34;_blank&#34;&gt;py-gaugette RotaryEncoder.Worker class&lt;/a&gt;
to poll the encoder GPIOs in the background which keeps the application code
very simple.&lt;/p&gt;

&lt;h2 id=&#34;128x32-ssd1306-oled-display&#34;&gt;128x32 SSD1306 OLED Display&lt;/h2&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-02-03/imgp3459.jpg&#34;   /&gt;


&lt;p&gt;I’ve written about using these great little
&lt;a href=&#34;https://www.adafruit.com/products/661&#34; target=&#34;_blank&#34;&gt;128x32 OLEDs&lt;/a&gt; from Adafruit
&lt;a href=&#34;//guy.carpenter.id.au/gaugette/blog/2012/11/11/font-support-for-ssd1306/&#34;&gt;before&lt;/a&gt;. Mounting it in
the block was a challenge. I used a router on the inside of the case to thin the
material down to just a few mm over an area big enough to place the PCB. I then
cut a rectangular hole for the display using a Dremel, file and scalpel, taking
great pains not to crack the thin wood. I couldn’t see a practical way to use
the mounting holes so I hot-glued the board in place. I positioned it with the
display powered up showing a test pattern so I could line up the active part of
the display with the hole.&lt;/p&gt;

&lt;p&gt;The bezel was printed on a Makerbot Replicator and painted with Plaid brand
&lt;a href=&#34;http://www.plaidonline.com/liquid-leaf-copper/89/6160/product.htm&#34; target=&#34;_blank&#34;&gt;copper Liquid Leaf&lt;/a&gt;. I’ve
been looking for a metallic paint that wouldn’t dissolve the ABS. Liquid Leaf is
xylene-based, which &lt;a href=&#34;http://books.google.com.au/books?isbn=0815515812&#34; target=&#34;_blank&#34;&gt;should be safe for ABS&lt;/a&gt;, although maybe
&lt;a href=&#34;http://www.intertradegrp.com/docs/IT-XYLENE-MSDS.pdf&#34; target=&#34;_blank&#34;&gt;not so safe for humans&lt;/a&gt;.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-02-03/imgp2505.jpg&#34;   /&gt;


&lt;p&gt;The effect of metallic paint on the printed surface is interesting; it
highlights the individual filaments in the print. I like it. It would be
possible to reduce the relief by brushing the surface with acetone before
painting, but I think the sharp relief is good for what I’m doing here.&lt;/p&gt;

&lt;h2 id=&#34;cooling&#34;&gt;Cooling&lt;/h2&gt;

&lt;p&gt;It occurred to me fairly late in this build that I hadn’t provided for any air
flow to help cool the processor. That got me to wondering, then to worrying… am
I cooking my Pi? And is there no end to the bad pie puns?&lt;/p&gt;

&lt;p&gt;Fortunately a recent firmware update provided a tool that allows us to measure
the CPU temperature in code, so I did a little experiment. I recorded the
temperature using &lt;a href=&#34;http://elinux.org/RPI_vcgencmd_usage&#34; target=&#34;_blank&#34;&gt;vcgencmd&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;
while :; do /opt/vc/bin/vcgencmd measure_temp; sleep 3; done
&lt;/pre&gt;


&lt;p&gt;I ran this loop from a cold boot for 25 minutes, first with the top off, then
again (after letting the system cool down) with the case closed up tight. For
the record the ambient temperature in my office was around 26°C.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-02-03/RPi-Temperature.png&#34;   /&gt;


&lt;p&gt;The results show that the closed box adds about 4°C to the CPU temperature at
idle. I tried removing the bulb from the centre of the cover to allow hot air to
be convected away, but that made no measurable difference in temperature.&lt;/p&gt;

&lt;p&gt;These temperatures were taken at idle. My application code runs around 20% CPU
utilization. With application running and the lid off the temperature settles in
around 46°C, and with the lid on at around 51°C.&lt;/p&gt;

&lt;p&gt;Based on these results I’m happy to ignore air flow for now. 51°C isn’t
worryingly high, and it looks like it would take a lot of work to improve air
flow enough to make an appreciable difference.&lt;/p&gt;

&lt;h2 id=&#34;software&#34;&gt;Software&lt;/h2&gt;

&lt;p&gt;The code for all of the I/O devices used here is available in the
&lt;a href=&#34;https://github.com/guyc/py-gaugette&#34; target=&#34;_blank&#34;&gt;py-gaugette library&lt;/a&gt;. I will release the application
source soon; there are a few loose ends I want to tidy up first.&lt;/p&gt;

&lt;h2 id=&#34;all-together-now&#34;&gt;All Together Now&lt;/h2&gt;

&lt;p&gt;In the video below, the LED colours are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;purple is idle - time not being logged&lt;/li&gt;
&lt;li&gt;slowly pulsing blue is active - time is being logged against a task, pulses slowly&lt;/li&gt;
&lt;li&gt;flashing is busy - updating the spreadsheet via Google Docs&lt;/li&gt;
&lt;/ul&gt;

&lt;iframe allowfullscreen=&#34;allowFullScreen&#34; frameborder=&#34;0&#34; height=&#34;390&#34; mozallowfullscreen=&#34;mozallowfullscreen&#34; src=&#34;http://www.youtube.com/embed/su-CXqMPJxM&#34; webkitallowfullscreen=&#34;webkitAllowFullScreen&#34; width=&#34;640&#34;&gt;&lt;/iframe&gt;

&lt;p&gt;The resulting spreadsheet looks like this:&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-02-03/TimeClockSpreadsheet.png&#34;   /&gt;</description>
    </item>
    
    <item>
      <title>Analog Gauge Stepper Breakout Board available on Tindie</title>
      <link>//guy.carpenter.id.au/gaugette/2013/01/18/analog-gauge-stepper-breakout-board-available-on-tindie/</link>
      <pubDate>Fri, 18 Jan 2013 07:27:00 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/2013/01/18/analog-gauge-stepper-breakout-board-available-on-tindie/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-01-18/analog-gauge-stepper-breakout.jpg&#34;  class=&#34;right&#34;   /&gt;

Check out this great new &lt;a href=&#34;https://tindie.com/shops/TheRengineer/analog-gauge-stepper-breakout-board/&#34; target=&#34;_blank&#34;&gt;Tindie project&lt;/a&gt;
launched by &lt;a href=&#34;http://www.therengineer.com/&#34; target=&#34;_blank&#34;&gt;The Renaissance Engineer&lt;/a&gt; &lt;a href=&#34;https://twitter.com/ajfabio&#34; target=&#34;_blank&#34;&gt;Adam Fabio&lt;/a&gt;
for a new breakout board designed for Switec motors and clones.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-01-18/analog-gauge-stepper-kit.jpg&#34;  class=&#34;right&#34;   /&gt;

The breakout board incorporates flyback diodes to protect your circuit from inductive kickback, and
the also serves as a convenient base to mount the motors.  The kit includes
the board, diodes, 6-pin header, a Switec X27.168 and 3d-printed needle.&lt;/p&gt;

&lt;p&gt;If you want to get in on this initial offering act quickly - it closes
in 12 days.  The project has already exceeded the funding target.
Nice work Adam!&lt;/p&gt;

&lt;p&gt;&lt;br clear=&#34;both&#34;/&gt;&lt;/p&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/p-9aR8eVrJY&#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>
    
    <item>
      <title>Rotary Encoder Library for the Raspberry Pi</title>
      <link>//guy.carpenter.id.au/gaugette/2013/01/14/rotary-encoder-library-for-the-raspberry-pi/</link>
      <pubDate>Mon, 14 Jan 2013 20:49:00 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/2013/01/14/rotary-encoder-library-for-the-raspberry-pi/</guid>
      <description>&lt;p&gt;Here&amp;rsquo;s a quick overview of the rotary encoder I/O class in
the &lt;a href=&#34;https://github.com/guyc/py-gaugette&#34; target=&#34;_blank&#34;&gt;py-gaugette library&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The encoder I&amp;rsquo;m using is a 2-bit quadrature-encoded rotary encoder,
&lt;a href=&#34;http://www.adafruit.com/products/377&#34; target=&#34;_blank&#34;&gt;available from Adafruit&lt;/a&gt;.&lt;br /&gt;
The &lt;a href=&#34;http://www.adafruit.com/datasheets/pec11.pdf&#34; target=&#34;_blank&#34;&gt;datasheet is here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The documentation for this encoder says that it gives 24 pulses per 360&amp;deg; rotation,
which I interpreted to mean 24 resolvable positions, but after trying it I see that
it has 24 detent positions, and between each detent is a full 4-step quadrature cycle,
so there are actually 96 resolvable steps per rotation.  This unit also includes
a momentary switch which is closed when the button is pushed down.  Takes a solid
push to close the switch.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-01-14/rotary-encoder.png&#34;  class=&#34;center&#34;   /&gt;


&lt;p&gt;The diagram above shows how I&amp;rsquo;ve connected the rotary encoder to the Raspberry Pi.
I&amp;rsquo;m using pin 9, one of the &amp;ldquo;Do Not Connect&amp;rdquo; (DNC) pins to get a second ground pin for convenience.
Eben &lt;a href=&#34;http://www.raspberrypi.org/archives/2233&#34; target=&#34;_blank&#34;&gt;made a public commitment&lt;/a&gt;
to keep the extra power and ground pins unchanged in future releases, so
I think it is safe to publish circuits using them.  Right?  Here&amp;rsquo;s a pinout
highlighting the functions of the DNC pins, along with the wiringpi pin numbers.&lt;/p&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/pi-pinout.png&#34;   /&gt;


&lt;h2 id=&#34;decoder-logic&#34;&gt;Decoder Logic&lt;/h2&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2013-01-14/quadrature.png&#34;  class=&#34;right&#34;   /&gt;


&lt;p&gt;The implementation configures pins A and B as inputs, turns on the internal pull-up resistors for each,
so they will read high when the contacts are open, low when closed.  The inputs
generate the following sequence of values
as we advance through the quadrature sequence:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SEQ&lt;/th&gt;
&lt;th&gt;B&lt;/th&gt;
&lt;th&gt;A&lt;/th&gt;
&lt;th&gt;A ^ B&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;One non-obvious detail here: the library uses the bitwise xor value &lt;code&gt;A ^ B&lt;/code&gt; to
efficiently transform the input bits into an ordinal sequence number.  There is
no reason behind the xor other than it gives us the bit sequence we want.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;        seq = (a_state ^ b_state) | b_state &amp;lt;&amp;lt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Because we are pulling our inputs high and
shorting to ground when the contacts close, our inputs for A and B are actually
inverted against those shown in Quadrature Output Table figure above.
It turns out you can ignore this inversion in the decode logic; inverting the signals moves
the quadrature half a cycle forward, but makes no difference at all to
the decode logic.&lt;/p&gt;

&lt;p&gt;Once the library has computed the sequence value, it determines the direction of movement
by comparing the current sequence position against the previous sequence position,
like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;delta = (current_sequence - previous_sequence) % 4
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which will yield values in the range 0 through 3, interpreted as follows:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;delta&lt;/th&gt;
&lt;th&gt;meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;no change&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1 step clockwise&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2 steps clockwise &lt;em&gt;or&lt;/em&gt; counter-clockwise&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;1 step counter clockwise&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;If we get a value of 2, we know we have missed a transition (oops!) but we don&amp;rsquo;t
know if the encoder has turned clockwise or counter-clockwise.  In this
case the library assumes the direction is the same as the previous rotation.
Of course if the encoder has actually moved 3 steps between reads, it will decode as 1 step
in the wrong direction.  You can only fix this by polling faster or using interrupts.&lt;/p&gt;

&lt;h2 id=&#34;polling-vs-interrupts&#34;&gt;Polling Vs Interrupts&lt;/h2&gt;

&lt;p&gt;The current implementation of the &lt;code&gt;RotaryEncoder&lt;/code&gt; class uses polling to monitor the inputs rather than
using GPIO interrupts.  It looks like the plumbing is in place within wiringpi to use interrupts on GPIOs,
but I&amp;rsquo;ll leave that for another day.  Instead I have included an optional worker thread class that can be used
to monitor the inputs, leaving the main thread free to go about its business.&lt;/p&gt;

&lt;p&gt;The push switch is handled by a separate Switch class that doesn&amp;rsquo;t do anything clever
like debounce - it just reads and returns the current switch state.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s how to read the rotary encoder and switch &lt;strong&gt;&lt;em&gt;without&lt;/em&gt;&lt;/strong&gt; starting a worker thread.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import gaugette.rotary_encoder
import gaugette.switch

A_PIN  = 7
B_PIN  = 9
SW_PIN = 8

encoder = gaugette.rotary_encoder.RotaryEncoder(A_PIN, B_PIN)
switch = gaugette.switch.Switch(SW_PIN)
last_state = None

while True:
    delta = encoder.get_delta()
    if delta!=0:
        print &amp;quot;rotate %d&amp;quot; % delta

    sw_state = switch.get_state()
    if sw_state != last_state:
        print &amp;quot;switch %d&amp;quot; % sw_state
        last_state = sw_state
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Spin the knob and you should see something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo python rotary_worker_test.py
switch 0
rotate 1
rotate 1
rotate -1
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Using the class as shown above, you must call &lt;code&gt;encoder.get_delta()&lt;/code&gt; frequently enough
to catch all transitions.  A single missed step is handled okay, but 2 missed steps will
be misinterpreted as a single step in the wrong direction, so if you turn the knob too quickly
you might see some jitter.&lt;/p&gt;

&lt;p&gt;To ensure the inputs are polled quickly enough, even if your application&amp;rsquo;s main thread
is busy doing heavy lifting, you can use the worker thread class
class to monitor the switch positions.  Using the worker class is trivial;
instantiate &lt;code&gt;RotaryEncoder.Worker&lt;/code&gt; instead of &lt;code&gt;RotaryEncoder&lt;/code&gt; with the same
parameters, and call the &lt;code&gt;start()&lt;/code&gt; method to begin polling - only lines 8 and 9 below have changed.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import gaugette.rotary_encoder
import gaugette.switch

A_PIN  = 7
B_PIN  = 9
SW_PIN = 8

encoder = gaugette.rotary_encoder.RotaryEncoder.Worker(A_PIN, B_PIN)
encoder.start()
switch = gaugette.switch.Switch(SW_PIN)
last_state = None

while 1:
    delta = encoder.get_delta()
    if delta!=0:
        print &amp;quot;rotate %d&amp;quot; % delta

    sw_state = switch.get_state()
    if sw_state != last_state:
        print &amp;quot;switch %d&amp;quot; % sw_state
        last_state = sw_state
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here&amp;rsquo;s a video showing the rotary encoder at work.  In this case
I use the main thread to service the OLED scrolling, with the worker thread
keeping an eye on the rotary encoder.  There is another worker thread that
manages the RGB led transitions.&lt;/p&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/AWssNKI06oE&#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>
    
    <item>
      <title>Alternative Raspberry Pi SSD1306 Library</title>
      <link>//guy.carpenter.id.au/gaugette/2012/12/21/alternative-raspberry-pi-ssd1306-library/</link>
      <pubDate>Fri, 21 Dec 2012 17:09:00 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/2012/12/21/alternative-raspberry-pi-ssd1306-library/</guid>
      <description>&lt;p&gt;The SSD1306 code in the &lt;a href=&#34;https://github.com/guyc/py-gaugette&#34; target=&#34;_blank&#34;&gt;py-gaugette library&lt;/a&gt; has been
modified at &lt;a href=&#34;https://github.com/andig/AdaPi&#34; target=&#34;_blank&#34;&gt;andig/AdaPi&lt;/a&gt; with several
extensions including I&amp;sup2;C support, and the addition of geometric drawing functions from
&lt;a href=&#34;https://github.com/adafruit/Adafruit-GFX-Library&#34; target=&#34;_blank&#34;&gt;Adafruit&amp;rsquo;s GFX Library&lt;/a&gt;.
If you need to drive the I&amp;sup2;C version of this display from a RPi,
this is the place to start.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Better Fonts for the SSD1306</title>
      <link>//guy.carpenter.id.au/gaugette/2012/11/11/font-support-for-ssd1306/</link>
      <pubDate>Sun, 11 Nov 2012 16:42:00 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/2012/11/11/font-support-for-ssd1306/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2012-11-08/ssd1306.jpg&#34;  class=&#34;right&#34;   /&gt;

The first release of the SSD1306 support library &lt;a href=&#34;https://github.com/guyc/py-gaugette&#34; target=&#34;_blank&#34;&gt;py-gaugette&lt;/a&gt;
used the 5x7 pixel fonts from the
&lt;a href=&#34;https://github.com/adafruit/Adafruit-GFX-Library/blob/master/glcdfont.c&#34; target=&#34;_blank&#34;&gt;Adafruit GFX library&lt;/a&gt;.
That&amp;rsquo;s a fine and compact font, but wouldn&amp;rsquo;t it be nice to have some pretty high-res fonts
to take advantage of the memory and resolution we have to work with?&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h2 id=&#34;generating-font-bitmaps&#34;&gt;Generating Font Bitmaps&lt;/h2&gt;

&lt;p&gt;&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2012-11-11/tahoma_16.jpg&#34;  class=&#34;right&#34;   /&gt;

I started with &lt;a href=&#34;http://www.pavius.net/2009/07/the-dot-factory-an-lcd-font-and-image-generator/&#34; target=&#34;_blank&#34;&gt;The Dot Factory&lt;/a&gt; by Eran Duchan.  Its a handy C# (Windows) tool for generating C and C++ bitmap files quickly, and &lt;a href=&#34;https://github.com/pavius/The-Dot-Factory&#34; target=&#34;_blank&#34;&gt;source code is available&lt;/a&gt;.  I modified it to generate Python code, and to add a kerning table to store the minimum number of pixels the cursor must move between any two characters to avoid collison.&lt;/p&gt;

&lt;p&gt;The kerning isn&amp;rsquo;t completely right yet  - I noticed that the underscore character can slip beheath other characters.  I&amp;rsquo;ll need to look at that some more in due time - and I&amp;rsquo;d also like to replace the C# app for a command-line tool to generate the rasterized image files.&lt;/p&gt;

&lt;p&gt;Each font is stored in a module like the following.  The size suffix (16 in this case) indicates the character height in pixels.
The descriptor table specifies the width of each character and the character&amp;rsquo;s offset in the bitmap.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Module gaugette.fonts.arial_16
# generated from Arial 12pt                                                                                                         

name        = &amp;quot;Arial 16&amp;quot;
start_char  = &#39;#&#39;
end_char    = &#39;~&#39;
char_height = 16
space_width = 8
gap_width   = 2

bitmaps = (
    # @0 &#39;!&#39; (1 pixels wide)
    0x00, #  
    0x80, # O
    0x80, # O
    0x80, # O
    0x80, # O
    0x80, # O
    0x80, # O
    0x80, # O
    0x80, # O
    0x80, # O
    0x80, # O
    0x00, #  
    0x80, # O
    0x00, #  
    0x00, #  
    0x00, #  

    # @16 &#39;&amp;quot;&#39; (4 pixels wide)
    0x00, #     
    0x90, # O  O
    0x90, # O  O
    0x90, # O  O
    0x90, # O  O
    0x00, #     
    0x00, #     
    0x00, #     
    0x00, #     
    0x00, #     
    0x00, #     
    0x00, #     
    0x00, #     
    0x00, #     
    0x00, #     
    0x00, #     

    # @32 &#39;#&#39; (9 pixels wide)
    0x00, 0x00, #          
    0x11, 0x00, #    O   O
    0x11, 0x00, #    O   O
    0x11, 0x00, #    O   O
    0x22, 0x00, #   O   O  
    0xFF, 0x80, # OOOOOOOOO
    0x22, 0x00, #   O   O  
    0x22, 0x00, #   O   O  
    0x22, 0x00, #   O   O  
    0xFF, 0x80, # OOOOOOOOO
    0x44, 0x00, #  O   O   
    0x44, 0x00, #  O   O   
    0x44, 0x00, #  O   O   
    0x00, 0x00, #          
    0x00, 0x00, #          
    0x00, 0x00, #          
...
)

# (width, byte offset)
descriptors = (
    (1,0),# !
    (4,16),# &amp;quot;
    (9,32),# #
...
)

# kerning[c1][c2] yeilds minimum number of pixels to advance
# after drawing #c1 before drawing #c2 so that the characters
# do not collide.
kerning = (
    (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,),
...
)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note the font is a module, not a class, because it allows a very concise syntax:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;from gaugette.fonts import arial_16
textSize = led.draw_text3(0,0,&amp;quot;Hello World&amp;quot;,arial_16)
&lt;/code&gt;&lt;/pre&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2012-11-11/old_english_text.jpg&#34;  class=&#34;right&#34;   /&gt;


&lt;h2 id=&#34;supporting-horizontal-scrolling&#34;&gt;Supporting Horizontal Scrolling&lt;/h2&gt;

&lt;p&gt;In the process of testing these fonts, I realized I would like to be able to scroll horizontally,
and the SSD1306 doesn&amp;rsquo;t have hardware support for that.  Vertical scrolling is accomplished using
the &lt;code&gt;SET_START_LINE&lt;/code&gt; command, but the horizontal scrolling commands do not support scrolling
through an image that is wider than the display.  We need to do it in software.&lt;/p&gt;

&lt;p&gt;It turns out that blitting memory from the Pi to the SSD1306 over SPI is pretty fast; fast enough
to get a reasonable horizontal scroll effect by blitting complete frames from the Pi&amp;rsquo;s
memory to the SSD1306.  There&amp;rsquo;s just one thing - the default memory mode of the
SSD1306 is &lt;a href=&#34;http://en.wikipedia.org/wiki/Row-major_order&#34; target=&#34;_blank&#34;&gt;row-major&lt;/a&gt;, and
for horizontal scrolling we really want to send a &lt;strong&gt;vertical slice&lt;/strong&gt; of the memory buffer
over SPI.  To avoid buffer manipulation I switched the Pi-side memory buffer to use
&lt;a href=&#34;http://en.wikipedia.org/wiki/Column-major_order#Column-major_order&#34; target=&#34;_blank&#34;&gt;column-major order&lt;/a&gt;,
and use &lt;code&gt;MEMORY_MODE_VERT&lt;/code&gt; on the SSD1306 when blitting.&lt;/p&gt;

&lt;p&gt;To illustrate: the memory buffer is stored as a python list of bytes.  Consider a virtual
buffer that is 256 columns wide and 64 rows high.  Using column-major layout
we can address the 128 columns starting at column 100 using the python
list addressing &lt;code&gt;buffer[100*64/8:128*64/8]&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;buffer = [0] * 256 * 64 / 8                              # buffer for 256 columns, 64 rows, 8 pixels stored per byte
start = 100 * 64 / 8                                     # byte offset to 100th column
length = 128 * 64 / 8                                    # byte count of 128 columns x 64 rows
led.command(led.SET_MEMORY_MODE, led.MEMORY_MODE_VERT)   # use vertical addressing mode
led.data(buffer[start:start+length])                     # send a vertical slice of the virtual buffer
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that using column-major layout we cannot easily blit a &lt;strong&gt;horizontal&lt;/strong&gt;
slice of the virtual memory buffer into display ram, so we can&amp;rsquo;t use the same method for
vertical scrolling.  Stick with &lt;code&gt;SET_START_LINE&lt;/code&gt; for vertical scrolling.  The combination
of these methods gives us fast horizontal and vertical scrolling.&lt;/p&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/fSCDr8A_ItU&#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;


&lt;p&gt;An updated &lt;a href=&#34;https://github.com/guyc/py-gaugette&#34; target=&#34;_blank&#34;&gt;library&lt;/a&gt; with &lt;a href=&#34;https://github.com/guyc/py-gaugette/blob/master/samples/font_test.py&#34; target=&#34;_blank&#34;&gt;sample code&lt;/a&gt; is available on github.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Controlling an Adafruit SPI OLED with a Raspberry Pi</title>
      <link>//guy.carpenter.id.au/gaugette/2012/11/08/controlling-an-adafruit-spi-oled-with-a-raspberry-pi/</link>
      <pubDate>Thu, 08 Nov 2012 10:31:00 +1000</pubDate>
      
      <guid>//guy.carpenter.id.au/gaugette/2012/11/08/controlling-an-adafruit-spi-oled-with-a-raspberry-pi/</guid>
      <description>&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2012-11-08/ssd1306.jpg&#34;  class=&#34;right&#34;   /&gt;


&lt;p&gt;Adafruit&amp;rsquo;s lovely little &lt;a href=&#34;http://www.adafruit.com/products/661&#34; target=&#34;_blank&#34;&gt;128x32 monochrome SPI OLED module&lt;/a&gt;
uses a SSD1306 driver chip (&lt;a href=&#34;http://www.adafruit.com/datasheets/SSD1306.pdf&#34; target=&#34;_blank&#34;&gt;datasheet&lt;/a&gt;),
and Adafruit have published &lt;a href=&#34;http://learn.adafruit.com/monochrome-oled-breakouts&#34; target=&#34;_blank&#34;&gt;excellent tutorials&lt;/a&gt; and
&lt;a href=&#34;https://github.com/adafruit/Adafruit_SSD1306&#34; target=&#34;_blank&#34;&gt;libraries&lt;/a&gt; for driving this from an Arduino.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;When &lt;a href=&#34;http://adafruit.com/forums/viewtopic.php?f=47&amp;amp;t=33040&#34; target=&#34;_blank&#34;&gt;asked in their forum&lt;/a&gt;
about Raspberry Pi support, Adafruit have said
that &lt;em&gt;there is a huge backlog of libraries to port to the RasPi and (they) don&amp;rsquo;t have any ETA on the SSD1306&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;m working on a project that was originally intended for an Arduino, but I&amp;rsquo;ve decided to
switch to the Raspberry Pi, so I need to get this display working with the Pi.
To that end, I&amp;rsquo;ve partially ported Adafruit&amp;rsquo;s SSD1306 library to Python for the Raspberry Pi.  The port is partial
in that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;it only supports the 128x32 SPI module (unlike the original that supports the I&amp;sup2;C and 128x64 modules) and&lt;/li&gt;
&lt;li&gt;it only supports pixel and text drawing functions (no geometric drawing functions).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&#34;signal-levels&#34;&gt;Signal Levels&lt;/h2&gt;

&lt;p&gt;The SSD1306 operates at 3.3V, and the Adafruit module has built-in level-shifters for 5V operation.
However I want to drive it at 3.3V from the Pi, and I wasn&amp;rsquo;t confident from the documentation that
it would operate at 3.3V without modification.  However the back-side silkscreen says very clearly 3.3 - 5V
and I can confirm it works very happily with both Vin and signalling at 3.3V.&lt;/p&gt;

&lt;h2 id=&#34;spi-signals&#34;&gt;SPI Signals&lt;/h2&gt;

&lt;p&gt;In &lt;a href=&#34;http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus&#34; target=&#34;_blank&#34;&gt;SPI nomenclature&lt;/a&gt;
MISO is &lt;em&gt;master in, slave out&lt;/em&gt;, MOSI is &lt;em&gt;master out, slave in&lt;/em&gt;.
The SSD1306 module is &lt;em&gt;write-only&lt;/em&gt; using SPI, and so there is no MISO connection available,
and &lt;strong&gt;MOSI is labelled DATA on the module&lt;/strong&gt;.
Of course SPI always reads while it writes, but it is fine to leave MISO disconnected.  It will
be pulled low, so if you ever looked at the data you would see all zeros.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;D/C&lt;/strong&gt; (Data/Command) signal on the module is not part of the SPI specification, and it took a little
experimenting to understand exactly what it is used for.  The data sheet says
&lt;em&gt;&amp;ldquo;When it is pulled HIGH (i.e. connect to VDD), the data
at D[7:0] is treated as data. When it is pulled LOW, the data at D[7:0] will be transferred
to the command register.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Initially I supposed &lt;em&gt;data&lt;/em&gt; to include the
argument bytes that follow the opcode when sending multi-byte commands.  For example the &amp;ldquo;Set Contrast Control&amp;rdquo;
command consists of a one-byte opcode (0x81) followed by a one-byte contrast value, so I was sending
the first byte with D/C high, and pulling it low for the argument byte.  Wrongo!  That&amp;rsquo;s not what they
mean by &lt;em&gt;data&lt;/em&gt;; &lt;strong&gt;keep the D/C line high for all bytes in a command, and pull it low
when blitting image data into the image memory buffer&lt;/strong&gt;.  Simple as that.&lt;/p&gt;

&lt;h2 id=&#34;platform&#34;&gt;Platform&lt;/h2&gt;

&lt;p&gt;I&amp;rsquo;m running Python 2.7.3 on a Rasberry Pi Model B (v1) with the following software:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://learn.adafruit.com/adafruit-raspberry-pi-educational-linux-distro/occidentalis-v0-dot-2&#34; target=&#34;_blank&#34;&gt;Occidentalis 0.2&lt;/a&gt; boot image,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/WiringPi/WiringPi-Python&#34; target=&#34;_blank&#34;&gt;WiringPi-Python&lt;/a&gt; for python access to the GPIO pins,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/doceme/py-spidev&#34; target=&#34;_blank&#34;&gt;py-spidev&lt;/a&gt; for python bindings to the spidev linux kernel driver.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Here&amp;rsquo;s how I&amp;rsquo;ve wired it up.  You can freely change the GPIOs for D/C and Reset.
&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2012-11-08/raspberrypi_and_ssd1306.jpg&#34;   /&gt;
&lt;/p&gt;

&lt;h2 id=&#34;test-code&#34;&gt;Test Code&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Note that pin numbers passed in the constructor are
the &lt;a href=&#34;https://projects.drogon.net/raspberry-pi/wiringpi/pins/&#34; target=&#34;_blank&#34;&gt;wiring pin numbers&lt;/a&gt;,
not the connector pin numbers!&lt;/strong&gt;
For example I have Reset wired to connector pin 8, which is &lt;em&gt;BCP gpio 14&lt;/em&gt;, but &lt;em&gt;wiringPi pin 15&lt;/em&gt;.
It&amp;rsquo;s confusing, but just refer to the &lt;a href=&#34;https://projects.drogon.net/raspberry-pi/wiringpi/pins/&#34; target=&#34;_blank&#34;&gt;wiringPi GPIO table&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The python library for the SSD1306 has been rolled into the
&lt;a href=&#34;https://github.com/guyc/py-gaugette&#34; target=&#34;_blank&#34;&gt;py-gaugette library&lt;/a&gt; available on github.&lt;/p&gt;

&lt;p&gt;The test code below vertically scrolls vertically between two display buffers, one
showing the current time, one showing the current date.&lt;/p&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/U2uF2-zGiAM&#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;


&lt;p&gt;This sample code is &lt;a href=&#34;https://github.com/guyc/py-gaugette/blob/master/samples/ssd1306_test.py&#34; target=&#34;_blank&#34;&gt;included in the py-gaugette library&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import gaugette.ssd1306
import time
import sys

RESET_PIN = 15
DC_PIN    = 16

led = gaugette.ssd1306.SSD1306(reset_pin=RESET_PIN, dc_pin=DC_PIN )
led.begin()
led.clear_display()

offset = 0 # buffer row currently displayed at the top of the display

while True:

    # Write the time and date onto the display on every other cycle
    if offset == 0:
        text = time.strftime(&amp;quot;%A&amp;quot;)
        led.draw_text2(0,0,text,2)
        text = time.strftime(&amp;quot;%e %b %Y&amp;quot;)
        led.draw_text2(0,16,text,2)
        text = time.strftime(&amp;quot;%X&amp;quot;)
        led.draw_text2(8,32+4,text,3)
        led.display()
        time.sleep(0.2)
    else:
        time.sleep(0.5)

    # vertically scroll to switch between buffers
    for i in range(0,32):
        offset = (offset + 1) % 64
        led.command(led.SET_START_LINE | offset)
        time.sleep(0.01)
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;about-fonts&#34;&gt;About Fonts&lt;/h2&gt;

&lt;img src=&#34;//guy.carpenter.id.au/gaugette/resources/2012-11-08/steve-jobs-does-not-approve.jpg&#34;  class=&#34;right&#34;   /&gt;


&lt;p&gt;This test code uses the 5x7 bitmap font from the
&lt;a href=&#34;https://github.com/adafruit/Adafruit-GFX-Library/blob/master/glcdfont.c&#34; target=&#34;_blank&#34;&gt;Adafruit GFX library&lt;/a&gt;
scaled to x2 and x3. It works, but &lt;strong&gt;Steve Jobs would
not approve!&lt;/strong&gt;  It isn&amp;rsquo;t taking advantage of the very high resolution of these
lovely little displays.  Larger fonts with kerning would be a great addition.&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>