a TiM Moodlight

dscn1798_26318788455_oA couple of weeks ago, I noticed a pair of old, first version TiM boards lying around at my local maker space, Maker’s Asylum and decided to put them to use by building a MoodLight. We love crazy names at WyoLum, and TiM is “The Intelligent Matrix”. We even tried building a controller for it called TiNA but it didn’t work out :)

dscn1788_26252600171_oTiM (The intelligent Matrix) is an array of 8×16 individually addressable 5050-WS2811 RGB “smart” pixels.  It is essentially 8 rows of 16 LED’s but with a very flexible connection scheme that allows you to control the whole array (128 LEDs) with a single pin or up to 10 boards (1280 pixels) chained together using 8 input pins. TiM boards can be linked together to create larger matrices. Stacking can be done in the vertical and horizontal orientations, and the pitch between individual LEDs is maintained when boards are stacked. Here’s the TiM User Guide.

dscn1793_26226395382_oI had two boards on hand, which I joined together to form a 16×16 matrix of 256 LEDs. TiM boards need an external controller, and I used an Arduino Clone that I designed for use at the Maker’s Asylum called MAPone (Maker’s Asylum Project #1). MoodLights require some form of user interaction, and I decided to use one push button (digital input) and one potentiometer (analog input). The whole thing is powered by a 5V wall wart.

dscn1799_26292824886_oFor the software, I tried some code I found on the web, but none of it did what I wanted – change modes by pressing the button, and change colors using the potentiometer. I can’t code if my life depended on it, so I chucked the problem at my go-to guys – Justin and Kevin. Justin is quick, like the Energizer bunny, and threw back code at me on the rebound. But it required using four potentiometer’s to control the colors. Since the HW was already wired up, I waited to see Kevin came up with something different, which he did. Nice code which allowed different modes to be selected by a button press. The first mode is the standard Rainbow colors from Adafruit’s StrandTest. Then, there’s a color changing mode, Breathing LEDs, Connection Machine (which looks something like Conway’s Game of Life), and finally a scrolling Text mode. This is enough to start with, and I’m sure if anyone at the Asylum wants to hack and dig in to the code, there’s a lot for them to play around with.

dscn1805_26363162042_oI designed the enclosure in OpenOffice Draw. A laser cut piece of MDF that wraps around the TiM PCB using some “living hinge” bends. I tried some junked 3mm MDF first, but the material was kinda bad – some parts cut well, while other areas were left with a charred and burnt top layer, so I had to scrap that. Next, I tried 5mm MDF that way lying around, and while it cut well, it was a tad thicker than I preferred and the hinges were stiffer being designed for thinner 3mm MDF. Anyhow, it worked and I was keen on just finishing this off. I also cut an additional square piece of 2mm white polypropylene sheet for the front diffuser. Most of the electronics was stuck in place using generous globs of hot glue. I added some hand drawn graphics to wrap it off, and left it at the asylum. Let’s see how they mount it up.

Here’s a video walk through of the MoodLight.


EDIT : Here’s a better walk through of the code by Kevin Osborn

MoodLight for TiM (The Intelligent Matrix)

This slideshow requires JavaScript.

Introducing VeloKey, the keyboard for your bike.

2015-02-28_0810260

Let’s face it, indoor training kinda sucks.  But our friends at Zwift.com have made it suck a lot less.  Actually they made it kinda fun.  Zwift allows you to ride with real friends and cyber friends in a virtual world.  You interact with the environment with (besides your bike) a keyboard, a mouse and a phone app.  It is great as is, but we’ve come up with a more intuitive interface we call VeloKey.

IMG_20160301_190323938

VeloKey is a Bluetooth interface to Zwift that consists of two a 1.8 inch dis,play thumbwheels, and a power up button.

VeloKey’s main screen allows you to navigate the Zwift world, and control the camera angles with ease.

IMG_20160301_192023109

Double-click the right scrollwheel to kick into Etch-a-mouse mode: left thumbwheel controls left-right mouse motions and the right thumbwheel controls the up-down mouse movement.  Pressing either thumbwheel acts as a mouse button.  Press both button’s in succession to get a double click on the connected computer.

IMG_20160301_193057374 (1)

Double click the left scrollwheel to activate the keyboard mode complete with caps, lowercase, letters and numbers, and don’t forget backspace.

IMG_20160301_193111135 (1)

VeloKey make riding indoors even more fun!

IMG_20160225_192746874

 

VeloKey is an Open Hardware project.  Download source files here.

WyoManiacal Display, no good can come of this!

Maniacal Labs has teamed up with WyoLum to make something amazing.

They’ve taken 24 TiM boards and assembled them into a 64×48 array of RGB addressable LED awesomeness with a refresh rate of 60 frames a second.

See the gallery below, sure, but don’t miss the opprotunity to see it in person March 13 at the NoVa Mini Maker Faire!

 

 

 

Pi Zero works with AlaMode and New Jessie Setup.

pi-zero-alamode

I confirmed today that the new Pi-Zero (super cheap/ super small new Raspberry Pi) works with AlaMode. As in the B+, the new GPIO connector is bigger than the old, but it’s less of a problem on the Pi-zero because of it’s small size. It’s a little hard to get a Pi-zero these days, but I managed to snag one as part of a “starter kit” from Adafruit, and since I needed the HDMI and USB OTG adapters anyway, It wasn’t a bad deal.

A help desk request came in saying there was something wrong with setup, and it turns out they changed the way startup happens in Raspbian between Wheezy and Jessie. Now getty is a simple service, and all startup services are controlled with systemctl

No more inittab, but you can download the new setup script: https://github.com/wyolum/alamode/blob/master/alamode-setup/jessie-setup
i
nstead of sudo ./setup, do sudo ./jessie-setup

I’ll eventually work the code back into regular setup, but I need to brush up on my bash-fu (unless someone else in the community wants to help?)

 

 

Adding OAuth2 to OpenSelfie

As in most things Internet, when you make them more secure, things get more complicated. A little while ago, photo uploads from OpenSelfie (our OpenSource Raspberry Pi AlaMode Photobooth) stopped working. It turns out that Google disabled “programmatic login” (e.g. with a username and password) from most of their apis, including the picasaweb api that we use to upload photos. Now the only thing that works is OAuth2, and it requires a little dance between a web browser signed into your google account, and granting of credentials for your application.

Diagram from the google developers site

Diagram from the google developers site

I had a real hard time figuring out how it all works until I found this link:

https://groups.google.com/forum/#!topic/google-picasa-data-api/4meiAJ40l3E

There were bits of information missing, and a couple of errors but I eventually figured it out. The new code is in boothcam.py in a procedure called OAuth2Login, which takes a pointer to a secrets json file (more on this below), a credentials store file (where the authenticated credentials are cached for you, and the user’s email address.

There’s also a standalone version for listing Album ids (useful for configuring a new album for an event in listalbums.py

You’ll need to install the latest google python api:

$ sudo pip install --upgrade google-api-python-client

If this is your first time, or you are looking to steal this code for another project, you’ll need some other python libraries, most notably

$ sudo apt-get install python-gdata
def OAuth2Login(client_secrets, credential_store, email):
 scope='https://picasaweb.google.com/data/'
 user_agent='picasawebuploader'

 storage = Storage(credential_store)
 credentials = storage.get()
 if credentials is None or credentials.invalid:
   flow = flow_from_clientsecrets(client_secrets, scope=scope, redirect_uri='urn:ietf:wg:oauth:2.0:oob')
   uri = flow.step1_get_authorize_url()
   webbrowser.open(uri)
   code = raw_input('Enter the authentication code: ').strip()
   credentials = flow.step2_exchange(code)

 if (credentials.token_expiry - datetime.utcnow()) < timedelta(minutes=5):
   http = httplib2.Http()
   http = credentials.authorize(http)
   credentials.refresh(http)

 storage.put(credentials)

 gd_client = gdata.photos.service.PhotosService(source=user_agent,
 email=email,

 additional_headers={'Authorization' : 'Bearer %s' % credentials.access_token})

You can see it creates a flow and asks google for credentials using your secrets file. (note that this is not checked in as you could use up my api credits. You;ll need to create your own.) It then spins up a web browser, makes sure you are logged in to your google account (the email address you configured OpenSelfie with) and asks your permission.

It will then give you a code to enter into OpenSelfie. I had troiuble cutting and pasting from the default web browser so I installed luakit, and made it the default browser

$ sudo update-alternatives --config x-www-browser

Creating your own API keys with the Google Developer console

Head on over to the Google Developer console and create a project for your OpenSelfie

Google-dev-step1

The name here doesn’t really matter. I just used OpenSelfie.

Next, click on your project and click on Credentials under API’s and auth.

If you haven’t already, you;ll need to configure the OAuth consent screen.

The only thing you really need to do is specify the  Product Name.

OAuth Consent screenYou’ll want to “Add Credentials/OAuth 2.0 client ID” Note: you don’t have to explicitely enable any additional APIs, as we are dealing with basic authentication and authorization here which is used by every API, and the photo apis haven’t been explicitly added to the console.

google-dev-step3

Next you specify the type “Other” and I named it Installed. Most of the instructions I saw seemed to imply there used to be a type called Installed. I’m not sure it’s critical that this name be here, but I used it to be safe. Click Create.

google-dev-step4

Now you’ll see it in your list of credentials for this app.

google-dev-step5

Click OK, and then click on the “Installed” credential. When that’s open, click on Download JSON. It will download a file with a name like client_secret_90328409238409238……json

google-dev-step6-download

rename this file OpenSelfie.json and put it in the OpenSelfie/scripts directory.

Configuring OpenSelfie

Start up OpenSelfie in a terminal window:

cd OpenSelfie/scripts
python ./photobooth_gui.py

If you’ve already configured your OpenSelfie, when it tries to login to google, it will find it doesn’t have credentials and then start the flow to create them. Your web browser will pop up, you should sign in to google, (with the same email address you configured.) and then it will ask you if OpenSelfie  can manipulate your photos.

Permission

Click on Allow, and then it will display a box with a long string of numbers and letters. Cut and paste that into the console window where it says “Enter the Authentication Code.” hit enter, and if all is well it will snap a photo and upload it to the album you have previously configured (or fail if you haven’t set it yet.)

paste-code

Fortunately, you only have to do this once! After this it will remember the credentials and periodically refresh them. The cached credentials are stored in a file called credentials.dat, so if you delete it, you’ll have to do the web dance again, as long as your json file is still there.

Conclusion?

Well, it seems to me that Google is trying to be a good security player, at the cost of ease of use. It seems that it’s very difficult to interact with devices with a limited UI (they suggest printing URLs and having them typed into another device). Fortunately we’re working with a full Raspberry Pi so it can all be done on the same machine. I’m sure the UI can be finessed, and if you do fork the project and make improvements, please make pull requests!