Arduino подключение дисплея на TM1637

ОБНОВЛЕНИЯ


  • v1.4 — поправлены типы данных и ошибки, добавлена совместимость с ESP

ТЕОРИЯ


7 сегментный дисплей с контроллером TM1637, очень дешёвый и удобный модуль для создания часов. Контакты CLK и DIO подключаются к любым цифровым пинам МК.

БИБЛИОТЕКА


GyverTM1637 v1.4

GyverTM1637 — бибилотека для 7 сегментного дисплея на чипе TM1637 с кучей приколюх

  • Вывод цифр массивом или прицельно
  • Вывод букв из списка доступных (листай ниже) массивом или прицельно
  • Отдельная функция вывода часов и минут (часы без нуля слева, минуты с нулём)
  • Вывод числа от -999 до 9999 с учётом знака
  • Готовая функция бегущей строки
  • Функции смены яркости и состояния двоеточия автоматически обновляют дисплей
  • Функция обновления значения с эффектом вертикальной прокрутки
  • Функция обновления значения с эффектом скручивания (лучше один раз увидеть)

Совместима со всеми Arduino платформами (используются Arduino-функции)

УСТАНОВКА


  • Библиотеку можно найти и установить через менеджер библиотек по названию GyverTM1637 в:
    • Arduino IDE (Инструменты/Управлять библиотеками)
    • Arduino IDE v2 (вкладка «Library Manager»)
    • PlatformIO (PIO Home, вкладка «Libraries»)
  • Про ручную установку читай здесь

ДОКУМЕНТАЦИЯ


GyverTM1637(uint8_t clk, uint8_t dio);									// объявление и инициализация

void display(uint8_t DispData[]);										// выводит цифры массивом по ячейкам. От 0 до 9 (byte values[] = {3, 5, 9, 0}; )
void display(uint8_t BitAddr, uint8_t DispData);							// выводит цифру DispData в указанную ячейку дисплея BitAddr
void display(uint8_t bit0, uint8_t bit1, uint8_t bit2, uint8_t bit3);	// если лень создавать массив, выводит цифры в ячейки

void displayByte(uint8_t DispData[]);									// выводит байт вида 0xe6 и буквы-константы вида _a , _b .... массивом
void displayByte(uint8_t BitAddr, uint8_t DispData);						// выводит байт вида 0xe6 и буквы-константы вида _a , _b .... в ячейку
void displayByte(uint8_t bit0, uint8_t bit1, uint8_t bit2, uint8_t bit3);	// если лень создавать массив, выводит байты в ячейки

void displayClock(uint8_t hrs, uint8_t mins);							// выводит часы и минуты
void displayClockScroll(uint8_t hrs, uint8_t mins, int delayms);		// выводит часы и минуты с эффектом прокрутки
void displayClockTwist(uint8_t hrs, uint8_t mins, int delayms);			// выводит часы и минуты с эффектом скрутки

void displayInt(int value);												// выводит число от -999 до 9999 (да, со знаком минус)

void runningString(uint8_t DispData[], byte amount, int delayMs);  		// бегущая строка (array, sizeof(array), задержка в мс)

void clear(void);														// очистить дисплей

void point(boolean PointFlag);											// вкл / выкл точку (POINT_ON / POINT_OFF)

void brightness(uint8_t bright, uint8_t = 0x40, uint8_t = 0xc0);		// яркость 0 - 7	

void scroll(uint8_t BitAddr, uint8_t DispData, int delayms);				// обновить значение прокруткой (адрес, ЦИФРА, задержка в мс)
void scroll(uint8_t DispData[], int delayms);							// обновить значение прокруткой (массив ЦИФР, задержка в мс)
void scroll(uint8_t bit0, uint8_t bit1, uint8_t bit2, uint8_t bit3, int delayms);	// прокрутка посимвольно
void scrollByte(uint8_t BitAddr, uint8_t DispData, int delayms);			// обновить значение прокруткой (адрес, БАЙТ, задержка в мс)
void scrollByte(uint8_t DispData[], int delayms);						// обновить значение прокруткой (массив БАЙТ, задержка в мс)
void scrollByte(uint8_t bit0, uint8_t bit1, uint8_t bit2, uint8_t bit3, int delayms);	// прокрутка посимвольно

void twist(uint8_t BitAddr, uint8_t DispData, int delayms);				// обновить значение скручиванием (адрес, ЦИФРА, задержка в мс)
void twist(uint8_t DispData[], int delayms);								// обновить значение скручиванием (массив ЦИФР, задержка в мс)
void twist(uint8_t bit0, uint8_t bit1, uint8_t bit2, uint8_t bit3, int delayms);	// скрутка посимвольно
void twistByte(uint8_t BitAddr, uint8_t DispData, int delayms);			// обновить значение скручиванием (адрес, БАЙТ, задержка в мс)
void twistByte(uint8_t DispData[], int delayms);							// обновить значение скручиванием (массив БАЙТ, задержка в мс)
void twistByte(uint8_t bit0, uint8_t bit1, uint8_t bit2, uint8_t bit3, int delayms);	// скрутка посимвольно

ПРИМЕРЫ


#define CLK 2
#define DIO 3

#include "GyverTM1637.h"
GyverTM1637 disp(CLK, DIO);

uint32_t Now, clocktimer;
boolean flag;

void setup() {
  Serial.begin(9600);
  disp.clear();
  disp.brightness(7);  // яркость, 0 - 7 (минимум - максимум)
  disp.clear();
  disp.displayByte(_H, _E, _L, _L);
}
void loop(){}
/*
   Пример вывода на дисплей с регистром TM1637
   показывает все возможности библиотеки GyverTM1637
   AlexGyver Technologies https://alexgyver.ru/
*/

#define CLK 2
#define DIO 3

#include "GyverTM1637.h"
GyverTM1637 disp(CLK, DIO);

uint32_t Now, clocktimer;
boolean flag;

void setup() {
  Serial.begin(9600);
  disp.clear();
  disp.brightness(7);  // яркость, 0 - 7 (минимум - максимум)

}

void loop() {
  runningText();
  scrolls();
  scrollClock();
  twists();
  twistClock();
  ints();
  bytes();
  fadeBlink();
  normClock();
}

void twists() {
  // скручивание массив ЦИФР
  byte digs[4] = {3, 5, 7, 1};
  disp.twist(digs, 50);     // скорость прокрутки 100
  delay(1000);

  // скручивание прицельно (ячейка, БАЙТ, скорость)
  disp.twistByte(0, _1, 50);
  delay(1000);

  // скручивание прицельно (ячейка, ЦИФРА, скорость)
  disp.twist(0, 8, 70);
  delay(1000);

  disp.clear();
  delay(200);
  for (byte i = 0; i < 10; i++) {
    disp.twist(3, i, 20);
    delay(200);
  }

  // скручивание массива БАЙТ
  byte troll[4] = {_t, _r, _o, _l};
  disp.twistByte(troll, 50);
  delay(1000);

  // прицельное скручивание БАЙТА (ячейка, байт, скорость)
  disp.twistByte(2, _G, 50);
  delay(1000);
}

void twistClock() {
  byte hrs = 21, mins = 55;
  uint32_t tmr;
  Now = millis();
  while (millis () - Now < 10000) {   // каждые 10 секунд
    if (millis() - tmr > 500) {       // каждые полсекунды
      tmr = millis();
      flag = !flag;
      disp.point(flag);   // выкл/выкл точки

      if (flag) {
        // ***** часы! ****
        mins ++;
        if (mins > 59) {
          mins = 0;
          hrs++;
          if (hrs > 24) hrs = 0;
        }
        // ***** часы! ****
        disp.displayClockTwist(hrs, mins, 35);    // выводим время
      }
    }
  }
  disp.point(0);   // выкл точки
}

void scrolls() {
  // прокрутка массив ЦИФР
  byte digs[4] = {3, 5, 7, 1};
  disp.scroll(digs, 100);     // скорость прокрутки 100
  delay(1000);

  // прокрутка прицельно (ячейка, ЦИФРА, скорость)
  disp.scroll(0, 8, 200);
  delay(1000);

  disp.clear();
  delay(1000);
  for (byte i = 0; i < 10; i++) {
    disp.scroll(3, i, 50);
    delay(400);
  }

  // прокрутка массива БАЙТ
  byte troll[4] = {_t, _r, _o, _l};
  disp.scrollByte(troll, 100);
  delay(1000);

  // прицельная прокрутка БАЙТА (ячейка, байт, скорость)
  disp.scrollByte(2, _G, 50);
  delay(1000);
}

void bytes() {
  // выводим байты из массива
  byte troll[4] = {_t, _r, _o, _l};
  disp.displayByte(troll);
  delay(1000);

  // выводим байты напрямую (4 в скобках)
  disp.displayByte(_L, _O, _L, _empty);
  delay(1000);

  // выводим байты "прицельно"
  disp.displayByte(3, _O);    // 3 ячейка, буква О
  delay(1000);

  // выводим цифры из массива
  byte hell[4] = {6, 6, 6, 6};
  disp.display(hell);
  delay(1000);

  // выводим цифры напрямую (4 в скобках)
  disp.display(1, 2, 3, 4);
  delay(1000);

  // выводим цифры "прицельно"
  disp.display(0, 9);    // 0 ячейка, цифра 9
  delay(1000);
}

void fadeBlink() {
  // пишем HELL
  disp.displayByte(_H, _E, _L, _L);

  Now = millis();
  while (millis () - Now < 3000) {    // 3 секунды
    for (int i = 7; i > 0; i--) {
      disp.brightness(i);   // меняем яркость
      delay(40);
    }
    for (int i = 0; i < 8; i++) {
      disp.brightness(i);   // меняем яркость
      delay(40);
    }
  }
}

void scrollClock() {
  byte hrs = 15, mins = 0;
  uint32_t tmr;
  Now = millis();
  while (millis () - Now < 10000) {   // каждые 10 секунд
    if (millis() - tmr > 500) {       // каждые полсекунды
      tmr = millis();
      flag = !flag;
      disp.point(flag);   // выкл/выкл точки

      if (flag) {
        // ***** часы! ****
        mins ++;
        if (mins > 59) {
          mins = 0;
          hrs++;
          if (hrs > 24) hrs = 0;
        }
        // ***** часы! ****
        disp.displayClockScroll(hrs, mins, 70);    // выводим время
      }
    }
  }
  disp.point(0);   // выкл точки
}

void normClock() {
  byte hrs = 15, mins = 0;
  uint32_t tmr;
  Now = millis();
  while (millis () - Now < 10000) {   // каждые 10 секунд
    if (millis() - tmr > 500) {       // каждые полсекунды
      tmr = millis();
      flag = !flag;
      disp.point(flag);   // выкл/выкл точки

      // ***** часы! ****
      mins ++;
      if (mins > 59) {
        mins = 0;
        hrs++;
        if (hrs > 24) hrs = 0;
      }
      // ***** часы! ****
      disp.displayClock(hrs, mins);   // выводим время функцией часов
    }
  }
  disp.point(0);   // выкл точки
}

void ints() {
  // тупо отправляем цифры
  disp.displayInt(-999);
  delay(500);
  disp.displayInt(-99);
  delay(500);
  disp.displayInt(-9);
  delay(500);
  disp.displayInt(0);
  delay(500);
  disp.displayInt(6);
  delay(500);
  disp.displayInt(66);
  delay(500);
  disp.displayInt(666);
  delay(500);
  disp.displayInt(6666);
  delay(500);
}

void runningText() {
  byte welcome_banner[] = {_H, _E, _L, _L, _O, _empty, _empty,
                           _e, _n, _j, _o, _y, _empty, _empty,
                           _1, _6, _3, _7, _empty, _d, _i, _S, _P, _l, _a, _y
                          };
  disp.runningString(welcome_banner, sizeof(welcome_banner), 200);  // 200 это время в миллисекундах!
}

