Originally part of the BuildBrighton / element14 global challenge, this blog describes how to make different USB input devices for any purpose.

Take Five

Right in the middle of the element14 global challenge, Toby announced a Retro Computing Sinclair Night on Thursday May 5th at the Skiff. So for a few minutes, all minds wandered (actually, that's not true - most of the time minds are wandering all over the place: it's taken a massive effort to stay on track with this little project for as long as we have!) onto all things Speccy.

It might be fun to try out your ZX Spectrum knowledge, if you're that way inclined.
Here are a few loading screens from some famous (and not-so-famous) ZX Spectrum games. How many can you identify (obviously game names have been removed, also author names so no popping off to Mr Google and asking him for the answers!)

Here are a few easy ones to get you started...

These will show us who was a casual user, and who had a drawer full of pirated C90 cassettes, with slightly more obscure titles....

Bonus marks for getting either of the last two:


Making the cube

Although we had a working dice prototype, to fully test our idea, we need to actually put a cube into the tray/reader. To achieve this, we need to get our breadboarded prototype inside a cube not more than about 4cm in size.

While we have access to surface mount PIC chips (16F628A in SSOP20 SMT package) with a total length of about 11mm and less than 1mm between pins, these chips are far too small to solder onto a home-made PCB by hand.
A slightly larger sized SMT chip is available (in SOIC package) but after investigation and trying a variety of PCB layouts, we discovered that using the standard SDIP (through hole) package requires a PCB that is only slightly larger than the one for SMT chips.

As a result, we've decided to stick with the slightly larger, but much easier to solder, through hole version of chips and components (hand-soldering SMT diodes is possible but can be tricky - using through-hole components for everything means almost anyone should be able to make a working dice PCB)

With all this in mind, we're making up some PCBs that will fit inside a cube, which can be used with the existing tray/reader board. The same technique will be used as for the tray reader, detailed in an earlier blog post.

Even using the larger through-hole components, the final PCB is small enough to fit inside a cube that will fit into the tray slots in the reader

The final, populated PCB, with through-hole components (PIC microcontroller and diodes) is small enough to fit inside a 4cm cube. Contacts on each of the six faces connect to the PCB/microcontroller using a number of micro-fine wires:

Green for ground, red for power, white for serial signals. It looks counter-intuitive because of where the components have been placed on the board, but if you follow the traces, you'll see it does actually match up with the schematics! 0 comments

A working prototype!

At the latest BuildBrighton meeting, (Thursday nights at the Skiff) we managed to get a working prototype of our cube and a tray/reader.

Each cube contains a 16F628A PIC microcontroller and is programmed to read two bytes from eeprom (internal memory) as a unique identifier (two bytes gives us 65,535 possible IDs to play with) and then broadcasts a message over serial in the following format:

<255, unique ID high byte, unique ID low byte, pin used to enable to cube/facing>

This message repeats over and over again.
The cube has three pins, one slightly longer than the others, so that when the cube is in place, in the reader, it pulls one of the input pins on the tray to ground. This is how the tray detects the presence of a cube.

The cube also looks at which of it's own PORTB pins has been pulled low (the input pins have internal pull-ups on them, so be default the input on all PORTB pins will be high). From this, the cube knows which face is face-down in the cube.

The reader has four trays and is connected to an 18F4550 PIC microcontroller. If a cube is present in tray1, one of the first four pins on PORTD will be pulled low (by the larger pin on the cube, bridging the contact between input pin and ground).
The tray/reader then knows to start reading serial data on the tray one serial RX pin (there are four serial RX pins, one for each tray, and all serial pins in tray one are connected, all serial pins in tray two are connected, and so on).

When in place, the cube draws its power from the tray/reader and starts broadcasting.
The reader checks for the presence of a cube and reads the serial data from it. Using the information from the cube, and by knowing which input pin the cube has pulled low, the tray can calculate
  • Which cube is in which tray
  • Which cube face is pointing down (and therefore infer which face is upwards)
  • Which way around in the tray the cube is (N,S,E,W)

By the end of the BuildBrighton evening we managed to acheive all of this, using a mixture of home-made PCBs and some breadboarded circuits. Although not exactly cube-shaped, the principle was tested and proved to work! 0 comments

Dice/cube schematic

