A few weeks ago, I started designing my own IoT gadget platform from scratch. At this point, I have a powerful microcontroller that can communicate over Bluetooth and Wi-Fi, and tons of I/O for making fun things. But, I haven’t actually made anything useful yet.

So, how about making something completely silly? This thing seems like a good start:

Photo of a large black circuit board with a single, very big seven-segment display.

Coming in at 11 inches tall and 6 inches wide, this gigantic seven-segment display seems like a great toy starting point for my high-octane IoT project.

Take a close look at the board, and you’ll see this text under the solder mask:

COMPONENT SIDE
DAKTRONICS, INC.
COPYRIGHT 1996

Daktronics is an American company that makes big LED displays, like digital billboards and scoreboards. If I had to guess, this fellow got yanked out of a discarded basketball scoreboard. It’s the right size for a score digit in a small gym, or a clock in a big gym.

I love science/electronics surplus stores, because oddities like this are abundant and cheap. On EBay, you might pay upwards of $50 for this thing. From a surplus shop? $4.

The shop had several of these, but I didn’t want to buy more than one until I had determined that these are actually worth buying. That was a mistake - I should have bought all of them. As it turns out, these displays are brutally simple, and extremely hackable. Someone knew better than I did, because by the time I had another chance to buy the shop’s remaining stock, they were sold out.

Deciphering the Display

There’s a 9-pin connector on the back, so it’s reasonable to guess that each segment is controlled individually. 9 pins gives us one common pin, 7 pins for each segment, and an extra pin full of fun and surprises. Maybe all those LEDs draw so much current that it needs a second common pin? Perhaps that pin does nothing, and it would be used for a decimal point on a different model?

Those two big DIP chips in the photo above gave me some pause: if there’s silicon in there, this thing could be a lot more complicated than it looks. Fortunately, the “R220” numbering is a dead giveaway: they’re just resistor packs. Mouser still has a product listing for these, although they appear to have been obsoleted years ago. Here’s how they’re wired inside:

Screenshot from a datasheet, showing 8 resistors wired inside of a DIP-16 chip

Simple enough - this board has sixteen 220-ohm resistors. Now we just have to figure out what it’s doing with those resistors.

By shining a bright light through the board, I was able to see most of the traces. By the way, there’s no ground plane on this board; that’s why I could shine a light through it. One of the traces coming out of the 9-pin connector is much larger than the others, and lo and behold, it snakes around the whole board. We’ve found our common pin!

By looking at the traces, I could see that each segment is wired as a parallel pair of 7 LEDs and a resistor. I don’t know the polarity yet, but we can guess the supply voltage from this:

  1. These chunky 5mm red LEDs are usually rated for something like 20mA with a 1.9V forward voltage.
  2. 7 LEDs in series × 1.9V = 13.3 volts dropped across the LEDs.
  3. 220 ohm resistor × 20mA = 4.4 volts dropped across the resistor.
  4. 13.3 volts + 4.4 volts = 17.7 volts… let’s round that to 18 volts dropped across each segment.
  5. 4.4 volts × 20mA = 0.088 watts dissipated across the resistor - comfortably below its power rating.
  6. 20mA per chain × 2 parallel chains per segment × 7 segments = 280mA max current draw for the whole display.
  7. 280mA × 18 Volts = roughly 5 watts for the whole display.

These LEDs might turn out to have a slightly different forward voltage than my 1.9V guesstimate, but it seems like this display might have used an 18 volt power supply. This is only a sort-of weird supply voltage - I would have guessed that it would use 12 or 24 volts, but 18 isn’t totally outlandish. At the very least, we probably won’t break anything by running this display at 18 volts. It’s also possible that Daktronics ran this display at 12 Volts, but as I describe below, there are several reasons to doubt that.

Poking and prodding

We have some estimates for the display’s power characteristics, but we’re still missing one very important detail: which way are the LEDs facing? To find out, I took a 12V supply and a couple alligator clips, and poked at the 9-pin connector.

By poking the board with a 12V supply, I was able to figure out two things. Most importantly, the display is wired as common-anode. Ta-daa! Here’s our completed schematic for one segment of the display:

Electrical schematic for one segment of the scoreboard display. Two parallel chains, each consisting of seven LEDs and a 220 ohm resistor.

Adding a multimeter into the mix, I was able to peek into the power characteristics of the LEDs. At 12V, each LED is only pulling 2.2mA (that’s 30.8mA for the whole display), slightly more than a tenth of my estimated current draw at 18V. the LEDs definitely aren’t close to their maximum brightness, but they’re still very clearly “on.”

Poking the display with 12V gave me even more reasons to believe something around 18V is probably the correct supply voltage. Anything over 18V would be getting into no-no territory for LED voltage drop. But, at 12V, the LEDs are quite dim, and this display is supposed to be easily readable in a brightly-lit gym. Furthermore, the LEDs’ current draw at 12V is so low that Daktronics’ use of 14 resistors would be complete overkill. If they ran this display at 12V, they could have replaced the fourteen 220 ohm resistors with seven 390 ohm resistors.

Prototyping a driver

We now have a complete understanding of how this giant 7-segment display is wired, so now I can create a circuit to control each segment. Even at the guesstimated max current draw, we will easily be able to power this thing with cheap, tried-and-true 2N3904 transistors:

Electrical schematic showing an NPN transistor powering one segment of the display.

I’ll drive each segment with the circuit shown above. With this combination of resistors and transistor, the circuit should switch from “off” to “on” somewhere around 0.6-0.8V. That’s not a standard logic level, but it does mean that this circuit should accept input from any microcontroller running on 5V, 3.3V, or 1.8V logic.

The 100k resistor pulls the transistor’s base to ground when the CTRL input isn’t being driven. This ensures that the output state will be “off” when CTRL isn’t connected to anything.

This circuit could be better, but it’s okay for some home hacking. I could make a much more efficient circuit by using a MOSFET, but I have a big pile of 2N3904s sitting around, so I might as well use them.

Making upgrades

This circuit was perfectly fine for switching the segments on and off, but I wanted more. Namely, I want to be able to control lots of giant 7-segment displays using only a handful of microcontroller pins. I could use a multiplexer, but that would strobe the LEDs and make them appear dimmer. That’s no fun, but you know what is fun? Latches!

Photo of the prototype driver circuit on a breadboard. The large display is in the background, with one segment lit.

That chip on the breadboard is a 74HC74 dual D-latch. It has clear and preset pins, but I don’t need those, so they are tacked to the supply rail through a couple 4.7k resistors. For poops and giggles, I decided to take a similar approach to the latch input pins, making them normally-high. This was the wrong choice, because it would make the output “normally on” when the input isn’t connected. But hey, prototypes.

Here’s that breadboard, turned into a schematic (the schematic doesn’t show the buttons - those are hooked from D/CLK to ground):

Electrical schematic of the breadboarded prototype. A 74HC74 driving the same NPN driver circuit from before.

Here’s how the circuit works:

  1. To turn the segment on, press and release the CLK button.
  2. To turn the segment off, hold the D button down while pressing and releasing the CLK button.

The 74HC74 updates its output state when it sees a rising edge on its CLK pin, so the segment should change when you release the CLK button. This isn’t always what happens in practice, because these switches are suuuuper cheap and I haven’t added a debouncing circuit.

Takeoff

My prototype circuit only handles one segment. I want to control all 7 segments with a tidy, permanent board that I could reuse for other projects in the future. Here’s what I came up with:

Download the schematic here (PDF).

Computer drawing of a circuit board layout.

This circuit provides all the same functionality as the prototype, but copied eight times over. Instead of a 74HC74, I use a 74HC273. This is another common D-Latch chip, but with 8 latches instead of two. It also lacks the preset pin, which I didn’t need anyway. I also added some rudimentary overvoltage protection via a 24 volt Zener diode, and a little bit of supply voltage cleanup with a 10uF capacitor. Instead of pulling the latch inputs high, I now pull them to ground. That way, the outputs default to “off” when nothing is connected to their corresponding inputs.

