Seven-segment and dot-matrix display designer
Click segments or dots to draw a digit, a letter or a symbol, and read off the bytes that light it, as hex, binary, or a C array, an Arduino array or a Verilog case. Seven-segment, 5×7 and 8×8 dot-matrix and Nixie tubes are here.
Or click the segments and decimal points below. A "." in the text lights the point of the digit before it.
Segment a is bit 0 and the decimal point is bit 7. A common cathode display lights a segment on a 1 bit.
| Digit | Segments lit | Hex | Binary |
|---|---|---|---|
| 1 | bcefg | 0x76 | 01110110 |
| 2 | adefg | 0x79 | 01111001 |
| 3 | def | 0x38 | 00111000 |
| 4 | abefg | 0x73 | 01110011 |
#include <stdint.h>
// bits 7..0 = dp g f e d c b a, common cathode
const uint8_t digits[4] = {
0x76, 0x79, 0x38, 0x73
};
Hex digits 0 to F on seven segments
Digits 0 to 9 use the same shapes as the seven-segment decoder. The letters are the usual lower-case b and d, so that B and D do not look like 8 and 0. This is generated from the same table the tool uses, with common cathode bytes in the order dp g f e d c b a and the common anode bytes beside them.
| Shows | Segments | Cathode hex | Cathode binary | Anode hex |
|---|---|---|---|---|
| 0 | abcdef | 0x3F | 00111111 | 0xC0 |
| 1 | bc | 0x06 | 00000110 | 0xF9 |
| 2 | abdeg | 0x5B | 01011011 | 0xA4 |
| 3 | abcdg | 0x4F | 01001111 | 0xB0 |
| 4 | bcfg | 0x66 | 01100110 | 0x99 |
| 5 | acdfg | 0x6D | 01101101 | 0x92 |
| 6 | acdefg | 0x7D | 01111101 | 0x82 |
| 7 | abc | 0x07 | 00000111 | 0xF8 |
| 8 | abcdefg | 0x7F | 01111111 | 0x80 |
| 9 | abcdfg | 0x6F | 01101111 | 0x90 |
| A | abcefg | 0x77 | 01110111 | 0x88 |
| b | cdefg | 0x7C | 01111100 | 0x83 |
| C | adef | 0x39 | 00111001 | 0xC6 |
| d | bcdeg | 0x5E | 01011110 | 0xA1 |
| E | adefg | 0x79 | 01111001 | 0x86 |
| F | aefg | 0x71 | 01110001 | 0x8E |
How a byte becomes lit segments
- The byte is a wiring convention. Eight port pins go to the segment pins through resistors, and bit 0 of the byte is whichever segment you wired to the lowest pin. Wiring a to bit 0 up to g as bit 6 and the point as bit 7 is a common choice, and it is what makes a zero 3F: bits 0 to 5 are a to f and nothing else is lit. If your wiring differs, change the bit order above or renumber the bits.
- Anode against cathode. The segments are LEDs. With the cathodes joined, a high pin lights a segment; with the anodes joined, a low pin does. The display's pattern is the same either way, so the byte is just inverted: 3F becomes C0.
- Several digits. Wiring the segment pins of all digits together and switching each digit's common pin in turn needs only 8 + n pins for n digits. Each digit is on for 1/n of the time, so the refresh must be fast enough to hide the flicker, and the current while a digit is on is often set higher to make up the brightness.
- The letters are conventions. No standard says what a seven-segment R or Y looks like. These glyphs are the common ones: A b C d E F H h J L n o P r t U y - _ = ? °. Anything else, such as G K M Q V W X Z, has no readable shape.
Dot matrices: rows, columns and scan direction
A 5×7 module has 35 dots. It is often scanned one column at a time: the controller puts a 7-bit pattern on the row lines, enables column 1, then column 2, up to column 5, over and over. That is why 5×7 fonts are often stored as five column bytes per character. An 8×8 module is just as often scanned by row, so its natural unit is a row byte. The tool gives you both and the choice of which pixel is the top bit; rotate and flip convert between them. Transposing swaps the row bytes for the column bytes, and rotating four times returns the original grid.
The built-in font here, drawn for this site and not copied from any named font, has these glyphs, shown as the tool would use them:
Nixie tubes and the BCD to decimal decoder
A Nixie tube holds ten cathodes shaped like the numerals 0 to 9, stacked one behind another, and a single anode. Connecting one cathode in the circuit makes its numeral glow, so a tube needs ten switched lines rather than seven. A BCD to decimal decoder driver such as the 74141 (the K155ID1 is the Soviet equivalent) turns four BCD bits into those ten lines: the code selects one output, and for codes above 9 none is selected, so the tube is dark. The table is generated from the same function that draws the tubes above.
| Code | B3 B2 B1 B0 | Cathode selected |
|---|---|---|
| 0 | 0 0 0 0 | 0 |
| 1 | 0 0 0 1 | 1 |
| 2 | 0 0 1 0 | 2 |
| 3 | 0 0 1 1 | 3 |
| 4 | 0 1 0 0 | 4 |
| 5 | 0 1 0 1 | 5 |
| 6 | 0 1 1 0 | 6 |
| 7 | 0 1 1 1 | 7 |
| 8 | 1 0 0 0 | 8 |
| 9 | 1 0 0 1 | 9 |
| 10 | 1 0 1 0 | none, tube dark |
| 11 | 1 0 1 1 | none, tube dark |
| 12 | 1 1 0 0 | none, tube dark |
| 13 | 1 1 0 1 | none, tube dark |
| 14 | 1 1 1 0 | none, tube dark |
| 15 | 1 1 1 1 | none, tube dark |
Each BCD digit is one hex digit of the packed value, so 2026 is the bytes 0x20 0x26. See the seven-segment decoder for the same idea with seven outputs.
Questions
Why is 0x3F the code for a zero on a seven-segment display?
A zero lights six of the seven bars, a to f, and leaves g dark. With a as bit 0, b as bit 1 and so on up to f as bit 5, those six bits are 111111 and g and the decimal point (bits 6 and 7) are 0, so the byte is 00111111, which is 3F in hex. On a common anode display the same zero is the complement, C0.
What is the difference between common cathode and common anode bytes?
Only the sign. On a common cathode display the shared pin goes to ground and a segment lights when its pin is driven high, so a 1 bit means lit. On a common anode display the shared pin goes to the supply and a segment lights when its pin is pulled low, so a 0 bit means lit. The byte for a given digit is therefore the bitwise complement: 0x3F becomes 0xC0.
Which bit order should I use for the segment bits?
Whichever matches your wiring. The common order puts segment a in bit 0 and the decimal point in bit 7 (dp g f e d c b a, reading from bit 7 down), which suits a port wired a to bit 0. Some wiring layouts and libraries put a in the top bit and the point in bit 0 (a b c d e f g dp). The two are mirror images of each other, and this page shows both so you can copy the one your hardware needs.
Which letters can a seven-segment display show?
Only a few, and the shapes are conventions rather than a standard. This page draws digits, A, b, C, d, E, F, H, h, J, L, n, o, P, r, t, U and y, plus a dash, an underscore, an equals sign, a question mark and a degree sign. It cannot draw G, K, M, Q, V, W, X, Z in any recognisable form. I and S borrow the shapes of 1 and 5.
Should I store a dot-matrix font as row bytes or column bytes?
Match the way the hardware is scanned. Some small 5 by 7 modules are driven one column at a time, so the natural unit is a column of 7 bits and a character is 5 bytes. An 8 by 8 module driven by shift registers or a driver chip may be written one row per byte. The two are the same picture rotated, and this page produces either, with the first pixel as the top bit or as bit 0.
What does a Nixie decoder do with the codes 10 to 15?
A BCD to decimal decoder driver for Nixie tubes, such as the 74141 or its Soviet equivalent K155ID1, selects one of ten outputs for the BCD codes 0 to 9. For the six codes 10 to 15 it selects none, so no cathode conducts and the tube stays dark. That is useful: leading zeros can be blanked by sending a code above 9.
How can a few pins drive many digits?
By multiplexing. The same-named segment pins of every digit are wired together, and each digit has its own common pin. The microcontroller puts one digit's segment byte on the shared lines, enables only that digit, and moves on to the next many times a second. Your eye blends the digits into a steady picture, at the price that each digit is lit only one share of the time, so the segments are often driven harder while on.