ПОДКЛЮЧЕНИЕ ДИСПЛЕЯ НА TM1637 К ARDUINO

Простенький 7-ми сегментный дисплей на базе сдвигового регистра TM1637. Есть встроенная динамическая индикация, всё работает без плясок с бубном. Двоеточие в центре делает его идеальным вариантом для создания часов и таймеров.

ОСОБЕННОСТИ

  • Идеальный вариант для часов
  • Встроенная динамическая индикация, работает гладко и плавно
  • Потребление: все индикаторы погашены – 0 мА, все индикаторы горят – 43 мА.
в магазин

СХЕМЫ И БИБЛИОТЕКИ

Библиотека TM1637.h, модифицирована мной для удобной работы, дописана куча удобных методов. Что умеет:

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

Список методов

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, int8_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, int8_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(int8_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, int8_t DispData, int delayms);             // обновить значение прокруткой (адрес, ЦИФРА, задержка в мс)
void scroll(int8_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, int8_t DispData, int delayms);         // обновить значение прокруткой (адрес, БАЙТ, задержка в мс)
void scrollByte(int8_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, int8_t DispData, int delayms);              // обновить значение скручиванием (адрес, ЦИФРА, задержка в мс)
void twist(int8_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, int8_t DispData, int delayms);          // обновить значение скручиванием (адрес, БАЙТ, задержка в мс)
void twistByte(int8_t DispData[], int delayms);                         // обновить значение скручиванием (массив БАЙТ, задержка в мс)
void twistByte(uint8_t bit0, uint8_t bit1, uint8_t bit2, uint8_t bit3, int delayms);  // скрутка посимвольно
ПЕРВЫЕ ШАГИ С ARDUINO

ВНИМАНИЕ!

Если вы не знаете, куда подключить Arduino, где взять программу для прошивки, как установить драйвера, как всё настроить и как устанавливать библиотеки – читайте статейку “Первые шаги с Arduino”, ссылка справа от этого текста. Там же разобраны типичные ошибки, описаны варианты питания и есть краткий FAQ.

ПЕРВЫЕ ШАГИ С ARDUINO

КАК ВЫВЕСТИ БУКВЫ?
В файле 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
/************** БУКВЫ И СИМВОЛЫ *****************/

ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ

/*
Пример вывода на дисплей с регистром 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
AlexGyver Technologies https://alexgyver.ru/
*/
//--- ПИНЫ ---
#define CLK 5
#define DIO 4
//--- ПИНЫ ---
//--- ОБЪЯВЛЕНИЕ ---
#include "TM1637.h"
TM1637 disp(CLK, DIO);
//--- ОБЪЯВЛЕНИЕ ---
void setup() {
disp.init();  // инициализация
disp.set(7);  // яркость, 0 - 7 (минимум - максимум)
}
void loop() {
// БЕГУЩАЯ СТРОКА!
// забиваем массив бегущей строки буквами из библиотеки
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), 300);  // выводим
delay(700);
disp.clearDisplay();
disp.displayByte(0x76, 0x79, 0x38, 0x38);  // вывести HELL "вручную"
delay(2000);
disp.clearDisplay();
disp.displayByte(_H, _E, _L, _L);   // вывести HELL, используя буквы из библиотеки
delay(2000);
disp.clearDisplay();
byte lol[] = {1, 2, 3, 4};    // вывести 1234 из массива
disp.display(lol);
delay(2000);
disp.clearDisplay();
for (byte j = 0; j < 99; j++) {  // вывести 0-99 счётчик с нулями слева
disp.displayIntZero(j);
delay(20);
}
disp.clearDisplay();
for (int j = 0; j < 1100; j += 5) {  // счётчик 0-1100 без нулей
disp.displayInt(j);
delay(20);
}
disp.clearDisplay();
for (byte i = 0; i <= 3; i++) {       // выводим цифры 0-9 по очереди в каждый порт
for (byte j = 0; j <= 9; j++) {
disp.display(i, j);
delay(100);
}
disp.clearDisplay();
}
disp.clearDisplay();
}
/*
// нумерация портов слева направо!
disp.display(port, num);      // вывести цифру num (0-9) в порт port (0-3)
disp.display(ARRAY);          // вывести ARRAY, где ARRAY - массив из 4х цифр ( byte ARRAY[4] = {0, 1, 2, 3}; )
disp.displayByte(port, Byte); // вывести символ Byte в порт port (0-3) (Byte вида 0x7d)
disp.displayByte(ARRAY_BYTE); // ARRAY_BYTE - массив кодов ( 0x7d, 0x7d, 0x7d, 0x7d )
disp.displayByte(Byte1, Byte2, Byte3, Byte4); // вывести побайтово
// для вывода некоторых букв доступен вывод вида _A, _b, _h. Полный список смотри в TM1637.h
disp.displayInt(value);       // вывести 1-4 значное число
disp.displayIntZero(value);   // вывести 1-4 значное число с нулями СЛЕВА
disp.point(state);        // включить/выключить двоеточие (1 и 0 соответственно)
disp.clearDisplay();      // очистить дисплей
disp.set(7);              // яркость, 0 - 7 (минимум - максимум)
*/
/*
Пример простейшего таймера на дисплее с регистром TM1637
AlexGyver Technologies https://alexgyver.ru/
*/
/* // нумерация портов слева направо!
tm1637.display(port, num);  // вывести цифру num (0-9) в порт port (0-3)
tm1637.display(ARRAY);      // вывести ARRAY, где ARRAY - массив из 4х цифр ( byte ARRAY[4] = {0, 1, 2, 3}; )
tm1637.point(state);        // включить/выключить двоеточие (1 и 0 соответственно)
tm1637.clearDisplay();      // очистить дисплей
tm1637.set(7);              // яркость, 0 - 7 (минимум - максимум)
*/
//--- ПИНЫ ---
#define CLK 5
#define DIO 4
//--- ПИНЫ ---
byte sec, mins;
byte TIME[4];
unsigned long halfsec;
boolean dots;
#include "TM1637.h"
TM1637 tm1637(CLK, DIO);
void setup()
{
tm1637.init();  // инициализация
tm1637.set(7);  // яркость, 0 - 7 (минимум - максимум)
}
void loop() {
if (millis() - halfsec > 500) {  // если прошло полсекунды
halfsec = millis();            // сбросить таймер
dots = !dots;                  // переключить точки
if (dots) tm1637.point(0);     // выключить точки
else tm1637.point(1);          // включить точки
sec = millis() / 1000;         // получить секунды со старта Ардуины
mins = floor(sec / 60);        // получить целые минуты из секунд
sec = sec - (mins * 60);       // найти оставшиеся целые секунды
TIME[0] = mins / 10;           // получить десятки минут
TIME[1] = mins % 10;           // получить единицы минут
TIME[2] = sec / 10;            // получить десятки секунд
TIME[3] = sec % 10;            // получить единицы секунд
tm1637.display(TIME);          // вывести массив на дисплей
}
}

ОСТАЛЬНЫЕ БИБЛИОТЕКИ

У меня есть ещё очень много всего интересного! Смотрите полный список библиотек вот здесь.

2019-09-16T18:02:03+03:00