КАК ВЫВЕСТИ БУКВЫ?
В файле TM1637.h есть список букв, которые я добавил для удобного вывода, чтобы вывести, нужно использовать один из вариантов с функцией displayByte(). Следующий код выведет букву a в самый левый порт дисплея

disp.displayByte(0, _a);

КАК ВЫВЕСТИ СТРОЧКУ?
Давайте выведем строчку HELL. Для вывода слов удобнее использовать следующий вариант:

disp.displayByte(_H, _E, _L, _L);   // вывести HELL, используя буквы из библиотеки

Ну и конечно, можно задать массив букв из библиотеки и пользоваться им:

byte lol[] = {_H, _E, _L, _L}; 
disp.displayByte(lol);

КАК СДЕЛАТЬ БЕГУЩУЮ СТРОКУ?

Очень просто, есть готовая функция runningString(). В качестве аргументов передаётся массив символов, длина строки и пауза-задержка вывода, то есть скорость бега бегущей строки. Для начала задаём массив, используя буквы из библиотеки или коды символов вида _буква:

byte welcome_banner[] = {_H, _E, _L, _L, _O, _empty, _empty,
                           _e, _n, _j, _o, _y, _empty, _empty,
                           _1, _6, _3, _7, _empty, _D, _i, _S, _P, _l, _a, _y
                          };

Далее скармливаем его функции runningString(). Длина выводимой строки определяется функцией sizeof, по другому не получилось. Здесь 300 — время в миллисекундах между обновлениями экрана, т.е. скорость движения строки.

disp.runningString(welcome_banner, sizeof(welcome_banner), 300);  // выводим

КАК ЗАДАТЬ СВОЙ СИМВОЛ?

На картинке справа показано, каким образом строится «код» символа: то есть в каком порядке расположены биты индикаторов и как они включаются и выключаются. Поняв закономерность, вы сможете задать любую конфигурацию светящихся индикаторов в одном порте. Вывести символ можно одним из вариантов функции displayByte.

disp.displayByte(0x76, 0x79, 0x38, 0x38);  // вывести HELL "вручную"

ОНЛАЙН-ГЕНЕРАТОР СИМВОЛОВ

А ещё можно воспользоваться онлайн генератором двоичных кодов для индикаторов! Смотри картинку ниже, думаю всё будет понятно.

Символы в библиотеке

/************** БУКВЫ И СИМВОЛЫ *****************/
#define _A 0x77
#define _B 0x7f
#define _C 0x39
#define _D 0x3f
#define _E 0x79
#define _F 0x71
#define _G 0x3d
#define _H 0x76
#define _J 0x1e
#define _L 0x38
#define _N 0x37
#define _O 0x3f
#define _P 0x73
#define _S 0x6d
#define _U 0x3e
#define _Y 0x6e
#define _a 0x5f
#define _b 0x7c
#define _c 0x58
#define _d 0x5e
#define _e 0x7b
#define _f 0x71
#define _h 0x74
#define _i 0x10
#define _j 0x0e
#define _l 0x06
#define _n 0x54
#define _o 0x5c
#define _q 0x67
#define _r 0x50
#define _t 0x78
#define _u 0x1c
#define _y 0x6e
#define _- 0x40
#define __ 0x08
#define _= 0x48
#define _empty 0x00
#define _0 0x3f
#define _1 0x06
#define _2 0x5b
#define _3 0x4f
#define _4 0x66
#define _5 0x6d
#define _6 0x7d
#define _7 0x07
#define _8 0x7f
#define _9 0x6f

ПОДДЕРЖАТЬ


Вы можете поддержать меня за создание доступных проектов с открытым исходным кодом, полный список реквизитов есть вот здесь.

5 1 голос
Рейтинг статьи
Подписаться
Уведомить о
guest

100 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх