Countdown timer 16x2 lcd

Hello, this is my code:

#include <LiquidCrystal.h>

LiquidCrystal lcd(6, 7, 8, 9, 10, 11, 12);

byte smiley[8] = {
B00000,
B10001,
B00000,
B00000,
B10001,
B01110,
B00000,
};

int backLight = 13; // pin 13 will control the backlight
void setup() {
pinMode(backLight, OUTPUT);
digitalWrite(backLight, HIGH);
lcd.begin(16,2);
lcd.clear();

Serial.begin(9600);
pinMode (2,OUTPUT);
pinMode (3,OUTPUT);
pinMode (4,OUTPUT);

pinMode (8,OUTPUT);
}

void loop() {
delay(1000);
// Turn off the display:
lcd.noDisplay();
delay(500);
// Turn on the display:
lcd.display();

int valor_sensor = analogRead(A0);

Serial.println(valor_sensor);
delay(1);
int keyVal = analogRead(A0);
Serial.println(keyVal);
if (keyVal == 0)
{
digitalWrite(2,LOW);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(7,LOW);
}
else if (keyVal == 10)
{
lcd.write
tone(5, 523, 2000);
delay(2000);
digitalWrite(5, LOW);

}
else if (keyVal == 341)
{
digitalWrite(4, HIGH);
delay(600000);
digitalWrite(3, HIGH);
delay(600000);
digitalWrite(2, HIGH);
delay(600000);
tone(5, 523, 2000);
delay(2000);

}
else if (keyVal == 1001)
{
digitalWrite(4, HIGH);
delay(300000);
digitalWrite(3, HIGH);
delay(300000);
digitalWrite(2, HIGH);
delay(300000);
tone(5, 523, 2000);
delay(2000);
}
else if (keyVal == 1023)
{
digitalWrite(4,LOW);
digitalWrite(3,LOW);
digitalWrite(2,LOW);
}
else {
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(7,LOW);
digitalWrite(8,LOW);
}
}

I want the else if (keyVal = 10) to start a timer of 45 minutes when I press the button, but i tried alot of things but cant get it to work

code has some long delays (60 sec)

consider

#undef MyHW
#ifdef MyHW
# include "sim.h"
byte pinsLed [] = { 10, 11, 12, 13 };

#else
# include <LiquidCrystal.h>
byte pinsLed [] = { 2, 3, 4, 8 };
#endif

LiquidCrystal lcd (6, 7, 8, 9, 10, 11, 12);
byte smiley[8] = {
    B00000,
    B10001,
    B00000,
    B00000,
    B10001,
    B01110,
    B00000,
};

int backLight = 13; // pin 13 will control the backlight

enum { Off = HIGH, On = LOW };

char s [40];

// -----------------------------------------------------------------------------
void setup () {
    pinMode (backLight, OUTPUT);
    digitalWrite (backLight, HIGH);

    lcd.begin (16,2);
    lcd.clear ();

    Serial.begin (9600);

    for (unsigned n = 0; n < sizeof(pinsLed); n++)  {
        digitalWrite (pinsLed [n], Off);
        pinMode      (pinsLed [n], OUTPUT);
    }
}

// -----------------------------------------------------------------------------
void
disp (
    char *s )
{
    lcd.clear ();
    lcd.setCursor (0, 0);
    lcd.print (s);
}

// -----------------------------------------------------------------------------
void loop () {
    int keyVal       = analogRead (A0);

#if 0
    Serial.println (keyVal);
#else
    sprintf (s, " val %d", keyVal);
    disp (s);
#endif

    if (keyVal == 0) {
        for (unsigned n = 0; n < sizeof(pinsLed); n++)
            digitalWrite (pinsLed [n], Off);
    }

    else if (keyVal == 10) {
        digitalWrite (2, On);
        tone (5, 523, 2000);
    }

    else if (keyVal == 20) {
        for (unsigned n = 0; n < sizeof(pinsLed); n++)  {
            digitalWrite (pinsLed [n], ! digitalRead (pinsLed [n]));
            delay (200);
        }
    }

    else if (keyVal == 1001) {
        digitalWrite (4, HIGH);
        delay (300000);
        digitalWrite (3, HIGH);
        delay (300000);
        digitalWrite (2, HIGH);
        delay (300000);
        tone (5, 523, 2000);
        delay (2000);
    }

    else if (keyVal == 1023) {
        digitalWrite (4,LOW);
        digitalWrite (3,LOW);
        digitalWrite (2,LOW);
    }
}

Does this part work, giving you a value of 10 when you press the button?

You sem to be lighting up LEDs every 5 minutes (300 seconds) or 10 minutes (600 seconds). To get 45 minutes, wouldn't you just use three intervals of 15 minutes (900 seconds, 900000 milliseconds)?

You have some very precise values you are looking for from analogRead() (10,20,341,1001...) which probably won't be true every time through loop() since the ADC will drift a bit...
A more typical approach is the define ranges for certain actions to take place.

@sjoerd17

Other post/duplicate DELETED
Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Continued cross posting could result in a time out from the forum.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

Hi @sjoerd17

Please redo your initial post and enclose your code in </> tags.
If you don't know how to do this then why not read the initial thread when registering in the forum.
Then read: How to get the best out of this forum.

Your code does not compile as it has at least 2 errors on line 55.
It remains to define what will be shown on the LCD and the semicolon at the end of the line.

RV mineirin

fixed the errors and let me explain myself

#include <LiquidCrystal.h>

LiquidCrystal lcd(6, 7, 8, 9, 10, 11, 12);
int backLight = 13; // pin 13 will control the backlight
void setup() {
pinMode(backLight, OUTPUT);
digitalWrite(backLight, HIGH);
lcd.begin(16,2);
lcd.clear();

Serial.begin(9600);
pinMode (2,OUTPUT);
pinMode (3,OUTPUT);
pinMode (4,OUTPUT);

pinMode (8,OUTPUT);
}

void loop() {
delay(1000);
// Turn off the display:
lcd.noDisplay();
delay(500);
// Turn on the display:
lcd.display();

int valor_sensor = analogRead(A0);

Serial.println(valor_sensor);
delay(1);
int keyVal = analogRead(A0);
Serial.println(keyVal);
if (keyVal == 0)
{
digitalWrite(2,LOW);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(7,LOW);
}
else if (keyVal == 10)
{
tone(5, 523, 2000);
delay(2000);
digitalWrite(5, LOW);

}
}

I have a project for school to make a timer for 45 minutes that buzzes after said 45 minutes but I want to make multiple buttons for 45 mins other button 30 minutes and last button 15 minutes

[quote="johnwasser, post:3, topic:912228"]
Does this part work, giving you a value of 10 when you press the button?
[/quote] I copied this from another tinkercad design and it worked so I didn't look in it further
but i want the "else if (keyVal == 10) to be a 45 minute timer but i dont know how

also i am currently only able to use tinkercad so i can't use #include sim.h
but once i can try on an actual arduino i will try this

They work, I just have to press the button a few times, but what do you mean with that last bit"?

the multi-turn pot on the multifunction shield had no problem reliably maintain a specific value when i tested the code, but it may be more difficult for other devices

a few approaches to consider


bool inline delta (int val, int targ,int  max) {
    return abs(val - targ) < max;
}

#define Delta 2
#define Targ  10

void loop(){
    int val = analogRead (A0);

    if ((Targ - Delta) < val && val < (Targ + Delta))
        Serial.println ("w/in range");

    if (abs(val - Targ) < Delta)
        Serial.println ("w/in delta");

    if (delta(val, Targ, Delta))
        Serial.println ("w/in inline");

    Serial.println (val);
    delay (200);
}

void setup(){
    Serial.begin(9600);
}

I'm sorry but I don't know how to work with this, i've tested it but there's a few things I don't understand, why is void loop first and not void setup? and how do I apply this to my code?

I see in the serial monitor though that its very accurate with the reading

there's no requirement for the order of setup() and loop() in arduino.

it seems the issue pointed out by @blh64 is not understood.

certainly confusing why you said " just have to press the button a few times". isn't keyVal read from a pot?

If I hold the button down, it works, but we´re not here for the button but for the timer, thanks for giving me alternatives though.

are you familiar with using millis() to perform some action after some period of time? presumably you can use your buttons to select how long to wait (e.g. 45 * 60 * 1000 msec)

I know that yes, but then I have to write alot of lines for code because I want the time printed out on the LCD too.

sorry i should´ve mentioned this in the first place^^

alot of lines of code?

the code needs to

  • recognize a button press (1 of 3) and set the corresponding delay (e.g. minsDelay = 45;)
  • set the millis() value corresponding to the delay (e.g. msecLst = millis() + (minsDelay * 60 * 1000);)
  • for a string with the delay amount (e.g sprintf, s, "%s timer", minsDelay);)
  • add code to recognize that the delay has expired (e.g. if (millis() > msecLst) {)

Yes. If you had mentioned that 17 replies ago we could have saved a LOT of other answers.

I'm going to assume you want to count down once a second. Do you still need the LEDs? If so, what do you want the LEDs to do?

Here is an outline of a sketch (NOT A COMPLETE SKETCH) that will show you how to display the number of seconds remaining in the countdown. See if you can fill in the rest.

unsigned SecondsRemaining = 0;
unsigned long PrevousMillis = 0;

void loop();
{
  unsigned long currentMillis = millis();

  // Count down once per second
  if (currentMillis - PreviousMillis = 1000)
  {
    PreviousMillis += 1000;

    if (SecondsRemaining > 0)
    {
      SecondsRemaining--;
      LCD.clear();
      LCD.println(SecondsRemaining);
      if (SecondsRemining == 0)
         SoundTheAlarm();
    }
  }

  // Check for input:
  if (keyVal == 341)
    {
    SecondsRemaining = 1800; // 30 minutes
    PreviousMillis = currentMillis; // Restart the timer
   }
   else if (keyVal == 1001)
    {
    SecondsRemaining = 900; // 15 minutes
    PreviousMillis = currentMillis; // Restart the timer
   }
   else if (keyVal == 10)
    {
    SecondsRemaining = 2700; // 45 minutes
    PreviousMillis = currentMillis; // Restart the timer
   }
}

Not the proper way to track elapsed time since millis() rolls over. The only sure way to do it is with subtraction

startTime = millis();
...
if ( millis() - startTime >= desiredDelay) ...