Source: https://mokxi.com/learn/arduino-tm1638

Learn

# A TM1638 LED&KEY board on an Arduino

Intermediate

Written by the Mokxi team

Start building free Open the editor

Or see every lesson.

- 455 parts on the bench
- 43 boards running now
- 1.00x real time, on every board

Click to open it in the editor

The LED and key example: each button lights its LED, and the display counts the presses.

The TM1638 "LED&KEY" board puts eight 7-segment digits, eight red LEDs and eight pushbuttons on one strip, all run by one TM1638 chip on three wires. It is the quick way to give a project a front panel: a counter, a menu, a timer with buttons to set it.

The circuit above is an Uno and an LED&KEY board running the TM1638plus library. Each button lights the LED above it while you hold it, and the display counts the presses and shows the last button’s number. Press Run, then press the buttons, two at once too.

## What you need

- An Arduino Uno
- A TM1638 LED&KEY board
- Five jumper wires

## Wiring

Part and pin | Goes to | Note

TM1638 VCC | 5 V |

TM1638 GND | GND |

TM1638 STB | Pin 4 | Strobe: low for each command

TM1638 CLK | Pin 6 | Clock

TM1638 DIO | Pin 7 | Data, both ways

## How the TM1638 works

The TM1638 does the hard parts itself. It keeps the picture for the digits and LEDs in sixteen bytes of its own memory and lights them over and over, so the Uno does not have to keep refreshing them. It also scans the buttons on its own. The Uno only sends a command now and then, and asks for the buttons when it wants them.

The three wires are not standard SPI or I2C. STB goes low for the length of each command. Each byte goes out least significant bit first, taken on the rising edge of CLK. DIO carries data both ways: the Uno drives it to send, and the chip pulls it low to answer a button read.

On the LED&KEY board, the even bytes of that memory are the eight digits and bit 0 of each odd byte is the LED next to it. The library hides all that.

## The sketch

TM1638plus tm(4, 6, 7) takes STB, CLK and DIO. In setup(), displayBegin() turns the display on, brightness(2) picks one of eight levels (0 to 7), and displayText("LED KEY ") writes eight characters, one per digit.

Every 20 ms the loop calls readButtons(), which returns one byte with bit 0 for S1 up to bit 7 for S8. When the byte changes, setLEDs(buttons << 8) lights the LED over each held button: the high byte of the number is which LEDs are red. Each new press adds one to the count and prints it. Press S3 and the serial monitor says "S3 pressed, 1 in all"; press S1 and S7 together and both are counted.

The LED and key sketch

## New presses, not held buttons

The line pressed = buttons & ~lastButtons is worth learning. ~lastButtons flips the old byte, so the AND keeps only the bits that are 1 now and were 0 before: the buttons that just went down. Without it, a button held for a second would count fifty times, once each loop.

The same trick works for any set of buttons read as bits: a shift register, a port read or an I/O expander.

## TM1638 or TM1637?

The TM1637 is its smaller cousin: four digits, usually with a clock colon, on two wires, and no buttons on the common boards. Use it for a clock or a counter. Use the TM1638 when you want buttons and LEDs as well, or more digits. There is a TM1637 page below.

There are TM1638 boards with sixteen buttons and no LEDs, and boards with two-color LEDs. They use the same chip but wire the keys differently, so TM1638plus has a separate class for some of them.

## Common mistakes

STB or CLK loose. The display stays dark, and worse, every button reads as pressed: with no strobe or clock, DIO just sits high, and the button byte comes back all ones. Pull STB in the circuit above and the serial monitor prints "S1 pressed" through "S8 pressed" at once.

DIO loose. The display stays dark and no button ever reads as pressed.

Sending bytes most significant bit first, as the SPI library does. The segments come out scrambled. The TM1638 wants least significant bit first; use a library, or shiftOut with LSBFIRST.

Counting held buttons instead of new presses. Compare with the last reading, as above.

Brightness out of range. It takes 0 to 7; there is no "off" level, so turn the display off with its own command instead.

## Questions

What library do I use for the TM1638?

TM1638plus by Gavin Lyons: TM1638plus tm(STB, CLK, DIO), then tm.displayBegin(), tm.displayText(), tm.setLEDs() and tm.readButtons().

How do I read the buttons on a TM1638?

tm.readButtons() returns one byte, bit 0 for S1 up to bit 7 for S8. Several held at once set several bits.

Does the TM1638 work at 3.3 V?

The chip is rated for 5 V. Many boards work from 3.3 V with dimmer digits, but 5 V is what the datasheet asks for.

Is the TM1638 SPI?

Not quite. It has a strobe, a clock and one data line used both ways, and sends bits least significant first. A library or shiftOut is easier than the SPI library.

Related

## Keep going

Arduino TM1637 Display: Library and Countdown Arduino 7 Segment Display: an Electronic Die Arduino MAX7219 8x8 LED Matrix: Wiring and Code Arduino Button Debounce: See the Bounce, Then Fix It How the TM1638 board is modeled The LED and key project Intermediate The Arduino Uno simulator The project page, with the full sketch Intermediate

## Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.

Start building free Open the editor
