More Digole OLED with Python and UART on Raspberry Pi

Although I would prefer to use SPI with the Raspberry Pi and the Digole displays and keep the UART available for console access to the Pi, I have a version of the subclass of the python serial class that provides commands similar to the arduino/u8glib libraries that Digole provides links to on their site.

Please make use of it if you wish:
* Updated May 6, 2015 – updated drawBox, drawFrame, drawHLine, drawVLine. Added drawBitmap256.

Remember, to use the UART for this purpose the console functionality needs to be disabled first.

The following sample code demonstrates use of this subclass of the serial class…


import sys
import time
from datetime import datetime
import digole_serial

def main():
    # setup oled display on serial port
    oled = digole_serial.doSerial("/dev/ttyAMA0", 9600)
    #oled.port = "/dev/ttyAMA0"
    #oled.baudrate = 9600
    oled.timeout = 1
    oled.drawStr( 0, 1, "Test TEXT" )
    print("log h/t end " +'%Y-%m-%d %H:%M'))

# This is the standard boilerplate that calls the main() function.
if __name__ == '__main__':

Digole OLED + Raspberry Pi + SPI + Python

The Digole OLED displays are reasonably priced, low power consumption displays with an on-board pic micro-controller and serial/i2c/SPI communication. They come configured for serial communication but can be changed to i2c or SPI with a soldered jumper.

Although the Raspberry Pi has a UART that could be used for Digole displays it is often desirable to keep it as a console for access to your Pi. The Serial Peripheral Interface (SPI) ports on the older Raspberry Pi’s allow for two SPI devices (the A+, B+ and Pi 2 have an extra SPI port) and can be the fastest way to communicate with the Digole displays. Here is how I connected my Digole OLED display for SPI communication:

RPI                            ->  DIGOLE OLED
5v (Pin 2 or 4) or 3.3v (Pin 1)  ->  VCC
MOSI BCM10 (Pin 19)              ->  DATA
SCLK BCM11 (Pin 23)              ->  CLK
CE0 BCM8 (Pin 24)                ->  SS
Ground (Pin 6)                   ->  GND

Master Out Slave In (MOSI) connects to the data line on the Digole display. Communication takes place in one direction. To connect a second Digole SPI configured display you would connect its SS pin to CE1 BCM7 (Pin 26) on the Rasperry Pi. The rest of the pins are shared with the other SPI device. When the CE0 or CE1 pin the SS pin is connected to is LOW it becomes the active device. I use the 5v power connection since it has a bit more current available than the 3.3v power pin.

Unfortunately, I had to read many resources before SPI began to make sense when I started using it in the beginning. The help on is a good one stop place as a reference but it doesn’t explain it for the beginner. Here are a few things I learned:

1) Make sure to download the latest version of the spidev python wrapper ( There are useful older posts out there that have links to older versions of py-spidev.

2) Make sure you do the loop back test of SPI on the Raspberry Pi. Once you are sure it is working then you can ferret out problems with how the attached device is connected.

3) When testing I set the communication speed at 500Khz. From what I have read the Pi can communicate at 8Mhz max. I think I will try it at 4Mhz. For uploading fonts I have had better luck at 1Mhz or less.

4) I found Brian Hensley’s post: “Getting SPI working on the Raspberry Pi” helpful. The spidev documentation at SpiDev_Doc.pdf while older and often no longer correct it did help me figure out more of the possible commands and settings.

5) I found it useful to try out SPI on the arduino with the Digole OLED and the arduino library on Digole’s web site first.

6) Digole’s programming manual is quite useful as well.

7) There was a great discussion about the Digole displays over at the Sparkfun forums.

