Help with TM1637 6-digit And Button

Greetings to everyone on this forum.
I have an Arduino code for a clock using a TM1637 6-digit display and 2 buttons to adjust the time. I have two questions:

  1. Add the decimal point between hours and minutes and between minutes and seconds.
  2. The function of the 2 buttons, which is to adjust hours and minutes, is not responding.

I would greatly appreciate any help.

#include <Arduino.h>
#include <TM1637TinyDisplay6.h>

// TM1637 pins
#define CLK 2
#define DIO 3

// Button pins
#define BTN_HOUR 4
#define BTN_MIN  5

// Cria uma instância de display para módulo de 6 dígitos
TM1637TinyDisplay6 display(CLK, DIO);

// Relógio de software simples (24 horas)
uint8_t hours   = 12;
uint8_t minutes = 0;
uint8_t seconds = 0;

// Cronometragem com milissegundos()
unsigned long lastTickMs = 0;

// Estado do botão para eliminação de simples debouncing
const unsigned long DEBOUNCE_MS = 50;

bool lastHourBtnState = HIGH;
bool lastMinBtnState  = HIGH;

unsigned long lastHourChangeMs = 0;
unsigned long lastMinChangeMs  = 0;

void setup() {
  // Initialize display
  display.begin();
  display.setBrightness(7);  // 0–7 (7 = mais brilhante)

  // Inicializa os botões com resistores pull-up internos.
  pinMode(BTN_HOUR, INPUT_PULLUP);
  pinMode(BTN_MIN,  INPUT_PULLUP);

  // Exibição inicial
  updateDisplay();
}

void loop() {
  unsigned long now = millis();

  // --- 1) Timekeeping: tick every 1000 ms ---
  if (now - lastTickMs >= 1000) {
    lastTickMs += 1000;
    tickClock();
    updateDisplay();
  }

  // --- 2) Botão de ajuste de horas (incrementa horas) ---
  handleHourButton(now);

  // --- 3) Botão de ajuste de minutos (incrementa minutos) ---
  handleMinuteButton(now);
}

// Avança o tempo em 1 segundo.
void tickClock() {
  seconds++;
  if (seconds >= 60) {
    seconds = 0;
    minutes++;
    if (minutes >= 60) {
      minutes = 0;
      hours++;
      if (hours >= 24) {
        hours = 0;
      }
    }
  }
}

// Auxiliares para manuseio de botões
void handleHourButton(unsigned long now) {
  bool reading = digitalRead(BTN_HOUR);

  // Detecção de bordas com debounce
  if (reading != lastHourBtnState) {
    // Estado do botão alterado; timer de debounce reiniciado.
    lastHourChangeMs = now;
  }

  if ((now - lastHourChangeMs) > DEBOUNCE_MS) {
    // Se o botão estiver pressionado (LOW) e anteriormente estivesse em HIGH, trata-se de um novo pressionamento.
    if (reading == LOW && lastHourBtnState == HIGH) {
      incrementHour();
      updateDisplay();
    }
  }

  lastHourBtnState = reading;
}

void handleMinuteButton(unsigned long now) {
  bool reading = digitalRead(BTN_MIN);

  if (reading != lastMinBtnState) {
    lastMinChangeMs = now;
  }

  if ((now - lastMinChangeMs) > DEBOUNCE_MS) {
    if (reading == LOW && lastMinBtnState == HIGH) {
      incrementMinute();
      updateDisplay();
    }
  }

  lastMinBtnState = reading;
}

void incrementHour() {
  hours = (hours + 1) % 24;
  // Opcional: faz o reset dos segundos ao configurar a hora
  // seconds = 0;
}

void incrementMinute() {
  minutes = (minutes + 1) % 60;
  // Opcional: faz o reset dos segundos ao configurar a hora
  // seconds = 0;
}

