TM1637 continuous loop after reaching 00:00.

Hi. I think got a coding problem with my TM1637. I set the timer to 60000ms which is 1 minute (01:00).

But TM1637 won't stop the timer after reaching 00:00. It continues the timer, restarts the countdown from 02:47 until 00:00 and again restart the counter from 59:59.

#define numberOfSeconds(time) ((time / 1000) % 60)
#define numberOfMinutes(time) (((time / 1000) / 60) % 60)
#include <TM1637Display.h>

const uint8_t OFF[] = {0, 0, 0, 0};
const uint8_t PLAY[] = {B01110011, B00111000, B01011111, B01101110};
unsigned long timeLimit = 60000;

TM1637Display display(8, 9);

void setup() {
  display.setBrightness(0x0c);
  display.setSegments(PLAY);
}

void loop() {
  unsigned long timeRemaining = timeLimit - millis();
  while (timeRemaining > 0) {
    int seconds = numberOfSeconds(timeRemaining);
    int minutes = numberOfMinutes(timeRemaining);
    display.showNumberDecEx(seconds, 0, true, 2, 2);
    display.showNumberDecEx(minutes, 0x80 >> 3, true, 2, 0);
    timeRemaining = timeLimit - millis();
  }

}

void displayText() {
  display.setSegments(PLAY);
  delay(2000);

}

I've tried to put

timeRemaining = 0;

and

timeLimit = 0;

after the while loop but still, the problem persists.

I think there is part of the code that I should reset whether after the while loop or formula? I don't really know where it is. I am new to Arduino.

Thank you,
Izuanika

Read the first post - Using millis() for timing. A beginners guide

You set timeRemaining as unsigned long, which means it can never be negative. Then you test while(timeRemaining > 0) which will always be true unless the previous calculation, by some stroke of luck, exactly equals 0.

Hi DKWatson

Been hours trying to figure out whats wrong. I've read the post on how to use millis but still can't get a clear picture of whats going on.

On the previous post

https://forum.arduino.cc/index.php?topic=565504.0

My problem solved. But this time on a second attempt the timer starts at 02:47 until 01:47.

To be clear this is my full code.

#define numberOfSeconds(time) ((time / 1000) % 60)
#define numberOfMinutes(time) ((time / 1000) / 60)
#include <TM1637Display.h>
#include <elapsedMillis.h>
const uint8_t OFF[] = {0, 0, 0, 0};
const uint8_t PLAY[] = {B01110011, B00111000, B01011111, B01101110};
unsigned long timeLimit = 65000;
unsigned long interval = 65000;
const int relay = 7;
const int coinpin = 2;
const int ledpin = 13;
const int targetcents = 5;
volatile int cents = 0;
int credits = 0;

TM1637Display display(8, 9);

void setup() {
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(coinpin), coinInterrupt, RISING);
  pinMode(ledpin, OUTPUT);
  pinMode(relay, OUTPUT);
  digitalWrite(relay, HIGH);
  //TIMER SECTION 2
  display.setBrightness(0x0c);
  display.setSegments(PLAY);
}

void loop() {

  if (cents >= targetcents) {
    credits = credits + 1;
    cents = cents - targetcents;
  }
  else {}

  Serial.print(cents);
  Serial.print(" cents toward current credit and ");
  Serial.print(credits);
  Serial.println(" credit(s) earned so far.");
  delay(1000);

  if (credits == 1) {
    digitalWrite(relay, LOW);
    unsigned long timeRemaining = timeLimit - millis();
    elapsedMillis timeElapsed;
    while (timeElapsed < interval) {
      int seconds = numberOfSeconds(timeRemaining);
      int minutes = numberOfMinutes(timeRemaining);
      display.showNumberDecEx(seconds, 0, true, 2, 2);
      display.showNumberDecEx(minutes, 0x80 >> 3, true, 2, 0);
      timeRemaining = timeLimit - millis();
    }
    digitalWrite(relay, HIGH);
    display.setSegments(PLAY);
    credits = credits - 1;
  }
}

void coinInterrupt() {
  cents = cents + 1;
}

void displayText() {
  display.setSegments(PLAY);
  delay(2000);
}

Ive replaced while (timeRemaining > 0) with (timeElapsed < interval) using elapsedMillis library.

My comment in #1 was meant more to suggest that you get rid of that elapsedMillis library as you clearly don't know how it works, and simply use millis() for your timing loops. If you insist on continuing to use that awful library, timeElapsed needs to be updated inside the while loop.

Look, when credits == 1 you want to start your hour countdown. Enter that condition and record startTime = millis(). Then your while loop simply becomes while((millis() - startTime) < timeLimit);. Surely you can calculate minutes and seconds on your own?