Single Board Computers


So here are the Beaglebone Black (left bottom) and the Creator CI20 (right bottom) single board computers. Also pictured is my Raspberry Pi B+ and my grocery store loyalty card for scale. Also, I’m hoping that Harris Teeter will cut me a fat check. But mostly it’s for scale.

The Beaglebone Black is courtesy of the Arm Connected Community who very kindly sent it to me free of charge for my Magic Window project idea. The fine folks at Imagination Technologies sent me this preview copy of the Creator CI20 free of charge for my project as well. Seriously, there’s a lot of generosity and support from the companies making SBC solutions! It was a strange week for me because I got these offers at practically the same time. I’m looking at this as a cool opportunity to do a bake off and post my thoughts in this space about how these two boards compare.

The Raspberry Pi is not competing, because it’s my retro gaming rig. But if the Raspberry Pi peeps want to send me a Raspberry Pi 2 B+ I’ll reconsider :-)

My grocery store loyalty card does not support Linux and is therefore disqualified.

Some initial observations:

  • The release version of the CI20 is purple, and it looks amazing! Seriously, take a look:
  • As you can see, the CI20 is slightly larger. It has WIFI and Bluetooth on board, as well as built-in memory (8GB on the release version, 4GB on my preview).
  • The CI20 is so new that no cases are available yet. I hope this changes soon, says the klutz!
  • Beaglebone Black has a very active support community as well as cases and other peripherals available. Check out my sweet case.
  • The one USB port on the Beaglebone Black is a little bit limiting, especially when compared with two on the CI20 and four on the Pi
  • Both the BBB and the CI20 have beefier processing power than my Raspberry Pi B+, so that’s nice. Raspberry Pi just released the 2 B+ board, which would probably be much more competitive with them. And the arms race continues…



Powered by Facebook Comments

Pretendo Entertainment System

Or “what I did on my Christmas vacation”. So, my first SBC (single board computer) project was a fairly simple one. I got a Raspberry Pi B+ for Christmas and made a retro gaming system with RetroPie.


This was such a basic project that I won’t describe it in too much detail.

In a nutshell:

1. assembled the hardware
2. burned latest retropie image to my MicroSD
3. booted the Raspberry Pi with MicroSD inserted
4. used raspi-config to a) expand disk to full size b) set the localization and keyboard settings to American (‘merica! Heck ya!) c) set overclock
5. booted startx and used the XWindows tool (wpa_gui) to configure my wifi
6. copied all my ROM’s over via the default SAMBA share
7. used RetroPie-Setup/ to a) update everything b) setup the default RetroArch controller for c) change the flash screen to the cool one with Mario and Luigi
8. created my controller settings in a file using the command line configuration tool:
cd /opt/retropie/emulators/RetroArch/installdir/bin
sudo ./retroarch-joyconfig -j 0 > /opt/retropie/configs/all/controllers.cfg
sudo ./retroarch-joyconfig -j 1 >> /opt/retropie/configs/all/controllers.cfg

9. Cleaned up my /opt/retropie/configs/all/retroarch.cfg file, removing keyboard controls and other junk
10. cat /opt/retropie/configs/all/controllers.cfg >> /opt/retropie/configs/all/retroarch.cfg
11. reboot
12. BOOM! Play games. My four year old son and I have been playing a lot of Ken Griffey Jr’s Winning Run and NBA Jam.

This probably is missing a couple of steps and ignores all of my mistakes. Seriously, there are better tutorials out there than this one!

My hardware includes copper heat sinks, but no fan. This is enough to support overclocking on “High” in retropie-config without the Pi ever getting hot, even after long gaming sessions. NES, SNES, and Genesis games all run smoothly for the most part. 90% of games just work.


Occasionally I try a ROM (usually not a major title) doesn’t work quite right, and very occasionally one won’t even load. I chalk this up to emulation optimizing the 90% case to get these running on Pi’s relatively limited hardware. SNES sound seems a little off on some titles (not broken but… off). But most of the time the games work as well as they would on the original systems. And the gaming world of 20+ years ago is brought back to life!



Powered by Facebook Comments

Project Idea: Eric’s Magic Window

This is a project idea that I have to turn a single board computer, LCD monitor, and a few other parts into a Magic Window. I’m hoping to actually work this idea and document it in this space, as I get parts/funding (funding is me saving up my fun money, I’m not looking for crowdsourcing). When it’s complete, I’ll probably share photos/video of the final product, system images, instructions, etc for anyone else looking to build one.

