martes, 7 de enero de 2014

Tutorial: Pantalla LCD con texto deslizante mediante pulsadores

Retomando la pantalla LCD, en esta entrada nos enfrentamos al reto de mostrar un texto largo que supera los 16 caracteres de longitud (nuestra pantalla LCD es de 16x2). Para ello usaremos dos pulsadores que actuarán dando la orden de deslizar el texto hacia la izquierda o hacia la derecha.

Y para darle mayor atractivo al proyecto, se ha añadido un LED rojo que se enciende cuando se llega tope último o al del principio.

Material usado
1xPantalla LCD 1602A
1xPlaca Arduino UNO
1xCable USB
Cables
1xBreadboard
1xpotenciómetro 50kohmnios
2xpulsadores
2xResistencias 220 ohmnios
2xResistencias 10k ohmnios
1xLED rojo

Cableado

El cableado de la pantalla LCD va a depender de la definición de los pines a usar por la misma en el programa.

Podéis recordar el cableado de la pantalla en la entrada anterior (link), la  diferencia es:
 - los pines D4-D7 cambian de 2 a 5 en vez de 9-12
-  pin E cambia al 11 en vez de al 8
- pin RS en el 12 en vez del 7

Pero esto lo podéis cambiar en la declaración de los pines de la LCD, siendo conscientes de que el orden es LiquidCrystal lcd(RS, E, D4, D5, D6, D7).

El resto del cableado es tal y como se indica en la figura siguiente:






























El pograma

Se han incluido comentarios a modo de guía para entender lo que está pasando a lo largo del código.
Primero se declaran los pines digitales, luego la pantalla LCD y posteriormente el LED.

#include <LiquidCrystal.h>

// === CONSTANTES Y GLOBALES ===
// -- PINES --
const int PIN_LCD_LED = 6;  // analog

const int PIN_ERR_LED = 7;  // digital
const int PIN_BUTTON1 = 8;  // digital
const int PIN_BUTTON2 = 9;  // digital

// -- LCD --
// PIN 12   -> RS
// PIN 11   -> Enable
// PINS 2-5 -> D4-7
LiquidCrystal lcd(12, 11, 2, 3, 4, 5);
// NÚMERO DE COLUMNAS DE LA LCD
const int LCD_COLS = 16;
// BRILLO LCD [0, 255]
const int LCD_BRIGHTNESS = 128;
// LCD ON o OFF
int state_lcd = LOW;
// Posición inicial del texto
int lcd_start = 0;

// -- LED --
// LOW -> LED está OFF - HIGH -> LED está ON
int state_led = LOW;
// tiempo cuando el LED está encendido
unsigned long t0_led;
// tiempo de espera para apagar el led
const int LED_TIMEOUT = 500;

// -- texto a imprimir --
// Nota: el texto que sea más largo de 16 caracteres
const char TEXT[] = "El cajon de Ardu, blog para aprender sobre Arduino";
const int TEXT_LEN = (sizeof(TEXT) / sizeof(char)) - 1;
const int LCD_LIMIT = TEXT_LEN - LCD_COLS;
// === CONSTANTES Y GLOBALES FIN===


En esta parte se va a iniciar el programa. Cuando se ejecuta el mismo por primera vez, la pantalla LCD estará "apagada" (no mostrará ningún caracter). Para que empiece a trabajar, se ha definido el encendido mediante la acción de la pulsación simultánea de los dos pulsadores.

// === INICIALIZACIÓN ===
void setup()
{
  // -- Configuración pines digitales --
  pinMode(PIN_BUTTON1, INPUT);
  pinMode(PIN_BUTTON2, INPUT);

  pinMode(PIN_ERR_LED, OUTPUT);

  // -- Configuración LCD --
  lcd.begin(16,2);
  lcd.noDisplay();
  digitalWrite(PIN_LCD_LED, state_lcd);

  // LED de error está apagado cuando se empieza
  digitalWrite(PIN_ERR_LED, state_led);
}
// === INITIALIZATION END ===


Aquí está la parte del programa que se encarga del deslizamiento del texto y el encendido del LED cuando se llega al límite, tanto inicial como final, del texto.

// === MAIN LOOP ===
void loop()
{
  // -- asignación botones --
  int state_button1 = digitalRead(PIN_BUTTON1);
  int state_button2 = digitalRead(PIN_BUTTON2);

  // == LCD aún apagada ==
  if(LOW == state_lcd)
  {
    // apretando los dos botones a la vez -> encendido pantalla LCD
    if(HIGH == state_button1 && HIGH == state_button2)
    {
      analogWrite(PIN_LCD_LED, LCD_BRIGHTNESS);

      lcd.display();

      state_lcd = HIGH;

      delay(250);
    }
  }
  else  // == LCD ON ==
  {
    // presionar pulsador 1 ->intentar deslizar hacia la izquierda o encender el LED si no se puede
    if(HIGH == state_button1)
    {
      if(lcd_start > 0)
      {
        lcd_start--;

        state_led = LOW;
        digitalWrite(PIN_ERR_LED, state_led);

        delay(200);
      }
      else
      {
        state_led = HIGH;
        digitalWrite(PIN_ERR_LED, state_led);

        t0_led = millis();
      }
    }

    //  presionar pulsador 2 ->intentar deslizar hacia la derecha o encender el LED si no se puede
    if(HIGH == state_button2)
    {
      if(lcd_start < LCD_LIMIT)
      {
        lcd_start++;

        state_led = LOW;
        digitalWrite(PIN_ERR_LED, state_led);

        delay(200);
      }
      else
      {
        state_led = HIGH;
        digitalWrite(PIN_ERR_LED, state_led);

        t0_led = millis();
      }
    }

    // -- Imprimir texto por pantalla --
    for(int i = 0; i < LCD_COLS; i++)
    {
      lcd.setCursor(i, 0);
      lcd.print(TEXT[lcd_start + i]);
    }

    // LED de error está ON
    if(HIGH == state_led)
    {
      unsigned long td = millis() - t0_led;

      // LED ha estado encendido más tiempo que LED_TIMEOUT ms . -> apagarlo
      if(td > LED_TIMEOUT)
      {
        state_led = LOW;
        digitalWrite(PIN_ERR_LED, state_led);
      }
    }
  }

  // normalmente 20FPS
  delay(50);
}
// === MAIN LOOP END ===

Resultado





Os animamos a subir vuestros vídeos del tutorial funcionando en nuestro Facebook
nombrándonos en Twitter.

P.