0

I purchased one of these 4 digit 7 segment displays using a TM1637.

I installed the TM1637 display library from the libraries manager and included it:

(#include <TM1637Display.h>).

I am trying to display the time, and I would like, preferably, to display 3 digit times with a colon, but without the leading zero.

I found this great reference online for using the library., and saw the usage for numbers with colons:

showNumberDecEx(number, dots, leading_zeros, length, position)

according to the guide, to have the colon in the center, you would pass 0b01000000 as the dots parameter.

And I figured that if I then want to display, for example, the time 1:36, then my number parameter would be 136, my leading_zeros parameter would be 0 (false), my length would be 3 for a 3 digit number, and my position would by 1 to start the number in the zero-indexed second position:

display.showNumberDecEx(136, 0b01000000, false, 3, 1); //displays 5136

But this displayed 5136 with no colon.

I tried a number of other things, including:

display.showNumberDecEx(136, 0b01000000, true, 3, 0); //displays 13:66 display.showNumberDecEx(136, 0b01000000, false, 3, 0); //displays 13:6A

I finally found code from this site, which works to display the time (albeit with a leading zero), but I don't fully understand it:

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

I get that 1*100+36 represents number of hours plus minutes, but I don't get the 0x80 >> 1 bit. I'm assuming the rest of it is just saying make it a 4 digit number and add a leading zero.

Can anyone possibly: * help me understand the above working code * tell me an easier way to construct a time so that I can ideally just pass a 3 or 4 digit number and have it automatically render out a clock time with separating colon * tell me why my previous attempts were incorrect

4

I tested your first code line and it outputs a right aligned 136 without colon at my display. (Said I have only a colon at the middle and no decimal points)

The 5 at the fist digit (and also the A at your third code line) must have been set somewhere beforehand. The function does not change the unused digit, so it will stay whatever you set it to beforehand (Even from before the last reset of the Arduino. The display doesn't reset with the Arduino). You can set the segments for that digit to zero (or set all segments to zero, to clear the complete display) before you show the decimal number.

About the colon: Here it is important on which position you start the printing of the number. The colon/decimal point bitmask, that you provide the function with, is seen from the starting position, that you provide. The middle colon of a 4 digit display is wired to the second digit. When providing 1 as the starting position, you start with the second digit. Thus the colon bitmask must set the most significant ("first") bit, to enable the middle colon, since it belongs to the first digit, that is processed by the function. Meaning:

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

The 0x80 >> 1 is just a different representation of your binary number. 0x80 is the hexadecimal form of the binary 0b10000000. The >> operator shifts the byte to the right, here by one digit. Thus:

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

So the code, that you found, enables the colon/decimal point at the second digit.

tell me an easier way to construct a time

Easier it relative. I used such a display in a project to display a time and used two showNumberDecEx() calls; one for the minutes and one for the seconds:

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

Having directly minutes and seconds may make it easier for you. About the no-leading-zeros: Since the library always prints left to right, you need to handle that by yourself. But that is rather easy. One if statement to check, if the minutes are greater than 9 or not. Depending on that you set the position to 0 or 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);
}

You could put that into a function, so that you don't have to write this code multiple times.

Note: For my last code snippet to work, you should first clear the display (or optionally only the first digit), so that no number from before will be displayed there.

| improve this answer | |
  • In your last code snippet, the case minutes ≤ 9 won't work as expected since, as you put it yourself, “the function does not change the unused digit, so it will stay whatever you set it to beforehand”. – Edgar Bonet Feb 18 at 9:24
  • That's true. I assumed implicitly, that the display is cleared beforehand. I will add a note for that. – chrisl Feb 18 at 9:28
1

Always start by reading the docs. The README of the TM1637 display library gives a short summary of the available functions, then states “Please refer to TM1637Display.h for more information.” It would thus seem the authoritative documentation is the header file itself, which is indeed rich ins structured comments. According to it, the signature of showNumberDecEx() is

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

where the parameters have the following meanings (emphasis mine):

  • num: the number to be shown
  • dots: dot/colon enable [...]
  • leading_zero: when true, leading zeros are displayed, otherwise unnecessary digits are blank
  • length: the number of digits to set
  • pos: the position of the most significant digit (0 - leftmost, 3 - rightmost)

The length and pos parameters control which digits are set. It is important to note that any digits that are not set are left as is. Note also that, if you are setting more digits than needed to display the number, the leftmost digits are either zeros or blank, depending on the value of leading_zero. And that is exactly what you want: you want the leftmost digit to be blank.

Here are some examples of what various calls display:

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"

In the examples above, “X” means “whatever was previously left there”, as the corresponding digit is not updated by the call. The last example is the one you want. Incidentally, the last three parameters of this example have their default values. You can thus achieve this simply with:

display.showNumberDecEx(136, 0x40);

You can also follow chrisl's advice and display the hours and minutes separately:

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

No need to separately handle the case where hours is larger than 9.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.