For those that don't know, November is when NaNoWriMo (National Novel Writing Month) takes place and there is a poster on the wall of my work that tracks the progress of my coworker's word count. However, since I work from home quite a bit, the poster in the office doesn't do me much good.... time to create a device that allows me to track people's progress.

Hello NaNoBox!

The basic idea of of the NaNoBox is to use a mini computer to access the NaNoWriMo wordcount API and do the following:

  1. Every hour, get the current word count of a small list of NaNoWriMo participants
  2. Loop through the list of participants and:
    1. illuminate something that represents a NaNoWriMo participant
    2. show the progress of the represented participant as a percentage on an analog meter

The Hardware

Earlier this month I acquired a Raspberry Pi from http://www.adafruit.com, and I felt that the device would be ideal for this project.... I was wrong.

While I still used the Raspberry Pi for my project, I will never purchase another one, nor will I ever use the Raspberry Pi for another similar project.

Why I don't like the Pi

  • There are no mounting holes. When I make a custom enclosure for a computer, I like to mount the motherboard on standoffs, and I can't do this with the Raspberry Pi. lame
  • Handling PWM is not as simple as just writing to a file, and I needed to compile a 3rd party application to help me with PWM. I was spoiled by the Beaglebone
  • The is little to no documentation for the Raspberry Pi at http://www.raspberrypi.org/. Very lame
  • Proprietary video drivers. Not a big deal for this project, but still less than ideal

Alright, that's enough complaining about the computer, let's get on with the build.

The Interface

At the suggestion of my friend who is a wood worker, I made a template of how I wanted the interface of the NaNoBox to look.

The Case

There is something about the scent of a nice cedar cigar box that tickles my brain.

This cigar box has been hanging out at my house for long enough. Time to chop it up.

Chop Chop

After laying out the design on the box, I used my poor selection of power tools to hack a bunch of holes in the cigar box.

The logo on the box was impossible to remove, but I sanded it down as best as I could.


On the back of the box I drilled a hole for the power cable to go through.

Ewww, there is a sideburn hair in the picture


After much sanding, I stained the top of the box with the only stain I have (other than coffee), some red leather stain.


On the inside of the box, I hot glued a piece of paper to diffuse light that shines upon it. What? you'll find out.


This is part of a DVD case. I like the way this plastic clip holds paper in the DVD case and I figure it would be a not too crappy way to hold the Raspberry Pi in place within the box.

Computer Mount

The DVD case clip was cut up and hot glued into the cigar box. See the black dots? LEDs will go there.

Like I said earlier, the lack of mounting holes is a serious downside of the Raspberry Pi (at least for the type of projects I like to do).

Put It On The Wall

Two screws and a bit of baling wire make for a great wall hanging bracket.

LEDs Wired Up

Here are the LEDs, soldered together and hot glued in place so that they shine through the square holes in the cigar box.

Voltmeter In Place

A 3.3V voltmeter was bolted into place, and an amber LED was hot glued over a small hole in the center of the box.

All Wired Up

The electronics are all done and ready to roll! I added a small 802.11n wireless USB adapter so that I wouldn't need another cable running to the computer.

Picture Holdy Thingies

Some thick paper was cut and folder in order to make holders for pictures that will be placed over the openings in the case.

Glued In Place

There it is! Two of the image holdy thingies were glued to the box for each of the images.

All Done

The pictures are in place and ready to light up.

The photographs are of my coworkers. The two other images represent podcasters that I listen too who happen to be participating in this years NaNoWriMo, and they are Thistleweb from Crivins and Moosical from The Bugcast.

Tim Kim

Hi Tim! Wow, I took a very unflattering picture of Tim for use in this project. Haha!

In Action

I dropped some test data into the code that runs the NaNoBox so that I could see the device in action before the event starts. When the participants get to 50,000 words, the amber LED in the middle of the box illuminates.

The Code

For this project, I decided to use Ruby because .... um... why not?

#!/usr/bin/env ruby
require 'open-uri'
require 'rexml/document'

class Pin
  def initialize(num)
    @gpio num
    #init this pin
    `gpio -g mode #{@gpioout`
  def on()
     `gpio -g write #{@gpio1`

  def off()
    `gpio -g write #{@gpio0`


class Nanobox
  def initialize()
    #keep it clean
    #define the pins
    @pins = [
    #create the PWM on 18 (AKA pin 12)
    `gpio -g mode 18 pwm`   

  def clean_up()
    #unexport all of the assigned pins
    `gpio unexportall`

  def set_pwm_percentnum )
    max 1023
    offset_percent num*0.92
    val max*offset_percent/100
    `gpio -g pwm 18 #{val}

  def read_config_file
    this_dir File.dirname(__FILE__)
    config File.join(this_dir"users.conf")

    @users = []
    File.open(configdo |file|
      file.each_line do |line|
        if line.chomp != ""
          user = {"name" => line.chomp}
          @users << user

  def update_wordcount_of_user(user)
      url "http://nanowrimo.org/wordcount_api/wc/"+user['name']
      xml_text open(url).read
      doc REXML::Document.new xml_text
      if doc.root.elements['error'].nil?
        wc doc.root.elements['user_wordcount'].text.to_i/500.to_i
        wc 0
      #do nothing
    if wc 100
      wc 100
    @users.each_with_index do |ui|
      if u['name'] == user['name']
        user['wc'] = wc
        @users[i] = user

  def update_all_wordcounts() 
    @users.each do |user|

  def run
    #read the config
    #do the initial wordcount update
    @running true
    update_wc_count 0
    count 0
    sleep_time #seconds
    update_wc_count_max 3600/sleep_time
    current_pin nil
    while @running
      unless current_pin.nil?
      current_pin @pins[count]
      if count >= @pins.length or count >= @users.length
        count 0
      if update_wc_count update_wc_count_max
        update_wc_count 0
      value @users[count]["wc"]
      if value >= 100 
      sleep 5
  def stop
    @running false
  def quit
    #turn off all of the LEDS
    @pins.each do |p|
    #do some cleanup

if __FILE__ == $0
  nano Nanobox.new
  trap("INT"){ nano.stop }

Yup, that's some ugly, uncommented code. While parsing the XML that gets returned by the Word Count API, I realized that I don't like processing XML in Ruby, and then I had an epiphany: XML is very consistant, I dislike parsing it in any language. ZING!

Wait a second. Don't I have more coworkers? Why aren't they represented in this project? Yes, I do have more coworkers, but the cigar box has a very limited amount of space. Fortunately, I have enough components to make another NaNoWriMo status tracker. Time to get to the drawing board.

Now quit reading, and get ready to start procrastinating.

2012-11-28 d-r:
Mr. Jezra -

You probably are already aware of this, but the latest rev of the Raspberry Pi has mounting holes (just got mine today!).

Also, have you checked out Adafruit's modification of Raspbian, called Occidentalis? They've done some stuff to make the GPIO stuff more useful, including PWM. I don't really understand that stuff, but perhaps a real hacker such as yourself will find it useful: http://learn.adafruit.com/adafruit-raspberry-pi-educational-linux-distro/occidentalis-v0-dot-2

It doesn't sound like they intend to maintain it like a real distro, but it looks useful for single purpose projects.

Maybe some day they'll get around to proper documentation . . . seems like a genuinely useful open graphics driver isn't going to happen though.


2012-11-28 jezra:
Is it still only two holes? 3 points make a plane, 2 points make a line.

The idea of installing as full Desktop distro just to get decent PWM support is not for me. I'll stick with the BeagleBone
2012-11-28 d-r:
Good point, it is just two holes. It seems like there's a real need for a barebones distro optimized for hardware hacking on the RPi . . . maybe someone will take Adafruit's modifications and turn it in to a real distro.
2012-11-28 jezra:
it's called "Arch"
not required
not required (will not be displayed)
not required (will link your name to your site)
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
3 plus 4