While development on the cube reader continues, when it's done, we're going to need something for it to actually read. That's why it's time to concentrate on the cube itself.

After much deliberation and possible methods of reading the position and location of a cube, we decided to go for the "intelligent cube" approach.
This basically means that each cube will have a microcontroller inside it, and will broadcast a message to the tray reader when it is in place. One of the biggest problems with any form of portable microcontroller-based project is that of power - usually solved by including a battery. This isn't suitable for our little cubes, because most of the time they won't actually need to be broadcasting. We don't want to be running down a battery unnecessarily while the device is idling because once a cube has been built, it will form a sealed unit (so replacing dead batteries will not be possible).

We don't want to use portable power, but we do want to use a microcontroller inside each cube - so it makes sense to have each cube draw power from the tray/reader when it is in place (since it's only when a cube is first introduced to a tray reader that we need it to broadcast its data: once a cube has identified itself, it can go back to sleep!)

As well as drawing power from the tray, the microcontroller will look at which of the six sets of power pins (there is one pair of power/ground pins on each face) was used to switch it on. From this, it knows which face is facing down in the tray (and by inference, which face is pointing upwards, being shown to the user). To achieve this, every ground pin goes directly to a digital input, and connects to the ground pin on the PIC, via a diode.


Schematic for tray reader

