Setting a Clock without RTC

I’m doing a project to have a clock that I can set with a button and encoder. I know how to add the clock in but what I really need help with is finding a way so that if i push the button once it puts it in the seconds and i can use the encoder to move it up and down, and if its pushed again it will go to minutes and again to hours. Currently, every time I press it it just shows what the encoder value is instead of moving it. I’ve included a copy of my code to see what i’m working with.

Final_Project_Encode_Time.ino (3.74 KB)

Please use code tags, so the code looks like this:

#include <LiquidCrystal.h>
LiquidCrystal lcdDriver(11, 9, 5, 6, 7, 8);
unsigned long Timer = 0;//Introduce timer
unsigned long Timer2 = 0;
volatile int encoderPosition = 0;//Introduce encoder
enum ButtonState {Idle, Wait, Low}; //set states
int input();// set input
ButtonState state = Idle; //start ButtonState at Idle

//function that will be called for switching states
int ButtonStateNext(int input)
{
  switch (state) //switch states
  {
    case Idle://Start Idle
      if (input == LOW)
      {
        Timer = millis();//set timer to milliseconds
        state = Wait; //set state to wait
      }
      break; //stop Idle
    case Wait: //start Wait
      if (input == HIGH)
      {
        state = Idle; //set state to Idle
      }
      else if (millis() - Timer >= 5)
      {
        state = Low; //set state to Low
        return 1;
      }
      break;//stop Wait
    case Low://Start Low
      if (input == HIGH)
      {
        state = Idle; //set state to Idle
      }
      break;//stop Low
  }
  return 0;
}
void volatile MonitorA()
{
  if (digitalRead(2) == digitalRead(3))
  {
    ++encoderPosition;//increment encoder
  }
  else
  {
    --encoderPosition;//decrement encoder
  }
}
void volatile MonitorB()
{
  if (digitalRead(2) == digitalRead(3))
  {
    --encoderPosition;//decrement encoder
  }
  else
  {
    ++encoderPosition;//increment encoder
  }
}
void setup() {
  pinMode(4, INPUT); //set up button
  state = Idle; //start state to Idle
  Timer2 = millis();
  Timer = millis(); //Timer in milliseconds
  attachInterrupt(0, MonitorA, CHANGE); //interrupt MonitorA
  attachInterrupt(1, MonitorB, CHANGE); //interrupt MonitorB
  encoderPosition = 0; //set encoder value to 0
  //Start LCD
  lcdDriver.begin(16, 2);//set up display
  lcdDriver.clear();//clear LCD

}

void loop() {
  if (ButtonStateNext(digitalRead(4)))
  {
    if (Timer2 - millis() >= 100)
    {
      lcdDriver.setCursor(7, 1);
      if (encoderPosition > 9)
      {
        encoderPosition = 0;
      }
      if (encoderPosition < 0)
      {
        encoderPosition = 9;
      }
      lcdDriver.print(encoderPosition);
      Timer2 += 100;
    }
  }
  if (ButtonStateNext(digitalRead(4)))
  {
    if (Timer2 - millis() >= 100)
    {
      lcdDriver.setCursor(6, 1);
      if (encoderPosition > 9)
      {
        encoderPosition = 0;
      }
      if (encoderPosition < 0)
      {
        encoderPosition = 9;
      }
      lcdDriver.print(encoderPosition);
      Timer2 += 100;
    }
  }if (ButtonStateNext(digitalRead(4)))
  {
    if (Timer2 - millis() >= 100)
    {
      lcdDriver.setCursor(4, 1);
      if (encoderPosition > 9)
      {
        encoderPosition = 0;
      }
      if (encoderPosition < 0)
      {
        encoderPosition = 9;
      }
      lcdDriver.print(encoderPosition);
      Timer2 += 100;
    }
  }if (ButtonStateNext(digitalRead(4)))
  {
    if (Timer2 - millis() >= 100)
    {
      lcdDriver.setCursor(3, 1);
      if (encoderPosition > 9)
      {
        encoderPosition = 0;
      }
      if (encoderPosition < 0)
      {
        encoderPosition = 9;
      }
      lcdDriver.print(encoderPosition);
      Timer2 += 100;
    }
  }if (ButtonStateNext(digitalRead(4)))
  {
    if (Timer2 - millis() >= 100)
    {
      lcdDriver.setCursor(1, 1);
      if (encoderPosition > 9)
      {
        encoderPosition = 0;
      }
      if (encoderPosition < 0)
      {
        encoderPosition = 9;
      }
      lcdDriver.print(encoderPosition);
      Timer2 += 100;
    }
  }if (ButtonStateNext(digitalRead(4)))
  {
    if (Timer2 - millis() >= 100)
    {
      lcdDriver.setCursor(0, 1);
      if (encoderPosition > 9)
      {
        encoderPosition = 0;
      }
      if (encoderPosition < 0)
      {
        encoderPosition = 9;
      }
      lcdDriver.print(encoderPosition);
      Timer2 += 100;
    }
  }
}

Please explain how you expect the state machine logic to work, and how you expect button action to change the display.

Your very premise doesn’t make sense. You can not set a clock without a clock.

You could set/increment/decrement a variable.

Your code has a lot of comments, but they are useless. We can see that state = Low; assigns the value of Low to state. We really don’t need your help to understand that. But WHY do you do that? That is NOT documented.

It is not clear why you call ButtonStateNext() 6 times on every pass through loop(). That needs to be documented.

Currently, every time I press it it just shows what the encoder value is instead of moving it.

I can’t see how pressing it (presumably the switch) makes the switch show the encoder value, or how you expect a switch to move.

So, clearly the three different uses of the pronoun it refer to three different nouns. Dump the pronoun. Use the nouns!

lcdDriver.print(encoderPosition); says Arduino to print encoder position on the LCD. So every time you press a button encoder position is displayed. If you want something else you need tell Arduino what you want. I didn't notice you to save time in any way.