I v dnešní době plné maticových displejů a dalších udělátek se někdy hodí stará dobrá sedmisegmentovka, protože je jednoduchá a jasně čitelná ve tmě i na světle. Způsobů, jak ovládat 7-seg displeje z Arduina, je spousta.

Hardwarový modul

Já jsem objevil zajímavý modul s čipem TM1637, který má z mého pohledu několik výhod:

Dá se snadno koupit na AliExpressu, příkladmo:

K dispozici je pět barev (bílá, červená, zelená, žlutá, modrá) a různé varianty rozložení teček. Moje verze má desetinnou tečku za každou číslicí (ty se mi ale nepodařilo rozchodit) a hodinovou dvojtečku mezi dvojicemi.

Softwarové knihovny

Našel a vyzkoušel jsem dvě knihovny, které s těmito moduly umějí pracovat:

Práce s knihovnou TM1637Display.h

Pro propojení s Arduinem potřebujete dva digitální piny (plus napájení 5 V a zem). Jeden z nich jsou hodiny (CLK) a druhý data (DIO jako data in/out). Můžete použít jakékoliv dva piny, já použil 2 a 3. Po vytvoření objektu TM1637Display máte k dispozici následující metody:

Kompletní přehled všech funkcí a parametrů najdete v hlavičkovém souboru TM1637Display.h

Zajímavá je možnost kombinace číslic a vlastních znaků. Pomocí overloadů metod showNumberDec a showNumberDecEx můžete nastavit délku a pozici zobrazovaného čísla. Pokud tedy například chcete zobrazit teplotu (např. 20°C) nebo chybové hlášení (např. Err1), můžete písmena a symboly zapsat pomocí setSegments a potom doplnit.

Napsal jsem ukázkový kód, který ukazuje základní možnosti knihovny a výše uvedenou kombinaci.

#include <TM1637Display.h>

// Piny pro pripojeni displeje
#define CLK 2
#define DIO 3

// Definice specialnich znaku
#define CHAR_LINES 0b01001001
#define CHAR_MINUS 0b01000000
#define CHAR_DEG   0b01100011
#define CHAR_C     0b00111001
#define CHAR_F     0b01110001
#define CHAR_E     0b01111001
#define CHAR_R     0b01010000

// Inicializace displeje
TM1637Display display(CLK, DIO);

void setup() {
  // Nastaveni jasu: 0 (min) - 7 (max)
  display.setBrightness(4);
}

void loop() {
  // Pocitani cisel 0 - 100 bez nul na zacatku
  for (int i = 0; i <= 100; i++) {
    display.showNumberDec(i, false);
    delay(20);
  }

  // Pocitani cisel 0000 - 0100 s nulami na zacatku
  for (int i = 0; i <= 100; i++) {
    display.showNumberDec(i, true);
    delay(20);
  }

  // Zobrazeni teploty - priprava
  byte segDataDeg[] = { CHAR_LINES, CHAR_LINES, CHAR_DEG, CHAR_C};
  display.setSegments(segDataDeg);
  delay(1000);

  // Zobrazeni teploty - 00 - 90 stupnu
  for (int i = 0; i <= 90; i += 10) {
    display.showNumberDec(i, true, 2);
    delay(250);
  }

  // Zobrazeni chyby Err0 - Err9
  byte segDataErr[] = { CHAR_E, CHAR_R, CHAR_R, CHAR_MINUS};
  display.setSegments(segDataErr);
  for (int i = 0; i <= 9; i++) {
    display.showNumberDec(i, true, 1, 3);
    delay(1000);
  }
}

Dvojtečka na mém displeji přímo vybízí k použití jako hodiny nebo stopky. Druhý ukázkový kód tedy ukazuje po sekundách čas.

#include <TM1637Display.h>

// Piny pro pripojeni displeje
#define CLK 2
#define DIO 3

// Zapni nbebo vypni tecku
#define DOT_OFF 0b00000000
#define DOT_ON  0b01000000

// Inicializace displeje
TM1637Display display(CLK, DIO);

// Aktualni mninuty a sekundy
byte mm = 0;
byte ss = 0;

// Cas pristi zmeny sekundy
unsigned long nextSecondChange = 0;

// Cas pristiho zapnutí dvojtecky
unsigned long nextDotChange = 0;

void setup() {
  // Nastaveni jasu: 0 (min) - 7 (max)
  display.setBrightness(4);

  // Zobraz 0000
  display.showNumberDecEx(0, true);
  nextDotChange = millis() + 500;
  nextSecondChange = nextDotChange + 500;
}

void loop() {
  // Zobraz cas, pokud uplynula sekunda
  if (millis() > nextSecondChange) {
    nextSecondChange += 1000;

    // Inkrementuj cas
    ss++;
    if (ss == 60) {
      ss = 0;
      mm++;
    }
    if (mm == 100) mm = 0;

    // Zobraz cas bez dvojtecky
    int displayValue = mm * 100 + ss;
    display.showNumberDecEx(displayValue, DOT_OFF, true);
  }

  // Zapni dvojtecku v pulce sekundy (zmena sekundy ji vypne)
  if (millis() > nextDotChange) {
    nextDotChange += 1000;

    // Zobraz cas bez dvojtecky
    int displayValue = mm * 100 + ss;
    display.showNumberDecEx(displayValue, DOT_ON, true);
  }
}