maxint-rd / TM16xx

Arduino TM16xx library for LED & KEY and LED Matrix modules based on TM1638, TM1637, TM1640 and similar chips. Simply use print() on 7-segment and use Adafruit GFX on matrix.
164 stars 34 forks source link
7-segment adafruit-gfx arduino arduino-library atmega attiny buttons esp8266-arduino led-display matrix onebutton-library tm1637 tm1638 tm1640 tm1650 tm1668

TM16xx

Arduino TM16xx library for LED & KEY and LED Matrix modules based on TM1638, TM1637, TM1640 and similar chips. Simply use print() on 7-segment displays and use Adafruit GFX on matrix displays.

TM16xx LEDs and Buttons library

This Arduino library facilitates driving LED displays using TM16xx LED driver chips. The TM16xx chip family allows driving 7-segment LED displays or LED matrices. Next to built-in high-frequency LED multiplexing, they offer control of LED brightness. Most TM16xx chips also support reading key-scan data for button presses. Using this library you can simply use print() on a 7-segment display or use Adafruit GFX on a LED matrix. Currently this library supports the TM1616, TM1618, TM1620, TM1628, TM1630, TM1637, TM1638, TM1640, TM1650 TM1652 and TM1668 chips. Note that there are similar chips made by other manufacturers that may be compatible with the Titan Micro chips. For instance: the HBS640 by WINRISE is compatible with the TM1640.

Made by Maxint R&D. See https://github.com/maxint-rd/

Initial version was based on the TM1638 library by Ricardo Batista. Further inspiration from the TM1637 library by Avishay, the Max72xxPanel library by Mark Ruys and the OneButton library by Matthias Hertel.

Table of contents

TM16xx chip features

The TM16xx family is quite large. Currently the following chips are supported:

Type Segments x digits Buttons Interface Notes
TM1616 7 x 4 n/a DIN/CLK/STB
TM1618 5 x 7 - 8 x 4 5 x 1 multi DIO/CLK/STB Anode*
TM1620 8 x 6 - 10 x 4 n/a DIN/CLK/STB
TM1628 10 x 7 - 13 x 4 10 x 2 multi DIO/CLK/STB
TM1630 7 x 5 - 8 x 4 7 x 1 multi DIO/CLK/STB
TM1637 8 x 6 (common anode) 8 x 2 single DIO/CLK
TM1638 10 x 8 8 x 3 multi DIO/CLK/STB Anode/Inverted/QYF*
TM1640 8 x 16 n/a DIN/CLK Anode*
TM1650 8 x 4 7 x 4 single DIO/CLK Not real I2C SDA/SCL
TM1652 8 x 5 - 7 x 6 n/a DIN Single data line
TM1668 10 x 7 - 13 x 4 10 x 2 multi DIO/CLK/STB

* Alternative configurations TM1638QYF/TM1638Anode/InvertedTM1638, TM1618Anode and TM1640Anode are also supported.

See the documents folder for datasheets containing more information about these chips and their pinouts.

Library structure

This library has a layered structure to simplify the support of multiple TM16xx chips. By using a base class that provides a uniform API, your application doesn't need chip specific code. Likewise, the library can offer common functionality in display specific classes that support multiple chips.

The figure below illustrates that concept:

Layered structure

Library installation

The easiest way to install this library is using the Arduino Library Manager. Just search for "TM16xx LEDs and Buttons" and click the install button. You can also download the latest version or select one from the releases as zipfile and use Add .ZIP library in the Arduino IDE.

NOTE: AdafruitGFX needs to be installed, even if you don't use TM16xxMatrixGFX. If you don't want to install AdafruitGFX you can remove TM16xxMatrixGFX.h and TM16xxMatrixGFX.cpp from the library directory to avoid compilation errors.

Basic usage

After installation you can use this library by including the class header that matches the chip on your module and then instantiate the object:

#include <TM1638.h>

TM1638 module(8, 9, 7);   // DIO=8, CLK=9, STB=7

In the setup() function you can set the intensity of the display, but that's not mandatory:

void setup() {
  module.setupDisplay(true, 2);   // on=true, intensity-2 (range 0-7)
  module.setDisplayToString("HALO");    // display simple text
}

In the loop() function you can use basic display methods provided by the base class:

void loop() {
  int nTime = ((millis() / 1000) / 60) * 100 + (millis() / 1000) % 60; // convert time to minutes+seconds as integer
  module.setDisplayToDecNumber(nTime, _BV(4)); // display milliseconds with dot on digit 4
}

For the easy to use print() method and more advance display methods you can use the TM16xxDisplay class.

The TM16xx chip makes it easy to see if a button is pressed. To check if a button was pressed you can use the getButtons() method:

  uint32_t dwButtons=module.getButtons();
  Serial.println(dwButtons, HEX);

Please note that while you don't need to write any code for debouncing, the button state may be reset when you display something. For advanced detection of button clicks, double clicks and long presses you can use the TM16xxButtons class.

TM16xxDisplay class

The TM16xxDisplay class adds some bytes to the memory footprint, but it provides the familiar easy to use print() and println() functions. Next to that it also provides some more advanced display methods. To use that class on top of the base class, all you need to do is instantiate it, refering to the chip specific class:

TM1638 module(8, 9, 7);   // DIO=8, CLK=9, STB=7
TM16xxDisplay display(&module, 8);    // TM16xx object, 8 digits

Simple print example using the TM16xxDisplay class:

#include <TM1638.h>
#include <TM16xxDisplay.h>

TM1638 module(8, 9, 7);   // DIO=8, CLK=9, STB=7
TM16xxDisplay display(&module, 8);    // TM16xx object, 8 digits

void setup() {
  display.println(F("HELLO !"));
}