// Atualiza o display de 6 dígitos para HHMMSS.
void updateDisplay() {
  char buffer[7];  // 6 dígitos + terminador nulo
  snprintf(buffer, sizeof(buffer), "%02u%02u%02u", hours, minutes, seconds);

  // Para um display de 6 dígitos, 'showString' exibirá exatamente esses 6 caracteres.
  display.showString(buffer);
}

Let's see it.

Use code tags or use the <CODE/> button in the message composition window toolbar and do what it says

type or paste code here

You might want to apply the IDE Autoformat tool first. It can help make your code readable.

a7

Thanks "alto777", I had gotten confused with that.

P.S.: The clock is working, that is, it is keeping the correct time.

I don't think the library you are using would let you just use periods in your sprintf format argument, but it would be easy to try.

So you'll have to do each part HH, MM and SS as two digit decimal numbers and in the call to HH hours and MM minutes parts specify that a decimal point should be added.

I'm looking through the tiny window in transit, so I can't take this much further.

The method I think you'll need to use is showNumberDec()

showNumberDec(long num, uint8_t dots, bool leading_zero, uint8_t length, uint8_t pos)

dots looks like a byte that sets decimal points on with 1s at certain bits. The other arguments should be easy to work out.

I am guessing that 0x40 would turn on the decimal point after the second of two digits.

Without the decimal point, this could be all you need to do in your update display function.

  display.showNumberDec(hours, 0, true, 2, 0);
  display.showNumberDec(minutes, 0, true, 2, 2);
  display.showNumberDec(seconds, 0, true, 2, 4);

The first zero in each line means no decimal point; that's where 0x40 (or maybe 0x2) would be used.

a7

An alternative is to try the display.setSegments() method to explicitly force a bit pattern to each display digit. This could even be useful just for testing, even to confirm that the decimal points are even connected to the TM1637 chip. This will usually be the case unless the display has a mixture of colons and decimal points.

I have an example of using this method, with ancestor library of yours, in this project: Basic single AA cell powered thermometer where I needed a decimal point and also special characters.

Also +1 for finding an apparently maintained library for this chip. The one I used had to be hacked to be compatible with some newer displays otherwise the digit order was somewhat shuffled.

Try the following untested sketch:

#include <TM1637Display.h>

// ----- TM1637 Pins -----
#define CLK 2
#define DIO 3

TM1637Display display(CLK, DIO);

// ----- Button Pins -----
#define BTN_HOUR 4
#define BTN_MIN  5

// ----- Clock Variables -----
int hours = 12;
int minutes = 0;
int seconds = 0;

unsigned long lastUpdate = 0;       // For 1-second timing
const long oneSecond = 1000;

// Debounce variables
unsigned long lastBtnH = 0;
unsigned long lastBtnM = 0;
const int debounceDelay = 200;

// ----- Setup -----
void setup() {
  pinMode(BTN_HOUR, INPUT_PULLUP);
  pinMode(BTN_MIN, INPUT_PULLUP);

  display.setBrightness(0x0f);   // Max brightness
}

// ----- Main Loop -----
void loop() {

  // --- Time update every second ---
  unsigned long now = millis();
  if (now - lastUpdate >= oneSecond) {
    lastUpdate = now;
    seconds++;

    if (seconds >= 60) {
      seconds = 0;
      minutes++;
    }
    if (minutes >= 60) {
      minutes = 0;
      hours++;
    }
    if (hours >= 24) {
      hours = 0;
    }
  }

  // --- Button: Adjust Hours ---
  if (digitalRead(BTN_HOUR) == LOW) {
    if (now - lastBtnH > debounceDelay) {
      hours++;
      if (hours >= 24) hours = 0;
      lastBtnH = now;
    }
  }

  // --- Button: Adjust Minutes ---
  if (digitalRead(BTN_MIN) == LOW) {
    if (now - lastBtnM > debounceDelay) {
      minutes++;
      if (minutes >= 60) minutes = 0;
      seconds = 0;    // Optional: reset seconds
      lastBtnM = now;
    }
  }

  // ----- Display Format: HHMMSS -----
  uint8_t data[6];

  data[0] = display.encodeDigit(hours / 10);
  data[1] = display.encodeDigit(hours % 10);

  data[2] = display.encodeDigit(minutes / 10);
  data[3] = display.encodeDigit(minutes % 10);

  data[4] = display.encodeDigit(seconds / 10);
  data[5] = display.encodeDigit(seconds % 10);

  display.setSegments(data);
}

