Wednesday, January 7, 2015

BattleTech Calculator

I finally released a personal app, as opposed to my usual map-based ones for work -- a calculator for the board game BattleTech.

In this board game from the 80s, giant robots run around blowing each other up. It involves a lot of dice and a fair amount of math; not simple, but tedious. It's so tedious we really did spend 5 hours going back and forth counting on our fingers, looking at the rules, losing our place as far as which fingers were which, ...

So, the calculator is a nice selector-based and checkbox-based tool: pick your target's status, your status, and whether there are trees in the way, and voila. It turned 5 hours of finger-counting into 2.5 hours of roboty-blowey-uppy action.

So, if you're interested:



Friday, January 2, 2015

Framework7 -- HTML5 framework for Cordova Mobile

It's been a long quiet time, I know. I've been working on a lot of stuff, but nothing had a "wow, folks would be interested to hear about this" sort of flavor.

But, as is typical at the time of the winter solstice holiday, clients went on vacation, backlogged lower-priority work got done, and eventually my inbox flatlined. That feels good... and opens me up to get back onto  thread I've been promising since September - - picking a new HTML5 toolkit, to use with Phonegap/Cordova.

To reiterate, our basic wish list (which could be interpreted as a gripe list with jQuery Mobile) is as follows:
  • Structured and configured in HTML and CSS, as opposed to code. Not that I myself am opposed to code, as much is that the designers are the ones who call the shots, so anything strongly based on prefab widgets declared in code is likely to run afoul of the designers wanting something that the code just doesn't do.
  • Highly configurable CSS. jQuery mobile is configurable and flexible, to a degree. Then again, it has a whole lot of decor already in place that we often need to override. Again, the clients of the designers specifically pick things that the toolkit doesn't do, since they don't like to look like a default kitchen sink demo. :-)
  • Not buggy. JQM has a lot of bugs that keep biting us. Some are in the design (text input do not get the same styling, not the same with, are visually inconsistent) and some are functional (a loading spinner won't show at all if the following AJAX call takes one second, buttons continue to look after the finger has been removed from the screen).
  • Performant. JQM is a bit laggy on two-year-old devices. Turning off page transitions and editing CSS to remove shadows helps somewhat, but then again ideally it would lack these shadows to begin with.
A few months ago I discovered this one: Framework7 http://www.idangero.us/framework7/ And over the solstice holiday break, I finally got to play with it and I really like it a lot. I used it to write a personal app, a calculator for playing BattleTech (a  board game from the 80s).

  • It is largely based on HTML and utility CSS classes, which is perfect for our needs.
  • It does not use jQuery, but their own lighter-weight DOM library with a syntax nearly identical to jQuery. It's not exactly the same, however, and lacks some features. (see below)
  • Visually, it's quite lightweight. The navigation bars are white and blue by default, thin outlines, and an otherwise not-very-cluttered visual feel. This is as opposed to the somewhat-heavy toolbars and buttons used by JQM.
  • When I needed to make arbitrary changes, it proved quite capable. For example, the panels are 100% wide and with no margin simply by adding a new CSS class with a margin:0, or by omitting a wrapper DIV which introduces a margin. Making the tab button 100% wide, was equally simple.
  • Adding FontAwesome took literally moments. Adding FontAwesome was necessary because the framework's own CSS classes do not include a rich set of icons. So this bullet point is both a point against Framework7, then that point rewarded back again -- the framework does not come with a rich set of icons, but has no problem working with your choice of icons. This point is then awarded a second time, because icons on buttons and panels can be quite arbitrary and flexible: rather than using data-icon="" attributes on elements which specifically supported, you declare your arbitrary <i class="fa"></i> elements wherever you like. This came in handy, for example, adding a X button to the slideout panel in order to close it.
  • It feels very performant and slick, even on an iPhone 4. This three-year-old phone represents the trailing edge of what we will be supporting for the next year or two. And under this framework, even this slightly obsolete hardware is plenty fast.
  • The resulting application is very consistent in its look between Android and iOS platforms. For us, this is preferable over a framework which tries to "look native" on both platforms -- the designers want a consistent outcome and not stuff that "looks default". And It looks like they'll get it.
I see a lot of promise with this one. Still, I should point out the problems I have had with it as well.
  • The documentation is incomplete and incorrect in parts. For example, their own "starting example" (at the time) does not render properly since they have one of the class names misspelled. The documentation for individual widgets such as checkboxes, consists of a lengthy paragraph of HTML forming an example, and it's up to you to visually tease apart which elements are the relevant ones since there are rarely any additional instructions.
  • The DOM library (called Dom7) is not exactly as functional as jQuery. For example, it does not have the :selected pseudo so you cannot pick the <OPTION> element itself and pull additional data-xxx="" attributes beyond the value itself. If you need to do more complex selections like that, you would need to iterate and compare value. Also, to touch upon the documentation, the narrative component of the documentation for Dom7 consists of one sentence: "Just what you already know" followed by a snippet of what looks like jQuery code (but it's Dom7). Then follows a list of supported functions, but not a in-depth description of what sorts of selectors are and are not supported; I had to discover myself the limitation about option:selected
  • Their documentation recommends that you assign $$ to Dom7, so you can act similar to jQuery with selectors such as $$('span.highlight') but not conflict with some other library which uses $. However, $$ is already defined and their advice is basically for you to override their $$ with a new $$ to Dom7. If your own assignment of $$ fails, you get some wonky behavior. The symptom here, is that $$ still returns elements but it's an array of raw DOM elements and not Dom7 object wrappers -- as a result, your call to $$('span.highlight') returns a set of <SPAN> elements, but your call to show() fails with "show is not a function" when you know perfectly well it's a function! For this reason, I recommend that you ignore their advice and assign to $ instead. At least that way, a mismatched brace somewhere in your 2000 lines, won't lead you on a wild goose chase (or is it a red herring fishing trip?) hunting for $$ results which exist but do not obey.

All told, I think we have a winner. If you are using PhoneGap or some other HTML web view type deal to write your hybrid mobile apps, you'll probably want to check this one out. Framework7 http://www.idangero.us/framework7/


Oh, right; my app

If you're interested in the BattleTech app, you can check it out over on Github:
https://github.com/gregallensworth/BattleTechCalculator

This app does not use the framework's wrapper classes for checkboxes, select elements, and so forth. This particular app is so heavy with dozens of checkboxes and a two-column layout, that we needed the most compact layout available. Although I gladly used the navbar, left slideout panel, and tab bar, this app is not representative of Framework7's decoration of form elements.

But even this is a good thing: you are not forced to use these decorated checkboxes and select elements, and this is a great scenario for we were allowed not to use them and thus achieve a more compact layout than would have been possible with JQM. So even in a case where we don't want the decor at all, Framework7 still came up a winner.

Tuesday, November 25, 2014

Not dead, just busy!

Happy thanksgiving holiday.
It's been some 7 weeks since my last post, simply because I've been pretty occupied with stuff at work and haven't come across anything really blog-worthy lately. But it's coming.

Some brief bits and pieces:
  • Been crazy-busy at work, including a server migration in a few days over the TG weekend. Huzzah for virtualization and how it makes migrations relatively simple. Ask me about it some time.
  • OSX Yosemite trashed my Mac, so I spent a day reinstalling the OS and then the whole build chain. My own blogs came in quite handy here, and I'm glad to say they're still quite applicable. The only annoyance was that virtually every package in the stack had an update: iOS 8 meant updating Xcode, meant updating to Yosemite, ... (the second upgrade from Snow Leopard to Yosemite went just fine, no sweat)
  • I've begun porting over an old jQuery Mobile application from 2012, into Cordova to form a mobile app. I don't expect much in the way of surprises, but it will be the most complex phone app I've ever done. Fortunately the already-working prototype provides a clear picture of expectations and some lessons on what works well and what can be streamlined.
  • Still no progress on trying to find a new HTML5 framework for building mobile apps. Just too busy on other tasks. Though the mental process is guiding me toward something very much like Ratchet but with a real page-turning behavior. (I mentioned that a while ago) I do hope to get some slack time soon to tinker around and find/invent something.
So yeah... Not a lot worth blogging, but a promise that more will come soon. :)

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.