TM16xx Arduino Library

repository·master·Indexed 42 days ago

https://github.com/maxint-rd/tm16xx

An Arduino library for driving LED/LCD displays and LED matrices using TM16xx family driver chips, including TM1637, TM1638, TM1640, TM1650, TM1668, and TM1680. It features a layered API supporting simple print commands, Adafruit GFX compatibility via TM16xxMatrixGFX, and callback-based button event handling via TM16xxButtons. Compatible with various microcontrollers including ESP8266, ESP32, ATmega, ATtiny, RP2040, and CH32 RiscV.

Tokens
10.5K
Snippets
48
Records
58
Agent score
54%

What's inside TM16xx

  1. Supported Microcontrollers and Hardware

    master

    The TM16xx library supports a wide range of MCUs, including:

    • ESP8266/ESP32
    • Atmel ATmega (e.g., ATmega328, ATmega168)
    • Atmel ATtiny (minimum supported is ATtiny44)
    • LGT8F328P
    • Raspberry Pi Pico RP2040 (tested with Earle Philhower core 2.5.2)
    • CH32 RiscV
    • STM32 (reported to work)

    Hardware Notes:

    • Daisy-chaining: TM16xx chips do not support native daisy-chaining. To use multiple modules, share data and clock lines but use separate latch lines. For two-wire modules, you can share the data line if using separate clock lines.
    • Mirroring: For the WeMOS D1 mini Matrix LED Shield and the TM1640 Mini LED Matrix 8x16 by Maxint R&D, call setMirror(true) to reverse x-mirroring.
  2. Note on TM1650 communication protocol

    master
    Although the TM1650 datasheet mentions SDA and SCL pins (resembling I2C), the protocol lacks addressing. Consequently, this library does not use the standard Arduino Wire library; instead, it uses bit-banging via digitalWrite, which is slower than hardware I2C.
  3. Install the TM16xx library

    master

    You can install the TM16xx library using the Arduino Library Manager by searching for "TM16xx LEDs and Buttons".

    Alternatively, you can download the latest version or a specific release as a ZIP file from GitHub and use the Add .ZIP library feature in the Arduino IDE.

    Note: You may need to install the AdafruitGFX library even if you are not using TM16xxMatrixGFX, as some compilers require it to avoid errors. If you do not wish to install it, you must remove TM16xxMatrixGFX.h and TM16xxMatrixGFX.cpp from the library directory.

  4. Use TM16xxButtons for advanced button handling

    master

    The TM16xxButtons class extends basic button polling by providing callback-based event handling (similar to the OneButton library). It allows you to respond to specific user interactions like clicks, double-clicks, long presses, and releases.

    Workflow:

    1. Instantiate: Create a chip-specific object (e.g., TM1638) and pass it to TM16xxButtons.
    2. Define Callbacks: Create functions that accept a byte nButton (where 0 is the first button).
    3. Attach Callbacks: In setup(), use attachClick(), attachDoubleClick(), attachLongPress(), or attachRelease() to link your functions.
    4. Process Events: In loop(), you must call buttons.tick() to detect state changes and trigger callbacks.

    Simultaneous Presses: For chips that support it, use isPressed() to implement features like shift keys.

    #include <TM1638.h>
    #include <TM16xxButtons.h>
    
    TM1638 module(8, 9, 7); // DIO=8, CLK=9, STB=7
    TM16xxButtons buttons(&module);
    
    void fnClick(byte nButton) {
      Serial.print(F("Button "));
      Serial.print(nButton);
      Serial.println(F(" click."));
    }
    
    void setup() {
      buttons.attachClick(fnClick);
    }
    
    void loop() {
      buttons.tick(); // Required to detect events
    }
  5. Use the TM16xx base class for simple display and button tasks

    master

    The base class (e.g., TM1637, TM1638) provides a uniform API for driving LED/LCD displays and reading button states.

    Initialization

    Include the header for your specific chip and instantiate the object with the appropriate pins (e.g., DIO, CLK, STB).

    Setup

    In setup(), call .begin(on, intensity) where on is a boolean and intensity is an integer from 0 to 7.

    Displaying Data

    Use methods like .setDisplayToString() for text or .setDisplayToDecNumber() for numeric values.

    Reading Buttons

    Use .getButtons() to retrieve a bitmask of the current button states. Note that button states may be reset when displaying new data. For advanced click detection (double clicks, long presses), use the TM16xxButtons class.

    #include <TM1638.h>
    
    TM1638 module(8, 9, 7);   // DIO=8, CLK=9, STB=7
    
    void setup() {
      module.begin(true, 2);   // on=true, intensity-2 (range 0-7)
      module.setDisplayToString("HALO");
    }
    
    void loop() {
      int nTime = ((millis() / 1000) / 60) * 100 + (millis() / 1000) % 60;
      module.setDisplayToDecNumber(nTime, _BV(4)); // display with dot on digit 4
    
      uint32_t dwButtons = module.getButtons();
      Serial.println(dwButtons, HEX);
    }
  6. Use TM16xxMatrixGFX for LED matrix graphics

    master

    The TM16xxMatrixGFX class provides an interface compatible with the Adafruit GFX library to drive TM16xx-based LED matrix modules.

    Prerequisites:

    • Install the Adafruit_GFX library.
    • Include the following headers:
      • Adafruit_GFX.h
      • TM1640.h (or your specific chip header)
      • TM16xxMatrixGFX.h

    Basic Usage:

    1. Instantiate the chip-specific class (e.g., TM1640).
    2. Instantiate TM16xxMatrixGFX passing the chip object and matrix dimensions.
    3. Use matrix.write() to commit changes from the memory bitmap to the physical display.

    Combining Multiple Modules: You can combine multiple identical modules into a single large matrix by sharing the data line and passing an array of module pointers to the TM16xxMatrixGFX constructor.

    #include <Adafruit_GFX.h>
    #include <TM1640.h>
    #include <TM16xxMatrixGFX.h>
    
    TM1640 module(13, 14); // DIN=13, CLK=14
    #define MATRIX_NUMCOLUMNS 8
    #define MATRIX_NUMROWS 8
    TM16xxMatrixGFX matrix(&module, MATRIX_NUMCOLUMNS, MATRIX_NUMROWS);
    
    void setup() {
      matrix.setIntensity(1);         // Brightness 0-7
      matrix.fillScreen(LOW);        // Clear
      matrix.drawPixel(1, 4, HIGH);  // Set pixel
      matrix.write();                 // Send to display
      matrix.drawChar(0, 0, 'A', HIGH, LOW, 1);
    }
  7. Optimize memory for TM16xxButtons on small MCUs

    master

    On memory-constrained MCUs like ATtiny84 or ATtiny85, the TM16xxButtons class may consume too much RAM. By default, the library tracks a limited number of combined button presses. You can reduce this footprint by modifying the TM16XX_BUTTONS_MAXBUTTONSLOTS definition in the TM16xxButtons.h header file.

    Note: Changing this definition requires recompiling the library.

    #define TM16XX_BUTTONS_MAXBUTTONSLOTS 2
  8. Initialize the TM1668 driver

    master

    To use the TM1668 driver, instantiate the TM1668 class by providing the communication pins and optional display configuration.

    Constructor Parameters:

    • dataPin: Data pin.
    • clockPin: Clock pin.
    • strobePin: Strobe pin.
    • numDigits: Number of digits (default: 4).
    • activateDisplay: Whether to activate the display immediately (default: true).
    • intensity: Starting brightness level from 0 to 7 (default: 7).
    • displaymode: The display mode (default: TM1668_DISPMODE_7x10).
    // Example instantiation
    TM1668 module(DATA_PIN, CLK_PIN, STROBE_PIN);
  9. Use the TM16xxMatrix class for LED matrix control

    master

    The TM16xxMatrix class provides basic methods for controlling a single LED matrix module. It allows you to set individual pixels or clear the entire matrix.

    To use it, instantiate the class by passing the chip-specific module, the number of columns, and the number of rows.

    #include <TM1640.h>
    #include <TM16xxMatrix.h>
    
    TM1640 module(9, 10);    // DIN=9, CLK=10
    #define MATRIX_NUMCOLUMNS 16
    #define MATRIX_NUMROWS 8
    TM16xxMatrix matrix(&module, MATRIX_NUMCOLUMNS, MATRIX_NUMROWS);
    
    void setup() {
      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
    }