I have created a subclass of the spidev library ( that allows python code similar to the U8Glib and Digole’s arduino library.
* Updated May 6, 2015, corrected some of the graphics commands.

Here is an example of a Digole OLED display using the above mentioned subclass ( of the py-spidev wrapper:


import digole_spi
import time
from datetime import datetime

def main():

    oled = digole_spi.doSpiDev()
    # open SPI 0, device 0 (if second device -, 1)), 0)
    oled.max_speed_hz = 500000
    oled.lsbfirst = False
    oled.bits_per_word = 8
    oled.mode = 1
    # Turn off start screen
    # Turn on display of interface configuration
    print("Prg End " +'%Y-%m-%d %H:%M'))

# This is the standard boilerplate that calls the main() function.
if __name__ == '__main__':

Controlling Digole Oled Display on Raspberry Pi with Python

I have found some low cost, graphic oled displays for the Raspberry Pi and my other microcontroller projects from a company called Digole. So far, I have tried out their 1.8″ colour 160×128 OLED, 1.3″ white 128×64 OLED, 0.96″ white 128×64 OLED and their character LCD controller intended for 16×2, 20×4 and other LCD modules.

Digole 1.8" 160x128 colour OLED display
Digole 1.8″ 160×128 colour OLED display
They come configured for 9600 baud serial by default but you can solder a jumper for I2C or SPI operation. The OLED’s work at 3.3v or 5v and draw little current. The LCD controller operates from 1.8v to 5.5v but that is usually dependant upon the voltage requirements of the LCD module which usually run at 5v. The OLED’s include a PIC18F26K20 based microcontroller and they have made some effort to standardize the commands across devices. There is an Arduino library on their web site and some example C code for the Raspberry Pi. There is also some more example code in C in a thread on the forum. There is also a downloadable .pdf file on the Digole site which describes the commands but no python.

The uart on the Raspberry Pi on gpio pins 14 & 15 is configured to act as a console. Some reconfiguration is required to make use of it. You may want to use i2c or SPI instead. Here is a little example in python configured to use the txd (gpio pin 14) on the Raspberry Pi:


import serial

def main():
    # setup oled display on serial (txd pin 14) at 9600 baud
    port = serial.Serial("/dev/ttyAMA0", baudrate=9600, timeout=1.0)
    port.write("SOO"+chr(1)+"SOO"+chr(1)) # turn the oled screen on (if off)
    port.write("CLCL") #clear screen, sets font to 0 (default) and cursor off at position 0,0
    # port.write("CS\x01") #cursor on, (\x01) hex value can be inserted in the text
    # the inline hex value (\0x01) will be converted to a character
    port.write("CS" + chr(0)) #cursor off, but chr(byte value) is perhaps clearer
    port.write("SC" + chr(1)) # set color to 1 (white)
    # text strings preceeded with the TT command and are terminated with 0x00 or 0x0D
    # they will wrap to the next line if long enough
    # port.write("TTexample text" + "\x00") # another hex value example in text
    # port.write("TTexample text" + "\o00") # octal value could be inserted in text
    port.write("TTdefault font 0" + chr(0)) # decimal byte value converted to a character
    port.write("SF"+chr(6)) #set font 6
    port.write("TRT") #text return, y value determined by current font size
    exampleMessage = "next line font 6"
    port.write("TT" + exampleMessage + chr(0))
    port.write("SF"+chr(10)) #set font 10
    port.write("TRT") #text return, y value determined by current font size
    exampleMessage = "next line font 10"
    port.write("TT" + exampleMessage + chr(0))

# This is the standard boilerplate that calls the main() function.
if __name__ == '__main__':

It took me a bit of time to sort out how to communicate with the displays using python. Commands are sent as text and then the parameters are often sent as bytes converted to characters. I found I needed to send the clear screen command twice and that the text command(TT) had to be terminated with a 0x00 or 0x0D (chr(0) or chr(13)). The onboard microcontroller does a pretty good job with the graphic commands. They are working well and I am happy with them.

A few odd things I noticed were that the english on the label on the 0.96″ and 1.3″ white OLED’s said they were blue so I quickly soldered headers on them to test them and was relieved to find they were actually white. I also found there was a fair amount of what appeared to be flux on the controllers which I cleaned off carefully with rubbing alcohol (trying very hard to avoid the actual screens). The colour OLED controller and character LCD controller didn’t have this problem.

I look forward to using these with various microcontrollers including the Arduino, MSP430, Stellaris & Tiva, the Raspberry Pi and the BeagleBone Black but I suspect I could use them with almost any microcontroller. I notice the vendor has been updating the libraries and documentation on the site. They have also added a new 0.96″ colour OLED. Happy Pi Day.

Digole Displays
Digole 1.3″ and 0.96″ white OLED and character LCD controller attached to 16×2 LCD.

Aard Dictionary on Fedora 18

I have been using Aard Dictionary to search though offline copies of Wikipedia and Wiktionary. It is available for Ubuntu, Windows, Mac and Android. Aard Dictionary doesn’t seem to be in the Fedora 18 repositories or available as an rpm file but it is a python program and it does run. The important thing to do is install the appropriate dependencies:

sudo yum install pyicu python-simplejson dvipng mediawiki-math libevent libicu PyQt4

I downloaded the source file from the Aard Dictionary site and extracted the files to a folder in my home directory and start the program by executing the “” file.

Windows Default from Grub

Modifying GRUB for Windows Default BootNormally, GRUB 2 uses the first entry on the boot menu to start by default. This is fine since most of the time Ubuntu adds the latest version of the kernel to the top of the list. This choice is controlled in the configuration file /etc/default/grub using the “GRUB DEFAULT” line which normally has the value “0”. “0” is an index number for the first item in the boot menu.

If Windows is on the machine then it would quite often be “5” but after a period of time as the kernel updates the list of entries in the GRUB2 boot menu grows. The entry for Windows will no longer be “5”.

It is possible to have GRUB automatically boot Windows by specifying the text line instead of the numeric index.

sudo gedit /etc/default/grub

I changed the “GRUB_DEFAULT” line to:

GRUB_DEFAULT="Windows 7 (loader) (on /dev/sda2)"

In my case I changed GRUB_DEFAULT to reflect the partition arrangement on my Acer netbook. The Windows partition is on the second partition on /dev/sda. I copied the line which refers to Windows exactly as it appears in /boot/grub/grub.cfg. There is a large amount of stuff in that file but the Windows line should appear after the “### BEGIN /etc/grub.d/30_os-prober ###” section but before “### END /etc/grub.d/30_os-prober ###”.

In my case it was:

menuentry "Windows 7 (loader) (on /dev/sda2)"

After making the change in /etc/default/grub you would need to save it and then update the GRUB configuration by executing the following:

sudo update-grub

As a self respecting Ubuntu user you may wonder why anyone would want to do this. In my case I have a new netbook with a chipset not fully supported yet. I have also set things up this way for Windows users who have allowed me to install Ubuntu for them to try out and use as a backup operating system.

Use Infocast Offline

Best Buy's Chumby Like DeviceNormally, the Insignia Infocast 3.5″ downloads its content including the main control panel from the Chumby server on the Internet. When everything is working fine that is the desirable way to use it. If you want to listen to the fm radio or some music on a flash drive and there is no internet connection then you would normally be out of luck. Fortunately, there is a way to use it offline. Thanks to the efforts of Christian from Austria you can download his little package to a flash drive, reboot the Infocast with it plugged in and you will be able to use it offline. Other Infocast users reported they had to copy the contents of the psp directory on the Infocast to the psp directory on the flash drive without replacing any of the existing files. I too followed this advice and it worked like a charm.

On an unregistered Infocast I had it working but each time I started it up it would ask to setup the wireless network. After registering it it worked fine. I can even connect to the Internet and use it independently from the Chumby servers. I can run local flash lite applets, use the fm radio, play music files on the flash drive, or stream from Internet radio stations. It appears to mirror the configuration panel for it to download from a web server on localhost.

See the thread here on the Chumby forum:

*** UPDATE 120315 – Another thread in the chumby forums here: (thanks for the heads-up none).

*** UPDATE 120420 – If the Chumby Servers were to disappear Zurk’s Offline Chumby files are hosted here:

A Kindle for $25 less? you buy a Kindle reader if it included advertisements and was $25 less? Amazon is offering a version of the already low priced, $139 WiFi Kindle for $114. The “Kindle with Special Offers” version replaces the screen saver featuring famous authors and the bottom of the home screen with Amazon related advertisements. They do not display while reading a book.

The Amazon Kindle 3 is an e-book reader that features an 6″ E Ink Pearl screen, extremely efficient power management, 4GB memory and WiFi connectivity. The E Ink Pearl screen comes closest to paper of any screen I have seen and only uses power when changing pages. This is the biggest reason it has a rechargeable battery that lasts up to a month of “normal” use between charges (if Wifi is off). It is also argued that this type of screen results in less eyestrain compared to backlit devices like an Apple or Android tablet. The 8.5 oz device is also lighter than the average tablet making it easier to hold for long periods of time.

The Kindle is also another example of a Linux powered device. The power sipping, Freescale 532 MHz, ARM-11 processor runs the Linux 2.6.26 kernel. Increasingly, Linux users don’t really know they are using Linux. As programmable, networked, electronic devices escape the confines of the desktop and become ubiquitous will most people care? The Kindle is an excellent example of the benefits and strengths of a well designed, special purpose device (created by the Amazon subsidiary Lab126).

So is $25 your price? How about $40? There has been a great deal of discussion out there that $99 is the magic number. They had me at $139.

(E-book reader users should check out calibre to manage their e-books.)

Use Wikipedia Offline

Wikipedia, the free encyclopedia is huge. The English version alone is currently at almost 3.6 million articles. One of the advantages of it being online is that no matter how big it is you can view the newest version of only the parts you are interested in without having to download the whole thing. But what if you did want to download it and use it offline?

You could download a copy of Wikipedia Static. It is composed of static HTML pages so it is quite big (~17GB compressed). It is also getting old, it was last generated in June of 2008. You could also setup a mirror of Wikipedia.

Fortunately, there are a few other options for offline viewing of Wikipedia content. The following are a few of my favourites:

Images, Tables and Text but only ~45,000 articles from Dec 2010, 3.7GB, GPL3, OSX, Windows, Linux.

Kiwix is client software for Linux, OSX, or Windows that uses an open data format for mediawiki developed by the openZIM project. The software includes a server mode for sharing on an intranet. The 3.7GB, Dec 2010 snapshot of Wikipedia consists of about 45,000 articles considered to be core articles tagged as part of the Wikipedia 1.0 Project. There are other zim format files available in other language versions of Wikipedia and also Wikipedia:Books. It is a newer project and format so additional zim formatted documents will likely become available as support and awareness grows.

Aard Dictionary
Text, Math and Tables, no Images, Mar. 12, 2010, 7.2GB, GPL3, OSX, Windows, Linux, Android, Nokia Maemo 5.

Aard Dictionary is a multi-platform word lookup program that supports large dictionaries and Wikipedia. The 7.2GB Wikipedia snapshot from March 12, 2010 contains more articles than Kiwix it does not support audio, video and images (except for images rendering math). It also doesn’t support all of the navigation features of Wikipedia. It is quite fast, however, and also supports a variety of other reference material such as Wikitionary, WikiQuote, Wikispecies, WordNet, The Collaborative International Dictionary of English, The Jargon File and other language versions of Wikipedia.

Text only, no Images, Tables or Math, Jan. 15, 2011, 4.3GB, GPL3.

The WikiReader is a handheld device and open software that allows you to take Wikipedia with you. This device supports text only and searches are limited to article titles. You can download free quarterly snapshots of Wikipedia to a microSD flash memory card that plugs into the device or pay for a subscription shipped on memory cards. Other language versions of Wikipedia, Wikitionary, WikiQuote, and Project Gutenberg and WikiTravel are also available. The WikiReader I purchased included a 4GB microSD card which is big enough for the Summer 2010 snapshot of English Wikipedia but the newer snapshots will require purchasing a larger microSD card. The 2 AAA batteries that power this device are expected to last about 90 hours so this little device is very careful with power consumption.

These are three solid options for carrying around a pretty good sized encyclopedia without all the bulk. The first two are free so I would recommend using both of them. Perfect for the laptop or netbook. The third is small, very reasonably priced, very power efficient and ready for travel.

* Edited April 13, 2013 – Updated url for Wikipedia Static and other Wikipedia dumps.

Yet Another Wifi Radio

I find MightyOhm’s WiFi radio project really inspirational. It uses an Asus WL-520gu router, Arduino and a usb audio adapter to create a very low power consumption WiFi radio. It also makes use of small, yet powerful, open source software packaged by the OpenWrt distribution. It also introduced me to the awesome power and flexibility of Music Player Daemon (MPD). It’s a great project that even covers putting it all in a nice display case.

I also like listening to music while I fall asleep so last summer I decided to try making my own WiFi Radio. I considered making an Asus based WiFi radio but a reluctance to potentially damage the Asus router trying to hook up a serial connection and uncertainty about whether or not it would work with WPA2-AES protocol encouraged me to look elsewhere for my WiFi radio solution. I decided to try reusing things I already own as much as possible.

I used a trusty old 733 MHz, Intel 386 based computer and set it up with Ubuntu 10.04 LTS. I added a USB LCDSmartie display from Sure Electronics and set it up to run headless (no monitor or keyboard). To control it I plugged in a USB keypad and installed OpenSSH Server so that I could remotely connect to it through the LAN. I setup the BIOS to start the computer at 9:45PM every day and to shut itself down after running for 4 hours. The speaker was provided by the external input of my alarm clock/radio (with its annoying amber glow).

I changed the LCD display from the bluish one the LCDSmartie shipped with to a red one. I prefer red lighting since it doesn’t mess up night vision or bother sleep as much. I have described how I configured the LCD display in a previous post: and how to control it using python:

The USB Keypad is a Belkin Nostromo N50 Speedpad but it could be any USB numeric keypad. I used EMPCd and Music Player Client (MPC) to control Music Player Daemon (MPD). The tricky part of configuring EMPCd is figuring out what device the USB Keypad is assigned. The EMPCd website mentions using using ‘/usr/sbin/empcd -K’ and ‘/usr/sbin/empcd -L’ respectively to determine which keys and functions are supported. I tried by process of elimination all the /dev/input/event* devices in the EMPCd configuration file /etc/empcd.conf and found that “eventdevice /dev/input/event3” responded to presses on the speedpad. I then was able to figure out which key was which event and altered the EMPCd configuration file accordingly.

I used a script (mpdcurrent.tcl.gz) adapted from one of Jannis Achstetter’s lcdproc clients and written in tcl to display the current status of MPD such as what song was playing or whether it was stopped, etc… Most scripts are started in /etc/rc.local.

#!/bin/sh -e
# rc.local
# Load script that displays current status of MPD using LCDProc
/home/phar/scripts/mpdcurrent.tcl &
# Clear any currently loaded MPD playlist
mpc clear
# Load predefined MPD playlist called "sleep", filled with sleep condusive music
mpc load sleep
# Play MPD playlist in random order
mpc random on
# When it gets to the end of the playlist it starts over
mpc repeat on
# Starts playing currently loaded playlist
mpc play &
# Shutdown in 4 hours
/sbin/shutdown -P +240 &
# Start EMPCd to capture events from speedpad and control MPD
/usr/sbin/empcd &
exit 0

I use Gnome Music Player Client (GMPC) to name and configure the playlists on MPD remotely. The playlists with various internet radio station urls and/or music are loaded using bash scripts executed by rc.local at startup and by EMPCd in response to specific key presses on the speedpad.

# loads MPD playlist containing Internet radio stations
# executed by EMPCd when correct button pressed on speedpad
mpc stop
mpc clear
mpc load stream
mpc random off
# Play first item in playlist
mpc play 1

I have 3 main playlist names: stream, sleep and elect. Here is a package (wifi_radio_files.tar.gz) of configuration files that may be helpful in understanding how I configured it. Each playlist can be loaded by pressing the appropriate button on the speedpad which executes a bash script which uses MPC to control MPD. Two more buttons select the previous or next item in the playlist and also stop and play the current item on MPD.

The 386 uses a low power consumption, DC to DC power supply and a Hitachi IC35L090AVV207-0 80GB Hard Drive that is fairly power efficient. The whole system idles at about 20 Watts and peaks at about 40Watts. It works very well. Admittedly the mini ATX case is not as small and elegant as MightyOhm’s project but it is quiet and can hide underneath the bed.

I have since replaced this “WiFi radio” and the clock/radio with the annoying amber glow with a Chumby like device called the Insignia Infocast 3.5 which I snagged on sale for $50. It is smaller, uses much less power, has a built-in speaker and is controlled with a touch screen. This machine currently resides in the basement shut down and waiting to be awaken with Wake On Lan (WOL) and act as an audio server once again.

Direct ATA to ATA Calling With The PAP2T-NA

As mentioned in my previous post, I have not abandoned plain old telephone service. It is very well engineered and integrates well with 911 service. There are, however, advantages to the flexibility of adding voip to your choices. My preferred home phone solution is to have two phones. One connected to the phone company and one (the long distance phone) connected to a flexible voip service like My preferred ATA is the Cisco PAP2T-NA. I have family in other parts of the country. We tend to call them frequently so it is cost effective for all of us to adopt the dual phone strategy. Either ATA can be configured to dial a “hotline number” direct to the other ATA over the Internet before using the voip service in the dial plan. To make direct ATA to ATA calls work over the Internet you need to do the following:

  1. Setup and use a service like to get a free domain name for your dynamic ip address.
  2. Configure the ATA to make and answer direct (unregistered) calls.
  3. Forward UDP ports on your router to the ATA.
  4. Configure the dial plan on the ATA be able to call the other ATA(‘s).

Most home internet service providers dynamically assign ip addresses so you need to get a domain name that doesn’t change. A service like offers free domain names for situations like this. If your IP address is static then you do not need this and can just use that in the ATA’s dial plan.

You need to log into your PAP2T-NA as admin and go to line 1 and/or line 2 and change in the “Proxy and Registration” section the “Make Call Without Reg:” and “Ans Call Without Reg:” options to “yes” and save your changes at the bottom of the configuration screen by clicking on “Save Settings”.

The next thing you need to do is forward the necessary ports for an SIP call to work. I found the PAP2T-NA needed UDP 5060-5061, UDP 5004 and UDP 16384-16482 (since this was the way rtp was setup on my ATA in the SIP settings). Keep in mind that if you are unsure about the risks of forwarding ports on your router you probably should not do this. You have been warned.

The next step is to change the dial plan for Line 1 and/or Line 2. It would be a good idea to it write down or copy and paste & save it before making any changes. Here is an example of what mine would be like:


When I dial 123 (my hotline number) the first rule in the dial plan is matched so it sends the call to 5194321111(not the real number) is the “User ID:” on the other ATA. In this case it happens to be the DID number of the voip service on the other ATA. For it would be the account number. is the newly assigned domain name.

For this to work the “Enable IP Dialing:” option must also be “yes”. Remember to save your changes at the bottom of the configuration screen by clicking on “Save Settings”. Any other number will be processed by the other rules in the dialing plan and be sent out to the regular registered voip service. The next example demonstrates a dial plan rule for a second ATA:


Hotline number 124 will match the second rule and send the call to

So there you have direct ATA to ATA calling. Setting it up is the hard part once that has been completed the person just has to pick up the phone at the other end when it rings.

Cicso ATA Administration Guide (pdf)
Linksys Dial Plan Tips and Tricks by Mango
Configure your Linksys VoIP ATA the right way! by Mango

efficient, open, low cost technology and other unexplained mysteries…