Say you want to make a pop-up book that can react to the reader -- such as by projection mapping various different scenes onto the pop-ups. This was the initial premise behind Tome of the Seashore, a digital-physical children's book I made as a part of my capstone at Arizona State University. It's a fun idea, but almost nothing exists on the internet to really offer any guidance on such a project. Rather than let my research go to waste in some forsaken PDF, I figured I'd organize everything I've learned into a single article about building and programming just such a book.
Use a Teensy
When you're considering putting electronic components into a book, it's absolutely crucial that everything remain small and flat. You can't use resistors because those are round and bulbous. You can't use a microcontroller with built-in headers because those stick out and create an uneven surface. For pretty much every component of the book, you have to find some way of making sure it doesn't push against anything or interfere with the natural functionality of the book.
You can save yourself a lot of trouble by skipping those problems and just using a Teensy. Because the digital ports on a Teensy all have built-in pull up resistors, you can actually set them to INPUT_PULLUP and save yourself the trouble of engineering a circuit with physical resistors. And, because they don't come with any headers, you can simply solder directly to the board.
Alternatively, you could use conductive thread to connect to the Teensy. In fact, seriously consider using conductive thread for this entire project. Solder is terrible at sticking to copper tape (which you'll want to use as much as possibly since it can lie flat) and it's never a joy to remove when you make a mistake. If you're like me and you like to think with your hands, the ability to easily undo and redo previous work is a must. Solder doesn't afford redoes well. Try to use conductive thread instead.
Use Copper Tape
I love copper tape. It's flat, it's conductive, and it's cheap. Also, copper is just a nice color to look at. Even if nobody else is going to be looking at the guts of your project, you will – so pick something that inspires you to make something beautiful.
That being said, there are a few challenges inherent to using copper tape instead of wire for a circuit, all of which come down to the challenges of maintaining contact and adhesion.
Sometimes you want two strips of copper to exist nearby but not form a complete circuit together. The solution to that is simple: don't let them touch. If they touch, there's a very strong chance they'll form a circuit. Obviously. However, the opposite is not necessarily true. Two strips of copper that come into contact with each other might form a connection, but they also might not. Copper tape is finicky in that regard. The only way to guarantee they will form a complete circuit is if you add a little bit of pressure to the contact point.
If the point of contact needs to remain constant, you can create that pressure by applying adhesive next to the copper tape and folding. Just make sure that you never put insulting adhesives between the two strips and check for continuity after you're done putting them together. Also, know that all adhesives add a slight amount of thickness that may be greater than the thickness of the copper tape. This is where the importance of testing really comes in. Always test on a small sample before applying to the larger project and do whatever you can to make sure the added thickness is less than the sum total of two copper strips.
If, however, you want the copper tape to move (such as on a slider), you'll have to get more creative. In the case of a slider, I recommend running the moving strip of copper through a snug paper loop which will help push a moving strip against a stationary copper lead, creating pressure. For added measure, place a small square of foam or felt behind the point of contact.
Just please, for the love of all that is holy, check for continuity before moving on.
The Sticky Situation With Adhesion
This is one of the challenges that I was never able to fully crack for Tome of the Seashore. If you're thinking about making your own interactive book, this is something you'll have to research yourself. I can, however, offer some help and a little bit of guidance on specific types of adhesive which I used and researched for this project.
The most common and the most discussed method of connecting two conductive materials together. Technically you can solder to copper tape but the connection is flimsy and prone to just breaking off.
In my experience this is just as reliable as solder with twice the convenience and none of the risks. I even used it instead of solder on my Teensy and it worked like a charm! I was able to make a slightly longer lasting connection between the wire and copper tape, but it was still prone to randomly just disconnecting from the copper surface.
By which I mean copper tape with a conductive backing. I know it exists, but I have never used it. The rolls I ordered both turned out to have insulating adhesive, so tread carefully when ordering from Amazon.
This is not conductive, but it needs to be discussed. I used a very specific type of double-sided tape – photo adhesive – and it is easily the most versatile material I used in the project. It's thin, it's flat, it has just the right amount of stickiness, and it comes in a convenient little tape dispenser that I basically took with me everywhere. Best of all, it hides behind the two things you're gluing together. It's a perfectly invisible adhesive!
Communicate Over Serial
I'll get to sensing which page is open and reporting user interaction in a moment, but first I want to talk about how that data should be reported to the computer.
Obviously you're going to use Serial. Sure, you could use TCP/IP or UDP if you really wanted to, but unless you're piping audio or video from your Teensy there's no point in going that complicated. A Teensy has a limited number of inputs and even if you report all of them at once, you'd have to be really determined to overflow a Serial buffer with that paltry amount of data.
The real question is how that data should be formatted. If all you're doing is reading which page is open then that's easy: just println the number of that page. No need to do anything fancy on either end of the port. If, however, you want to read when a pull tab is pulled or when a switch has been activated, you're going to have to decide which mode of delivery you prefer: all-at-once or one-at-a-time.
All At Once
Where every println contains a complete horizontal table of data. The advantage of this is that you don't have to tell the recipient of this data what each cell means. You hardcode that into the receiving software. If the book is open to page six and has three pull tabs all of which are pulled, you could just send a line like “6\t1\t1\t1\n” or “6 1 1 1” and all you'd have to do at the other end is split by “\t” or “ ”. As long as the recipient knows that cell is the page number and cell[1-3] is pull tabs 1-3, you're good.
However, because you're civilized and would never do something as human unreadable as that, I recommend sending key-value pairs anyway. “Page=1 Pulltab1=1 Pulltab2=1 Pulltab3=1” is much easier on the debugging brain and all you're really doing on the other end is adding another function to split by “=”. If you have the space in your buffer, you really should use key-value pairs. They're more human readable and they're safer to change later on in the production.
One At A Time
For when you don't have room in the buffer. Other than that I have no idea why you'd do this.
Loop Through Your Inputs
I like to change things often during production so it was important to me to have code that was easily extensible. That meant using functions and loops.
The following is the actual code I uploaded to the Teensy for the showcase, and you'll notice that it relies heavily on for-loops. Feel free to take what you want from it. I can't take credit for it anyways (that credit should go to Mike Krzyzaniak, who probably won't want it, and who spent a lot of time helping me traverse the heavily-typed and unsafe perils of the C language, for which I am eternally grateful).
First, the main file: