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...

Monday, October 6, 2014

Raspberry Pi and a brief primer on GPIO (still coming, a binary clock!)

I mentioned that I got my Raspberry Pi B+ last week. Sadly I've had fairly little free time to play with it. Still, a few days ago, about 24 hours after I received it, I put together a cute program I thought I'd share. It's a clock that counts out the time in binary. Nothing too earth-shaking, but a little more involved than the tutorials.


Before I get into that project, though, I want to lay out some information on how GPIO works.

My goal is to provide a tutorial and technical explanation, for those who already know what a Python comment is, but who need something more meaty than "here's a photo my my Pi, now copy-paste this Python code" The tutorials are cool, but they often lack background information and (for example, in my first project) I had to find a different site to explain how GPIO ports really work since the light wasn't blinking when it should have been.

First off, go find a copy of the Raspberry Pi GPIO diagram for your model. My personal favorite is this one for the B+. And I'll assume that you know a little bit about electricity, e.g. that GND means "ground" or "negative terminal".

GPIO ! OMG !

What's GPIO? General Purpose Input and Output. It means that there's a bank of pins on the computer, and that these pins can be connected to things that generate input (buttons, thermometers, motion sensors) and to things that generate output (LEDs, motors and relays, radio transmitters). The GPIO bank also has several pins to act as grounds (- terminals) and power supplies (+ terminals at both 3.3V and 5V).

What decides whether a GPIO pin is input or output, and when it generates voltage? Software! That's the awesome part. The same GPIO pin may attach to a button (input) in one program or to a LED to light up (output) in another program, and that choice of behaviors is controlled by your Python program.

GPIO Output

In Output mode, what defines whether a GPIO output is on or off?

Well, that's a little more involved...

When a GPIO pin is defined as Output (or GPIO.OUT in Python) the pin can be in either a High state or a Low state (GPIO.HIGH and GPIO.LOW, or True/False, or 1/0).
  • When it's in a High state the pin is generating +3V DC If you connect that pin to the anode (+ side) of a LED and connect the LED's cathode (- side) to the ground, the LED would light.
  • When it's in a Low state, the pin is grounded and acts as a negative terminal. In this case, you could still connect an LED but the - would go to the GPIO pin and the + would go to a power source.
So it's not quite as simple as "on and off" or "the LED lights when the pin is High" as much as "the GPIO pin will go to +3V (High) or to 0V (Low), and the behavior of your circuit depends on the structure of your circuit"

Check out the following photo and diagram.



In my initial experiments, I simply didn't quite grok this simple relationship between voltage and tyhe High/Low state, and I had plugged in an LED backwards. As a result, High meant that the LED was off and Low turned it on -- the opposite of my intent! It all makes sense now that I know these basics.


GPIO Input

When a GPIO pin is set to receive input, what is it looking for? A button being pushed, or what?

When a GPIO pin is set to GPIO.IN mode, it listens for incoming voltage, e.g. +3V being applied to the GPIO pin. When there is voltage coming in, the pin reads High. And when there is no voltage... it reads randomly!

A pin in GPIO.IN state is floating, meaning that it is not clearly energized to +3V nor is it clearly grounded out. If you have a Python program doing While True: print input(12); you'll see that the input fluctuates between 0 and 1, even if there's nothing connected to the pin at all!

This is not a signal from your button, but simply line noise. To correct for this, you must pull down the line voltage to force it to clearly be Low. This means to connect the GPIO pin to ground so it is constantly draining voltage (and constantly reads 0 or Low), until such time as you hit the switch and connect +3V to the GPIO input.








It's not as convenient as having just the button that is clearly reading High or Low. On higher end hardware they have cleaner line voltage and built-in pull down mechanisms. But not here.

That resistor is important! When you engage the switch, you're connecting +3V directly to GND, and that's a short circuit. Putting in the resistor, reduces the voltage sufficiently so as not to reboot your Raspi with a short circuit, while also "encouraging" the power to flow up the GPIO pin.


So Now What ?

Well, those are the rudiments of GPIO, that took me an evening to figure out. Hopefully it saved you some time.

Coming shortly, the walkthrough of my binary clock.

Saturday, October 4, 2014

HTML5 mobile framework: part 3, Bootstrap & Ratchet

Sorry to keep splitting up threads here. A few weeks back, I posted that we're using jQuery Mobile to make our mobile apps, and that while it's good it's not awesome. So the R&D continued for a new HTML5 framework to build our mobile apps using Cordova/Phonegap.

Again, it's opinions and impressions as I try things out to see how they fit our needs. If your opinion varies please share it in the comments! I'd love your input on HTML5 and hybrid mobile apps.

Here's the next one I tried out (this was a good 3 weeks ago): Ratchet.


Bootstrap / Ratchet


