Introduction: Magic Answers Ball With Arduino Pro Mini and TFT Display
A while back, my daughter and I took apart a Magic 8 ball so that she could replace the twenty responses with ones of her choosing. This was a gift for a friend of hers. That got me thinking of how to do that on a larger scale. Could we have a lot more than 20 responses? With an electronic version we can!
So this will describe how I disassembled a Mattel Magic 8 Ball (sorry, Mattel) and used a round TFT display to show an incredible number of additional responses (the smallest micro-SD card I could find was 8GBs, so it is really overkill for what it's being used for). The ball uses a Sparkfun Wake-on-shake board to trigger the response and to turn off the ball afterward to conserve the battery. A recharging board is used to allow for the battery to be recharged from a USB connection.
Organizer 12pcs TP4056 Charging Module 5V Micro USB 1A 18650 Lithium Battery Charging Board with Protection Charger Module (you only need one of these, but the 12 pack was less than $9)
DAOKI 5Pcs Micro SD Storage Board (again, you only need one, but the 5 pack was still less than $9)
Kingston 8 GB microSD (you might have an old one of these lying around your house)
Perma-Proto Quarter-sized Breadboard PCB (you can also just use whatever PCB you like)
FTDI Basic breakout 3.3V (you might already have one of these if you've done a similar project with the Arduino Pro Mini or similar board)
4 Pin Housing with 2.54mm JST XH Male/Female Pin Header Dupont Wire Connector Kit (optional, but recommended for connecting the battery)
Other basic supplies:
Sugru Moldable Glue (could use duct tape and hot glue, but I like this better)
Double-sided foam tape
Rotary tool of your choice (i.e. Dremel)
Step 1: Cut the Magic 8 Ball in Half
First you will need to split the Magic 8 Ball in half. I secured mine to a work table with the flat side down using a furniture clamp. Using a Dremel with a basic cutting disk attached, cut along the seam of the ball. You will need to cut deep, pretty much as far as the cutting disk will allow. Take it slow. Even after you have cut all the way around, you may need to use a flat head screwdriver or chisel to do the final separation. There is a cylinder that holds the "magic" liquid and the icosahedron (twenty sided shape - yes, I had to look that up) inside. Just throw that away or use it in some other project. If you do use it in another project, let me know what you did so I will know what to do with mine.
You'll be left with two halves as shown in the pictures. I have done this three times now and the most recent time, the white lip was smooth rather than having ridges, so your ball may look slightly different than the one in the picture.
There will still be some plastic slag around the outer edge (the melted and rehardened plastic). Brake that off with your hands, if you can; using a tool runs the risk of scuffing up the finish on the ball and the slag comes off pretty easily.
Step 2: Prepare the Ball
There are two modifications we will need to make to the plastic halves of the ball.
First, in the open half, the one that has the "8" painted on it, we will need to shave out an area large enough for our USB charging board to sit with the USB port sticking out. I used my Dremel with a coarse sanding drum attached. You want this as thin as you can get without going clean through. Then cut a small opening just big enough to allow the USB port to poke through to the outside. I used a caliper to measure the USB port, but you could probably eyeball this if you need to. Again, I used the Dremel with a small cutting attachment to make the opening. The first two pictures show the opening and what that looks like with the USB board behind it.
Second, in the other half, the one with hole on BOTH sides and the white plastic lip, prepare a spot for the display to sit. Just inside the opening where the display will sit, there are plastic ridges and a rubber(?) flange on the inside of the opening. Take the flange out and set it aside. We will be putting that back later, but we want that out of the way for this step. The display has a rectangular extrusion on one side that will not allow it to sit flat in the opening if some of these ridges aren't removed. Using the coarse sanding drum on the Dremel again, shave these down as much as possible. Come in from the hole where the display will be for the best angle. It should look like the pictures when complete. Note, the pictures show the display in place, but DO NOT ATTACH IT yet.
Step 3: Prepare the Responses on the Micro-SD Card
This step is a bit more complicated than you might think. If you don't want to create your own list of responses, skip to the last paragraph of this step.
The intention is that we can give the ball any list of strings to be used as possible responses and they will be centered on the screen without any breaks in the middle of words. We don't want to do this processing on the microcontroller and we want a file with static record size in order to be able to find any particular line quickly.
Even though the display is round, it is functionally a virtual rectangular display with only pixels within the circle visible. The display can show multiple size text, but we only use the smallest version which is 6 x 8 pixels. Using this size, there are 315 characters that the display can put on a screen (21 characters per line times 15 lines), but only 221 are visible and each line has a different number of visible characters. See the problem?
I wrote a Java program to take in a file of unformatted responses and convert them into fully centered records that could be easily displayed on the round TFT. (link to download the "FormatToPicksFileFullyCentered.java" file).
Without going into an explanation of the whole code, the general idea is that we work our way backwards from the center(ish) and inserting spaces to make sure that we don't break words across visible lines, then do the same thing from the center forward. Finally, we loop through all of the lines and center each line inside of the full 21 character lines to create a record of exactly 316 bytes (315 alphanumeric characters plus a new-line character). The code actually works through three fonts, x 3, x 2, and x 1 to see which is the largest font that can be used and still fit the text. The centering is a little off for the x 2 and x 3 fonts, sorry. Be careful of characters that take up more than one byte, these can throw off the file that is output.
Copy the "picks.txt" file onto the micro-SD card.
If you don't want to go through the trouble of creating your own list of picks, I've included my list of picks that you can just copy onto the SD card and use. I could not upload a .txt file to instructables at this time so here is a link to where you can download the picks.txt file.
Step 4: Upload Code to the Arduino Mini
First off, if you have never used the Arduino Pro Mini before, you can't just plug in a USB cable and download; you have to use an FTDI board and connect the wires to the appropriate pins on the mini. I won't give a tutorial on that here, there are plenty out on the web. For me, I did not want to solder a permanent connector onto the microcontroller board that would only be used once to download the code, so I created a little clip that can be used to program the mini without soldering (see pictures). This was inspired by products like Fiddy, but I don't have easy access to a 3D printer, so I made my own out of a potato chip clip. If people are interested, I'll make an instructable just for that.
On to the code. There are a couple of interesting parts to this code, but it is mostly straight forward.
In the setup function, there is a decent amount of code that is dealing with getting a good random seed. The typical method of using the analog reading from an unconnected pin does not give a varied enough response in my experience. I get a number between 477 and 482. Since the Arduino random function has one and only one sequence and the seed determines where to start in that sequence, such a narrow range will not produce enough possible responses in the end. Keep in mind that this code essentially starts over every time the Wake-on-shake board turns the power off and back on, so the initial sequence position determined by the seed is crucial. To help with this, I write a very small file to the SD card to keep track of the last seed and add that to a new value coming from the unconnected pin.
Once a pick is selected in the loop function and read into a character array, we can't just print out the whole string. The display has a limit of how long of a string it can handle at a time. For that reason, we have to loop through each of the fifteen lines and send them to the display one at a time.
Required external libraries:
Step 5: Wire Up the Components
Time to do all the soldering of wires. I tended to err on the side of slightly longer wires than I really needed, but that ended up working out well.
In the attached schematic, the TFT display is represented by a connector rather than a picture of the whole display (which I could not find a Fritzing part for). I've labeled the wires/pins based on how they are labeled on the part. Similarly, the SD card is not the exact one I used, but I labeled the wires/pins for the part listed.
There is one component that I did not solder together at this step: the battery. Instead, I used a four-pin connector with the two middle pins removed (second picture). This let me test all the components wired together and then disconnect the battery while I attached everything to the ball.
Finally, I used a quarter-size permanent breadboard PCB to make the power and shared connections easier. You'll see that in the assembly pictures.
Test that everything is working.
Step 6: Attach Components to the Ball
First put the display in place and use some Sugru to secure it (first two images). Don't forget about the flange you removed earlier, you should have that back in place before securing the display in place.
Next, I taped the proto-board into the bottom of the empty half of the ball. I kept all of my solders on one side of the board, so I still had half the board that I could tape over. I then taped the battery on top of that same half of the proto-board (third image).
Both halves are now connected by wires. Figure out where the USB hole will end up when you put the two halves together. If the white lip has the spines sticking up, keep in mind that it needs to come down centered into one of the wedges of the white lip because we will be securing the USB charging board between two of the plastic ridges on the lip.
Using a small piece of double-sided foam tape, attach the USB charging board. The double-sided tape should not cover all of the bottom of the charging board because the end with the wires attached will hang over the center edge of the white lip. So the tape should cover about three quarters of the bottom surface of the board. Put the tape on the bottom of the board first, then press it into the spot you've decided on. The USB connector should be at the edge of the ball, sticking into the black area of the plastic without going outside of the ball. Finally, use some more Sugru over the top of the board and securing on both sides. This just adds additional strength for when a cable is pushed into the USB port.
Put the micro-SD card into the SD card module now.
You can secure the other components to the white lip if you wish. I just tucked the remaining components behind the display.
Step 7: Put the Two Halves Back Together
Double check that you have inserted the SD card and that you have tested all the components together.
Ok, if you're ready, make a long snake out of some Sugru glue and run it all the way around the edge of the half of the ball with the white lip (first picture). The glue should be laid right on the junction where the black and white sections of the plastic come together. Putting the glue here makes sure you have a strong bond while minimizing the amount of glue that squeezes out from the crack after the two halves are joined.
Press the two halves together making sure that the USB port sticks through the hole previously cut for it. Using the furniture clamp, clamp the two halves together just tight enough to keep the halves together, no need to clamp it down hard. The Sugru glue will harden in about 24 hours.
If you have some of the glue that squeezed out of the joint, feel free to scrape it off with your finger or a smooth cloth/paper towel.