Friday, February 6, 2015

Meet Elbert

And now, for something completely different.  Lest you think my interest in electronics begins and ends with blinkenlights, I'd like to introduce you to Elbert.


The Elbert V2 from Numato is an entry-level FPGA board.  The best way to explain it for someone new to the game is that while you tell a CPU what to do, you tell an FPGA what to be.  The FPGA is basically a blank slate of basic logic elements which can be wired together to create almost anything. Video cards, CPUs, digital signal processors, you name it.  Your imagination--and the size of the FPGA you can afford--are the only limits.

I have been interested in FPGAs for quite some time, but until recently, the barrier to entry has been pretty high, and there hasn't been much information available for the hobbyist. Several enterprising makers are committed to bringing FPGAs to the masses with projects like the Papilio and the Mojo which sell for around $75 and provide a lot of hobbyist-friendly projects and tutorials.

Unfortunately, neither of the above boards includes any peripherals beyond some basic buttons and LEDs.  To add peripherals, you must buy an external add-on board that plugs into the FPGA board's headers. Generally, these peripheral boards cost $40 or more, depending on the peripherals. This adds quite a bit to the price of entry, and was a little more than I wanted to pay for something I was still unsure if I would get into.

When I found the Elbert V2 FPGA board from Numato Lab for only $30, it seemed like a safe jumping off point.  The board includes a number of built-in peripherals and connectors, including dip switches, push buttons, seven segment displays, VGA and audio output, and an SD card slot. The XC3S50A FPGA in the Elbert is tiny; probably one of the most basic chips you can buy. However, I would argue that's a not a bad thing because you need to learn the basics before you take off on any really ambitious projects, and having a limited platform forces you to do that.

The low price plus built-in peripherals make Numato's products an excellent value, and I have had a great experience so far with their tech support.

Elbert's Big Brother

Once you've exhausted the capabilities of the Elbert, Numato has the next step up the FPGA food chain waiting in the wings: the Mimas V2, which is only $50.  The Spartan 6  FPGA in the Mimas has over 5X the available logic elements and 10X the built-in memory of the Elbert. It also comes with a 64MB external DRAM chip, which vastly expands its potential.  It should be possible to recreate a lot of famous 8-bit and even 16-bit computers and video game consoles on this board.

Honestly since the Mimas is only $20 more than the Elbert, it might make sense to go ahead and buy it to begin with since it's a much more capable board.

Github Repository

I have checked my code for the various peripherals supported by the Elbert and Mimas into the numatolib Github repository.  Also check out the wiki on the same repository, which has a lot of resources and notes for using the Numato FPGAs.

The Matrix Gets Smart

In my search for a better LED matrix, I've finally arrived at what actually feels like a finished product: the SmartMatrix from PixelMatix.  This comes in a complete kit for $130 with everything that you need to build a nicely finished project. The only thing you have to add is an 8x8 shadowbox frame that sells for less than $10 on Amazon. Since I have sold off my soldering equipment during my move, I opted to order the pre-assembled kit for an additional $20.

With all the hardware taken care of for me, I could focus on the software to make interesting displays, which is what I've really wanted to do all along. The SmartMatrix is driven by a Teensy 3.1 from PRJC, which is a tiny ARM microcontroller board that can be programmed with Arduino. It comes with some really nice software called Aurora that has lots of interesting visual displays.  I have made my own fork of it to which I've added several features.

TPM2 Streaming Mode

One of the first things I wanted to do was add TPM2 streaming over the Teensy's serial USB connection.  This allows the matrix to be controlled from PC software such as Jinx!, PixelController, and Glediator.  I made a YouTube video showing off the results:


Instructions for using Streaming Mode are on the Aurora wiki.

The Game of Life

Finally I come full circle to the goal I had stated for myself in my very first LED Matrix post: to run Conway's Game of Life.  Aurora came with a basic game of life implementation that only had one color that cycled through as the generations progressed.  I decided I could make it more colorful so I tweaked the algorithm a bit.  Each cells is colored according to the number of times it has come to life.  Also, as a cell dies, it slowly fades into darkness instead of immediately disappearing.   It's definitely more colorful and feels more, well, organic.  I find the effect quite mesmerizing.

Munching Squares

After I was satisfied with my changes to the game of life, I went on to implement what is perhaps the original display hack, Munching Squares.  This interesting pattern is simply the result of applying the XOR operator to the X and Y coordinates on the grid.  It was discovered by the O.G. Hackers at MIT who were programming the PDP-1 in the 60's. 



Coincidentally, these same hackers went on to become obsessed with Conway's Game of Life and discovered and cataloged many of the interesting emergent patterns that the Game of Life produces.

Gifs

There is an alternative LED Matrix Kit called PIXEL, which has a lot of really cool animated gifs that were designed by artists especially for a 32x32 LED Matrix.  I loaded up my SD card with these so now I have a lot more animations to look at.

Troubleshooting

At one point, I had a scare while uploading a new Aurora sketch and thought my Teensy had bricked itself during reprogramming, but I was eventually able to revive it.  Being a tech support engineer by day, my natural instinct is to share my experience in case it helps anyone else out with a similar problem.

When I hit program on the Arduino UI, it encountered a program error, and went completely unresponsive. The matrix wouldn't light up, Windows said I had connected a USB device that had malfunctioned, and the COM port no longer shows up. I tried disconnecting the power and USB, reconnecting it, reconnecting only the power without USB, hitting the program button multiple times, switching to a different USB port and nothing worked.

