The Tinct is a full-colour RGB buttonpad that plays a colourized version of Conway’s Game of Life. It was originally inspired by the monome and, with a firmware replacement, can function as a monome-compatible device using a superset of the monome serial protocol and OSC command set.
This page is meant to collect information about what the Tinct is, what it does, and how it works, and it will be updated as I update the device (and as I have time). If you’re interested in building one yourself, and might want to buy a kit, please get in touch with me via email (jonathan@ this domain name).
Conway’s Game of Life
For a detailed explanation, I recommend the Wikipedia entry, but I’ll give it a brief overview. Conway’s Game of Life isn’t a “game” in the traditional sense, because there’s only one player and no winning or losing. There are, however, rules, turns, and a board. Here’s how it works: the “board” is a grid of squares, as big as you’d like. Each square is called a “cell” and it can be “alive” or “dead.” Before the game starts, the “player” chooses which cells are alive and dead. Then, on each subsequent turn, a cell is determined to be alive or dead based on a few simple rules:
- If the cell was alive the previous turn, and it had either 2 or 3 neighbours that were alive (but no more or fewer), then it stays alive; otherwise, it dies.
- If the cell was dead the previous turn, and it had exactly 3 neighbours that were alive, then it is “born” and becomes alive; otherwise it stays dead.
The “game” is interesting for many reasons, but mainly because simple start positions can cause complex, unpredictable, and sometimes beautiful patterns and consequences to emerge.
Life on the Tinct
The Tinct is only an 8×8 grid, which isn’t very big for a Game of Life. To make things a little more interesting, the edges wrap around. That is to say, a cell on the left edge is considered to neighbour with the cell in the same row on the right edge, and a cell on the bottom edge is considered to neighbour the cell in the same column on the top edge. Technically, this means we’re playing the game on a torus, or donut.
On the Tinct, you can toggle the state of a cell by pressing the button. If the entire board goes completely dead, or if the pattern stops changing, then after a few seconds the board will reset, randomly choosing a new starting position.
Life in Colour
Typically, Life is played with cells being either on (alive) or off (dead). To make things more visually interesting, I coloured the cells according to a formula inspired by this article. When the board resets, or when a button is pressed, the living cell’s colour is chosen randomly. After that, when a new cell is born, its colour is a mixture of its three “parent” cells’ colours. The mixing is done like this: each colour is treated as a unit vector on the colour wheel. The three parents’ vectors are all added up, and the result is rescaled to also be a unit vector, whose angle gives the new cell’s hue. This will all make more sense when I make some diagrams, but for now just trust me that it ends up looking cool.
The cells also “age” in two ways: first, as a cell stays alive, its saturation is gradually decreased, so that older cells fade to white. Second, as a cell stays alive its hue also moves slowly around the colour wheel, so that no single colour can continue to dominate.
How it works
The Tinct is made up of two different PCBs: a button board (there are four copies of this) and a controller board (just one copy). The controller board is a shield that attaches to an Arduino.
There are two main tasks that the hardware needs to take care of: detecting button presses and illuminating the LEDs. The button presses are read using multiplexing. What this means is, at any given moment, electricity is only going through one row of buttons, and all the columns are read. The microprocessor is constantly cycling through the rows very quickly, so that button presses are never missed. This is explained well, and in more detail, in this article. The controller board uses two shift registers — a 74HC164 8-bit serial in/parallel out and a 74HC165 parallel in/serial out — to handle the button scanning.
The LEDs are handled using TLC5940 16 channel PWM LED driver chips. Each 4×4 board has one of these nifty little ICs on it, and each RGB LED is connected to one channel. The LEDs are multiplexed over colour; that means that red, green, and blue are never on at the same time. Rather, each colour is on very briefly, so that it fools are eyes into thinking they’re blended. This method lets me use one chip per board instead of three.
The code is an Arduino sketch, but it makes extensive use of direct port manipulation and the advanced features of the ATMega328 chip, specifically hardware SPI and timer interrupts.
I hate sharing my code when I haven’t cleaned it up, but I’m biting the bullet. More explanation, optimization, cleaning out the cruft, and commenting will be forthcoming, but for now here it is in all its ugly glory.