Having an issue making a separate variable increase along with millis()

I'm making a digital clock display on my LCD screen but the only issue I'm having is creating an accurate read on the milliseconds without blowing up my code. I incorporated a count system so I can increase the hours, minutes, and seconds by command to match real world time. Throwing this away and attaching everything to millis() through division seems to remove any way to "set" the time. So I am looking for a way to increase a separate variable that increases exactly along with millis() but is able to subtracted from as millis() nonstop increases.

Attached is the code I wrote:

#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 5, 6, 7, 8);

unsigned long time;
unsigned long period = 0;
int rate = 0;

int millisecond = 0;
int second = 0;
int minute = 0;
int hour = 0;
int x = 0;
int buttonA = 10;
bool pressedA = true;
int buttonB = 11;
bool pressedB = true;
int buttonC = 12;
bool pressedC = true;


void setup() {
  lcd.begin(16, 2);
  pinMode(buttonA, INPUT_PULLUP);
  pinMode(buttonB, INPUT_PULLUP);
  pinMode(buttonC, INPUT_PULLUP);
}

void loop() {
  check();
  lcd.setCursor(0, 0);
  clock();
}


void clock(){
  time = millis();
  if (time - period >= rate){
    period = time;
    millisecond ++;
  }
  time_check();
  clockprint();
}

void time_check(){
  if (millisecond > 1000){
    millisecond -= 1000;
  }
  if (second >= 60){
    second -= 60;
    minute ++;
  }
  if (minute >= 60){
    minute -= 60;
    hour ++;
  }
  if (hour >= 13){
    hour -= 12;
    x ++;
  }
}


void hour_pad(){
  if (hour < 10){
    lcd.print("0");
  }
}

void minute_pad(){
  if (minute < 10){
    lcd.print("0");
  }
}

void second_pad(){
  if (second < 10){
    lcd.print("0");
  }
}

void millisecond_pad(){
  if (millisecond < 100){
    lcd.print("0");
  }
}

void clockprint(){
  hour_pad();
  lcd.print(hour);
  lcd.print(":");
  minute_pad();
  lcd.print(minute);
  lcd.print(":");
  second_pad();
  lcd.print(second);
  lcd.print(":");
  millisecond_pad();
  lcd.print(millisecond);
  if (x % 2 == 0){
    lcd.print(" AM");
  }
  else{
    lcd.print(" PM");
  }
  lcd.print("   ");
}

void check(){
  if (digitalRead(buttonA) == LOW && !pressedA){
    hour ++;
    pressedA = true;
  }
  else if (digitalRead(buttonA) == HIGH){
    pressedA = false;
  }
  if (digitalRead(buttonB) == LOW && !pressedB){
    minute ++;
    pressedB = true;
  }
  else if (digitalRead(buttonB) == HIGH){
    pressedB = false;
  }
  if (digitalRead(buttonC) == LOW && !pressedC){
    second ++;
    pressedC = true;
  }
  else if (digitalRead(buttonC) == HIGH){
    pressedC = false;
  }
}

not exactly your need but I had shared that in the past

// code showing the time passing by on an I2C LCD
// allowing time editing through a rotary encode (double click = enter/exit edit mode, single click = select field to modify)
// modifying days, hour, minute, second will impact the full date (ie add 1 day at the end of the month goes to next month or add one second at 59 and you go to the next minute)
// month and year are direct editing (1-12 or 0-99)

it might give you some ideas

1 Like

That was just a previous input testing how fast the variable would increase and guessing it would cause be in line with millis()

no the loop runs much faster than millis() (assuming you don't use delay nor do crazy stuff in the loop).

For extra information and examples look at

Using millis()+offset will increase in step with millis(), and allow you to adjust it by adjusting offset.

void loop(void){
   unsigned long myMillis = millis() + offset;
   ...

}

A separate variable that tracks millis(), maybe

unsigned long negativeMillis = millis() * -1;

Edit: never mind. Tested this and no dice.

1 Like

A quickie clock (untested, don't have time). :grin:

unsigned long
  secTimer,
  elapsed,
  micsInSec = 1000000; // adjust + / - for accuracy
byte
  sec,
  min,
  hour;
unsigned int blinkTime = 50000;

void setup()
{
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  digitalWrite(LED_BUILTIN,elapsed < blinkTime);
  elapsed = micros() - secTimer;
  if(elapsed >= micsInSec)
  {
    secTimer += micsInSec;
    if(++sec >= 60)
    {
      sec = 0;
      if(++min >= 60)
      {
        min = 0;
        if(++hour >= 24)
        {
          hour = 0;
        }  
      }  
    }
    if(hour < 10)
    {
      Serial.print(0);
    }
    Serial.print(hour); Serial.print(":");
    if(min < 10)
    {
      Serial.print(0);
    }
    Serial.print(min); Serial.print(":");
    if(sec < 10)
    {
      Serial.print(0);
    }
    Serial.println(sec);
  }
}
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.