Bootstrap is a rich set of CSS classes and mobile-friendly behaviors. It looks a little bit cartoonish for my tastes, and it really stands out where it's in use, but it is the current vogue and it is quite flexible as far as modifying the theme. You start with a rich set of utility classes but you're not constrained to use only what you're given. That counts for a lot!

However, Bootstrap is not a mobile development framework. There is no page swapping, no interception of # hyperlinks to swap which panel/page is currently showing, and so on. And while it is mobile-friendly and responsive, it is not designed to "look native".

Ratchet attempts to fill this gap by adding more CSS classes for listviews, thumbnail icons, badges and mini icons that float to the right-hand side, and so on. Ratchet was created for quickly prototyping mobile apps using HTML web pages: "visit this URL; after we create the app, here's what it would look like."


I was quite excited to find this, since my own idea had been to write some jQuery wrappers over Bootstrap to roll our own framework. But as they say, why reinvent the wheel? (obviously a phrase from before we had Github, where literally thousands of projects are out there reinventing wheels)

What I saw, got me excited quickly:
  • It's pretty, it's pure CSS. It's tiny. It's a superset of Bootstrap.
  • We're not tied down to a specific development technique. It's just CSS.
  • The documentation is quite well organized, and there's not much of it.
  • Separate CSS for iOS and Android, trying for a more-native look. Using Cordova's merge capability, this could turn out well.
  • A nice set of glyphicons.
  • Again, it's just a bunch of CSS, so could work with any programming and eventing toolkit, e.g. jQuery. (I repeat this cuz it's really core to the uber-flexible "style first then redesign repeatedly" approach we need)
  • There's virtually no overhead, so rendering and response is quite swift.
But then things took a turn as I tried to use it to develop a real app:
  • No events. We'd need to add jQuery to add click and tap handlers, which is fine. Then again, this could be addressed with TouchSwipe, adding swipe and pinch handlers to jQuery. Not a problem, but does illustrate that Ratchet is intended for prototyping apps, not for building real apps.
  • The prefab behaviors do not include popup dialogs. Again, not killer but if we want to show a Please Wait there's no supplied way to do that.
But then the show-stopper!
  • All that page-changing behavior is done with Push.js, which loads HTML pages from the server. It does not (as far as I could tell from the source and the docs) in any way support switching pages within the document. You're loading up HTML pages, not switching visibility to show and hide a specific panel.
  • This means that you can't just switch over to the results page; you load results.html from the server (or from the in-app device storage)... but without any of your DOM changes. A typical use case, is a search function which populates a results list on another page, then switches over to that page. Even if you got the page-change timing right so the results content were visible at the right time... switching away from the results and then back again would effectively lose the results.
So ultimately, we had to say no here and shelve it. Push.js is cute for what it is, but isn't suitable for even a moderately simple use case of showing/hiding/adding DOM elements in another panel. (again, Ratchet doesn't claim to be this)

But it's not over...


Still, I'm reluctant to let it go entirely. My current line of thinking, is to make a fork of Ratchet minus Push.js, then replace Push.js with something that simply switches which <div class="page"> is currently visible. Given this, we would have a nice set of CSS utility classes and a homegrown page-management framework. All that's missing is support for dialogs, which doesn't sound difficult on the surface.

So this one was shelved, but remains on the radar. It's the closest thing I've found so far, to the ideally-minimal CSS toolkit we need. I'm gonna try out a few more such as Ionic and Sencha,before I go for reinventing a framework.

Wednesday, October 1, 2014

My first tastes of Raspberry Pi (and next, a binary clock project!)

I received my Raspberry Pi on Monday night. It's quite nifty.

What Is It ?


A Raspberry Pi is essentially a small computer, the size of a pack of playing cards. It has a microprocessor (ARM 700 MHz), 512 MB of RAM, 4 USB ports, and an Ethernet adapter... and it can run Linux. That means that any USB stuff that works on Linux should work here, e.g. wifi adapters, packet radio adapters, even a GSM adapter for cell service. Even better -- it has a bank of GPIO and I2C slots so you can plug in physical inputs and outputs such as temperature sensors, motors and relays, motion sensors, cameras, LEDs, LCD readouts, touchscreens, and serial I/O such as GPSs. And it all runs off a USB phone charger, and doesn't even have a fan to make noise.

More info here:  http://www.raspberrypi.org/products/model-b-plus/

The whole concept of the Raspberry Pi is a dirt-cheap prototyping platform. Remember those electronics kits we had as kids, where you wire up resistors to antennas and make a crystal radio? Same idea, except one of the components is a Linux computer connected to the Internet. And that computer has 26 software-controlled input and output ports.

And of course, there's a real thrill and "tee-hee" value to a working computer that's the size of a hamburger patty, which runs X Window and a SMTP server and a MySQL server, and just about anything else that runs under Debian Linux.

Anyway, it's not really map related at all but is some cool stuff. In upcoming weeks, expect a few raspi postings mingled in with my usual map postings and my (overdue) series on choosing a HTML5 framework for mobile dev.