My infant daughter has always been fascinated by anything with one of those old LED digit displays. Whether it’s the stove, or an alarm clock, or an ancient VHS player, if she sees one she points at it and practically demands that you make it do something. So, I decided to build her own interactive box with an LED display for her for Christmas! This simple toy has a 4-digit display and two lighted buttons: green to add to the count on the display, and red to subtract from it.

The parts I used are:

Note: I realize that the Teensy++ 2.0 has way more GPIO pins than is needed, but I happen to have it laying around, and using it meant I could start work immediately. It had literally been sitting in a box for years anyway! The PCB itself was more of a learning exercise as well as everything could have been done inline.

The following write-up is a mix of general interest and technical, and I hope you enjoy it.

Concept

I wanted something that was:

Simple

Cheap

Always reacts to button presses

Turned on and off automatically

Feasible to build before Christmas

My personal learning goals were:

Design a PCB

Design a nice laser-cut box

Learn something about power-saving modes on Arduino and clone devices

My limitations were:

Lack of time

I don’t actually know what I’m doing

I still have that book! Also still awkward.

That last one isn’t totally accurate. I do have a little bit of an idea what I’m doing. I had a book called Getting Started in Electronics when I was an awkward tween, and checked off every chapter as I read through it, so I at least know the basic components. I did a digital logic course as an awkward adult during an undergrad but that was not much help here.

After fantasizing about a speaking, music-playing, multi-function box, I settled on a simple adder/subtractor. Negative numbers are not something I’m going to explain to a 16 month old, so the counter only goes to zero. If she pushes subtract again, she gets a little animation of the zero going right to left and back again to let her know that the box is still listening, but can’t go any lower.

Breadboard Version & Code

The core of any project like this is the microcontroller, which is a cheap and not-very-sophisticated computer. In my case I’m using one called the Teensy++ 2.0. It has a number of general-purpose input/output (GPIO) pins attached to it, and things like buttons and displays are hooked up to these pins. The microcontroller reacts to the input on pins and sends output on other pins according to the software that has been uploaded to it. In the past, microcontrollers with a development board were expensive and generally inaccessible to hobbyists. Companies like Arduino and Adafruit have a done a lot to simplify programming and bring prices down to as low as just a few dollars per unit, allowing tinkerers like me to make our fun little projects.

If you want to build a prototype of something like this, you generally do so on a breadboard, a board with a grid of electrically connected holes in it that all the components and wires can easily plug into. When you’re sure the connections are correct, you can upload a program to the microcontroller and start testing.

I pushed the microcontroller onto the breadboard and started connecting the jumble of wires for the other components. Since I didn’t have my new parts yet, I used some old buttons to increment and decrement a counter and sent that output to the console on my computer.

Once I was happy with the basics, I had to wait for some parts to arrive.

Parts! I ended up sourcing a different battery box and didn’t use the “perma-proto” board. The microcontroller is already pushed onto the breadboard.

I bought some buttons that would be easy for a baby to push, and my 4-digit display with the all-important display controller.

Buttons

The buttons I bought had lights inside to make things a little more interesting to look at, so this required two of the GPIO pins for each button. The switch function is hooked up to a pin that takes input, and the LED inside is hooked up to a pin set to output. The outputs I used were pulse width modulation (PWM) pins, which means instead of just being on or off, they can be set to rapidly oscillate between the two in what is called a duty cycle.

Duty cycle

The amount of time it spends “on” is expressed as a percentage. If the duty cycle is 50%, that means it’s on half the time. Why is this important? It’s a means of controlling the brightness of an LED. The duty cycle is switching back and forth faster than something called the flicker fusion threshold, which means the human eye won’t detect the LED as switching between on and off, but rather as a kind of average value depending on the ratio of on to off. So we vary the duty cycle and control the brightness of the LED. For this device, I have them fairly dim in resting mode (short duty cycle) with an increase in brightness of the LED when the button is pushed (long duty cycle).

You might notice in the circuits shown later that there is also a resistor connected to the LED, which will reduce the brightness in a more conventional way as well. This is good practice, but I still wanted to vary brightness depending on input and so used PWM as well.

Display

