Início›Scroll
⬤ LCD · Intermédio

📜 Scroll e Animações de Texto

⏱️ 25 min 🧩 scrollDisplayLeft() · Mensagens longas · Barra de carga · Transições

Nesta página

📜 Scroll de Mensagem Longa

O LCD tem 20 colunas mas pode conter mensagens maiores — o conteúdo extra fica oculto à direita. scrollDisplayLeft() desloca todo o conteúdo visível 1 posição à esquerda a cada chamada.

💡
Para fazer scroll suave de uma mensagem numa linha sem afectar as outras, usa a abordagem de substring manual — mais controlada que o método nativo.
ex_scroll_msg.ino
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);

// Scroll de mensagem longa numa linha sem afectar as outras
void scrollLinha(int linha, const char* msg, int espera_ms) {
  String s = String("                    ") + msg + String("                    ");
  int total = s.length();
  for (int i = 0; i <= total - 20; i++) {
    lcd.setCursor(0, linha);
    lcd.print(s.substring(i, i + 20));
    delay(espera_ms);
  }
}

void setup() {
  lcd.init(); lcd.backlight();
  // Linhas 0 e 2 ficam fixas enquanto 1 e 3 scrollam
  lcd.setCursor(0, 0); lcd.print("  PR.FT9_5 LCD 20x4 ");
  lcd.setCursor(0, 2); lcd.print("Temp: 23.5C Hum: 61%");
}

void loop() {
  scrollLinha(1, "Interface LCD 20x4 com Motor Driver L293D para Arduino UNO Rev3", 220);
  scrollLinha(3, "LED Portugal -- Laboratorios de Educacao Digital -- PR.FT9_5", 180);
}

⏳ Barra de Carga Animada

ℹ️
O caractere ASCII 0xFF (255) é um bloco cheio nativo do HD44780 — não precisa de CGRAM. Usa-o para barras de progresso simples sem gastar slots de char custom.
ex_barra_carga.ino
// Barra de carga em qualquer linha — não usa CGRAM
void barraCarregamento(int linha, int pct, const char* label) {
  int blocos = pct * 18 / 100;  // 18 blocos + '[' + ']'
  lcd.setCursor(0, linha);
  lcd.print("[");
  for (int i = 0; i < 18; i++)
    i < blocos ? lcd.write(0xFF) : lcd.write(' ');
  lcd.print("]");

  lcd.setCursor(0, linha + 1);
  lcd.print(label);
  lcd.print(" "); lcd.print(pct); lcd.print("%   ");
}

void setup() {
  lcd.init(); lcd.backlight();
  lcd.setCursor(3, 0); lcd.print("A INICIALIZAR...");
}

void loop() {
  for (int p = 0; p <= 100; p += 2) {
    barraCarregamento(2, p, "Carreg.:");
    delay(60);
  }
  lcd.setCursor(0, 2); lcd.print("[##################]");
  lcd.setCursor(4, 3); lcd.print("SISTEMA PRONTO!");
  delay(2000);
  lcd.clear();
}

📡 Ticker — Linha 3 Rola, Linhas 0–2 Fixas

Temp: 23.5C Hum:61%Motor: FWD Vel: 180Estado: OK t:0142s <<< ALERTA: temperat
💡
Padrão profissional: linhas 0–2 mostram dados em tempo real (sem scroll), a linha 3 é um ticker de notícias/alertas que scrolla continuamente. Actualiza cada zona no seu próprio timer com millis().
ex_ticker.ino
// Ticker na linha 3 — dados fixos nas linhas 0–2
const char* alertas[] = {
  "Temp. acima do limite!",
  "Motor em funcionamento",
  "Humidade: 61% - OK",
  "PR.FT9_5 LED Portugal"
};
#define N_ALERTAS 4

unsigned long tScroll = 0, tDados = 0;
int  alertaAtual = 0, posScroll = 0;
String msgScroll;

void setup() {
  lcd.init(); lcd.backlight();
  msgScroll = String("                    ") + alertas[0];
}

void atualizarDados() {
  lcd.setCursor(0,0); lcd.print("Temp: ");
  lcd.print(analogRead(A0) * 0.48828, 1); lcd.print("C  ");
  lcd.setCursor(0,1); lcd.print("Luz: ");
  lcd.print(analogRead(A1)); lcd.print("      ");
}

void loop() {
  unsigned long agora = millis();

  if (agora - tDados > 500) { // Dados a cada 500ms
    atualizarDados(); tDados = agora;
  }

  if (agora - tScroll > 250) { // Scroll a cada 250ms
    lcd.setCursor(0, 3);
    lcd.print(msgScroll.substring(posScroll, posScroll + 20));
    posScroll++;
    if (posScroll >= (int)msgScroll.length() - 19) {
      posScroll = 0;
      alertaAtual = (alertaAtual + 1) % N_ALERTAS;
      msgScroll = String("                    ") + alertas[alertaAtual];
    }
    tScroll = agora;
  }
}

🎬 Transição Slide-in entre Ecrãs

ex_transicao.ino
// Slide-in da direita: novo ecrã entra col a col
void slideIn(const char* l0, const char* l1,
             const char* l2, const char* l3) {
  const char* linhas[4] = {l0, l1, l2, l3};
  for (int col = 0; col < 20; col++) {
    for (int row = 0; row < 4; row++) {
      lcd.setCursor(19 - col, row);
      int idx = (int)strlen(linhas[row]) - 1 - col;
      if (idx >= 0) lcd.write(linhas[row][idx]);
      else           lcd.write(' ');
    }
    delay(25);
  }
}

void loop() {
  lcd.clear();
  slideIn("  ECRA 1 — SENSOR ",
           "Temp: 23.5C         ",
           "Luz:  412           ",
           "Estado: OK          ");
  delay(3000);
  lcd.clear();
  slideIn("  ECRA 2 — MOTOR  ",
           "Dir: FORWARD        ",
           "Vel: 200/255  78%   ",
           "t: 00:02:15         ");
  delay(3000);
}

🏆 Para ir mais longe

PR.FT9_5 · LCD 20×4 · L293D Motor Driver · Arduino UNO Rev3 · Início · led.dge.medu.pt