Need help improving this timer

Hello, this is my first Arduino project Im working on, and am still trying to learn programming for these.
My only previous experience is a little visual basic a long time ago.
Ive been meaning to get into Arduino some time back for various projects, but have only really had the time to do so now.

Im basically wanting to design a simple timer, that allows me to reset it if I push a button, and also allow me to set a custom time interval by means of a rotary encoder.

Im getting rid of the buzzer, its not needed.
Ive constructed this project here, and have got the LCD and relay all going.
I probably will want to add other functions in future to control other relays and inputs etc, so would possibly need to switch to a serial based LCD that uses less of the pins.

Im wanting to add:

rotary encoder selection.
selectable timer between any interval up to 30 mins.
I want to change the countdown timer on the LCD to mins and seconds rather than just seconds alone.

I also want to add a function where another relay will turn on after a fixed time if the reset button is not pressed.

The sketch is below:

#include <LiquidCrystal.h>
LiquidCrystal lcd(7,8,9,10,11,12);
int runTimer = 1; 
int runFor = 60; // time in seconds
int buzzerPin = 13;
int relayPin=4;
int data = 0;
 
void setup() {
   pinMode(buzzerPin, OUTPUT);
   pinMode(relayPin,OUTPUT);
   lcd.begin(16, 2);
}
 
void loop() {
   if(runTimer == 1){ 
      digitalWrite(relayPin,LOW); // relay is OFF during countdown
      /* *change to HIGH if you want the relay to be ON while countdowning */
      lcd.clear();
      lcd.print("TIMER=");
      //Start timer
      timer(); 
   } else {
      digitalWrite(relayPin,HIGH); // relay is ON when time expired
      /* *change to LOW if you want the relay to be OFF when the time expired */
   }
   runTimer = 0;
   lcd.noDisplay();
   delay(250);
   for(int duration = 0; duration < 100; duration ++){
      digitalWrite(buzzerPin, HIGH);
      delayMicroseconds(500);
      digitalWrite(buzzerPin, LOW);
      delayMicroseconds(500);
   } 
   lcd.display();
   delay(250);
}
 
void timer() {
   for(int timer = runFor;timer > 0; --timer){
   if(timer >= 10) {
      lcd.setCursor(6,0); 
   } else {   
      lcd.setCursor(6,0);
      lcd.print("0");
      lcd.setCursor(7,0);
   }
   lcd.print(timer);
   lcd.print(" SECOND!");
   delay(1000);
   }
   lcd.setCursor(0,0);
   lcd.clear();
   lcd.print(" TIMER ALERT!");  
}

I don't see how this can possibly work, and doubt if it will compile.

Your timer function locks up the processor in delay() for almost all the processor's time. Where are you reading the button or setting the timer via the rotary encoder?

Rewrite it using an approach such as in the BlinkWithoutDelay example in the IDE and you'll have a chance

regards

Allan

Thanks for your response.

The code compiles and works fine on my initial tests.

when the time is up, the relay switches on and the LCD displays the alert.

Im basically trying to find the best approach to add code to allow a rotary encoder to input the time of a given range (in mins) and set it, once the time is selected.

In this code its preset at 60 seconds, but I want to be able to change that.

Im trying to find examples of code that allow me to change the value of "runfor" within a specified range.

Have a look at how millis() is used to manage timing without blocking in several things at a time

...R

Have a look at tone() and noTone(), how to implement a non-blocking sound.

For a variable duration you have to read your encoder, and convert that reading into a time interval. What type is that encoder, which libraries apply to it?

DrDiettrich:
Have a look at tone() and noTone(), how to implement a non-blocking sound.

For a variable duration you have to read your encoder, and convert that reading into a time interval. What type is that encoder, which libraries apply to it?

I bought some Keyes KY-040 encoders for prototyping, but I believe they are nothing fancy.

I think there is a basic library for these that comes with the Arduino IDE

With such encoders you can use one of its pins for the clock signal, and the other one indicates the direction. If the clock signal goes high (or low - your decision) examine the direction pin, whether the count should be incremented or decremented.