Прокрутка текста I2C

Я хочу попробовать сделать программу для отображения текста на ЖК-дисплее I2C. Текст должен прокручиваться на одну позицию каждый раз при вызове функции.

В Интернете я видел много решений, но все они отличались от того, что мне нужно.

Поэтому я попытался написать свой собственный код. Код работает хорошо, за исключением той части, где я пытаюсь прокручивать текст слева.

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

char Str[12] = {'T', 'r', 'u', 'e', 't', 'z', 's', 'c', 'h', 'l', 'e', 'r'};
int pos = 0;
int posretry = 0;
bool ledon = false;



void setup()
{
  pinMode(13, OUTPUT);

  lcd.init();
  lcd.backlight(); //lcd.noBacklight();
}

void scroll()
{
  for (int i = 0; i < 12; i++)
  {
    // Печатаем текст
    lcd.setCursor(i + pos, 0);
    lcd.print(Str[i]);

    //Двигаемся по тексту слева

    if (pos >= 6)
    {
      lcd.setCursor(i + pos, 0);
      lcd.print(Str[i]);

      lcd.setCursor(posretry, 0);
      lcd.print(Str[11 - posretry]);

      posretry++;
    }
  }
  delay(500);
  lcd.clear();

  pos++;
}

void changeled()
{
  if (ledon == false)
  {
    digitalWrite(13, LOW);
  }
  else
  {
    digitalWrite(13, HIGH);
  }

  ledon = !ledon;
}

void loop()
{
  scroll();
  changeled();  //Пример события
}

Цель состоит в том, чтобы переместить текст вправо и показать не отображаемые буквы слева.

Пример:

|er    Truetzschl|  -->
|                |

Видео об ошибке можно посмотреть здесь: https://data.jonas-heinze.de/shares/stackexchange/lcd/

Спасибо за помощь.

, 👍0

Обсуждение

Что в нем не работает? Вы не дали нам симптом. Вы описали свое ожидаемое поведение, так что хорошо с этим справились. Теперь вам нужно сказать, что происходит на самом деле и чем это отличается от ваших ожиданий., @Delta_G

О, мне так жаль, что я забыл описать проблему. Добавил видео проблемы в свой пост., @MrWaffelXD

Хорошо, я бы помог, если бы вы могли это описать, но я не могу смотреть видео на этом устройстве. Удачи., @Delta_G

Кажется, случайным образом отображается другой текст. Иногда в первый раз во второй ряд. Часто бывают странные персонажи. Это трудно объяснить. По этой причине я добавил видео., @MrWaffelXD

Хм, это должно быть простой задачей, когда вам просто нужно увеличить индекс строки и обработать его переполнение. Чего вы достигаете, проверяя if(pos>=6)? Вам действительно нужны повторы (для чего)? Серьезная проблема заключается в том, что вы никогда не сбрасываете pos и posretry, поэтому они превысят допустимый диапазон и даже станут отрицательными, когда int переполнится. Определенно не прав, @Sim Son

Не так просто понять это, просто посмотрев видео и не имея своего оборудования для фактического тестирования, но я уверен, что вы делаете это намного сложнее, чем необходимо., @Sim Son

Я понимаю, что его трудно зафиксировать. Как бы вы это сделали?, @MrWaffelXD

Слово должно вводиться слева `if (pos >= 6)`: Потому что, если первая буква находится вокруг этой позиции, последняя буква обрезается из-за ограничения отображения. Так что вроде: `if (pos >=6){начинать входить слева}`. `Posretry`` был просто обходным путем для печати последней буквы (букв) в первой позиции (позициях). Вы понимаете, что я имею в виду?, @MrWaffelXD


1 ответ


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

1

Вы делаете какие-то странные вещи, которых я, по крайней мере, не понимаю (например, я не вижу, для чего вам нужен posretry), но у вас может быть причина для этого. Но вы не сбрасываете posretry и pos, что означает, что они очень скоро выйдут за пределы разумного диапазона. В какой-то момент int фактически переполнится отрицательными значениями, что определенно не сработает!

Чтобы сделать это менее сложным, вы должны написать функцию, которая печатает массив символов, сдвинутый на желаемое значение, в качестве начала.

Приведенный ниже код полностью не тестировался, так как у меня нет вашего оборудования, и я знаю, что он не включает все нужные вам функции. Но это должно дать вам представление о том, как прокрутка может быть реализована в принципе, и вам решать, как ее улучшить/исправить.

#define LCD_SIZE 16
#define STR_LEN 12
char str_to_print[STR_LEN]={'T', 'r', 'u', 'e', 't', 'z', 's', 'c', 'h', 'l', 'e', 'r'};

void print_scrolled (uint8_t scrolled_by) {
  for (uint8_t i=0;i<LCD_SIZE;i++) {
    lcd.set_cursor(i,0);
    if (scrolled_by>=LCD_SIZE) scrolled_by=0;

    if (scrolled_by<STR_SIZE) lcd.print(str_to_print[scrolled_by]);
    else lcd.print(' ');
    scrolled_by++;
  }
}

Можно назвать это так:

for (uint8_t i=0;i<STR_LEN;i++) {
  print_scrolled(i);
  delay(500);
}

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

,

Большое спасибо. Завтра сделаю тест. Хорошего дня, @MrWaffelXD