I went to the PJRC Teensy forum and found this thread.  It seems to be a fairly common problem. Some of the people on the board suggested to either "double-click" the programming button or hold down the button while plugging in the USB cable. I'm not quite sure which, but one of these worked.

When I did it, Windows no longer showed the "one of your USB devices has malfunctioned and is not recognized" error, but I still didn't see it show up as a COM port.  However, I noticed that device manager was refreshing when it loaded so I dug around elsewhere and found it was showing up as an extra "HID-compliant device" under the "Human Interface Devices" tree, but Windows showed no apparent way to distinguish the 3 identically named devices. 

I rebooted my computer into Linux and ran lsusb and was relieved to see that Teensyduino was listed as one of the devices. I installed Arduino and Teensyduino and successfully programmed the blink sketch and confirmed the light on the back of the Teensy was blinking.  I'm not sure if booting into Linux was really necessary--maybe it would have worked if I had tried to program in Windows immediately after the Teensy showed up as a HID device.  

At this point, I didn't really want to go through the trouble of installing all the Aurora library dependencies, so I booted back into Windows. The Teensy showed up again as a COM port, so I went into Arduino and re-flashed Aurora.

Future Plans

I'm working on a heuristic to determine when the game of life has reached convergence.  Currently, Aurora resets the world after a fixed number of generations, and sometimes it cuts off the game while interesting things are still happening.  My idea is to detect when the universe has devolved to a steady state containing only still life, or simple oscillators. I have come up with a pretty good algorithm, but it still gets tripped up occasionally, usually when the only thing left is a glider that circles the screen and never runs into anything.

Additionally, I'd like to implement the ability to send the Aurora software commands over the serial interface to do things like switch the display mode or offer more customization for the patterns with settings would be too difficult to adjust using the IR remote.  I would eventually like to extend this with a mobile web interface that will allow you to connect to your computer and control the settings from your smart phone.

LEDs, Take Two

This blog post has been languishing half-written in my blogger account for a long time. I have since found an even better solution for driving a 32x32 LED matrix called SmartMatrix (more on that later), but I wanted to share what I had already written about my second attempt along the way.

With the red/green matrix I shared in my last post, I never got past the single 8x8 prototype that I demonstrated in my video.  I eventually tired of the tedium of endless soldering and the frustration of trying to find a way to route all the wires required to connect the 216 pins of the 9 8x8 panels together.

I had taken a break from electronics for a while, but was looking for an excuse to dive back in.  Then I found this video made by Henner Zeller, who has written some software to drive an RGB matrix from the Raspberry Pi.




After seeing this, I ordered the Raspberry Pi Starter Pack along with a 32x32 RGB LED Matrix from Adafruit.  At the time I bought it, the matrix was pretty pricey at $120, so I only opted to get one instead of the four that are chained together in the video above. The price has come down to around $40 since then.

Wiring

This matrix is already fully assembled so the only wiring required is a power cable and 16-pin data cable. The pins were not labelled on the matrix I got, so I looked at Adafruit's instructions to get the pinout for the matrix.  I found the GPIO pinout of the Raspberry Pi on the eLinux wiki, which is a great resource for all kinds of information about the Pi.

With this information in hand, I wired up a prototype using breadboard jumper wire to connect the appropriate pins on the Raspberry Pi's 26-pin ribbon cable to those on the 16-pin ribbon cable provided with the matrix. I connected each pin from the matrix's cable to the corresponding pin on the Raspberry Pi's cable as documented in the software's README. The important thing to remember when making these connections is that the pinout is flipped when looking at the connectors of the ribbon cables.

Once I had the prototype working, I wanted something a little more permanent, so I got some female to female pre-crimped wires plus some 2x8 and 2x12 connector housings from Pololu.  To make a custom cable, you just snap the end of the wire into the appropriate place in the housing.  Before doing this, I decided to move OE- from pin 2 to 27 on the Pi and CLK from pin 3 to 11 so that pins 2 and 3 remain free for the I2C expansion bus.

Adafruit now offers a Raspberry Pi LED Matrix Hat that is a much tidier solution, but if you don't like to solder, you may find the technique I used above more to your liking.

Software

I started with Henner Zeller's original code is on Github.  I have forked his code on Github and made a few changes:


  • Swap blue and green pins so they match wiring shown in Adafruit's documentation
  • Changed OE- from pin 2 to 27 on the Pi and CLK from pin 3 to 11 so that pins 2 and 3 remain free for the I2C expansion bus.
  • Added support for the TPM2.net protocol for streaming video from your PC to the matrix over UDP.
  • Compiled against the Xenomai real-time kernel. Instructions for building a Raspberry Pi linux kernel with Xenomai support are here. There is also a Github repository with some helpful scripts here.


Results

It works pretty well, but because Linux is a multitasking operating system, getting precise timings is not always possible, and when the loop gets preempted, it causes noticeable flicker on the display. Compiling with Xenomai helps this somewhat but it's still noticeable at times.  Also, a bare Raspberry Pi with a wire connected to a bare matrix doesn't really feel like a finished project; however, it's a lost farther than I ever got with my last attempt.

Eventually, I found a better solution the SmartMatrix kit that I mentioned at the beginning of the post. I'll talk more about that in my next post.