Serial monitor while scanning for user input

So, I have a question. In the program below, I have a pushbutton connected to digital pin 2 and a pull-up resistor, hence when button is pushed, the pin senses low.

When the button is not pushed (pin is HIGH), I want the serial monitor to display the text “Machine ready”.

When the button is pushed, this starts the machine (I have not included this in the code).

int pushButton = 2; 


void setup (){
  pinMode(pushButton, INPUT);
  
  Serial.begin(9600);
}


void loop(){
  if (digitalRead(pushButton) == HIGH){ //Button not pushed
    Serial.print("Machine ready"); //Simulating an LCD
  }
  else if (digitalRead(pushButton) == LOW){ //Button pushed
    Serial.print("Operating"); //Simulating an LCD
  }
delay(1);
}

My question is:
When the button is not pushed in the code above, the serial monitor (or future LCD) receives quite a lot of data as it loops every 1ms. It is not an option to increase the delay time as it needs to continuously scan for button status.

Is this a good solution for an LCD screen if I want this at a later stage? Receiving input that often? Anyone having an idea as to how I can change the program so the text "Machine ready" displays only one while waiting for input?

Best regards
Aleksander Hansen

An "if" has no memory. Since it's in a loop, it will be called repeatedly and "do its thing" repeatedly. This is not recommended, for many reasons. What you need is to detect when the button changes state, and react only to that.

(P.S. you may want to look up "debounce" too!)

What you need is to detect when the button changes state, and react only to that.

There is an example sketch that comes with the IDE that does just that.

Hi,

That actually worked great! Thanks. However, there is still one litte thing I cant figure out. Actually, I want to have 8 different buttons, which depending on what button was pressed populates a variable used for a switch case statement. I tried outlining it in the code below.

However, the first time I run the program, the serial monitor displays "select drink" the same number of times as I have buttons. I would like it to display that just once the first time.

If I push any button, the next time it loops through, it shows "select drink" correctly - just once.

Any ideas?

const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int buttonPin2 = 9;
const int ledPin = 13;       // the pin that the LED is attached to

// Variables will change:
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

int buttonState2 = 0;         // current state of the button
int lastButtonState2 = 0;     // previous state of the button
int selected = 0;


void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  pinMode(buttonPin2, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
}


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

  if (buttonState != lastButtonState) {
    if (buttonState == LOW) {
       Serial.println("Selected drink 1");
       selected = 1;
       delay(2000);
    }
    else {
      Serial.println("Select drink");
    }
  }

  buttonState2 = digitalRead(buttonPin2);
  if (buttonState2 != lastButtonState2) {
    if (buttonState2 == LOW) {
       Serial.println("Selected drink 2");
        selected = 2;
        delay(2000);
    }
    else {
      Serial.println("Select drink");
    }
  }
  lastButtonState = buttonState;
  lastButtonState2 = buttonState2;

  switch (selected) {
  case 1:
    Serial.println("Creating drink1");
    delay(1000);
    Serial.println("Drink1 finished");
    delay(1000);
    selected = 0;
    break;
  case 2:
    Serial.println("Creating drink2");
    delay(1000);
    Serial.println("Drink2 finished");
    delay(1000);
    selected = 0;
    break;
  }

}

On every pass through loop, you need to set selected to 0.

Then, after checking all the switches, the switch statement should have a case 0 that prints the "select a drink" message (once).

To print the message only once, you'll need a flag that indicates that the message has been printed(set to true when the message has been printed and set to false when a drink has been selected/dispensed). check the flag before printing the message.

If your push-buttons have one end connected to ground, then try this:
(used INPUT_PULLUP and set button state variables to 1)

const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int buttonPin2 = 9;
const int ledPin = 13;       // the pin that the LED is attached to

// Variables will change:
int buttonState = 1;         // current state of the button
int lastButtonState = 1;     // previous state of the button

int buttonState2 = 1;         // current state of the button
int lastButtonState2 = 1;     // previous state of the button
int selected = 0;

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
}

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

  if (buttonState != lastButtonState) {
    if (buttonState == LOW) {
      Serial.println("Selected drink 1");
      selected = 1;
      delay(2000);
    }
    else {
      Serial.println("Select drink");
    }
  }

  buttonState2 = digitalRead(buttonPin2);
  if (buttonState2 != lastButtonState2) {
    if (buttonState2 == LOW) {
      Serial.println("Selected drink 2");
      selected = 2;
      delay(2000);
    }
    else {
      Serial.println("Select drink");
    }
  }
  lastButtonState = buttonState;
  lastButtonState2 = buttonState2;

  switch (selected) {
    case 1:
      Serial.println("Creating drink1");
      delay(1000);
      Serial.println("Drink1 finished");
      delay(1000);
      selected = 0;
      break;
    case 2:
      Serial.println("Creating drink2");
      delay(1000);
      Serial.println("Drink2 finished");
      delay(1000);
      selected = 0;
      break;
  }
}