The display uses four of something called a 7-segment display. These displays are really just a set of LEDs in a fancy shape, seven of which are used for each number, plus some decimal point and the colon between digits. If you try to manage this as just a set of lights, it needs a lot of GPIO pins — one for each light! Since this isn’t feasible in most applications, the manufacturer of the four digit display designed it to use multiplexing, allowing one set of input pins to control the lights on all four digits. First you use a special pin to select which digit of the four you’re working on, then eight more pins to activate the lights in the shape of whatever number you want to display plus the optional decimal point. You can only do one digit at a time though, so if you want to display four digits you have to exploit part of human visual perception called persistence of vision, a phenomenon closely related to the flicker fusion threshold mentioned above. A lit object doesn’t disappear from vision as soon as light from it stops entering the eye; the image persists for slightly longer than this. We take advantage of this by lighting up one digit for a few milliseconds, then switching to the next place over and lighting that digit and so on, rapidly enough that it looks like all four digits are simultaneously lit. Having played with this in a test project a while ago, I assure you that it’s tedious to wire and makes the code much more complicated.

Enter the display controller, which does all the work of managing those lights for you. It uses a method called I2C to communicate, so only two GPIO pins are needed to control the 7 x 4 different segments for the numbers, plus the : and 4 x . between the numbers. All I have to do is use the provided library when programming and send it the number I want to display. Neat!

The display and controller required soldering together. Unfortunately at this point I had a soldering iron from a hardware store with a large tip that was more meant for heavy duty work, so my soldering doesn’t look that great. My near complete lack of soldering experience also didn’t help things any. I added the display with controller to the breadboard and used Adafruit’s excellent library to get it going. This was actually one of the more pleasant parts of the whole build, in fact, because everything just worked.

With these additions, the device was functionally complete.

Optimization & Power Usage

I didn’t take great pains to make the code particularly elegant or efficient, but I did spend some time trying to minimize energy use in sleep mode. Initial steps included reducing the brightness of the display, which is plenty bright for this application, and reducing the overall speed of the microcontroller. I reduced the microcontroller speed to 2 Mhz from 16 Mhz and set the display to half the brightness level. This gave me a running power usage of about 17 mA. That’s 17 milliamps, which is a measure of the current drawn by the circuit. The more milliamps used, the faster it will deplete a battery.

Of course the biggest power saver with any device is turning it off. I didn’t want to have a separate power switch though, because I wanted my daughter to be able to push a button and have it start working. Instead of being completely off, the device is programmed to go into an extreme low-power sleep mode. The code includes a timer to put the device into sleep mode 30 seconds after the last button push. After going to sleep, you need a way to wake it up. There are many ways to wake up a sleeping device, and I elected to do so with some extra interrupt-enabled input pins attached to the two buttons. A hardware interrupt tells the microcontroller to stop what it’s doing and pay attention, switching code execution from whatever is happening currently to whatever code is attached to the interrupt. In this case, “wake up!” So she pushes a button, the device wakes up, and the timer is reset again for another 30 seconds.

In sleep mode, it was initially consuming 0.75 mA. A decent drop, but I knew I could do better! Following the manufacturer’s instructions I was able to reduce the power usage significantly. Disabling the analog/digital converter (ADC) further reduced the power, and setting unused GPIO pins to output mode to eliminate floating voltages helped as well. I was able to get it down to 0.35 mA during sleep.

Measuring power consumption in sleep mode. 😴

The box runs off rechargeable Eneloop AA batteries, which can provide 2000 mAh of charge. That mAh stands for milliamp hours, which is a measure of how long an energy storage device like a battery can provide a certain amount of charge. If you’re drawing 2000 mA from a 2000 mAh battery, it will last about an hour. If you’re using 0.35 mA, it will last a lot longer. According to Digikey’s calculator, running this device with 2000 mAh batteries would last for 5714 hours during sleep, or about 238 days. I’ll take it! The final code is hosted on Github for those interested.

The PCB

Designing a PCB for this project wasn’t strictly necessary, but something I wanted to learn about. Honestly it’s barely a circuit: just two resistors for the button LEDs, the microcontroller, and a bunch of header pins. It probably could have been done inline with connections directly to the Teensy++ 2.0 pins, but it would have looked messy. Anyway this is more fun, because I wanted to see what a PCB designed by a person who has no business designing PCBs would look like.

I ended up using a popular open-source schematic and PCB design program called KiCAD. The tutorial was really straightforward, and the time I spent struggling with things was just me trying to get a semi-decent looking schematic and wrapping my head around the slightly weird pin placement in the representation of the Teensy++ 2.0. The process was basically taking what I had on the breadboard and then mapping it to a schematic, which is a drawing of a circuit that looks nothing like real life. It’s just something that says, these things should somehow be connected in the physical world. How you choose to accomplish that is up to you.

Here is what I ended up with:

Lines.

