Дисплей TM1637: подключение к Arduino (4 цифры, 2 провода)
Индикатор на чипе TM1637 это самый дешёвый способ добавить на устройство крупные цифры: четыре разряда, два управляющих провода и ни одного резистора в обвязке. Часы, счётчик секунд, таймер обратного отсчёта, показания датчика: всё это выводится одной функцией showNumberDec из библиотеки TM1637Display.
Ниже схема подключения к Uno и Nano, код с яркостью и двоеточием, честный разбор токов и чек-лист для молчащего экрана. Пошаговый разбор с граблями в уроке TM1637: четырёхразрядный индикатор, а покрутить цифры можно в симуляторе: дисплей подключается к плате сам по коду скетча.
Отдельные разделы ниже отвечают на то, что обычно всплывает позже: почему вместо цифр мусор, почему двоеточие мигает, как устроены кнопки на этом же модуле и какой индикатор вообще стоит брать.
Схема: два провода и питание
| Вывод TM1637 | Arduino Uno | Зачем |
|---|---|---|
| CLK | Любой цифровой, например D4 | Тактирование |
| DIO | Любой цифровой, например D5 | Данные |
| VCC | 5 В | Питание (от 3.3 В работает, но тусклее) |
| GND | GND | Земля |
Пины CLK и DIO берите любые: протокол TM1637 не I2C, у него нет адресов, и на I2C-сканере дисплей не появится, поэтому искать его сканером бесполезно. Библиотека сама дёргает обе линии побитно и жёстко контролирует тайминги, так что прятать CLK и DIO можно хоть на D2 и D12, лишь бы в конструкторе TM1637Display(CLK, DIO) стояли те же номера, что в проводке.
Отдельно про маркировку выводов: на разных платах одни и те же контакты подписаны по-разному, и это источник путаницы. Управляющие линии называются CLK и DIO, но встречаются варианты DIN и CLK, а на модулях с кнопками к ним добавляются D1 и D2, через которые чип читает состояние кнопок. Сам чип TM1637 это драйвер семисегментного индикатора со встроенным сканером клавиш: он не просто «горит цифрами», а умеет формировать изображение на сегментах и опрашивать кнопки, поэтому протокол такой простой, но не I2C.
Код: цифры, яркость, двоеточие
#include <TM1637Display.h>#define CLK 4#define DIO 5TM1637Display disp(CLK, DIO); void setup() { disp.setBrightness(5); // 0..7 — восемь уровней} void loop() { disp.showNumberDec(1234); // 1234 delay(1000); disp.showNumberDecEx(1435, 0x40); // 14:35 — двоеточие горит delay(1000); disp.showNumberDec(57, true); // 0057 — ведущие нули delay(1000);}Двоеточие включается флагом 0x40 во втором аргументе showNumberDecEx, на модулях с часами это разделитель между второй и третьей цифрой. Выводить его «насовсем» нельзя: каждый кадр перезаписывает буфер, поэтому в часах showNumberDecEx вызывается в loop постоянно. Аргументы length и pos позволяют писать число в часть экрана: showNumberDec(12, true, 2, 2) выведет 12 начиная с третьего разряда. Отрицательные числа печатаются с минусом вразрез, а больше четырёх знаков индикатор не умеет физически, и showNumberDec(98765) покажет младшие разряды, то есть 8765. Порядок байтов в setSegments тоже обратный: нулевой элемент массива это самый правый разряд, и об этом стоит помнить, когда рисуете что-то вроде надписи «Err».
Ток и яркость: числа для планирования
Сам контроллер TM1637 ест копейки, сотни микроампер без нагрузки, и почти весь ток расходуют зажжённые сегменты: все 32 сегмента на максимальной яркости дают порядка 80 мА на модуль, это половина бюджета USB-порта. Яркость регулируется восемью уровнями setBrightness(0..7): на 5 дисплей уверенно читается из пары метров, а ток падает в разы. Для батарейного проекта мы ставим 1–2 или гасим дисплей вызовом clear() при простое. Заодно это объясняет, почему на максимуме при включённой лампе рядом с индикатором кажется, что он «слепит»: дело не в яркости как таковой, а в потреблении, которое тянет всю линию питания.
Что показать кроме цифр
Библиотека умеет и буквы, но не все. Функция setSegments() принимает четыре сырых байта, где каждый бит это сегмент a–g, и на семи сегментах осмысленно выглядят только A, b, C, d, E, F, H, L, P, U, o, t, минус и знак градуса. Слово «HELP» соберётся, а «MOM» нет: M и W на семи сегментах физически не существуют. Для текста это тупик, для символов вроде минус, градус и «E» вполне рабочий путь.
- showNumberDec(число) — цифры, минус, ведущие нули по второму аргументу
- showNumberDecEx(число, 0x40) — то же с двоеточием: штатный режим часов
- setSegments(массив[4]) — сырые байты: буквы, минус, свои символы
- setBrightness(0..7) — восемь уровней яркости
- clear() — погасить все разряды
- scanKeys() и getKey() — опрос кнопок, если они есть на модуле
Кнопки на том же модуле
На большинстве плат с TM1637 есть ещё две кнопки, и чип умеет их опрашивать: специальными командами он отдаёт состояние клавиш, и библиотека TM1637Display это умеет. Практически это значит, что к индикатору можно добавить две кнопки и обойтись всего четырьмя проводами вместо шести, а кнопки будут работать без отдельной тактовой подтяжки и без дребезга в коде. Мы использовали это в проекте с таймером: одна кнопка меняет режим, вторая запускает отсчёт. Минус один: опрос кнопок нужно вызывать регулярно, и если забыть про это, кнопки «залипнут».
Тупик: вместо цифр мусор
Первый дисплей в нашем проекте показывал не цифры, а случайные сегменты, и это выглядело как поломка самого модуля. Мы перепрошивали скетч, меняли местами CLK и DIO в проводке, переставляли библиотеку и в какой-то момент решили, что индикатор сгорел.
Дело было в том, что номера пинов в конструкторе не совпадали с реальной проводкой. Мы перенесли дисплей на другую пару выводов, поменяли их в коде, а в схеме забыли, и кадр приходил в неверном такте, а чип показывал то, что осталось в буфере. Второй случай с похожей картиной: мы добавили в проект датчик DS18B20, и он занял тот же вывод, что использовался для данных индикатора. Выводы нельзя расходовать молча, и перед добавлением каждого нового модуля стоит нарисовать таблицу «вывод и кто его использует».
Личный опыт: часы на TM1637
Мы собирали часы на TM1637 и RTC DS3231, и индикатор оказался удобнее, чем мы ожидали: крупные цифры читаются через всю комнату, а стоит такой модуль дешевле, чем LCD с тем же числом знакомест. Первая версия показывала время с мигающим двоеточием, и мы приняли это за дефект, хотя это была обычная особенность перерисовки буфера каждый кадр.
Второе, что мы поменяли, это яркость. На уровне 5 индикатор ночью был просто слишком ярким, и мы опустили его до 2, а в вечерние часы гасили совсем. Побочный эффект оказался приятным: ток упал, и часы на батарейках стали жить заметно дольше. Третье наблюдение касается семисегментного ограничения: мы хотели вывести слово «ALARM», и буквы A, L, R, M... M на семисегментах не существует, поэтому надпись пришлось сократить. Планировать текст под семисегментный алфавит нужно заранее, иначе проект упрётся в физику.
Авторская позиция: какой индикатор взять
Мы советуем брать TM1637, когда нужно показать одно число: время, температуру, счётчик, цену. Модуль стоит копейки, занимает два вывода, не требует ни резисторов, ни подтяжек, и умеет восемь уровней яркости плюс кнопки. Для большинства бытовых приборов этого достаточно, а ограничение в виде «только цифры» обычно не мешает.
Берите MAX7219, если цифр нужно больше, чем четыре, или нужна матрица, или нужны бегущие строки и эффекты. Он ярче, ток задаётся одним резистором, а библиотека умеет извращения вроде сдвига текста. И берите LCD или OLED, если нужен настоящий текст: семисегментный алфавит физически ограничен, и любая длинная надпись превращается в набор букв A, b, C, d, E, F, H, L, P, U. Наш выбор по умолчанию: TM1637 для цифр, OLED для текста и графики.