int nCount=0;
void loop() {
  delay(1000);
  display.print("Count:");
  display.println(nCount++);
}

If you want you can combine multiple modules into a single TM16xxDisplay object. When combined print() and println() will use all available digits to print the string. See TM16xxDisplay.h for the provided methods.

TM16xxMatrix class

The TM16xxMatrix class provides basic methods for using a single LED-matrix module. For more advanced graphics use the TM16xxMatrixGFX class. To use the TM16xxMatrix class on top of the base class, all you need to do is instantiate it, refering to the chip specific class:

TM1640 module(9, 10);    // DIN=9, CLK=10
#define MATRIX_NUMCOLUMNS 16
#define MATRIX_NUMROWS 8
TM16xxMatrix matrix(&module, MATRIX_NUMCOLUMNS, MATRIX_NUMROWS);    // TM16xx object, columns, rows

Note that the TM1640 has sufficient outputs to drive two 8x8 matrices.

These methods can be used to set the pixels of the matrix:

  matrix.setAll(true);    // set all pixels on
  matrix.setPixel(5,6, true);   // set one pixel on
  matrix.setPixel(3,2, false);   // set another pixel off

See TM16xxMatrix.h for the provided methods.

TM16xxMatrixGFX class

The TM16xxMatrixGFX class implements the popular Adafruit GFX interface to drive one or more TM16xx based LED-matrix modules. To use the TM16xxMatrixGFX class you first need to include the proper header files:

#include <Adafruit_GFX.h>
#include <TM1640.h>
#include <TM16xxMatrixGFX.h>

Then you can instantiate the TM16xxMatrixGFX class, refering to the chip specific class:

TM1640 module(13, 14);    // For ESP8266/WeMos D1-mini: DIN=D7/13/MOSI, CLK=D5/14/SCK
#define MATRIX_NUMCOLUMNS 8
#define MATRIX_NUMROWS 8
TM16xxMatrixGFX matrix(&module, MATRIX_NUMCOLUMNS, MATRIX_NUMROWS);    // TM16xx object, columns, rows

Note that the TM1640 has sufficient outputs to drive two 8x8 matrices. The WeMOS D1 Mini Matrix LED Shield also uses the TM1640, but has only one 8x8 matrix.

These methods can be used to draw on the matrix:

  matrix.setIntensity(1);         // Use a value between 0 and 7 for brightness
  matrix.fillScreen(LOW);         // Clear the matrix
  matrix.drawPixel(1, 4, HIGH);   // set one pixel in the memory bitmap on
  matrix.write();                 // Send the memory bitmap to the display

In addition all the Adafruit GFX methods can be used, e.g.:

  matrix.drawChar(0, 0, 'A', HIGH, LOW, 1);
  matrix.drawLine(0, matrix. height(), matrix.width(), 0, HIGH);
  matrix.drawRect(0, 0, 6, 6, HIGH);

Multiple identical modules can be combined to form a large matrix. The data line can be shared to reduce the number of pins:

  TM1640 module(D7, D5);    // For ESP8266/WeMos D1-mini: DIN=D7/13/MOSI, CLK=D5/14/SCK
  TM1640 module2(D7, D6);   // For ESP8266/WeMos D1-mini: shared DIN=D7/13/MOSI, different CLK
  TM16xx * modules[]={&module,&module2};      // put modules in an array
  TM16xxMatrixGFX matrix(modules, MODULE_SIZECOLUMNS, MODULE_SIZEROWS, 2, 1);    // modules, size of each module, size combined

See Adafruit GFX documentation and TM16xxMatrixGFX.h for the provided methods. See the library examples for more information.

NOTE: AdafruitGFX needs to be installed, even if you don't use TM16xxMatrixGFX. If you don't want to install AdafruitGFX you can remove TM16xxMatrixGFX.h and TM16xxMatrixGFX.cpp from the library directory to avoid compilation errors. To reduce this dependency, the TM16xxMatrixGFX class may be moved to a separate library in future versions

TM16xxButtons class

The TM16xxButtons class enlarges the footprint a bit, but based on the popular OneButton library library, it adds more advanced methods to use buttons. Next to simply polling the state of each button, you can define callback functions that will be called when a button is released, clicked, double-clicked or long pressed. To use this class on top of the base class, all you need to do is include the proper headers and instantiate the buttons object, refering to the chip specific class, for example:

#include <TM1638.h>
#include <TM16xxButtons.h>

TM1638 module(8, 9, 7);   // DIO=8, CLK=9, STB=7
TM16xxButtons buttons(&module);    // TM16xx object

Then you define the functions you want to use to handle the button events:

void fnClick(byte nButton)
{ // byte nButton is the button-number (first button is number 0)
  Serial.print(F("Button "));
  Serial.print(nButton);
  Serial.println(F(" click."));
}

In setup() you need to attach the callback function:

void setup()
{
    .
    .
    buttons.attachClick(fnClick);
}

(BTW. Besides a click function, you can also attach a function to handle release, doubleclick and longpress events).

In loop() you need to call the tick() function that detects all state changes and calls the callback functions as needed:

void loop()
{
  buttons.tick();
  .
  .
  // do your other things
}

Some TM16xx chips support multiple simultaneous key presses. To implement a shift key, you can use the isPressed() function. See TM16xxButtons.h for the provided methods and the Button clicks example for more information.

New in this library

Added library functionality:

Functionality in original library by Ricardo Batista:

Features & limitations

More information

Examples

See the library examples for more information on how to use this library. See also the original examples by Ricardo Batista. Most will still work or only require minor changes.

Real world devices using a TM16xx chip

Some users found a TM16xx chip in their device and shared their experience:

If you happen to own a device featuring a TM16xx chip, feel free to open a new issue, sharing your experience. All contributions are appreciated!

Links

Disclaimer