Why go through describing a circuit that is already built? Because setting up the schematic allows us to start generating the PCB design, and can be used to check that everything that is supposed to be connected ends up that way on the finished product. And here is my finished product:

Getting closer to real life!

The large yellow holes are just for mounting screws. All those smaller yellow holes are where the components will be soldered in. Something new I learned in this project was the existence of board layers, and that apparently that it’s pretty standard to have two. The red lines are the top layer and will become the etched copper connections visible on the board itself. All the ground connections go to a different layer called the ground plane, and ultimately back the negative terminal of the battery.

KiCAD will even give you snazzy 3D rendering of your board:

Should look just like this IRL. (The Teensy is missing because it doesn’t have a 3D model.)

I chose a company called Oshpark to manufacture the PCB, and I can’t say enough good things about them. The upload of the design was super easy, and although I paid for the basic service, they threw me on an express service batch that had some extra room. That, and the boards are a really cool purple color!

It’s happening! Three is the minimum order, so I had a couple of spares. I might end up framing one of these.

I filed off the sharp tabs on each side and then set about soldering things together. The Teensy was easy to solder, as the pins were nice and straight. I think I did a decent job here considering I’ve soldered for about 15 minutes in my whole life. This was definitely helped by my investment of $25 in a proper soldering iron for electronics.

Was it necessary to solder every pin if I’m only using a few of them? That’s an awesome question for an electrical engineer, which I am not. My reasoning was that I didn’t want potential weird arcing or floating voltages to mess things up. Also I was really feeling my soldering skills here, so I just kept going…

The header pins ended up being a complete disaster though. The plastic melted and the pin shifted in position! So my board looks a bit snaggle-toothed, to be honest.

Absolute disaster on the SUB connector on top, but otherwise okay.

I hooked up my switches and output for a test run, and to my absolute shock everything worked perfectly. I thought for sure I would have missed something!

The Box

Now for the fun part! I wanted to make a nice case for this thing. I picked up a wooden box at a craft store for cheap, but didn’t end up using that. I think it would have flown apart if I tried to drill or cut it anyway, and I don’t think I could get the needed accuracy doing it all by hand. Instead I designed a custom box and had it laser cut through Ponoko, a laser cutting service that does wood, plastic and metal.

Designing a box is harder than it sounds. You have to figure out some way to attach the sides together, which in a bigger box would be glue or screws, but in something this small (12 cm x 8 cm x 8 cm and 3.2 mm thick sides) is generally done with interlocking tabs. To get the tabs to fit properly you have to account for something called the kerf, which is the amount of material removed during the cutting process. Think of a saw cutting through the middle of a 1 foot long piece of wood. When you’re done, you don’t have two pieces exactly half a foot long. They are half a foot long minus that bit that ends up as saw dust on the floor! If you don’t account for this, you’ll find your joints are too loose and the holes are slightly too large for what they’re supposed to contain. I used to do some papercraft things when I was a kid, building things out of cardboard that has a decent thickness, so I do remember a little bit about having to compensate for that kind of thing…

But it was 2019, and I certainly wasn’t interested in figuring that out manually again! So I found a plugin for a simple drawing program called Inkscape that promised to generate a box with interlocking pieces for me, automatically accounting for the kerf. The edges were nicely generated for sure, but I still had to do a lot of manual calculations to position the holes for components. I ended up with a notepad full of numbers like this:

Uhhh square root of 197… and then… carry the one…

The tedious part is measuring all those distances within the program, and having to manually move everything if one part changes. I think in the future it would be worth learning a real CAD program to do this kind of thing. Anyway, it worked, and Ponoko came through with my laser cut box:

Space on top for the 7-segment display and its 4 M2 mounting screws, the 17 mm button, and two M3 sized holes that connect to a support that holds the bottom on. The back has 4 M3 sized holes for mounting the PCB.

Final Assembly

The last steps were soldering the buttons and power supply to their connectors, and making a F-F 4 wire connector for the display. The components are attached to the case with a little space between using some M2 and M3 brass standoff kits from Amazon.

Getting ready to assemble. Not pictured: bowl of M&Ms for energy.

I guessed right with spacing for components, and everything fit well.

Ready to close! That long black thing at the bottom is a brace that will make sure bottom is firmly screwed on and that the whole thing won’t fly apart if dropped.

All together now

Whew, all done. Nothing left to do but give it to her. I thought that even if she didn’t end up liking it, I had fun building it. Here it is working on Christmas morning:

Not pictured: her smile, for privacy reasons.

She liked it! She played with it throughout the day and then gave her mamabee a big hug. 😊

Thoughts & Future projects

Some things for next time: