Hacking an Arduino Library to support a NewHaven OLED with an MCP23008 port expander


After looking at several sample Buffalo DAC projects I decided that I didn’t like the LCD screens most people were using. I had a Sansa Clip a few years back that used a very crisp OLED display – a quick search on Mouser and I found an inexpensive 20×4 NewHaven OLED (NHD-0420DZW-AY5-ND) that looked like it was  HD44780 compatible.  

It isn’t.

After reading a bunch of forum posts complaining about this display, I stumbled across someone who had tweaked the standard Arduino LiquidCrystal library to make it compatible with the OLED timing parameters: http://www.elcojacobs.com/controlling-an-oled-character-display-with-arduino/.  I swapped his library for LiquidCrystal and – huzzah! – my DAC was humming along with a beautiful OLED display.

The next step was to minimize the number of pins I was using on my Arduino using an I/O port expander.  By using the two i2c pins (A4 and A5) on the Arduino, a port expander gives you 8 outputs.  The downside is that the port expander makes things considerably slower – too slow to be usable.  So I was excited to find the LiquidTWI library as it promised to speed things up by “bursting” all 8 pins at once, rather than trying to address each pin serially: http://blog.lincomatic.com/?p=956.

And it worked!  Sort of.  I had to tweak the timing parameters again, but Elco had already shown me how to do that.

Everything worked perfectly except for custom characters – which is something the HiFiDuino code uses to display the volume.  You might be able to print one or two custom characters, but the display would ultimately go into WTF mode and you’d have to restart it.

I tried a very long “delay()” when custom characters were being written, but regardless of how long I waited, nothing helped.  As far as I could tell, the problem has something to do with the D7 pin on OLED display, which serves both as an input to the OLED and an output that indicates when the DAC is busy.  According to the datasheet, you are supposed to poll the busy pin and only write a command when the busy pin tells you the OLED has finished processing.

So, by hacking the Adafruit MCP23008 library, I was able to implement a function that reads the busy pin.  We only need to use this function when we are writing/creating custom characters, so it really doesn’t slow things down too much.  And the library takes care of invoking the function when necessary, so it’s invisible to anyone using the library.


The volume display is tied to the movement of the rotary encoder, which uses an interrupt to indicate when it is being turned.  It seems the delay that the readBusy() function creates wreaks some havoc with the rotary encoder functionality, so a quick spin of the encoder doesn’t register.  So after all that, I’ve reverted back to directly connecting the OLED to the Arduino.

But maybe somebody else can benefit from the library I wrote.  If so, grab the code here: https://github.com/tharmas/LiquidJWM


One thought on “Hacking an Arduino Library to support a NewHaven OLED with an MCP23008 port expander

  1. Hello,

    I actually wanted to do this too, but I was using the Newhaven NHD-3.12-25664UCY2 OLED with the u8glib library (https://code.google.com/p/u8glib/). We actually got this working very nicely, but my project has stalled because the friends helping me are no longer free to help me code. Maybe you could benefit from our code?

    I agree with you that the Hifiduino’s interface is quite ugly… also you don’t need info like “Quantizer” on the front screen always… we were implementing a menu system to hide all of that stuff in the background.

    I would be very interested to speak with you about this project! If you want, email me. justin at takaji [dot] ca.

    And good work!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s