Although it seems backwards, here's the schematic for the dice tray reader.
(it was actually designed before the pcb mentioned in earlier posts, but not written up properly 'til now!)

The design is quite simple - ports PORTB and PORTD have internal pull-up resistors, so we'll enable those and use them for the digital inputs. Each slot in the tray has four input pins (so we can work out which way around the cube has been placed) plus one serial data line. The input pins need to be pulled high/low when a cube is not present, so slot 1 uses PORTD.0-3, slot 2 uses PORTd.4-7, slot 3 uses PORTB.0-3 and slot 4 uses PORTB.4-7. The serial data lines have been put onto any four free input pins (PORTA.2-5) and any remaining (output) pins are used to illuminate some LEDs.

When we start reading a cube, we'll turn a red LED on.
When a cube has been read (and the data validated as correct) the red LED goes out and a green LED is lit.

This way, all empty slots have no light and if any cube fails a read, a red LED will indicate which cube(s) have caused the error. Cubes that have been successfully recognised will light the LED green. We may even use bi-colour LEDs instead of two separate components - reducing component count and allowing a yellow colour to be achieved if necessary for future development. 0 comments

Making the reader PCB

With the pcb design drawn out (check out that trace routing!) it's time to have a go at making a circuit board. Each cube location (there are four in total) has five pins. Four of which are simple digital inputs and one a serial comms input pin.
Four lots of four digital inputs make 16 digital inputs - perfect for use with an 18F4550 PIC microcontroller. Ports PORTB and PORTD both have eight pins and internal pull-up resistors, making them perfect for these digital inputs. Another four pins will be used to read data over serial, one serial pin per location.

The only way to see if the design will work in practice is to get on and make the board! This design uses pin headers and some left over IDE cable to create just the cube location part of the tray. The processing side of the board can be designed later - for now, we'll connect the tray reader part to a PIC microcontroller on a breadboard.

To actually make our pcb, we're using the tried-and-tested "toner transfer" method to get our layout design onto some copper clad board.

Step 1:
print out the pcb design onto some press-n-peel blue paper using a laser printer. Inkjet printers won't work! If you've not done this before, print the design onto regular paper first, then cut a smaller piece of press-n-peel and stick it over the design. Re-print the pcb layout onto the paper - that way you're not using a large sheet of expensive transfer paper for a small circuit design!

Step 2:
Tape one edge of the press-n-peel to some copper board using masking tape.

Run the copper board through an industrial laminator at 180 degrees celcius about four or five times, to ensure a good quality transfer. Don't forget to feed the board with the taped edge first!

If you don't have access to a laminator, you can use a t-shirt transfer hot press, or even a domestic iron. Note that the more pressure you use (with a laminator/heat press) the less heat needed. If you're using an iron, get ready to put plenty weight behind it, and try not to move it too much during the transfer process (else your press-n-peel will smudge around on the copper board and ruin the design!).

When the printed image shows through on the reverse of the press-n-peel, the image should be fully transferred. Note that the darker the black, the better the transfer. Four or five passes through a laminator is usually sufficient - too few and not all of the image will transfer resulting in broken traces, but too many and the toner will start to spread, resulting in fused or joined traces. With a hot iron on "cotton" or just before the steam option, you can expect to be ironing for about five minutes. Only experience will tell you when it's done, so be prepared for a few trial runs to get the perfect transfer!

Step 3:
Peel off the press-n-peel and check the board for broken/fused traces.

If any traces have fused together, run a small craft knife between them, to separate them completely. If any traces are broken (check the press-n-peel backing paper for bits of black to see where potential broken traces may be) touch them up with a thin-tipped permanent pen (a 0.5mm Sharpie pen should do it).
Use the backing sheet to help identify possible broken traces. If you see any black toner left on the backing sheet, look at the image on the copper board and you should see where it has come from. Touch up any broken traces as necessary. Scrape away (using the tip of a craft knife) any toner that has spread and cause traces to join - it's easier to remove the etching mask now, than it is to cut through fused copper traces after etching.

Step 4:
Now the magic begins! Cut the copper board to size and place in a tub of Ferric Chloride etching solution. Use a plastic (ie non-metallic) container for the etchant and be very careful not to splash it about - this stuff stains like mad (and will make a real mess of your kitchen's stainless sink)

Step 5:
Agitate the ferric chloride to speed up the etching process. If you're in a rush, place the container in a hot water bath to increase the temperature. Where possible, etch your board with the copper side down. When all traces of copper have been removed from the board (ferric chloride etches from the edges of the board, towards the centre, so make sure all traces have etched fully) clean off the board and remove the toner (I use something like a sponge-sanding block for simplicity). You should be left with a shiny new copper-only PCB!

Replace the used etchant solution into a non-metallic container (I use a large glass coffee jar). It can be used again for future etching, and is good for up to six months. Do not dispose of this stuff down the sink: it will damage any steel surface (even stainless steel) permanently and can even damage your mains drains if there are any iron pipes still in your home!

Step 6:
One last check for fused and broken traces - hold the etched board up to a strong light source and you should be able to clearly see all traces. At this stage you can, if necessary, separate traces with careful use of a craft knife. Broken traces can be fixed with a fine-tipped soldering iron and really careful solder re-flowing, but it's a tricky job and not for the faint-hearted!
Now drill any holes (using a Dremel or hand-operated PCB drill with a 1mm drill bit) and your board is ready for populating. Done!


Tray reader PCB

At this stage of the blog, we've already explored a few ideas and have a decided on a method for reading the position of up to four cubes at a time, which will be explained in more detail later.

The basic idea is that each cube will be relatively low cost and simple.
It is important that each cube does not require batteries or similar power source - the cubes will draw their power (where needed) from the tray.
Although we're working on a specific task for the BuildBrighton/element14 Global Challenge, we've decided to make the tray and cubes into a generic input device, so that they can be used for a number of other projects in future.

To this end, we've decided that each cube should be uniquely identifiable - so we're going to use a PIC16F628A inside each cube, and on the face of each cube, in one corner, have a set of four pins:
  • power
  • ground
  • serial data
  • another ground

When powered, the cube will look at which of the six power pins on each of the faces has been used to power the microcontroller, and from here decide which face is face-down in the reader (from here, inferring which face is face up and being shown to the user). The cube will then broadcast a message over serial comms, containing a 4-byte unique ID (ok, not globally unique, but like an IP address, there are 255^4 = 4,228,250,625 - more than 4228 million - possible id numbers) and a single byte to tell the tray which face is lying in the tray.

That takes care of which cube is in which "slot" in the tray/reader, and which face is up/down. The last thing to work out is the orientation of the cube (how it is twisted in the tray - whether it's top edge is facing north, south, east or west). To do this, we're going to use four groups of four pins arranged in a square.

When the a cube is placed into the tray, one of the four pins gets pulled to ground while the other power, ground and serial pins make contact to the corresponding pins on the cube. This allows us to transfer data from the cube to the tray (over serial) AND depending on which pin has been pulled low, to work out which way around in the tray the cube is sitting.

A diagram will probably explain this a little better.
Here's the PCB layout of the version attempt at a tray reader (drawn with ExpressPCB):