Thursday, October 9, 2014

Raspberry Pi binary clock

And as promised, here is my exciting, awesome world-changing invention... a Raspberry Pi application which shows the time... in binary! Okay, not that killer, but a simple project demonstrating some wiring, some code, and a visual output.

You'll need:


Hardware (GPIO, Wires, LEDs)

The circuitry itself is dead simple: just five LEDs in a row, with their anodes (+ side, long leg) connected to 5 GPIO pins and their cathodes (- end, short leg) connected to the GND. Just pick any five GPIO pins, connect your GND to the breadboard, and insert the LEDs.

Here it is, as both a photo and  a circuit diagram.



The choice of GPIO pins is up to you. I picked the 5 nearest the end of the bank on my B+.

Question: Why would I show only the last 5 bits of the time, instead of a nice nerdy number like 8? I didn't have 8 LEDs: I lost a bag of two LEDs and burned out another LED during an experiment, so I only had 5.

The RPi.GPIO Library

My favorite GPIO programming API, is RPi.GPIO

You can grab a copy and install it manually, here on its Python package page

Or you can let the package manager do it for you:   sudo apt-get install python-rpi.gpio


The Program (Python)

# CONSTANTS
LIGHT_PIN_0 = 21
LIGHT_PIN_1 = 20
LIGHT_PIN_2 = 16
LIGHT_PIN_3 = 12
LIGHT_PIN_4 = 26

# SETUP
import RPi.GPIO as GPIO
from time import sleep
from time import time as epoch

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

# initialization: setup the pins for output
# and set all pins HIGH for an initial blast of light, like how a car tests its lights
def init():
    GPIO.cleanup()
    GPIO.setup(LIGHT_PIN_0, GPIO.OUT)
    GPIO.setup(LIGHT_PIN_1, GPIO.OUT)
    GPIO.setup(LIGHT_PIN_2, GPIO.OUT)
    GPIO.setup(LIGHT_PIN_3, GPIO.OUT)
    GPIO.setup(LIGHT_PIN_4, GPIO.OUT)

    GPIO.output(LIGHT_PIN_0, GPIO.HIGH)
    GPIO.output(LIGHT_PIN_1, GPIO.HIGH)
    GPIO.output(LIGHT_PIN_2, GPIO.HIGH)
    GPIO.output(LIGHT_PIN_3, GPIO.HIGH)
    GPIO.output(LIGHT_PIN_4, GPIO.HIGH)

# convert an interger into binary, then pull out the 1s and 0s to light the pins
# count back from the end, so we get the last 5 digits; the first 5 digits won't change for years
def updateLightsFromInteger(value):
    bits = bin(value)
    GPIO.output(LIGHT_PIN_0, bits[-1] == '1')
    GPIO.output(LIGHT_PIN_1, bits[-2] == '1')
    GPIO.output(LIGHT_PIN_2, bits[-3] == '1')
    GPIO.output(LIGHT_PIN_3, bits[-4] == '1')
    GPIO.output(LIGHT_PIN_4, bits[-5] == '1')

# THE MAIN LOOP
# JUST SIT AND UPDATE THE BLINKY, AND WHEN IT'S TIME TO QUIT BE GRACEFUL ABOUT IT
if __name__ == '__main__':
    init()
    sleep(3)
    print("Running. Hit ctrl-c to terminate.")

    try:
        while True:
            sleep(1)
            value = round(epoch())
            updateLightsFromInteger(value)
    except KeyboardInterrupt:
        print('Shutting down')
        GPIO.cleanup()


Pretty darn simple, huh? Just keep looping forever, fetching the time and converting it into 1s and 0s for the lights. And I'm almost ashamed at how cute and entrancing it is... shiny...

For yourself, feel free to pack the LEDs more tightly and add a few more. With only 5 bits, it recycles every 32 seconds, but if it has 12 it would recycle every 4096 seconds (68 minutes).


My next project should be more interesting. As soon as I quit... watching the... blinky... lights...

No comments:

Post a Comment