The Concept

Eric’s Magic Window is a framed LCD screen mounted to the wall. It looks sort of like a window. It is controlled by a remote control, and has the following operating modes:

1. The Digital Window – in this mode, it will stream one of several live camera feeds from around the world. In this mode, it will look most like a window. A number of live camera feeds are broadcast on sites such as

2. The Digital Frame – in this mode, family photos are shown slow slideshow style from a photo collection, either stored locally or in the cloud.

3. The Digital Gallery – same as digital frame mode, except we see landscape photos and paintings instead of family photos.

4. The Wall Calendar – in this mode, you see a month view of Google Calendar.

5. Weather Center – The current weather report. Stretch: figures out current location from IP address.

Parts Needed

1. Single Board Computer (e.g. Imagine Tech Creator CI20, Raspberry Pi B+, Banana Pi M2, or BeagleBone Black)
2. SD or MicroSD for storage, 16+ GB
3. WiFi dongle if board doesn’t have it built it
4. Remote control + receiver of some sort, possibly a mini-keyboard or maybe just a basic remote
5. LCD display w/ HDMI connector in the neighborhood of 13″ – 17″ + HDMI cable
6. Hardware to mount LCD on the wall
7. clever way to attach the board out of site behind the monitor
8. Custom cut wooden frame
9. I need some solution that will save me from having a power cable hang down my wall.

The Plan

My plan is to get enough parts to develop this and to get the proof of concept working. I’ll then tweak it until I’m happy, and only then tackle the mounting, framing, etc.

Resources and Challenges

I’ve been working with Linux for 20 years now, including some systems administration experience. I’ve been a professional software developer for 16 years and currently work as a web developer on a LAMP/js stack. I have the skills needed to make all the software do what it needs to do.

The biggest challenges for me will be on the mounting/building side of the project. Luckily, that comes last, which will give me time to figure it out I hope. If the challenge of this part of the project looks like it’ll be too much, I’ll just put the monitor on top of one of our bookcases and punt on the wall mounting.


As soon as I have what I need to get started, I’ll start the project and start blogging a developer’s diary here. I’ll take this as an opportunity to provide review information from any computer hardware I use for the project. Follow me on Twitter at @ericwburns if you want to keep tabs on this.



Powered by Facebook Comments

Why your fonts don’t look right on the Chrome app


So, fun fact: the Chrome app for Android or iOS tries to help you SOOOO MUCH. In fact, it will hijack the CSS styles of text on your web site and tweak them to be more readable. It tweaks them by as much as 300%. It tweaks only some of the text elements and leave other ones alone. So yeah, HUUUUUUGE form labels next to teeny tiny form elements for example. Ugh.

Chrome calls this “font boosting”. I call this “stress boosting”.

If you’re like me (and I know I am), you find this annoying because it makes your web site look like garbage.

Do you want to tell the Chrome to disable font boosting? Luckily, it’s easy to do so. Just apply this style to some root element of your page like this:

#page_wrapper {
max-height: 999999px;

if you have a page wrapper. If not, do this instead:

html * {
max-height: 999999px;

The style will cascade down, and Chrome will stop being such a control freak helpy helperton. You’ll have control to style your css as you see fit.



Powered by Facebook Comments

Facebook Login, My Old Nemesis

An Alternative Login with Facebook Implementation

So every app of sufficient complexity has one feature that always seems to break in odd ways. You tweak it, duct tape it, adjust it, but it just breaks, breaks, breaks. When this happens enough, you tear it down and rebuild the silly thing from scratch. This is what happened with my Facebook login implementation for


I used to have an implementation based on this:

This default implementation runs on event listeners. For whatever reason, this version of Facebook login proved to be really fragile for me. After many hours trying to shore it up, I spent some quality time with the Facebook API documentation and built the version below instead.

My version works by passing callbacks to the FB.login function to perform an app login on success.

1. Create a Facebook app

Just follow the instructions here under section 1 of this page:

2. Initialize the Facebook SDK on your page

Next, make sure your page initializes with Facebook’s API correctly. There’s no need to nest any of the javascript in a document ready function.

<div id="fb-root"></div>

<script type="text/javascript">
   var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
   if (d.getElementById(id)) {return;}
   js = d.createElement('script'); = id; js.async = true;
   js.src = "//";
   ref.parentNode.insertBefore(js, ref);
window.fbAsyncInit = function() {
      appId      : '123456789123456789', // replace this with your appId
      channelUrl : '//'+window.location.hostname+'/channel.php', // Path to your Channel File
      status     : true, // check login status
      cookie     : true, // enable cookies to allow the server to access the session
      xfbml      : true  // parse XFBML

3. Write a function to handle success

Let’s skip to the end before circling back. After we have a successful Facebook login, we’ll need to tell our app that we’ve validated a Facebook login for a specific user and create the appropriate session. At this stage we’ll have a Facebook user object to work with, ‘me’. We’ll see how we get that in step 4 below – just go with it for now.

Let’s make sure this object is valid (i.e. has an id). If it is, I hit an endpoint in the app to get a signature for that id. This is to prevent people from spoofing my app’s facebook login form and creating bogus accounts and sessions in the app. Once we get the signature (‘key’) back from the app’s endpoint, we enter the id, the signature, and some basic user information (found on the user object) into the login with facebook form and submit it. The form submits to an action that will validate the id against the signature. If it checks out, it will see if a user exists in the app. If not, we create one. And then either way we create a session.

The code I’m showing you is everything in the view layer. I leave the signature endpoint and login endpoint to your imagination. Those will be specific to your app anyway. This code also does not need to be in a wait for document ready.

<script type="text/javascript">

// this is the function to login to our app once the Facebook login
// is successful and we have a Facebook user object
function login_with_facebook(me) {
   // this is the endpoint in my app that I get a validation signature from
   url = '/facebook/jskey';

   if ('id' in me && {
      $.post(url, { 
      }, function(response) {
         // use the user object data and jskey signature to post the #fb_form form
         if ( {
            $('#fb_form input.fb_name').val(;
         if ( {
            $('#fb_form input.fb_id').val(;
         if (me.gender) {
            $('fb_form input.fb_gender').val(me.gender);

         var data = jQuery.parseJSON(response);
         $('#fb_form input.fb_key').val(data['key']);

4. Hook up a login button or link and a logout link

Finally, we create a button or a link with the class ‘login_with_facebook’ somewhere on our page and another link with the ‘fb_logout’ class. To make it functional, we use this code.

<script type="text/javascript">
$(document).ready(function() {

      // Get the login status, perform actions accordingly
      FB.getLoginStatus(function(response) {
         if (response.status === 'connected') {
            // user is logged into Facebook and has already authorized your
            // app. request a user object and call our app login function
            // with it
            FB.api('/me', function(me) {
               if ('id' in me) {
         else if (response.status === 'not_authorized') {
            // user is logged into Facebook, but has not authorized your app.
            // Facebook login, passing in a callback to fetch the user object
            // and perform an app login on success
            FB.login(function(response) {
               if (response.authResponse) {
                  FB.api('/me', function(me){
         } else {
            // not logged in to Facebook. We do a Facebook login, passing in
            // a callback that fetches the user object and fires an app login
            // on success. The same actions as the previous case, but I'm
            // keeping them separate to more clearly show the three possible 
            // states you can be in relation to Facebook. You also may want
            // to handle these cases differently.
            FB.login(function(response) {
               if (response.authResponse) {
                  FB.api('/me', function(me){

   // who said breaking up is hard to do?
      // preventing default to make sure our logout request fires and
      // then redirects to where the link points
      window.location = $(this).attr('href');


5. Knit it into your web app
The parts that I haven’t shown you are on the backend of my app. You’ll need to figure out what makes sense for your app. Specifically, the parts of my app I’m not showing you are:
1. the /facebook/jskey endpoint that creates a signature for an id. For best security, the signature for a given id should change over time.
2. the endpoint that the form submits to. This endpoint validates the id against the signature. If valid, it checks to see if the user exists yet for that Facebook id in our app. If so, it just creates a session and redirects back to the page. If not, it will also create a new user.

Also, I leave my #fb_form form, login button, and logout link html to your imagination.

We’re not handling failure with much sophistication, just ignoring it. In the places where failure is detected, you could easily add some code to flash the user a helpful message if you desire.

That’s it, I hope you find this useful.



Powered by Facebook Comments