Как заставить ЖК-экран прокручивать текст , позволяя вводить кнопки?

Вот что я хочу, чтобы мой код делал: это часть проекта по завариванию чая, который автоматизирует заваривание чая, часть этого изначально имеет выбор либо черного/травяного чая, либо белого/зеленого чая, это будет затем зафиксируйте несколько других факторов на временной шкале. Я хочу, чтобы на ЖК-дисплее отображалось и прокручивалось сообщение «Выберите чай». при этом сохраняя возможность ввода с помощью кнопок.

Я занимался этим весь день и перепробовал несколько способов. Сначала я попытался использовать обычную функцию задержки, чтобы мой текст мог правильно прокручиваться, но проблема в том, что она останавливает весь код и не позволяет вводить какие-либо другие данные, поэтому я быстро обнаружил, что мне нужна была функция millis(). использовать. Однако, когда я пытаюсь применить его к этому конкретному примеру, он просто очень быстро прокручивает весь мой текст на ЖК-дисплее. Возможно, я туплю и игнорирую что-то очевидное, но, пожалуйста, дайте мне знать.


#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();
  }


}

, 👍0

Обсуждение

почему бы вам не решить проблему прокрутки перед добавлением кода кнопки, @jsotola

Это то, что я сделал, я просто добавил код кнопки для иллюстрации, с кодом кнопки или без него прокрутка все еще остается проблемой., @thatgenericguy


2 ответа


Лучший ответ:

0

Я разобрался. Я думал обо всем этом неправильно, мне просто нужно было понять, как работает прокрутка для ЖК-дисплея, а остальное было намного проще. Единственная текущая проблема с моим кодом заключается в том, что в начальном прокрутке «Пожалуйста, выберите чай»; сразу после "Загрузка..." процесс, кажется, он начинается не с (16,0), а ближе к началу, что делает его не очень легким для чтения изначально, но он исправляется после одной прокрутки.

Вот код для тех, кому интересно:

#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;    // сохраняет значение millis() при каждой итерации loop()
unsigned long previous_scroll_millis = 0;






void setup() {
  Serial.begin(9600);
  //Кнопки выбора чая
  pinMode(black_herbal_pin, INPUT);
  pinMode(white_green_pin, INPUT);


  //Настройка ЖК-экрана
  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); //Эта часть, скорее всего, вам не нужна, так как это ошибка моего собственного ЖК-дисплея
      lcd.print("d"); // без этого выводится "d" во втором ряду
      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();
  }

}

,

Вместо этого вы можете сделать код «Пожалуйста, выберите чай» функцией. Итак, void selection() { lcd.setCursor(16, 0); lcd.print("Пожалуйста, выберите чай"); current_millis = миллис(); for (int position_counter = 0; position_counter < 16; position_counter++) { если (текущая_миллис - предыдущая_прокрутка_миллис >= LCD_scroll) { lcd.scrollDisplayLeft(); предыдущая_прокрутка_миллис += LCD_scroll; } } }, а затем добавьте selection();, где код, который раньше находился в цикле для конечного автомата, выглядит lmao, @thatgenericguy


0

См. мой ответ на аналогичный вопрос - о двигателях, но идея та же. Вы вызываете функцию для каждой части работы, которую необходимо выполнить. Функция сама решает, нужно ли это еще сделать, и если да, то делает и возвращает, иначе просто возвращает. Функция loop() просто вызывает все ваши другие функции действий и больше ничего не делает — вся реальная работа выполняется в этих функциях.

Глядя на ваш код прокрутки, я думаю, что одна функция могла бы печатать последовательные фрагменты сообщения, запоминая, что было последним. Другой может прочитать и устранить дребезг кнопок и сохранить их состояние.

И как только вы доберетесь до управления процессом инфузии, для этого можно будет использовать одну (или несколько) функций.

,