отображение 3-значного времени часов на 4-значном 7-сегментном дисплее

Я купил один из этих 4-разрядных 7-сегментных дисплеев с использованием TM1637.

Я установил библиотеку отображения TM1637 из диспетчера библиотек и включил ее:

(#include <TM1637Display.h>).

Я пытаюсь отобразить время, и я хотел бы, предпочтительно, отображать 3-значное время с двоеточием, но без начального нуля.

Я нашел в Интернете отличный справочник по использованию библиотеки. и увидел использование чисел с двоеточиями. :

showNumberDecEx(число, точки, ведущие_нули, длина, позиция)

согласно руководству, чтобы двоеточие было в центре, необходимо передать 0b01000000 в качестве параметра dots.

И я прикинул, что если я потом захочу отобразить, например, время 1:36, то мой параметр number будет равен 136, мой leading_zeros Параметр будет 0 (false), моя длина будет 3 для трехзначного числа, а моя позиция будет равна 1 чтобы начать номер во второй позиции с нулевым индексом:

display.showNumberDecEx(136, 0b01000000, false, 3, 1); //отображает 5136

Но это отображало 5136 без двоеточия.

Я пробовал и другие способы, в том числе:

display.showNumberDecEx(136, 0b01000000, правда, 3, 0); //отображает 13:66 display.showNumberDecEx(136, 0b01000000, false, 3, 0); //отображает 13:6A

Наконец-то я нашел код с этого сайта, который работает для отображения времени (хотя и с начальным нулем), но я не совсем понимаю:

display.showNumberDecEx(1*100+36, 0x80 >> 1, 1, 4, 0);

Я понимаю, что 1*100+36 представляет количество часов плюс минуты, но я не понимаю 0x80 >> 1 бит. Я предполагаю, что остальная часть просто говорит: сделайте его четырехзначным числом и добавьте начальный ноль.

Может ли кто-нибудь: * помогите мне понять приведенный выше рабочий код * скажите мне более простой способ построить время, чтобы в идеале я мог просто передать 3 или 4-значное число и автоматически отображать время на часах с разделяющим двоеточием * скажите мне, почему мои предыдущие попытки были неверными

, 👍0


2 ответа


Лучший ответ:

3

Я проверил вашу первую строку кода, и она выводит на мой дисплей выравнивание по правому краю 136 без двоеточия. (Сказал, что у меня есть только двоеточие в середине и нет десятичных точек)

Цифра 5 в первой цифре (а также буква А в третьей строке кода) должна быть где-то установлена заранее. Функция не изменяет неиспользуемую цифру, поэтому она останется такой, какую вы установили заранее (даже до последнего сброса Arduino. Дисплей не сбрасывается с помощью Arduino). Вы можете установить сегменты для этой цифры равными нулю (или установить все сегменты равными нулю, чтобы очистить весь дисплей) перед отображением десятичного числа.

О двоеточии: Здесь важно, с какой позиции вы начинаете печать числа. Битовая маска двоеточия/десятичной точки, которую вы предоставляете функции, видна из начальной позиции, которую вы предоставляете. Среднее двоеточие 4-разрядного дисплея связано со второй цифрой. При указании 1 в качестве начальной позиции вы начинаете со второй цифры. Таким образом, битовая маска двоеточия должна установить самый старший («первый») бит, чтобы включить среднее двоеточие, поскольку оно принадлежит первой цифре, обрабатываемой функцией. Значение:

position = 0 and bitmask = 0b10000000 --> colon/decimal point at first digit on
position = 0 and bitmask = 0b01000000 --> colon/decimal point at second digit on
position = 0 and bitmask = 0b00100000 --> colon/decimal point at third digit on
position = 1 and bitmask = 0b10000000 --> colon/decimal point at second digit on
position = 1 and bitmask = 0b01000000 --> colon/decimal point at third digit on
position = 2 and bitmask = 0b10000000 --> colon/decimal point at third digit on
position = 2 and bitmask = 0b01000000 --> colon/decimal point at fourth digit on

Код 0x80 >> 1 — это просто другое представление вашего двоичного числа. 0x80 — это шестнадцатеричная форма двоичного 0b10000000. Оператор >> сдвигает байт вправо, здесь на одну цифру. Таким образом:

0x80 >> 1 = 0b10000000 >> 1 = 0x40 = 0b01000000

Итак, код, который вы нашли, включает двоеточие/десятичную точку во второй цифре.

подскажите, как проще построить время

Проще относительно. Я использовал такое отображение в проекте для отображения времени и использовал два вызова showNumberDecEx(); один для минут и один для секунд:

display.showNumberDecEx(seconds, 0x00, true, 2, 2);
display.showNumberDecEx(minutes, 0x40, true, 2, 0);

Наличие непосредственно минут и секунд может облегчить вам задачу. Насчет отсутствия начальных нулей: поскольку библиотека всегда печатает слева направо, вам нужно справиться с этим самостоятельно. Но это довольно легко. Один оператор if для проверки, больше ли минут 9 или нет. В зависимости от этого вы устанавливаете позицию на 0 или 1.

display.showNumberDecEx(seconds, 0x00, true, 2, 2);
if(minutes > 9){
    display.showNumberDecEx(minutes, 0x40, false, 2, 0);
} else {
    display.showNumberDecEx(minutes, 0x80, false, 1, 1);
}

Вы можете поместить это в функцию, чтобы вам не приходилось писать этот код несколько раз.

Примечание. Чтобы мой последний фрагмент кода заработал, вы должны сначала очистить дисплей (или, при желании, только первую цифру), чтобы там не отображались предыдущие числа.

,

В вашем последнем фрагменте кода случай minutes ≤ 9 не будет работать должным образом, поскольку, как вы сами выразились, «_функция не меняет неиспользуемую цифру, поэтому она останется такой, какой вы ее установили заранее_»., @Edgar Bonet

Это правда. Я неявно предполагал, что дисплей предварительно очищается. Я добавлю примечание для этого., @chrisl


1

Всегда начинайте с чтения документации. README дисплея TM1637 библиотека дает краткий обзор доступных функций, а затем указывает «Пожалуйста, обратитесь к TM1637Display.h для получения дополнительной информации». Таким образом, это было бы кажется, что авторитетная документация - это сам заголовочный файл, который действительно богат структурированными комментариями. Согласно этому, подпись showNumberDecEx()

void showNumberDecEx(int num,
                     uint8_t dots = 0,
                     bool leading_zero = false,
                     uint8_t length = 4,
                     uint8_t pos = 0);

где параметры имеют следующие значения (выделено мной):

  • число: отображаемое число
  • точки: точка/двоеточие включить [...]
  • leading_zero: при значении true отображаются ведущие нули, в противном случае ненужные цифры пусты
  • длина: количество цифр для установки
  • pos: позиция старшей значащей цифры. (0 – крайний левый, 3 – крайний правый)

Параметры length и pos определяют, какие цифры будут установлены. Это важно отметить, что любые цифры, которые не установлены, остаются как есть. Также обратите внимание, что если вы устанавливаете больше цифр, чем необходимо для отображения числа крайние левые цифры либо нули, либо пустые, в зависимости от на значение leading_zero. И это именно то, что вы хотите: вы хотите, чтобы крайняя левая цифра была пустой.

Вот несколько примеров отображения различных вызовов:

display.showNumberDecEx(136, 0x40, true,  3, 1)  →  "X1:36"
display.showNumberDecEx(136, 0x40, false, 3, 1)  →  "X1:36"
display.showNumberDecEx(136, 0x40, true,  3, 0)  →  "13:6X"
display.showNumberDecEx(136, 0x40, false, 3, 0)  →  "13:6X"
display.showNumberDecEx(136, 0x40, true,  4, 0)  →  "01:36"
display.showNumberDecEx(136, 0x40, false, 4, 0)  →  " 1:36"

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

display.showNumberDecEx(136, 0x40);

Вы также можете последовать совету Крисла и отображать часы и минуты. отдельно:

int hours = 1;
int minutes = 36;
display.showNumberDecEx(hours, 0x40, false, 2, 0);
display.showNumberDecEx(minutes,  0, true,  2, 2);

Нет необходимости отдельно обрабатывать случай, когда hours больше 9.

,