How do I make my LCD screen scroll text while allowing for button input? Here's what I want my code to do: This is part of a tea infusing project that would automate the steeping of tea, part of this is initially having a selection of either Black/Herbal tea or White/Green tea, this will then set off several other factors down the timeline.
I want my LCD screen to display and scroll &quot;Please select a tea&quot; while still being able to take in pushbutton input.
I've been doing this all day, and I've tried several things. I firstly tried using a normal delay function so my text could scroll properly, but the problem with that is that it halts all the code and doesn't allow for any other input, so I quickly found millis() was likely what I needed to use. However, when I try to apply it to this specific example, it just scrolls all my text extremely quickly through the LCD.
Perhaps I'm being stupid and ignoring something obvious, but please let me know.

#include &lt;LiquidCrystal_I2C.h&gt;
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);

const int black_herbal_osb = 2;

int black_select;

//Timing
unsigned long prev_millis;
unsigned long current_millis;
const unsigned long LCD_delay = 500;

void setup() {

  //Tea selection buttons
  pinMode(black_herbal_osb, INPUT);


  //LCD screen setup
  lcd.init();
  lcd.backlight();

}

void loop() {

  lcd.autoscroll();
  lcd.setCursor(16, 0);
  lcd.print(&quot;Please&quot;);

  current_millis = millis();

  black_select = digitalRead(black_herbal_osb);

  if (black_select != HIGH) {

    if (current_millis - prev_millis &gt;= LCD_delay) {
      lcd.print(&quot; select &quot;);
      prev_millis = current_millis;
    }
    if (current_millis - prev_millis &gt;= LCD_delay * 2) {
      lcd.print(&quot;a &quot;);
      prev_millis = current_millis;
    }
    if (current_millis - prev_millis &gt;= LCD_delay * 3) {
      lcd.print(&quot;tea &quot;);
      prev_millis = current_millis;
    }
  }

  else if (black_select == HIGH) {
    lcd.clear();
    lcd.autoscroll();
    lcd.setCursor(16, 0);
    lcd.print(&quot;Black/Herbal &quot;);
    delay(500);
    lcd.print(&quot;tea &quot;);
    delay(500);
    lcd.print(&quot;selected&quot;);
    delay(2000);
    lcd.noAutoscroll();
    lcd.clear();
  }


}
See my answer to a similar question - about motors but the idea is the same. You call a function for each piece of the job that needs to be done. The function itself decides whether it needs to be done yet, and if so, does it and returns, otherwise it just returns. The loop() function just calls all your other action functions and does nothing else -- all of the real work takes place in those functions.
Looking at your scrolling code, I think one function could print successive pieces of the message by remembering what did last. Another could read and debounce the button(s) and save its/their state.
And once you get to controlling the infusing process, one (or maybe more) functions could be used to control that.