Introduction: Tic Tac Toe on the Arduino With Multiplexing

[beginner-intermediate level]

Multiplexing.
I know a ton of instructables exist on it already, but I felt like making one and decided to start with something simple. Also, I wanted to make Tic Tac Toe!

What is it?

Multiplexing is a smart way of using your outputs and inputs. Instead of dedicating each input to a single source and each output to a single actuator, you can make combinations to be able to reach many more targets (with which I mean sensors and actuators).

What allows us to do that is timing. For example an input source, like a button or a sensor, often doesn't need to be read 100% of the time. Relative to the speed of any modern processor, a button press takes a long time and reading it's input a few cycles later will not change it's value. As you might suspect already, the same holds for a lot of actuators, like LEDs (which, if activated frequently enough, will look like they are burning constantly).

Some targets don't need to be accessed as frequently. This is a more rare application. An example for infrequent access is a bluetooth headset with line-in. Think of the switch between line-in and bluetooth, do we still need to access the inactive component? This is something that could be done using multiplexing (although it probably isn't).

For both cases the time that's left can be spent on other inputs and outputs. And that part is multiplexing.

This instructable will focus on targets that need to be accessed frequently.

But how can you do that?

In short: we apply a coordinate system to our targets (so each target gets a unique coordinate) and have our Arduino address each coordinate individually. Well, maybe it's best to explain that using an example.

You know how chess boards can have numbers and letters on the sides? That's a coordinate system. Those allow a player to uniquely identify each position on the board. In our case, each position will be a target.

Now, how can we apply that to electronics?

If you imagine a 3x3 grid (!) of LEDs, and want to control each of those lights individually, you'd need 9 outputs and a ground. However, using multiplexing you'd only need 6 outputs and no ground. Each output is then responsible for either a row or a column. This way we can address coordinates individually.

However, the downside is: there's limits on what you can address at a time. In general you can address every target in a row OR in a column at once (so for a 3x3 grid of buttons that means you only need to do 3 addressing rounds to read all buttons).

It might sound counter-intuitive to control an electronic circuit that is connected to only outputs. But it's as simple this: if you set one output to 0V, that turns into a ground. The target can then use the 5v of the other output as a source.

What am I going to show you?

Well, as I said: I wanted to make Tic Tac Toe.
This simple game has a 3x3 grid of positions, which can be either a cross or a circle. I decided to indicate crosses and circles with differently colored LEDs. Effectively, that makes it a 3x3x2 LED grid..

On top of that, a player needs buttons to indicate what position he chooses. I decided to use a button for each position, for each player, so that means 18 buttons in total to be read. So again, that is another 3x3x2 grid. (You could save outputs by making arrow buttons and a select button, but that wasn't the point of this instructable).

Wait! 3x3x2? You didn't say anything about a third dimension!

Well, to be honest, that's also not what we want to implement (we could, but let's keep it simple), so we're going to make a 3x6 grid! This covers the same amount of targets as a 3x3x2 grid and simplifies the thing a whole lot.

I'll add 2 more separate LEDs to indicate whose turn it is, but there's no multiplexing going on there. Ow and I'm going to connect everything to a single Arduino Uno. So we're going to connect 20 LEDs and 18 buttons to an Arduino Uno which only has 14 digital connections and 6 analog connections. So let's go to the first step!

Step 1: Requirements

1x Arduino Uno

10x LED of color 1

10x LED of color 2
I used Red and White (or green in the schematics)

19x 330 ohm resistor
or anything else that keeps your leds from frying, but keeps them lit. Yes, 19 isn't a typo.

6x 680 ohm resistor
The only reason these are used is to keep the button inputs from fluctuating when no button is pressed. There's a very very large range of other values that can do that job as well.

18x buttons (6x6 mm)

6x mini breadboards
You can use different types of course, then you might even get away with using just 4 (or even 3 if you use the big ones I guess). Do make sure they can click together (and removing the power lanes might be a nice option), it'll make things way easier.

1x small breadboard
This one is kinda optional, you can check step 5 to see what it is used for. Again: any other breadboard will do, even mini, you'll just have to puzzle a bit.

A whole bunch of breadboard wires. I counted 58 in my setup, but definitely get more.
Personally I never have enough of these things, and it's quite annoying to be blocked in your progress by lacking something as simple as a wire instead of a component.

Optionally: a set of tweezers can be a big relief sometimes.

I get most of my things from ebay, since it's really cheap and gets delivered to your home for no extra cost (if ordered from the right countries).

Step 2: LED Grid Fun 2x2

Let's start with an easy one, a 2x2 LED grid, which we'll expand on later. Use the 330 ohm resistors. If you're feeling confident, you can skip to the next step (or even to the one after that).

Try to follow the example shown in the figure exactly. While connecting this, try to understand what connections you're making and what they do. One tip: try to make smart use of the different colors of your wires (for example: green for columns, yellow for rows, etc.).

I chose the positions in such a way that the LEDs should form a nice square. So if you're using the large breadboards, try to take the power lanes into account if you want a nice square shape (or like I said: remove the power lanes if possible).

Here's a small piece of code that should show you if you connected everything properly. The LEDS should light up individually, clockwise. This is also an example of a slow type of multiplexing (only 1 light active at a time).

If you have no coding experience, there are plenty of tutorials on that and I highly promote playing with what you just build (1. Try to make it go counter-clockwise. 2. Try to make a pattern: 3 circles clockwise, 2 circles counter-clockwise).

Step 3: LED Grid Fun 2x2x2

Here's an extra level of complication: the second color of LEDS! As I said before: we're not going to do 3 dimensions, so we're making a 2x4 grid.

Again, as in step 2, follow the example shown in the figure exactly. Try to see it's just more of the same, and that the colors you're adding form a separate column.

For the fun of it, try to expand the test program from step 2 to include the new lights (and if you feel like a challenge: have one color rotate clockwise, and the other counter-clockwise, at the same time!)

Step 4: LED Grid Fun 3x3x2

Aaaaand more of the same! Do it!

I've added 2 test programs for this one.

  1. Will simply turns lights on and off like the previous programs.
  2. Is a small introduction into fast multiplexing. This allows multiple lights to be turned on at once.

Step 5: Buttons!

Alright, now here's where things become a tiny bit more complex (only a little bit, I promise!). Of course, we're again implementing a 3x6 grid. The LED grid is not included in the schematic (to keep me from making schematical spaghetti), but do keep it connected to the Arduino! For this step use the 680 ohm resistors.

For the LED grid you've been able set things up as I had explained them: with actual columns and rows. However, I decided to put all buttons for a single player on a single breadboard. As it turns out, it fits, but hardly! (You might want to "convince" some buttons to use less space by bending the pins a tiny bit).
It forced me to rearrange the connections in such a way that the rows and columns don't match the physical location of the rows and columns.
What that means is that, for instance, the button that Arduino thinks is in the first row and first column, isn't actually in the first row and first column of your breadboard. (Yes, that means we need to compensate for that in the software).

Of course I could have used more breadboards and made this as easy as the LED grids, but I decided to keep it in to demonstrate the difference between your perception and the perception of the Arduino.

The program I added is the full program for Tic Tac Toe. There's one more tiny step you need to do, but you could already start playing (if you connected everything right;) ).

Step 6: Status Light

Well, to finish, here's an easy task for you: the status light! This light indicates whose turn it is.

I hope you had fun building Tic Tac Toe and learned something from it. Have fun playing Tic Tac Toe!