I don't see where your sketch turns on decimal point or colons.

a7

Did your AI bot give any reason for changing the library to one that appears to have been abandoned ?

I asked the AI to provide codes using the said library as it is supported by Wokwi.

Anyway, Wokwi is asking for paid version which I cannot manage. I will collect my hardware (TM1637 Module) tomorrow and will test the sketch.

I am aware about it and hoped that I will add codes for the dot during simulation in Wokwi.

Anyway, Wokwi is asking for paid version which I cannot manage. I will collect my hardware (TM1637 Module) tomorrow and will test the sketch.

*GolamMostafa. Hello! First of all, thank you for sharing the code, but it didn't work. The numbers on the display remain static at 021420.
When I press the hour advance button (D4), it advances the digits all the way to the left from 02 to 09. And the minute advance button (D5) advances the seconds (digits all the way to the right) from 22 to 29.
I believe this code is for a 4-digit display.
My code was obtained from ChatGPT, through another person who sent it to me. But the function of the buttons is not working.

Right! Wokwi supports only TM1637 4-digit.

The sketch is simple. I have a 4-digit TM1637 display which I hope to test tomorrow and come up with a working sketch.

Okay, if you can reply to me later, I would appreciate it.

In the meantime, you may try the following sketch to show 12.45.23 on the display unit. Argument-2 of showNumberDec() method controls the dot between two digits. Let me know the result.

#include <TM1637TinyDisplay6.h>

// TM1637 pins
#define CLK 2
#define DIO 3

TM1637TinyDisplay6 display(CLK, DIO);

void setup() 
{
   display.begin();
   display.setBrightness(7);   // max brightness (0–7)

  // Show 12.45.23 on the 6 digits
  display.showNumberDec(12, 0b01000000, true, 2, 0); // 12. at position 0, 1
  display.showNumberDec(45, 0b01000000, true, 2, 2); //45. at position 2, 3              
  display.showNumberDec(23, 0b01000000, true, 2, 4); //23. at postion 4, 5              
}

void loop() {}

Correct!

  //! @param dots Dot/Colon enable. The argument is a bitmask, with each bit corresponding to a dot
  //!        between the digits (or colon mark, as implemented by each module). i.e.
  //!        For displays with dots between each digit:
  //!        * 00.0000  (0b01000000)
  //!        * 0.00000  (0b10000000)
  //!        * 00.0000  (0b01000000)
  //!        * 000.000  (0b00100000)
  //!        * 0000.00  (0b00010000)
  //!        * 00000.0  (0b00001000)
  //!        * 000000.  (0b00000100)
  //!        * 00.00.00 (0b01010000)
  //!        For displays with just a colons:
  //!        * 00:00:00 (0b01010000)  

Hello friend *GolamMostafa; thank you for helping me. I added the 3 lines to the code but it didn't change anything.
I was looking at the "TM1637_Countdown" example from the (used) "TM1637TinyDisplay6" library which has this function (showNumberDec) but I couldn't understand it.

But, if you want to leave this as is, and look into the issue of the 2 buttons that aren't working, I would appreciate it.

Yes, the points work, because I tried it with another example from the library. Tks.

Did you try @GolamMostafa's complete sketch from #14 above?

a7

*GolamMostafa
The sketch you shared in 'post #6' added to part of 'post #14' is working, including the buttons, except for the decimal points.

Yes, except for the decimal points.