Encoder setting time with lcd i2c

hello ,
i have the following code and it is run ok, this code for setting a time in seconds by using encoder

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address to 0x27 for a 16 chars and 2 line display

#define Start 4            // start stop button D4
// possible without button
// use encoder longpress to start
#define LED_PIN 11        // LED connected to Pin 13
#define BACKLIGHT_PIN 13
int x = 0; // Initialize x as 0
int y = 0; // Initialize x as 0
const int inputPin = 5; // Connect the input pin to pin 5
int counter = 0; // Initialize the counter variable
int prevInputState = HIGH; // Variable to track the previous state of the limit switch

int seconds = 0;
int setseconds = 0;
boolean timeState = false;
#define encoderPinA 2      // encoder  CLK right
#define encoderPinB 3      // encoder  DT  left
#define encoderButton 4    // encoder  SW  switch
int HMS = 1;
int encoderPos = 0;          // a counter for the dial
unsigned int lastReportedPos = 1; // change management
static boolean rotating = false;  // debounce management
boolean A_set = false;
boolean B_set = false;

void setup()
{
  lcd.init();             // initialize the lcd
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
Serial.begin(9600);
  pinMode(Start, INPUT_PULLUP);
  pinMode(encoderPinA, INPUT_PULLUP); //enabling pullups
  pinMode(encoderPinB, INPUT_PULLUP);
  pinMode(encoderButton, INPUT_PULLUP);
  pinMode(inputPin, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT); // Set LED pin as OUTPUT
  digitalWrite(LED_PIN, LOW); // Turn off the LED initially
  attachInterrupt(0, doEncoderA, CHANGE); //pin 2
  attachInterrupt(1, doEncoderB, CHANGE); //pin 3
  Serial.begin(9600); // output

  lcd.setCursor(0, 0);
  lcd.print("Set Seconds : ");
  lcd.setCursor(14, 0);
  lcd.print("00");
  delay(500);
}

void loop()
{
  if (digitalRead(encoderButton) == LOW)
  {
    HMS = HMS + 1;
    if (HMS == 3)
    {
      HMS = 1;
    }
    digitalWrite(LED_PIN, LOW); // Turn off the LED
    int t = 80;
    while (digitalRead(encoderButton) == LOW)
    { 
      
      delay(1);
      t = t - 1;
      lcd.setCursor(0, 0);
      lcd.print(t);
      lcd.print("          ");
      if (t == 60)
      {
        digitalWrite(LED_PIN, HIGH); // Blink the LED
        delay(50);
        digitalWrite(LED_PIN, LOW);
      }
      if (t == 40)
      {
        digitalWrite(LED_PIN, HIGH); // Blink the LED
        delay(50);
        digitalWrite(LED_PIN, LOW);
      }
      if (t == 20)
      {
        digitalWrite(LED_PIN, HIGH); // Blink the LED
        delay(50);
        digitalWrite(LED_PIN, LOW);
      }
      if (t <= 1)
      {
        t = 1;
        timeState = true;
        setseconds = seconds;
        lcd.setCursor(0, 0);
        lcd.print("Get Set Go      ");
        digitalWrite(LED_PIN, HIGH); // Blink the LED
        delay(200);
        digitalWrite(LED_PIN, LOW);
      }
    }
  }

  if (HMS == 1)
  {
    lcd.setCursor(0, 0);
    lcd.print("set seconds : ");
  }

  rotating = true; // reset the debouncer
  encoderPos = constrain(encoderPos, -1, 1);
  if (lastReportedPos != encoderPos)
  {
    if (HMS == 1)
    {
      setseconds = setseconds + encoderPos;
      setseconds = constrain(setseconds, 0, 60);
      
    }

    lcd.setCursor(14, 0);
    if (setseconds <= 9)
    {
      lcd.print("0");
    }
    lcd.print(setseconds);
    encoderPos = 0;
    lastReportedPos = encoderPos;
  }

  if (digitalRead(Start) == LOW || timeState == true)
  { //start count down timer
   
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Countdown : ");
    timeState = true;
    delay(10);
    while (timeState == true)
    {
      
      int period = 1000;
      unsigned long time_now = 0;
      time_now = millis();
      
      while (millis() < time_now + period)
      { //wait approx. [period] ms}
      }

      setseconds = setseconds - 1;

      if (setseconds == 0)
      { //count down alarm
    
        while (timeState == true)
        {
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Time End");
          lcd.setCursor(5, 1);
          lcd.print("Alarm!");
          digitalWrite(LED_PIN, HIGH); // Blink the LED
          delay(300);
          digitalWrite(LED_PIN, LOW);
          delay(300);
        
          

          if (digitalRead(Start) == LOW)
          { // turn alarm off with switch
            timeState = false;
            setseconds = 1;
            lcd.clear();
          
            break;
          }

          if (digitalRead(encoderButton) == LOW)
          { // turn alarm off with rotary encoder switch
            timeState = false;
            lcd.clear();
            lcd.setCursor(0, 0);
            lcd.print("Countdown :  ");
            lcd.setCursor(12, 0);
            lcd.print("Done!");
            while (digitalRead(encoderButton) == LOW)
            {
              delay(1000);
            } //wait for release switch
            setseconds = seconds;
            break;
          }
        }
      }

      lcd.setCursor(12, 0);
      if (setseconds <= 9)
      {
        lcd.print("0");
      }
      lcd.print(setseconds);

      if (digitalRead(Start) == LOW)
      { // pauze countdown with start button
        delay(1000);
        timeState = false;
        break;
      }

      if (digitalRead(encoderButton) == LOW)
      { // pauze countdown with encoder button
        delay(1000);
        digitalWrite(LED_PIN, HIGH); // Blink the LED
        delay(200);
        digitalWrite(LED_PIN, LOW);
        timeState = false;
      
        break;
      }
    }
  }

}

// Interrupt on A changing state
void doEncoderA()
{
  // debounce
  if (rotating) delay(1); // wait a little until the bouncing is done

  // Test transition, did things really change?
  if (digitalRead(encoderPinA) != A_set)
  { // debounce once more
    A_set = !A_set;

    // adjust counter + if A leads B
    if (A_set && !B_set)
      encoderPos = 1;

    rotating = false; // no more debouncing until loop() hits again
  }
}

// Interrupt on B changing state
void doEncoderB()
{
  if (rotating) delay(1);
  if (digitalRead(encoderPinB) != B_set)
  {
    B_set = !B_set;
    // adjust counter – 1 if B leads A
    if (B_set && !A_set)
      encoderPos = -1;

    rotating = false;
  }
}

i want to add a counter that calculate how many times D5 goes LOW ( pull-down pin ) as long as the time is counting down

As in, a boolean variable? Strange, since you already have some of those in your code...

yes, as boolean

Then wouldn't you want 'x' to have the values 'true' and 'false'?

which variable ?
i don't seen any it , help me please :slight_smile:

Here is one in your code:

boolean timeState = false;

What would be the purpose of this variable 'x'?

Sir, I will explain the full idea that I want to apply, i want to set a time and by encoder and put a limit switch on a digital pin, i want to make a counter to calculate how many times i pressed the limit switch while the time was counting down and shown the results of counter on lcd . after i pressed the encoder switch the timer will reset as well as the counter :frowning:

Okay. How does your proposed variable influence that program specification? Why do you think you need it?

How does the program operate now? What specific difference would your modification make to that operation?

Because, we all just "parachuted in" and have no idea what you are doing.

Now, it's hard to separate what you want from what you have.

Why do you speak of pressing a limit switch? Normally those are not human operated.

I want to make a device with a specific design, the design depends on ( setting time and calculating how many times goes up and down manually, i put a limit switch to calculate it )

There is a lot to "catch up with" here. Did you write the posted sketch?

honestly, i found it in the internet..

Great. What does it do? Can you please link to the source?

i trying to edit it, but when the timer starts counting down, the arduino enters in frizz mode until the timer finishes counting down.

Please provide a link to the place where you found the code. Maybe they can explain it better than you can.

source

sir, all what i need,
add a counter the count how many times pin D5 goes LOW while the timer run

Do you want just a solution, or do you want to learn how to solve it?

By the way, is it necessary that you be able to set different times, or is that feature just something that happened by chance to come with the timer sketch you found?

1 Like

just solution :slight_smile:

Then please send a moderator request to move this to the "paid consultancy" section. The time I've already spent on this is pro bono.

It's the flag icon below the post...