There are two 0.188-inch holes on the board, spaced three inches apart. These holes line up perfectly with the mounting holes on the scoreboard display. That will be helpful if I decide to package this thing up neatly in the future.

After a couple weeks of anticipation, the boards finally arrived. Here’s the top:

Photo of the top of the circuit board. There are no components soldered to it yet. The board is black, with gold-plated holes and shiny copper traces.

Here’s the bottom:

Photo of the bottom of the circuit board. There are no components soldered to it yet. Nearly the entire bottom of the board is covered by a shiny copper ground plane.

I had these boards manufactured with a black substrate and transparent solder mask, so you can see all of the gold and copper in its shiny metallic glory. I think these boards are beautiful, and I’ll definitely have more boards made this way in the future.

Here are a couple photos of the assembled board:

Photo of the top of a fully-assembled circuit board.

Photo of the bottom of a fully-assembled circuit board. A couple of surface-mount components look very ugly.

Please excuse the horrendous SMD soldering work. I haven’t done any SMD soldering in quite a while, and this was my first time ever trying to hand-solder teeny-tiny 0603 components. It won’t be my last time, either - I ordered 50 of them, and I only needed 10 to assemble this board.

There is one mistake in this board’s design: I forgot to label the inputs and outputs. It’s an annoyance, but not the end of the world. All the traces go to the right places, and that’s the most important thing.

I managed to find the connector Daktronics used on this display. As it turns out, they’re garden-variety TE “Mate-N-Lok” connectors, and Digi-Key will sell you a bag full of them for very cheap.

The assembled circuit board, now wired to a connector that can plug into the scoreboard display.

You may notice that some of the component choices are a little strange. There’s a hodgepodge of surface-mount and through-hole parts. The 1/4-watt 4.7k resistors are unnecessarily bulky for this use case. The 24V Zener diode really should be 20V if I want to protect the display properly. As mentioned before, swapping out the 2N3904s for N-channel MOSFETs would make the circuit more efficient.

The reason for the odd component choices is simple: it’s what I had sitting around. The screw terminals, TE connector, and 10k surface-mount resistors are the only parts I ordered specifically for this project. I had some 10k through-hole resistors lying around, but using SMD resistors allowed me to make the boards a lot smaller, and thus, cheaper.

Back to the Keyboard

I wanted to tie this project back into my IoT platform project, which I introduced a few weeks ago in this post. That meant integrating my display driver into the Zephyr RTOS. Zephyr’s auxdisplay driver API fits the 7-segment display reasonably well, so that’s where I implemented the driver. You’ll be able to find the code for that on my personal fork of the Zephyr SDK.

Here’s a photo of the display in action, driven by a microcontroller running my driver:

The scoreboard display digit showing the number “2.” The number is visible, but dim.

In the above photo, I am running the driver board from a 12 volt supply. The LEDs are predictably dim, but still visible. This is a nice voltage for testing code, since I can look at the display without being blinded by red light. Here’s what it looks like at the full 18 volts:

The scoreboard display digit showing the number “2” again. The number is much brighter now.

Obviously, photographs can’t really communicate the difference all that well, but the display is almost blindingly bright when running at 18 volts. This is perfect for a gym where the scoreboard is far away, but when it’s sitting on your desk, it’s a bit much.

Okay, so I throw together some state management for the MQTT broker connection, subscribe to a topic, and…

Screenshot of Zephyr logs, showing warning messages for unrecognized modem commands

See those two lines near the bottom that say no match for cmd 128: Recv N bytes? That’s the Zephyr’s ESP32-AT driver deciding it doesn’t know what to do with the TCP packets being received from the MQTT broker. This, despite it receiving the CONNACK successfully. The broker sends a SUBACK, but Zephyr gets confused, so my code never receives the event.

At this point, I’ve had enough of that horrible, half-broken driver - read the first post about my IoT platform design adventure to learn about my ESP32/ESP-AT frustrations. It’s entirely possible that I created this bug when I shimmed some rudimentary Bluetooth support into the driver, or if there’s something totally broken with the driver itself. I don’t particularly care to find out, either. It might just be time to throw ESP32 out the window, and switch to a proper Wi-Fi controller module.