Skip to content

Commit

Permalink
Better words
Browse files Browse the repository at this point in the history
  • Loading branch information
pikesley committed Oct 9, 2016
1 parent 18f04ae commit ac4a2a3
Showing 1 changed file with 17 additions and 8 deletions.
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ This story begins with a man named [Frank Howarth](https://www.youtube.com/user/

## Everything is a circle

When all you have is a lathe, everything you make is round. It occurred to me that I might be able to fashion a clock, using some [Neopixel rings](https://shop.pimoroni.com/products/adafruit-neopixel-ring-24-x-rgb-led-w-integrated-drivers) for the dials, and driven by a [Raspberry Pi](https://www.raspberrypi.org/products/pi-zero/). So I turned a simple clock body out of a maple disc, bought some Neopixels and a Pi Zero, and this is what I came up with...
When all you have is a lathe, everything you make is round. It occurred to me that I might be able to fashion a clock, using some [Neopixel rings](https://shop.pimoroni.com/products/adafruit-neopixel-ring-24-x-rgb-led-w-integrated-drivers) for the dials, and driven by a [Raspberry Pi](https://www.raspberrypi.org/products/pi-zero/). So I bought some Neopixels and a Pi Zero, turned a simple clock body out of a maple disc, and this is what I came up with...

## The hardware

I was given to understand, from reading the specs, that a Pi would not be able to handle the timing requirements of the Neopixels, and I would need an [Arduino](https://www.arduino.cc/en/Main/ArduinoBoardUno) in between Pi and pixels. However, after a conversation with [Chris](https://twitter.com/elsmorian) at a [very weird bar in South London](http://www.doitinlondon.co.uk/en/drink-and-food/little-nans-tropical-den-le-cocktail-bar-vient-se-nicher-a-peckham-19456) I discovered that there is [at least one PWM pin on a Pi](http://raspberrypi.stackexchange.com/questions/298/can-i-use-the-gpio-for-pulse-width-modulation-pwm) have enough grunt to drive the Neopixels, and that even better, there's a [Ruby Gem](https://github.com/TwP/pixel_pi) - no Arduino required.
I was given to understand, from reading the specs, that a Pi would not be able to handle the timing requirements of the Neopixels, and I would need an [Arduino](https://www.arduino.cc/en/Main/ArduinoBoardUno) in between Pi and pixels. However, after a conversation with [Chris](https://twitter.com/elsmorian) at a [very weird bar in South London](http://www.doitinlondon.co.uk/en/drink-and-food/little-nans-tropical-den-le-cocktail-bar-vient-se-nicher-a-peckham-19456) I discovered that there is [at least one PWM pin on a Pi](http://raspberrypi.stackexchange.com/questions/298/can-i-use-the-gpio-for-pulse-width-modulation-pwm) with enough grunt to drive the Neopixels, and that even better, there's a [Ruby Gem](https://github.com/TwP/pixel_pi). So, no Arduino required.

### Wiring it up

Expand All @@ -28,7 +28,7 @@ It turns out you can chain the Neopixels together and then address them as one l

### Installation

The code is, of course [on Github](https://github.com/pikesley/wen). To get it up and running from a clean install of [NOOBS](https://www.raspberrypi.org/downloads/noobs/) 1.9 on a Pi Zero, the steps are:
The code is all [on Github](https://github.com/pikesley/wen). To get it up and running from a clean install of [NOOBS](https://www.raspberrypi.org/downloads/noobs/) 1.9 on a Pi Zero, the steps are:

sudo apt-get update
sudo apt-get upgrade
Expand All @@ -46,19 +46,21 @@ The code is, of course [on Github](https://github.com/pikesley/wen). To get it u

sudo reboot

This sets up _everything_, including the [systemd](https://wiki.debian.org/systemd) startup scripts, and a shell alias called `rewen` which checks out the latest code from Github and restarts the service.
This sets up _everything_, including the [systemd](https://wiki.debian.org/systemd) startup scripts. It also deletes nano, and gives you a shell alias called `rewen` which checks out the latest code from Github and restarts the service.

### Internals

Getting a computer to tell you the time is very easy: in [Ruby](https://www.ruby-lang.org/en/), we just do `DateTime.now` and there it is. Translating that into lighting the correct lights on a string of LEDs is slightly more challenging, but not much, and I had a crude script working in about an hour. But I quickly fell into the over-engineering rabbit hole, so here's what I have now:

#### Two rings, with two hands

The inner, hour ring has 12 pixels, which is the correct number of pixels for an hour ring to have, and conceptually, _Wen_ thinks about it as having a _hand_ (the single pixel which indicates the hour) and a _face_, the other 11 pixels. The outer minutes ring, however, has 24 pixels, which is a little trickier to deal with: a single pixel accounts for 2.5 minutes of actual time, and lighting just that one light to indicate the minutes didn't really work very well. My compromise is to attempt to be a bit vague and also light the pixels on either side, (which isn't entirely satisfactory wither), so for this ring, the _hand_ is 3 pixels combined, with a _face_ of 21.
The inner, _hour_ ring has 12 pixels, which is the correct number of pixels for an hour ring to have, and conceptually, _Wen_ thinks about it as having a _hand_ (the single pixel which indicates the hour) and a _face_, the other 11 pixels. The outer _minutes_ ring, however, has 24 pixels, which is a little trickier to deal with: a single pixel accounts for 2.5 minutes of actual time, and lighting just that one light to indicate the minutes didn't really work very well. My compromise is to attempt to be a bit vague and also light the pixels on each side of the main one, (which isn't entirely satisfactory either), so for this ring, the _hand_ is 3 pixels combined, with a _face_ of 21.

It should be noted that 60-pin Neopixels [do exist](https://www.adafruit.com/product/1768) but they're too big to mount on anything I'd be able to turn on my mini-lathe.

#### _Everything_ gets a RESTful API eventually

Why the hell does a clock need a RESTful API? Well, here's how I justified it to myself: my first script ran a `while true` loop, updating the LEDs every 10 seconds, which worked OK, but then I started thinking about how I might be able to get the clock to show patterns and so on, and because of the way my mind works now, I immediately reached for [Sinatra](http://www.sinatrarb.com/) and started wrapping some HTTP around it.
Why the hell does a clock need a RESTful API? Well, here's how I justified it to myself: my first script ran a `while true` loop, updating the LEDs every 10 seconds, which worked OK, but then I started thinking about how I might be able to get the clock to show patterns and so on, and because of the way my mind works now, I reached for [Sinatra](http://www.sinatrarb.com/) (via my [Skellington](http://sam.pikesley.org/projects/skellington/) gem) and started wrapping some HTTP around everything.

So it now has two main endpoints:

Expand Down Expand Up @@ -98,9 +100,16 @@ It also _Accepts_ a PATCH with some JSON like
mode: 'shuffle'
}

(which is what happens behind the buttons). All of these _PATCH_ requests then get pushed onto the [Sidekiq](http://sidekiq.org/) where th...
(which is what happens behind the buttons). All of these _PATCH_ requests then get pushed onto the [Sidekiq](http://sidekiq.org/) queue for asynchro...

#### Wait, there's a queue in here too?

How else would you do this? The [ClockWorker](https://github.com/pikesley/wen/blob/master/lib/wen/clock_worker.rb) pulls the jobs off the queue and throws them at the [Clock](https://github.com/pikesley/wen/blob/master/lib/wen/clock/clock.rb) class, which passes them to the [Neopixels](https://github.com/pikesley/wen/blob/master/lib/wen/clock/neopixels.rb) singleton, which talks to PixelPi, which actually makes the lights come on. I'm actually genuinely amazed at how much bullshit a £4, 65x23mm computer can handle
How else would you do this? The [ClockWorker](https://github.com/pikesley/wen/blob/master/lib/wen/clock_worker.rb) pulls the jobs off the queue and throws them at the [Clock](https://github.com/pikesley/wen/blob/master/lib/wen/clock/clock.rb) class, which passes them to the [Neopixels](https://github.com/pikesley/wen/blob/master/lib/wen/clock/neopixels.rb) singleton, which talks to PixelPi, which actually makes the lights come on. I'm actually genuinely amazed at how much bullshit a 4 quid, 65x23mm computer can handle.

## What else?

This is definitely a prototype: I can certainly turn a better clock body, and hopefully I can come up with a more elegant solution to the 24-pixels-into-60-minutes problem.

## There's a movie, too

[![Wen, the Movie](http://i.imgur.com/GmuLpRC.png)](https://youtu.be/FGRnSwF10Dw)

0 comments on commit ac4a2a3

Please sign in to comment.