This is going to be a very long tutorial. But, before you go further, you might have a look at the last section, where I've put some demos, so that you have an idea what the end result looks like!
The idea for building an electronic chess board, that you could actually play with, came to me a long time ago. When I was a kid I used to play on my own because neither my father nor my sister wanted, or had time, to play with me... Then computers started to evolve and you could play against the computer, which was great. Nowadays, you can even play on your smartphone. So, who needs a physical chess board anymore? Right?
Well, about 6 years ago I became a father and, when my kid was about 4 and a half years old, I started to teach her how to play chess. I realised that it would be much easier for her if she could actually have a chess board that showed her the allowed moves for each chessman. Especially the knights. These were a real pain for her to learn how to properly move.
As a consequence, the engineer in me started to contemplate at building a physical chess board that could help kids learn easier and, of course, be capable enough to even play against it. But before starting any actual work, I did some research to see if I could buy such a chess board. I'm an engineer alright, and I like building things, but if the product I want to build is already on the market and it's cheap enough, I'd rather buy it than spend a lot of time and money re-inventing the wheel.
Well, it turns out there are very capable products out there... at similarly "capable" prices. The best I've found, and probably the only one worth looking at, was more than 3000$.
So, now what? Where do I start? How do I design this thing?
This one was a trickier subject than I first thought. There are a myriad of sizes to choose from. FIDE (World Chess Federation) states that the size of a square should be between 5 to 6 cm. So, a competition chess board should be at least 50cm x 50cm. Do I really need the board to be that big? I'd prefer it smaller, more compact, so I can store it somewhere when not used. However, for this project, the board must have enough space under it for the electronics to fit in. And the squares must be large enough to be able to fit a sensor and an LED under each.
After lots of web searching, I wasn't able to find a single piece chess board with enough space under it for the electronics. The ones I found were either too small (3cm x 3cm squares) or they had no box to hide all the electronics in. They were just one piece of wood...
In the end, after analysing every possibility on the market (well, almost), the best option was a foldable chess board. When folded, these form a box where you can place the chessmen. So, I could use the box for the electronics. The only issue was that I had to split the electronics somehow for each half of the board and be able to communicate with the main board in order to send sensors' states and get commands to switch square LEDs on/off. Luckily, I2C comes to the rescue. It was designed for inter/intra board communications and, with this in mind, I went ahead and acquired a foldable number 6 chess set (board and pieces) for about 51 Euros. The square size is 58mm and the size of the king is 96mm. The board looks pretty nice but the top is 3mm plywood which, as you'll see later, will prove to be quite beneficial. Also, the chessmen are weighted and feel very well balanced.
There are not many possibilities here. The really expensive boards on the market use some sort of RFID technology to perform chessmen detection. Each piece has a RFID tag under it and the board will properly detect the piece type and color. This is, probably, the best way of doing the detection but, also, the most difficult to implement for a hobbyist, like I am. So, this method had to go.
The other possibility is to use magnets attached to each piece and a sensor under each square to detect it. The problem with this approach is that we always have to start from a known position... But, that's a trade-off I can live with. The logic will keep track of the moves and we'll always know the current position. The starting position can be a new game or a custom position. For the latter, a web interface must be implemented in order to configure the board with the starting position.
So, using magnets seemed to be the best trade-off. Now, the sensors under each board can be hall sensors or reed relays. At first, hall sensors seemed like the best method. You can place them in the center of the square and the detection will be quite precise. Also, they're supposed to last a lot more than reeds since there are no moving parts involved. However, there are two issues that made me dump them in favour of the reed relays: they have 3 pins, Vcc, Gnd and Digital_out, and they need power in order to perform the detection. That means that the wiring will be slightly more complicated (64 more extra soldering points) and, also, the firmware has to take care of powering them up row by row in order to read their output.
Reeds, on the other hand, are dead simple to use, they have only 2 pins, so less wires, and, since they'll be used to detect chess pieces, they'll also last forever as they're guaranteed to work from 10000 switches to millions. Unlikely to reach that number any time soon with a chess board!
This one was the easiest part, really... On my short list, at the time I was designing this (exactly a year ago), was the Raspberry Pi 1 B+, Beaglebone Black and Intel Edison (with the mini-breakout board). The Edison won by a good margin. It was dual core, small footprint and it had WiFi/BT integrated in it! No need for extra dongles. Exactly what I needed. Oh, I guess there was something else that counted when I chose the Edison... At that time, I was an Intel employee and I got it at a discount. Though it was still more expensive than the Rpi... Oh, well.
Now that the brains, board and sensing technology has been decided, let's move to the design. Since the board was split in half and, also, there were sensors and LEDs under each square, it was pretty obvious that I couldn't do it with just the Edison. Too many wires going to the other half of the board, since the Edison will be placed in one half. Also, I needed also a way to configure the board and start a game without the need of a PC. So, some sort of "command panel" was needed which will accept the user input through push buttons and send it to Edison.
Also, I thought it would be nice to have some clocks, so the player(s) see the remaining time. For this I decided to use common cathode 4 digit 7 segment displays which needed a driver chip in order to function.
The best way to put this all together was to equip each half of the board with its own controller and perform the communication between Edison and the controllers over I2C. Also, each controller will have an interrupt pin to Edison in order to avoid polling on the Edison side.
A little explanation of the above diagram. Top and Bottom Controllers perform, essentially, the same three main jobs:
- monitor reed switches states and send an interrupt to Edison board whenever there is any change;
- switch on/off the square LEDs;
- start/stop the chess clock;
The Top Controller performs two additional jobs:
- Regulate the 12V DC power supply input down to 5V, as needed by the controllers and command panel;
- Perform level shifting from 5V to 1.8 and viceversa, because Intel Edison needs 1.8V signals. Hence, the I2C bus signals and the interrupt lines need to be shifted;
The Command Panel's job is to allow the user to select various settings, using push buttons:
- select the game mode: normal or learning. When in learning mode, all the possible moves will be highlighted immediately after a user picks up a chessman. This mode is useful for kids (and not only);
- select the game level: 0 - play against another human, 1 to 7 - play against Stockfish chess engine (1 being the easiest level, 7 the hardest level). There are 3 status LEDs that will show the current level;
- select the opponent color, when playing against the Stockfish engine. Hence, the engine can play with either the whites or the blacks;
- select the time for the game, starting from 90 minutes and going down to 5 minutes;
- start the game. When this button is pushed, a new (or custom) game is started;
Now that you have the overall picture, let's begin with some wood work. Specifically, 64 x 3mm holes for the squares LEDs, 1 x 10mm hole for the DC socket, 8 x 3mm holes for the status LEDs of the command panel, 5 x 4mm holes for the push buttons.
But, before you start, fire-up your preferred 2D CAD software (fwiw, I used QCad) and create a template for the 3mm squares LEDs like in the picture below.
I find this to be the best way to drill perfectly aligned holes. Be careful though, you'll have to take into account the edge width of the box when deciding the offset of the LED hole from the bottom edge of the square. See below picture:
Once you have the template printed out, place it on top of the squares and, with a very sharp object (I used a small screwdriver), punch through the paper in order to mark the drill holes. Move the template around and do the same, until you're done.
Now it's time to start drilling. Take your time, you're only 64 holes away.
We're not done drilling yet but, for now, take a break. We'll complete the rest of the holes later.
These will be needed, at the end, in order to attach the polycarbonate covers. You can leave the electronics open, if you wish, but there's always a risk of touching the electronics inside when you open the box or, if you have a curious kid, worse things can happen!
So, head to your local bricolage store and buy some square and corner wood sticks, cut them 3mm less then the box depth, depending on your polycarbonate sheet width, and glue them like in the picture below. At the end, we'll screw the polycarbonate sheet to them.
Now it's time to cut the Lexan sheet. Remember, measure twice, cut once! For cutting Lexan, I used a jig saw with special polycarbonate blades to avoid melting. Finally, you should end up with something like this:
Do not remove the Lexan sheet protective cover just yet because you might scratch it. Also, do not forget to test that the box closes correctly.
To be 100% sure you'll have no issues, do this: cut the spacers but don't glue them just yet, cut the lexan sheet, put everything together carefully, test that the box closes correctly then, if everything went just fine, make it permanent.
This one was the hardest thing for me as I didn't really have the proper tools to do the job. With a rotary tool (like those Dremels) I would've probably done it much easier.
Anyway, for this, return to the 2D CAD software and prepare a template that looks like below:
You'll have to measure your 7 segment display dimensions first, obviously, and, again, take into account the box edge so you don't cut into it. For the "lucky" ones without a Dremel, drill those holes first to give yourself some room to move.
I had a tiny saw blade that I wrapped in some cloth and, with patience (lots of it), I ended up with two little windows like the one below.
This phase has 4 steps. First step is to remove the old felting from the pieces, in order to attach the magnets. This is how the chessmen looked with the old felting attached (the white piece) and removed (the black piece). Did you see the depression where the weights are? That's actually good news. That's where the magnets will fit in and, after putting back new felt, everything will be levelled.
In order to remove the old felting, use a sharp cutter and slowly rotate the piece while cutting off the felting. After, you might want to use some sand paper to remove the remaining old glue.
Second step, is to attach the magnets right in the center of the piece, where the weight is. I used a little drop of SuperGlue to fix the magnet. Doesn't have to be some special glue as it only has to keep it in place for re-felting.
The third step is to put new felting on. Apply glue (I used the same universal glue that I used to glue the wood spacers on) on the bottom of each piece and then lightly press the pieces on the felt. Just arrange them all on the felt and do the cutting after the glue has cured.
Next day, cut off little squares around each piece:
The last step is to trim away the excess with some scissors. Here's a video of the process:
Now it's time to build the controllers. We'll need them ready in order to arrange them inside the box and prepare the next steps.
I started with the Top Half Controller as it contains the power regulator and the level shifter. Without it, we'll not be able to daisy chain the rest of the controllers for testing.
The power regulation is achieved by using a LM78705 to step the power down from 12V to 5V. This will be used for everything else, except for Intel Edison which comes equipped with an on-board power regulator.
The microcontrollers used for all 3 boards will be Atmega8 from Atmel. I had quite a bunch of these around and were quite a good fit for this: 3 timer counters (one of which will be used for the real-time clock), enough I/O pins to use for the reed switch detection, SPI for communicating with the 7 segment display driver (MAX7219) and TWI needed to communicate with Intel Edison. Perfect.
For the level shifters, I followed this NXP application note. However, the MOSFETs must be chosen carefully since we're dealing with a very low signal level on the Edison side: 1.8V. If the gate threshold voltage is high, those MOSFETs will never switch. After some research, I found the TN0702N3-G (from Microchip) which offers a very low gate threshold voltage from 0.5V (minimum) to 1V (maximum). Absolutely brilliant!
A few words about the chess clocks and the square LEDs connections. I was very lucky here. The MAX7219 is able to drive eight 7 segment digits plus the associated dot for each digit, or 64 individual LEDs. However, we can also combine 7 segment digits and individual LEDs! Hence, the first DIG0-DIG3 lines on MAX7219 will be used for the chess clock and we are left with the possibility to drive 4 digits x 8 LEDs = 32 additional LEDs. It's exactly what I needed for half a board: 4 rows x 8 columns. So the MAX7219 will be fully used. No waste! :)
Now would be a good moment to talk about the Atmega8 feature to connect a 32768Hz crystal and have a pretty accurate chess clock on Timer 2. The design recommendations state that, for low frequency crystals, it is not necessary to connect external capacitors. It will use the internal ones. Unfortunately, earlier chip revisions have the following problem "CKOPT Does not Enable Internal Capacitors on XTALn/TOSCn Pins when 32KHz Oscillator is Used to Clock the Asynchronous Timer/Counter2" (page 318, Errata section). Hence, your chip may not oscillate with a 32kHz crystal without external capacitors. It took me a day to realize that after I had to switch to another Atmega8 that I bought from somewhere else... So, keep this in mind if you have issues. Better yet, test you uC on a breadboard first and make sure it oscillates without external capacitors. BTW, the main clock is given by the internal RC oscillator.
The reed switch matrix is pretty common. The diodes are needed to avoid ghosting. I'm not going to get into detail about ghosting but a simple search on the web about "keyboard ghosting" or "sensor matrix ghosting" will reveal a lot of details about it. Using the 1N4007 diodes for the switch matrix is kind of a waste since they are quite overrated for this application. But I got them cheap...
Regarding the Command Panel design. If you look at the schematics you'll notice that the current limiting resistors for LEDs are 1kO. Generally, is good to limit the current through your LEDs as it will increase their lifetime but you'll have to calculate that value depending on your LEDs. However, I didn't use any limiting resistors on the final board! That's because the space on the board was too tight and, also, because I was going to use PWM to decrease the average voltage applied to the LED, hence reducing the intensity.
On to soldering....
If you have the means to do PCB etching, I would highly recommend it. I used perf boards. They're convenient but once you finished the board and you notice it doesn't work from the first try, debugging will be pretty difficult. So, test the connections as you go, using an ohmmeter. The sooner you discover a problem, the easier to fix.
That said, here's how my top/half controllers looked like:
I left the Command Panel last as it needs special attention. This little board has to stay in front of the board, in the bottom half, so the the user can change the game settings. So, the space is pretty tight as I mentioned above. I chose to mount the push buttons and the status LEDs on one side, the uC and the rest on the other. The challenge here is to solder the push buttons and the LEDs perfectly straight (well, as straight as you can). Also, the LEDs must be of the same hight so they look nice from the front. I used a breadboard for that.
The LEDs were inserted through the perf board into the breadboard, so they couldn't move easily. With the help of a digital caliper, I made sure they were the same height before soldering the LEDs to the board.
Before fitting the electronics in the box, we need to create a small channel for the ribbon cable that go between the top half of the box to the bottom half of the box. Before starting, put the two main controllers in their respective position and visualize the position of the ribbon cable. Then, make a sign for the approximate position of the channel and start carving, but don't make it too deep. About 3-4mm deep is enough. Using sand paper, smooth out the channel and make it slightly curved towards inside.
Now, small openings have to be done in the Lexan sheets as well, so the cable can go from one side to the other. Use the sand paper on the Lexan openings too. They need to be smooth enough not to damage the wires. Use the below picture as guidance:
Now that we have the Command Panel done, we need to drill the holes for the push buttons and the status LEDs. This step was a real challenge. Firstly, if the push buttons or the LEDs are not perfectly perpendicular to the perf board, you'll have a hard time inserting the board through those holes. Secondly, make sure the holes are perpendicular to the chess box. If you fail at both, don't worry, you're not alone!
Now, return to your 2D CAD software and create a top view of the Command Panel board, like in the picture below.
At first sight, creating this template seems complicated as it has to match the board exactly. It turns out, it's not that hard. I used a perf board with hole spacing of 2.54mm. Using this info, I could calculate precisely where my buttons and LEDs are. Print it and put the board on top of the template. The button tips and LEDs should land exactly on the marks.
So far so good! Until I started drilling. Since I didn't have any special drilling machine to drill perfectly perpendicular holes, the holes were slightly off when they reached the other side. With the help of really fine sand paper wrapped around a very thin screwdriver, and a lot of patience, I could enlarge the holes and make them in a cone shape. BTW, the push buttons do have a cone shape.
Don't forget to use LEDs without edge, so you can insert them through the holes. In the end, you get something like this:
As you can see, because of the slight misalignment, I had to enlarge the holes a little in order to fit the board.
And finally, the last hole in the chess box will be for the DC power supply jack socket. But, before that, you'll have to create a splitter, so that we can supply both the Edison and the controllers. Here's how it should look like:
Once this is done, or before (it doesn't really matter), use the caliper to measure the diameter of the socket's screw.
Mine had 10.87mm so I used a 10mm wood drill bit. Once I finished drilling, I screwed the socket into the box. I had to use some pliers to screw it in. Cannot be done with the bare hands.
Before connecting to it, the mini-breakout board needs the pins soldered. As this is not a tutorial about soldering the headers to Intel Edison, here's a good link that shows how to solder the headers to the mini-breakout board.
Connect the wires for the power supply, on J21.
The rest of the connections are below:
- I2C6_SCL -> J17 - Pin 7;
- I2C6_SDA -> J17 - Pin 9;
- V1.8 -> J19 - Pin 2;
- TC_INT -> J19 - Pin 4;
- BC_INT -> J19 - Pin 5;
- CP_INT -> J19 - Pin 6;
I used wrapping to connect these wires. But you don't have to.
At the other end, attach a Dupont 6 pin socket that will go to the Top Half Controller's header.
At this point you should have all 3 controllers ready. Attach some plastic standoffs, four of them, to each controller board. For Edison as well. Use female standoffs! This way, you'll be able to easily remove the board using a screwdriver. But before glueing to the chess box, arrange them in the desired position, put the Lexan covers on and close the box. If it closes completely, you're good to go. Apply glue on the plastic legs (do not remove them from the boards) and fix them to the box.
At this stage, you can glue the 7 segment displays as well. Be careful with the display pins. Don't cover them with glue.
Let the glue cure till the next day. This is how it looks like after the controllers and the Intel Edison were fitted:
Before glueing any reed switch to the box, make sure you solder the diodes to the reed switches first. Use an ohmmeter and a magnet to test that the diode-reed pair conducts current when you put the magnet near the reed switch. Test all 64 pairs.
How to place the reed switches? Well, depends on the reeds you use and the magnets. You'll have to test for yourself what is the better way to place the reed switch so that, when you move the magnet inside the square, it will close when you're around the middle of the square. The reed should open when going towards the edges of the square.
You'll have to find the right mix between: square size, reed switch length and magnet diameter.
For this particular foldable chess board, with 58mm squares, 14mm reed switches and 10mm x 1mm magnets were perfect.
The best position of the reeds is on the diagonal, slightly off center. On the inside, you'll need to guide yourself after the LED holes to know where the squares are. Mirroring the holes template you used above, and putting it on the inside, helps a lot in marking the squares corners.
Using a hot glue gun, fix all diode-reed pairs to the wood. You might want to use less glue than I did. :)
After the glue has set, solder the wires.
You will need to remove the controller from the board as some wires will go below it. Repeat the process for the other half.
Now it's time to put the controllers back and make the connections for the reed matrix and the chess clocks. Prepare three 12 pin female headers for each controller. Plug them in the controller's 12 pin headers and connect the wires to them. I used wrapping for this job but, again, you don't have to. You can solder them.
Put the chess board on a flat table and start inserting the LEDs into the holes. Since the top of the board is made of 3mm plywood, the LEDs will fit just in, down to the LED's edge. Make sure the LED heads do not come out on the other side. If they do, level them. Using the hot glue gun, fix the LEDs in place.
Solder the matrix wires and connect them to the Top and Half Controllers. This is how the top half of the box looks like after the LED matrix is done:
Now, what's left to be done is connecting the controllers to Edison. For that, we'll need some ribbon cable (the same as ones used for wire jumpers), a crimping tool and Dupont connectors (a couple of 6 pin connectors and a couple of 5 pin connectors):
For connecting the Top Half and the Bottom Half controllers, you'll need to measure the ribbon cable carefully as it will go through the channel, between the two halfs of the chess box.
Repeat the procedure for connecting the Bottom Half Controller to the Command Panel:
Before doing any tests, the controllers need to be flashed. For that, you'll need an AVR programmer and the firmware. You have to grab the firmware from my repository:
To compile it, you'll need avr-gcc installed on your machine. If you're running a Debian compatible Linux distro, run:
sudo apt-get install avr-gcc avr-libc binutils-avr
For Mac users, you need to use brew to install the AVR toolchain:
brew tap osx-cross/avr brew install avr-libc avr-binutils avr-gcc
I don't have any instructions for the Windows users as I don't use Windows. But you can install Linux in a VM and compile the firmware on it. I guess that's the best method I could come up with for the Windows users... Sorry.
To compile, just run:
When that finishes, in the out/ directory, you'll find the binaries: bot_hb_controller.hex, top_hb_controller.hex and cmd_controller.hex.
Flash them to the right controller.
As you already know, the controllers can perform just a few tasks: detect the chessmen movement, switch square LEDs on/off, start/stop the chess clock and allow the user to send commands to Intel Edison. However, the entire chess logic will be located on Edison.
Ok, let's take it step by step.
First, let's grab the chess engine. There aren't many good opensource chess engines to choose from. Actually, the best one is Stockfish. It's even better than payed chess engines.
I forked the official Stockfish repo because it needs a small patch applied before compiling for Intel Edison. So, clone the repo from my Github account:
$ git clone https://github.com/lrntplc/Stockfish.git
Then checkout the ecb branch:
$ cd Stockfish && git checkout -b ecb origin/ecb
Now that we have the chess engine source code, we need to compile it. However, it has to be cross-compiled in order to run on Intel Edison. For that, you need to download the cross-compile SDK from Intel downloads page. Pick the one for your platform. That is, if you're running a 64bit Linux distro, get the 64bit SDK. Keep in mind, though, that the following instructions are for those running a 64bit Linux distro on their machine.
To run the installer for Edison SDK you'll need Python 2.7 on your machine:
$ bash iot-devkit-toolchain-linux-64bit-edison-20160606.sh
Follow the installation instructions. Once it finished, source the environment script:
$ source <PATH_TO_THE_SDK_DIR>/environment-setup-core2-32-poky-linux
Now, it's time to compile the Stockfish for Intel Edison:
$ cd Stockfish/src $ make build ARCH=x86-32
The stockfish binary is in Stockfish/src directory. You can go ahead and copy that to Edison:
$ scp Stockfish/src/stockfish firstname.lastname@example.org:
If the compilation went well, you should be able to execute it on target.
Now, the chess engine must be able to communicate with the controllers somehow. For this, grab the host part of the project from my repo:
$ git clone https://github.com/lrntplc/ecb-host.git
It contains the userspace driver for the controllers, the state machine, the main script and some static files that will be used for the web server.
I guess, you're now wondering, what web server am I talking about? Well, remember that I mentioned earlier that I want to be able to start a game from a custom position? Well, since there's no way to detect the chessmen types using magnets and reed sensors, I had to do it through a web page, on Edison. But I'll get into that later.
You will find the requirements and the deployment procedure in the repo's README.md file. I'm not going to repeat it here.
However, I will try to explain a little how the host side software is structured. Basically, it consists of 3 main Python files and the static files needed by the webserver:
- EcbDriver.py - here are all the low level functions needed to control the Top/Bottom half and Command controllers. Nothing fancy here. Also, when the controllers are instantiated, a callback must be passed on that will be called when an interrupt is received from the physical controllers. The driver depends on libmraa to function properly;
- EcbFSM.py - here is the state machine containing the entire logic. Also, here we interface with the chess engine and the openings database;
- ecb.py - this is the main file that will instantiate the state machine and so on. Also, it will start a basic webserver on port 8080 where you can see what happens on the physical board and, also, can configure a custom position;
There is one more thing you might want to download. You can do without it but I highly recommend downloading a good openings book in polyglot format. Otherwise, it'll be very boring. I successfully used the ones found here. Remember to configure the paths to your engine and openings book in ecb.py file.
You're now ready to perform the first tests. Connect the controller boards one by one. Use EcbDriver.py to perform tests. You can execute this file as it is and modify it to test that your LEDs switch on/off, that your reed switches work, you can start/stop the clocks, press buttons on the command controller, etc. In the main function there are some tests I used. Feel free to play with them.
Once you're satisfied that everything is ok, you can start the entire stack with:
$ systemctl start ecb
and play some chess.
In order to protect the electronics inside, the Lexan transparent sheets are used. Seal the box when you're done testing and you're confident that it works. You'll be able to open it up later as well, if issues arise. Two issues worth mentioning here: pre-drill the wood spacers with a smaller drill bit before screwing the Lexan sheet and use a countersink on the Lexan sheets so that the screw head doesn't come out.
That's about it! You've made it to the end!