Constant button reading

Hi, I'm working on a coaster for new year's that will blink after 20 minutes if the person didn't drink. The problem is, my code can't detect the button constantly, it only sees it when pressed. My code here has the delay shortened to 20 seconds for testing:

int ledPin=5;
int scale=6;
const int  buttonPin = 2;
int buttonPushCounter = 0;
int buttonState = 0;
int lastButtonState = 0;

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}


void loop() {
  buttonState = digitalRead(buttonPin);

   if (buttonState == HIGH) {
     delay(20000);
     digitalWrite(ledPin, HIGH);
     delay(1000);
     digitalWrite(ledPin, LOW);
     delay(1000);
     digitalWrite(ledPin, HIGH);
     delay(1000);
     digitalWrite(ledPin, LOW);
     digitalWrite(ledPin, HIGH);
     delay(1000);
     digitalWrite(ledPin, LOW);
     delay(1000);
     Serial.print(buttonState);
    } else {
      digitalWrite(ledPin, LOW);
      Serial.print(buttonState);
    }
  }
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH)

What, if anything, is keeping the buttonPin LOW when not pressed ?

Hi
please explain better the sequence of events that the user must proceed.

What's drinking with the button?
Also post a schematic of how the button is on.

Your code does exactly what you have coded.

If button == HIGH ist detected start delaying.
delay()
You can imagine this as the microcontroller beeing on vacation on the other side of the earth / not at home / can't answer can't even open the door.

or imagine the microcontroller beeing unconcious.

If you want your microcontroller do wait and be full concious there is no way around non-blocking timing based on function millis().

But first of all post an explanation of each step of the functionality you want to have.
write the description in normal words.

If you shout at Alexa "Alexa ! make my dreams come true!" but nothing happens

There is no way around a clear and detailed analysis of the functionality you want to have.
Any too short descriptions just consume extra time for reading a ask-back-posting and writing an answer-back-posting.

So do yourself a favor and take time for a detailed description.

User takes glas off the coaster before timelimit is reached what should your code do? describe it in normal words

glas stays on coaster for a long time.
timelimit is reached what shall your code do? describe it in normal words.

user takes glas off the coaster after timelimit was reached - what shall your code do?
describe it in normal words

best regards Stefan

Essentially the user puts the mug on, forgets about it, and after a time it starts flashing to remind them to drink. The exact circuitry doesn't matter because it worked, all that matters is that pin2 reads it with high is on low is off

Okay,
‘’’
If {glass is on start to wait some amount of time
If during time glass it taken off, restart
}{Else if continue timer and start flashing led at the end a certain number of time
}
‘’’

If the button isnt pressed, it is inactive meaning buttonstate is low. Im not sure i understand the nature of your question

there is a reason why I want the description in normal words:
beeing sure there are no misconceptions about programming hidden

User takes glas off the coaster before timelimit is reached:______________________________________

glas stays on coaster for a long time. Timelimit is reached _______________________________________

user takes glas off the coaster after timelimit was reached _______________________________________

add the description where the underline is
best regards Stefan

If you want i can write it normally.
Object coaster with button on it. When a mug is placed on it, the button is activated. When the button is activated, if after, say, twenty minutes the mug was not lifted off, it will start blinking intermittently to remind the person to drink, until they take the mug off. If they take it off before the timer runs out, the light doesn't flash and just restarts the timer. My problem is on the first step, checking wether or not it was lifted continuously, which in the code is the delay(20000)

In your format,
Glass stays on time is reached blink led until glass is removed

Glass is removed, timer resets when glass is set down again

First things first. How is your button wired? You are configuring it as INPUT which implies you have a pull-up or pull-down resistor. Your code implies you have a pull-up resistor. If you do, you can eliminate the resistor by configuring the pin as INPUT_PULLUP to use the internal pull-up resistor.

OK this means,

you have to detect state-change

and you have a sequence of steps
This is a classical case for a programming-technique called state-machine
a state-machine reduces the number of if-conditions you have to check

You will need some time to understand the concept of state-machines

the alternative is to add a lot more if-conditions with boolean variables to achieve the same behaviour.

Once you have understood the concept of state-machines it becomes very easy

the state-machine is initialised to a state "startTimer"
if mug is placed on coaster (IO-pin-signal HIGH) // this is even the case on power-up
myActualState = startTimer

inside state "startTimer" the time-measuring is started
previousMillis = currentMillis and the state-variable gets immediately assigned the next statevalue
actual State = measureTime

in state measureTime you check two things:

  1. if 20 minutes are over or not
    if 20 minutes are over you assign a boolean variable blinkLED = true

  2. if mug is taken off the coaster (IO-pin == LOW)
    if (IO-pin == LOW)
    actualState = "waitForMugPlacedAgain"
    blinkLED = false

in state "waitForMugPlacedAgain"
check if mug is placed back on the coaster
if ((IO-pin == HIGH)
actualState = startTimer

is called everytime
if (blinkLED == true)
code that makes what the name says

best regards Stefan

Has the OP looked into millis()? millis() is a way to count time.

unsigned long TimeToBlinky = 1200*(60*1000);
unsigned long LastTimeDrink = millis();
loop()
{

if (millis()-TimeToBlinky >= LastTimeDrink) 
{ 
Do the LED blinky thingy
}

if ( tookdrinkSwitch==DrinkTook )
{
 Stop the LED Blinky
LastTimeDrink = millis();
}


}

millis() and delay do not work well together but by using millis() the CPU is not put to NOP and can respond to the lifting and setting down of the drink glass.

Search on this site for things like doing multiple things at the same time and you might look into implementing a state machine for this project.

Look to getting rid of those delays.

Thanks a ton, I will try those solutions. I was also wondering if it would work to to do something with a loop like

loop()
delay(20)
if(buttonvalue==HIGH)
continue loop
else
end loop

only problem is you need to control duration and be able to end the loop, though maybe you could potentially do that with setup()?

aalso to answer your question it is a button, with the pin on input one one side with ground(in series with a resistor) and 5 volts on the other side if i remember correctly

This is a demo-code that shows the principle of a state-machine.

This example has not exact your functionality. After looking at this example ask as many questions as you like. I'm interested in improving the explanation to become easier to understand.

best regards Stefan

I do not use delay.

I tried your way, here is what i have so far

unsigned long lastTimeDrink = millis();
const int mugSensor = 5;
const int timeToDrinkBoi = 6;

void setup() {
pinMode(5, INPUT);
pinMode(6, OUTPUT);
}

void loop() {
if(millis()-120000 >= lastTimeDrink){
digitalWrite(timeToDrinkBoi, HIGH);
delay(1000);
digitalWrite(timeToDrinkBoi, LOW);
delay(1000);
digitalWrite(timeToDrinkBoi, HIGH);
delay(1000);
digitalWrite(timeToDrinkBoi, LOW);
delay(1000);
digitalWrite(timeToDrinkBoi, HIGH);
delay(1000);
digitalWrite(timeToDrinkBoi, LOW);
}
}

also sorry about delay fuction i do not really know work around in this code

i tried the code and for some reason it starts to blink right away. any reason why? great thanks