ОБНОВЛЕНИЯ
- v1.4 — поправлены типы данных и ошибки, добавлена совместимость с ESP
ТЕОРИЯ
7 сегментный дисплей с контроллером TM1637, очень дешёвый и удобный модуль для создания часов. Контакты CLK и DIO подключаются к любым цифровым пинам МК.
БИБЛИОТЕКА
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
ПОДДЕРЖАТЬ
Вы можете поддержать меня за создание доступных проектов с открытым исходным кодом, полный список реквизитов есть вот здесь.