0

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 "Please select a tea" 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 <LiquidCrystal_I2C.h>
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("Please");

  current_millis = millis();

  black_select = digitalRead(black_herbal_osb);

  if (black_select != HIGH) {

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

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


}
2
  • why don't you solve the scrolling problem before adding button code
    – jsotola
    Jul 29, 2020 at 19:48
  • That's what I did, I just added the button code for illustration reasons, with or without the button code the scrolling is still an issue Jul 30, 2020 at 5:22

2 Answers 2

0

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.

0

I figured it out. I was thinking about it all wrong, I just needed to figure out how the scrolling worked for the LCD and the rest was much easier. Only current issue with my code is that on the initial scroll of "Please select a tea" right after the "Booting..." process, it doesn't seem to start at (16,0) but nearer to the front which makes it not super easy to read initially but it corrects itself after a single scroll.

Here's the code for those interested:

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);

const int black_herbal_pin = 2;
const int white_green_pin = 3;
const int LCD_scroll = 200;


int black_select;
int white_select;


unsigned long current_millis = 0;    // stores the value of millis() in each iteration of loop()
unsigned long previous_scroll_millis = 0;






void setup() {
  Serial.begin(9600);
  //Tea selection buttons
  pinMode(black_herbal_pin, INPUT);
  pinMode(white_green_pin, INPUT);


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

}

void loop() {


  if (current_millis == 0) {
    lcd.setCursor (0, 0);
    lcd.print("Booting");
    delay(500);
    lcd.print(".");
    delay(500);
    lcd.print(".");
    delay(500);
    lcd.print(".");
    delay(1000);
    lcd.clear();
  }

  lcd.setCursor(16, 0);
  lcd.print("Please select a tea ");

  current_millis = millis();
  for (int position_counter = 0; position_counter < 16; position_counter++) {

    if (current_millis - previous_scroll_millis >= LCD_scroll) {
      lcd.scrollDisplayLeft();

      previous_scroll_millis += LCD_scroll;
    }
  }

  if (digitalRead(black_herbal_pin) == HIGH) {
    lcd.clear();
    lcd.setCursor (16, 0);
    lcd.print("Black/Herbal tea selecte");
    for (int position_counter = 0; position_counter < 26; position_counter++) {
      lcd.setCursor (0, 0); //This part is likely not necessary for you as it seems to be a bug within my own LCD
      lcd.print("d"); // without this it prints "d" on the second row
      lcd.scrollDisplayLeft();
      delay (150);
    }

    delay(2000);
    lcd.clear();
  }

  if (digitalRead(white_green_pin) == HIGH) {
    lcd.clear();
    lcd.setCursor (16, 0);
    lcd.print("White/Green tea selected");
    for (int position_counter = 0; position_counter < 26; position_counter++) {
      lcd.scrollDisplayLeft();
      delay (150);
    }

    delay(2000);
    lcd.clear();
  }

}

1
  • You could make the "Please select a tea" code a function instead. So void selection() { lcd.setCursor(16, 0); lcd.print("Please select a tea "); current_millis = millis(); for (int position_counter = 0; position_counter < 16; position_counter++) { if (current_millis - previous_scroll_millis >= LCD_scroll) { lcd.scrollDisplayLeft(); previous_scroll_millis += LCD_scroll; } } } and then add selection(); where the code used to be in the loop for a state machine look lmao Jul 30, 2020 at 11:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.