liquid crystal

45

Click here to load reader

Upload: nandojam

Post on 28-Nov-2015

525 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Liquid Crystal

LiquidCrystal

La librería LiquidCrystal te permite controlar displays LCD que

sean complatibles con el driver Hitachi HD44780. Hay muchos de

ellos ahí fuera, y puedes comunicarte con ellos a través del

interfaz de 16 pines.

Este sketch de ejemplo imprime "Hello World!" en el LCD y

muestra el tiempo en segundos desde que Arduino fué

reseteado por última vez.

salida del sketch en un LCD de 2x16

El LCD tiene un interfaz paralelo, significando esto que el

microcontrolador tiene que manipular varios pines del interfaz a

la vez para controlarlo. El interfaz consta de los siguientes pines:

Un pin de selección de registro (RS) que controla en qué parte

de la memoria del LCD estás escribiendo datos. Puedes

Page 2: Liquid Crystal

seleccionar bien el regisro de datos, que mantiene lo que sale

en la pantalla, o un registro de instrucción, que es donde el

controlador del LCD busca las instrucciones para saber cual es lo

siguiente que hay que hacer.

El pin de lectura/escritura (R/W)que selecciona el modo de

lectura o el de escritura.

Un pin para habilitar (enable) que habilita los registros.

8 pines de datos (D00-D07). Los estados de estos pines (nivel

alto o bajo) son los bits que estás escribiendo a un registro

cuando escribes, o los valores de lectura cuando estás leyendo.

Hay también un pin de contraste del display (Vo), pines de

alimentación (+5V y GND) y pines de retro-iluminación (Bklt+ y

Bklt-), que te permiten alimentar el LCD, controlar el contraste

del display, o encender y apagar la retro-iluminación,

respectivamente.

El proceso de controlar el display involucra la colocación de los

datos que componen la imagen de lo que quieres mostrar, en los

registros de datos, y luego, colocar las instrucciones, en el

registro de instrucciones. La libreríaLiquidCrystal te simplifica

todo este proceso de forma que no neesitas saber las

instrucciones de bajo nivel.

Los LCD-s compatibles con Hitachi pueden ser controlados de

dos modos: 4 bits u 8 bits. El modo de 4 bits requiere siete pines

Page 3: Liquid Crystal

de E/S de Arduino, mientras el modo de 8 bits requiere 11 pines.

Para mostrar texto en la pantalla, puedes hacer la mayoría de

las cosas en modo 4 bits, por lo que el ejemplo muestra como

controlar un LCD de 2x16 en modo de 4 bits.

NOTA: La librería LiquidCrystal tiene revisiones venidas a menos

después de la versión 0016 de Arduino. Gracias a Limor

Fried por reescribirla para incluir los modos de 4 y 8 bits y otras

funcionalidades. Estas notas hacen referencia a la versión actual

como es Arduino 0017.

Otros ejemplos de la librería LiquidCrystal

Hello World  - muestra "hello world!" y los segundos desde el últio reset

Blink  - control del cursor en forma de bloque. Cursor  - control del cursor en forma de guión bajo. Display  - limpieza rápida del display, sin perder lo que había en

él. Text Direction  - controla en qué sentido fluye el texto desde el

cursor. Autoscroll  - scroll automático del nuevo texto. Serial input  - acepta la entrada serie y la muestra. SetCursor  - establece la posición del cursor. Scroll  - realiza un scroll del texto a la izquierda y a la derecha

Circuito

El pin RS del LCD conectado a la E/S digital en el pin 12 El pin enable del LCD conectado a la E/S digital en el pin 11. Los pines D4 - D7 conectado a las E/S digitales desde el pin 5

hasta el 2. Los pines de voltaje y tierra conectados a +5V y tierra. El pin Vo, que controla el constraste, conectado a un

potenciómetro. Ajusta el potenciómetro para que el texto tenga el contraste que tú quieras.

Page 4: Liquid Crystal

Nota: Este diagrama de wiring es diferente que el que había en

anteriores versiones la de librería LiquidCrystal. Los pines de R/W

(lectura/escritura) están conectado a tierra, y el pin de enable se

mueve al pin 11, liberando el pin E/S para otros usos.

pincha en la imagen para aumentarla

image developed using Fritzing. For more circuit examples, see the Fritzing

project page

Esquemático:

Page 5: Liquid Crystal

pincha en la imagen para aumentarla

/* LiquidCrystal Library - Hello World Demonstrates the use a 16x2 LCD display. The LiquidCrystal library works with all LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you can usually tell them by the 16-pin interface. This sketch prints "Hello World!" to the LCD and shows the time. The circuit: * LCD RS pin to digital pin 12 * LCD Enable pin to digital pin 11 * LCD D4 pin to digital pin 5 * LCD D5 pin to digital pin 4 * LCD D6 pin to digital pin 3 * LCD D7 pin to digital pin 2 * 10K resistor: * ends to +5V and ground * wiper to LCD VO pin (pin 3) Library originally added 18 Apr 2008 by David A. Mellis library modified 5 Jul 2009 by Limor Fried (http://www.ladyada.net)

Page 6: Liquid Crystal

example added 9 Jul 2009 by Tom Igoe modified 8 Feb 2010 by Tom Igoe This example code is in the public domain.

http://www.arduino.cc/en/Tutorial/LiquidCrystal */

// include the library code:#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pinsLiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() { // set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. lcd.print("hello, world!");}

void loop() { // set the cursor to column 0, line 1 // (note: line 1 is the second row, since counting begins with 0): lcd.setCursor(0, 1); // print the number of seconds since reset: lcd.print(millis()/1000);}

Page 7: Liquid Crystal

LiquidCrystal - Serial Input

La librería LiquidCrystal te permite controlar displays LCD que

sean complatibles con el driver Hitachi HD44780. Hay muchos de

ellos ahí fuera, y puedes comunicarte con ellos a través del

interfaz de 16 pines.

Este sketch de ejemplo acepta entrada serie desde un

ordenador servidor y lo muestra en el LCD. PAra usarlo, sube el

sketch, después abre el monitor serie (Serial Monitor), escribe

algunos caracteres y pulsa Send (Enviar). El texto aparecerá en

tu LCD.

NOTA: La librería LiquidCrystal tiene revisiones venidas a menos

después de la versión 0016 de Arduino. Gracias a Limor

Fried por reescribirla para incluir los modos de 4 y 8 bits y otras

funcionalidades. Estas notas hacen referencia a la versión actual

como es Arduino 0017.

Otros ejemplos de la librería LiquidCrystal

Hello World  - muestra "hello world!" y los segundos desde el últio reset

Blink  - control del cursor en forma de bloque. Cursor  - control del cursor en forma de guión bajo. Display  - limpieza rápida del display, sin perder lo que había en

él. Text Direction  - controla en qué sentido fluye el texto desde el

cursor. Autoscroll  - scroll automático del nuevo texto. Serial input  - acepta la entrada serie y la muestra. SetCursor  - establece la posición del cursor. Scroll  - realiza un scroll del texto a la izquierda y a la derecha

Page 8: Liquid Crystal

Circuito

El pin RS del LCD conectado a la E/S digital en el pin 12 El pin enable del LCD conectado a la E/S digital en el pin 11. Los pines D4 - D7 conectado a las E/S digitales desde el pin 5

hasta el 2. Los pines de voltaje y tierra conectados a +5V y tierra. El pin Vo, que controla el constraste, conectado a un

potenciómetro. Ajusta el potenciómetro para que el texto tenga el contraste que tú quieras.

Nota: Este diagrama de wiring es diferente que el que había en

anteriores versiones la de librería LiquidCrystal. Los pines de R/W

(lectura/escritura) están conectado a tierra, y el pin de enable se

mueve al pin 11, liberando el pin E/S para otros usos.

pincha en la imagen para aumentarla

Page 9: Liquid Crystal

image developed using Fritzing. For more circuit examples, see the Fritzing

project page

Esquemático:

pincha en la imagen para aumentarla

Page 10: Liquid Crystal

/* LiquidCrystal Library - Serial Input Demonstrates the use a 16x2 LCD display. The LiquidCrystal library works with all LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you can usually tell them by the 16-pin interface. This sketch displays text sent over the serial port (e.g. from the Serial Monitor) on an attached LCD. The circuit: * LCD RS pin to digital pin 12 * LCD Enable pin to digital pin 11 * LCD D4 pin to digital pin 5 * LCD D5 pin to digital pin 4 * LCD D6 pin to digital pin 3 * LCD D7 pin to digital pin 2 * 10K resistor: * ends to +5V and ground * wiper to LCD VO pin (pin 3) Library originally added 18 Apr 2008 by David A. Mellis library modified 5 Jul 2009 by Limor Fried (http://www.ladyada.net) example added 9 Jul 2009 by Tom Igoe modified 8 Feb 2010 by Tom Igoe

Page 11: Liquid Crystal

This example code is in the public domain. http://www.arduino.cc/en/Tutorial/LiquidCrystal */

// include the library code:#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pinsLiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup(){ // set up the LCD's number of columns and rows: lcd.begin(16, 2); // initialize the serial communications: Serial.begin(9600);}

void loop(){ // when characters arrive over the serial port... if (Serial.available()) { // wait a bit for the entire message to arrive delay(100); // clear the screen lcd.clear(); // read all the available characters while (Serial.available() > 0) { // display each character to the LCD lcd.write(Serial.read()); } }}

Page 12: Liquid Crystal

Cómo conectar display LCD Keypad Shield a Arduino UNO

En este tutorial explicaremos y mostraremos ejemplos para trabajar con una pantalla LCD (display LCD Keypad Shield) conectada a Arduino. Para ello necesitaremos una pantalla LCD (Display LCD Keypad Shield), en concreto usaremos un Arduino LCD Keypad Shield 16x2 HD44780 con un coste aproximado de 18 euros:

Por supuesto necesitaremos un Arduino UNO, en el siguiente tutorial explicamos cómo adquirirlo y cómo conectarlo al PC para transferir el programa:

Adquisición del hardware necesario: Arduino UNO, cable USB tipo A-B y LED .

Conectaremos el LCD a Arduino como mostramos en la imagen:

Page 13: Liquid Crystal

En el siguiente tutorial explicamos cómo descargar el software para realizar programas y enviarlos a Arduino, también explicamos cómo conectar Arduino a un PC para el envío de programas:

Conectar Arduino UNO a un PC con W7, instalar y configurar Arduino IDE .

 

Programa Arduino para mostrar texto en display LCD y contador que se va incrementando

Una vez conectado el display LCD a Arduino y conectado Arduino al PC por el puerto USB, desde el IDE de desarrollo de Arduino pegaremos el siguiente programa:

/* Ejemplo de uso de display LCD 16x2. Usando la librería LiquidCrystal library compatible con el driver de Hitachi HD44780 driver */

// incluimos la libreria LiquidCrystal#include

// inicializamos la librería con los numeros pins del interfaz// cada LCD puede llevar sus propios numerosLiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);

void setup() { // establecemos el numero de columnas y filas del display lcd.begin(16, 2); // enviamos el mensaje a mostrar en el display

Page 14: Liquid Crystal

lcd.print("www.ajpdsoft.com");}

void loop() { // enviamos la posicion del cursor al display // (nota: la linea 1 es la segunda fila, empieza a contar en 0 lcd.setCursor(0, 1); // mostramos el numero de segundos desde el inicio del programa lcd.print(millis()/1000);}

Comprobaremos la sintaxis pulsando en "Verificar":

Page 15: Liquid Crystal

Si todo es correcto pulsaremos en el botón "Cargar" para enviar el programa a Arduino:

Si todo es correcto el programa quedará transferido a la memoria de Arduino y se iniciará, mostrando el texto indicando en el display LCD (en nuestro caso "www.ajpdsoft.com") y un contador de segundos en la segunda línea:

Page 16: Liquid Crystal

 

 

Programa Arduino para mostrar texto en scroll en display LCD

Un ejemplo de programa Arduino para mostrar un texto en movimiento en un display LCD:

// include the library code:#include

// initialize the library with the numbers of the interface pinsLiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);

void setup() { // set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. lcd.print("www.ajpdsoft.com"); delay(1000);}

void loop() { // scroll 13 positions (string length) to the left // to move it offscreen left: for (int positionCounter = 0; positionCounter < 13; positionCounter++) { // scroll one position left: lcd.scrollDisplayLeft(); // wait a bit: delay(150); }

Page 17: Liquid Crystal

// scroll 29 positions (string length + display length) to the right // to move it offscreen right: for (int positionCounter = 0; positionCounter < 29; positionCounter++) { // scroll one position right: lcd.scrollDisplayRight(); // wait a bit: delay(150); } // scroll 16 positions (display length + string length) to the left // to move it back to center: for (int positionCounter = 0; positionCounter < 16; positionCounter++) { // scroll one position left: lcd.scrollDisplayLeft(); // wait a bit: delay(150); } // delay at the end of the full loop: delay(1000);}

 

 

Programa Arduino para introducir texto en el LDC con las teclas de desplazamiento

Un ejemplo de programa Arduino para mostrar un texto en la primera línea de una pantalla LCD y en la segunda permite que el usuario introduzca un texto usando las teclas de desplazamiento del display LCD:

#include

LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);

int adc_key_val[5] = {50, 200, 400, 600, 800 };int NUM_KEYS = 5;int adc_key_in;int key=-1;int oldkey=-1;boolean luzEncendida=true;boolean cursorActivo=false;unsigned long time;int x=0;char caracterActual = 'A';

void setup(){ lcd.clear(); lcd.begin(16, 2); lcd.setCursor(0,0); lcd.print("www.ajpdsoft.com");

Page 18: Liquid Crystal

time = millis(); // pinMode(10, OUTPUT);}

void loop(){ if (millis()-time > 10000) { // Si han pasado mas de 10 segundos apagamos la luz pinMode(10, OUTPUT); digitalWrite(10, LOW); luzEncendida=false; } if (millis()-time > 5000) { // Si han pasado mas de 5 segundos apagamos el cursor lcd.noBlink(); cursorActivo=false; }

adc_key_in = analogRead(0); // Leemos el valor de la pulsacion key = get_key(adc_key_in); // Obtenemos el boton pulsado

if (key != oldkey) // if keypress is detected { delay(50); // Espera para evitar los rebotes de las pulsaciones adc_key_in = analogRead(0); // Leemos el valor de la pulsacion key = get_key(adc_key_in); // Obtenemos el boton pulsado if (key != oldkey) { time = millis(); // TODO: falta la comprobacion de si se ha desbordado el tiempo if (!luzEncendida) { // Al pulsar cualquier tecla encendemos la pantalla pinMode(10, INPUT); luzEncendida=true; } else { // si la pantalla esta encendida seguimos funcionando normalmente lcd.setCursor(x, 1); oldkey = key; if (key >=0){ // Si se ha pulsado cualquier tecla lcd.blink(); // Mostramos el cursor parpadeando cursorActivo=true; } if (key == 0){ // Se ha pulsado la tecla derecha x++; if (x>15) x=15; caracterActual='A'; } if (key == 1) { // Se ha pulsado la tecla arriba caracterActual++; if (caracterActual > 'Z') caracterActual='Z'; lcd.write(caracterActual); } if (key == 2) { // Se ha pulsado la tecla abajo caracterActual--; if (caracterActual < 'A') caracterActual='A'; lcd.write(caracterActual);

Page 19: Liquid Crystal

} if (key == 3) { // Se ha pulsado la tecla izquierda x--; if (x<0) x=0; caracterActual='A'; } if (key == 4){ // Se ha pulsado la tecla de seleccion } lcd.setCursor(x, 1); } } } delay(100);}

// Convertimos el valor leido en analogico en un numero de boton pulsadoint get_key(unsigned int input){ int k;

for (k = 0; k < NUM_KEYS; k++) { if (input < adc_key_val[k]) { return k; } }

if (k >= NUM_KEYS)k = -1; // Error en la lectura return k;}

 

 

 

Programa Arduino para mostrar menús y submenús en display LCD

Un ejemplo de programa Arduino para mostrar un menú y sus submenús correspondientes en una pantalla LCD:

#include

LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);

const int numeroDeMenus=5;const int numeroMaximoDeSubmenus=4;

char tituloMenu[numeroDeMenus][16] = { "1 Menu 1 ", "2 Menu 2 ", "3 Menu 3 ", "4 Menu 4 ",

Page 20: Liquid Crystal

"5 Menu 5 " }; byte numeroDeSubmenus[numeroDeMenus] = {4,3,2,1,4};

char tituloSubmenu[numeroDeMenus][numeroMaximoDeSubmenus][16] = { "1.1 Submenu 1","1.2 Submenu 2","1.3 Submenu 3","1.4 Submenu 4", "2.1 Submenu 1","2.2 Submenu 2","2.3 Submenu 3","", "3.1 Submenu 1","3.2 Submenu 2","","", "4.1 Submenu 1","","","", "5.1 Submenu 1","5.2 Submenu 2","5.3 Submenu 3","5.4 Submenu 4"};

int adc_key_val[5] ={ 50, 200, 400, 600, 800 };int NUM_KEYS = 5;int adc_key_in;int key=-1;int oldkey=-1;boolean luzEncendida=true;boolean cursorActivo=false;unsigned long time;int x=0;int y=0;

void setup(){ lcd.clear(); lcd.begin(16, 2); lcd.setCursor(0,0); lcd.print("www.ajpdsoft.com"); lcd.setCursor(0,1); lcd.print("Menu version 0.1"); delay(5000); lcd.setCursor(0,0); lcd.print("Muevase con las "); lcd.setCursor(0,1); lcd.print("teclas direccion"); delay(4000); lcd.clear(); lcd.setCursor(0,0); lcd.print("Menu principal"); lcd.setCursor(0,1); lcd.print(tituloMenu[x]); time = millis(); // pinMode(10, OUTPUT);}

void loop(){ // Si han pasado mas de 10 segundos apagamos la luz if (millis()-time > 10000) { pinMode(10, OUTPUT); digitalWrite(10, LOW); luzEncendida=false; } // Si han pasado mas de 5 segundos apagamos el cursor if (millis()-time > 5000) {

Page 21: Liquid Crystal

lcd.noBlink(); cursorActivo=false; }

adc_key_in = analogRead(0); // Leemos el valor de la pulsacion key = get_key(adc_key_in); // Obtenemos el boton pulsado

if (key != oldkey) // if keypress is detected delay(50); // Espera para evitar los rebotes de las pulsaciones adc_key_in = analogRead(0); // Leemos el valor de la pulsacion key = get_key(adc_key_in); // Obtenemos el boton pulsado if (key != oldkey) { // TODO: falta la comprobacion de si se ha desbordado el tiempo time = millis(); if (!luzEncendida) { // Al pulsar cualquier tecla encendemos la pantalla pinMode(10, INPUT); luzEncendida=true; } else { // si la pantalla esta encendida seguimos funcionando normalmente oldkey = key; if (key >=0){ // Si se ha pulsado cualquier tecla lcd.blink(); // Mostramos el cursor parpadeando cursorActivo=true; } if (key == 0){ // Se ha pulsado la tecla derecha x++; if (x>numeroDeMenus-1) x=numeroDeMenus-1; y=0; } if (key == 1) { // Se ha pulsado la tecla arriba y++; if (y > numeroDeSubmenus[x]-1) y=numeroDeSubmenus[x]-1; } if (key == 2) { // Se ha pulsado la tecla abajo y--; if (y < 0) y=0; } if (key == 3) { // Se ha pulsado la tecla izquierda x--; if (x<0) x=0; y=0; } if (key == 4){ // Se ha pulsado la tecla de seleccion } lcd.clear(); lcd.setCursor(0,0); lcd.print(tituloMenu[x]); lcd.setCursor(0,1); lcd.print(tituloSubmenu[x][y]); } } } delay(50);

Page 22: Liquid Crystal

}

// Convertimos el valor leido en analogico en un numero de boton pulsadoint get_key(unsigned int input){ int k;

for (k = 0; k < NUM_KEYS; k++) { if (input < adc_key_val[k]) { return k; } }

if (k >= NUM_KEYS)k = -1; // Error en la lectura return k;}

 

Programa Arduino para mostrar temperatura, opciones modificables, luminosidad en display LCD

Un ejemplo de programa Arduino para mostrar la temperatura de un habitáculo usando un sensor de temperatura (NTC o resistencia variable con la temperatura de coeficiente negativo) en una pantalla LCD Keypad Shield. El programa también permite modificar la luminosidad (intensidad de la retroiluminación) del display LCD, cambiar parámetros, guardar valores en memoria EEPROM, etc.

Para conectar el sensor de temperatura (NTC o resistencia variable con la temperatura de coeficiente negativo) se pueden seguir las intrucciones del siguiente tutorial:

Obtener temperatura con sensor SEN118A2B de cabeza de acero y Arduino .

Con la diferencia de que hemos conectado el sensor de temperatura a la entrada analógica 1 porque la 0 la usa el LCD.

El código del programa completo Arduino:

 

#include #include #define ThermistorPIN 1 // Analog Pin 1#define NUM_KEYS 5

/* Circuito del dispaly LCD: * LCD RS pin to digital pin 8 * LCD Enable pin to digital pin 9 * LCD D4 pin to digital pin 4 * LCD D5 pin to digital pin 5 * LCD D6 pin to digital pin 6 * LCD D7 pin to digital pin 7 * LCD BL pin to digital pin 10 * KEY pin to analogl pin 0

Page 23: Liquid Crystal

* * Esquema del sensor de temperatura: * [Ground] -- [10k-pad-resistor] -- | -- [10k thermistor] --[Vcc (5v)] * | * Analog Pin 1 */

LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);

const int numeroDeMenus=6;

char tituloMenu[numeroDeMenus][16] = { "Fijar Temp.: ", "Fijar Tiempo:", "Kp: ", "Kd: ", "Ki: ", "Intensidad: " };

int adc_key_val[5] ={ 50, 200, 400, 600, 800 };int adc_key_in;int key=-1;int oldkey=-1;boolean luzEncendida=true;boolean cursorActivo=false;boolean enMenu=false;unsigned long time;unsigned long tiempoPID;byte numeroLecturas=0;int x=0;int signo=0;char temp[10];int lecturas[100];byte numeroLectura=0;//int lectura=0;int maximo, minimo, diferencia, t1, t2, t3;byte consigna=25;byte tiempo=1;byte kp=1;byte kd=1;byte ki=1;byte intensidad=10;

void setup(){ cargarConfig(); pinMode(10, OUTPUT); analogWrite(10,intensidad*25); Serial.begin(9600); lcd.clear(); lcd.begin(16, 2); lcd.setCursor(0,0); lcd.print("www.ajpdsoft.com"); lcd.setCursor(0,1);

Page 24: Liquid Crystal

lcd.print("C.Ventanas v1.0 "); delay(2000); // lcd.setCursor(0,0); // lcd.print("Muevase con las "); // lcd.setCursor(0,1); // lcd.print("teclas direccion"); // delay(4000); lcd.clear(); lcd.setCursor(0,0); lcd.print("Temperatura: "); lcd.setCursor(0,1); int lectura=getTemp(1); sprintf(temp, "%3d%c%1d%cC", lectura/100, '.', lectura/10%10,223); lcd.print(temp); time = millis(); tiempoPID = millis();}

void loop(){ int lectura = getTemp(ThermistorPIN); lecturas[numeroLectura++] = lectura; if (millis()-time > 20000) { // Si han pasado mas de 20 segundos apagamos la luz digitalWrite(10, LOW); luzEncendida=false; } if (millis()-time > 7000) { // Si han pasado mas de 7 segundos salimos del menu if (enMenu) guardarConfig(); enMenu = false; x=0; time = millis(); // } // if (!enMenu) { lcd.clear(); lcd.setCursor(0,0); lcd.print("Temperatura: "); lcd.setCursor(0,1); sprintf(temp, "%3d%c%1d%cC", lectura/100, '.', lectura/10%10,223); lcd.print(temp); // Serial.print("Temperatura["); // Serial.print(numeroLectura); // Serial.print("]: "); // Serial.println(temp); } if (millis()-time > 5000) { // Si han pasado mas de 5 segundos apagamos el cursor lcd.noBlink(); cursorActivo=false; }

adc_key_in = analogRead(0); // Leemos el valor de la pulsacion key = get_key(adc_key_in); // Obtenemos el boton pulsado

if (key != oldkey) // if keypress is detected {

Page 25: Liquid Crystal

delay(50); // Espera para evitar los rebotes de las pulsaciones adc_key_in = analogRead(0); // Leemos el valor de la pulsacion key = get_key(adc_key_in); // Obtenemos el boton pulsado if (key != oldkey) { time = millis(); // TODO: falta la comprobacion de si se ha desbordado el tiempo if (!luzEncendida) { // Al pulsar cualquier tecla encendemos la pantalla analogWrite(10,intensidad*25); luzEncendida=true; } else { // si la pantalla esta encendida seguimos funcionando normalmente oldkey = key; char accion = 0; if (key >=0){ // Si se ha pulsado cualquier tecla lcd.blink(); // Mostramos el cursor parpadeando cursorActivo=true; } if ((key == 0) && (enMenu)){ // Se ha pulsado la tecla derecha x++; if (x>numeroDeMenus-1) x=numeroDeMenus-1; } if ((key == 1) && (enMenu)) { // Se ha pulsado la tecla arriba accion++; } if ((key == 2) && (enMenu)) { // Se ha pulsado la tecla abajo accion = accion-1; } if ((key == 3) && (enMenu)) { // Se ha pulsado la tecla izquierda x--; if (x<0) x = 0; } if (key == 4){ // Se ha pulsado la tecla de seleccion } enMenu = true; lcd.clear(); lcd.setCursor(0,0); lcd.print(tituloMenu[x]); lcd.setCursor(0,1); switch (x) { case 0: // Estamos en fijar temperatura consigna += accion; lcd.print(consigna); lcd.print((char)223); lcd.print("C"); break; case 1: // Estamos en fijar tiempo tiempo += accion; lcd.print(tiempo); lcd.print("0 seg."); break; case 2: // Estamos en Kp. kp += accion; lcd.print(kp);

Page 26: Liquid Crystal

break; case 3: // Estamos en Kd. kd += accion; lcd.print(kd); break; case 4: // Estamos en Ki. ki += accion; lcd.print(ki); break; case 5: // Estamos en Ki. intensidad += accion; if (intensidad > 254) intensidad = 0; if (intensidad > 10) intensidad = 10; lcd.print(intensidad); lcd.print("0%"); analogWrite(10,intensidad*25); break; } } } } if ((numeroLectura > 99) && (numeroLecturas < 2)) { long suma = 0; maximo = -10000; minimo = 10000; for (int i=0; i < 100; i++){ suma = suma + lecturas[i]; if (lecturas[i] > maximo) { maximo = lecturas[i]; } if (lecturas[i] < minimo) { minimo = lecturas[i]; }

// Serial.print("Temperatura["); // Serial.print(i); // Serial.print("]: "); // Serial.println(lecturas[i]); } diferencia = maximo - minimo; suma = suma / 100; // Si la diferencia es superior a un grado //es que ha habido un error en la lectura if (diferencia > 100) { Serial.println("Lectura no valida"); // TODO: Descartar lectura y repetir la medida } else { numeroLecturas++; t3=t2; t2=t1; t1=suma; } Serial.print("Suma: "); Serial.println(suma); /* Serial.print("Media: "); Serial.print(suma/100);

Page 27: Liquid Crystal

Serial.print(","); Serial.println(suma/10%10); Serial.print("Maximo: "); Serial.print(maximo/100); Serial.print(","); Serial.print(maximo/10%10); Serial.print(" - Minimo: "); Serial.print(minimo/100); Serial.print(","); Serial.print(minimo/10%10); Serial.print(" - Diferencia: "); Serial.print(diferencia/100); Serial.print(","); Serial.println(diferencia/10%10); */ } if (numeroLectura > 99) { // Cuando se termina de tomar las 100 //lecturas empezamos de nuevo por la primera numeroLectura = 0; } PID(); delay(10); // Si se desborda millis() empieza otra //vez por cero, ocurre cada 50 dias if (millis() < time){ time = millis(); }}

void PID(){ // Si se desborda millis() empieza otra // vez por cero, ocurre cada 50 dias if (millis() < tiempoPID){ tiempoPID = millis(); } // Si no ha pasado todavía el timepo de ciclo del PID if (millis() < tiempoPID + (tiempo*10*1000)){ // entonces mantenemos la fuerza y esperamos mas tiempo // s = sActualPID; } else if (numeroLecturas >= 2){ numeroLecturas--; Serial.print("Distancia a la consigna: "); Serial.print(t1-consigna*100); Serial.print(" - Velocidad: "); Serial.println(t1-t2); tiempoPID = millis(); }

}

// Convertimos el valor leido en analogico // en un numero de boton pulsadoint get_key(unsigned int input){ int k;

Page 28: Liquid Crystal

for (k = 0; k < NUM_KEYS; k++) { if (input < adc_key_val[k]) { return k; } }

if (k >= NUM_KEYS)k = -1; // Error en la lectura. return k;}

int temperaturaFicticia = 2450;int ptf= 0;int getTemp(byte input){ int celsius = Thermistor(analogRead(input))*100; return celsius; temperaturaFicticia += (random(7)-3-ptf); if (temperaturaFicticia > 2800) ptf = 1; if (temperaturaFicticia < 2000) ptf = 0; return temperaturaFicticia;}

float pad = 10000; // balance/pad resistor value, set this to // the measured resistance of your pad resistor// float thermr = 10000; // thermistor nominal resistance

float Thermistor(int RawADC) { long Resistance; float Temp; // Dual-Purpose variable to save space.

Resistance=((1024 * pad / RawADC) - pad); // Saving the Log(resistance) so not to calculate it 4 times later Temp = log(Resistance); Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp)); Temp = Temp - 273.15; // Convert Kelvin to Celsius

return Temp; // Devolver temperatura}

boolean cargarConfig(){ if ((EEPROM.read(0) == 27) && (EEPROM.read(1) == 28) && (EEPROM.read(2) == 13) && (EEPROM.read(3) == 18)) { // Comprobamos que la eeprom tenga una // configuracion valida con numeros concretos // solo cargamos el valor de la configuracion si los valores coinciden if (EEPROM.read(4) == EEPROM.read(5)) consigna = EEPROM.read(4); if (EEPROM.read(6) == EEPROM.read(7)) tiempo = EEPROM.read(6); if (EEPROM.read(8) == EEPROM.read(9)) kp = EEPROM.read(8); if (EEPROM.read(10) == EEPROM.read(11)) kd = EEPROM.read(10); if (EEPROM.read(12) == EEPROM.read(13)) ki = EEPROM.read(12); if (EEPROM.read(14) == EEPROM.read(15)) intensidad = EEPROM.read(14); return true; }

Page 29: Liquid Crystal

return false;}

void guardarConfig(){ EEPROM.write(0,27); EEPROM.write(1,28); EEPROM.write(2,13); EEPROM.write(3,18); // Ponemos nmeros concretos en el comienzo // de la EEPROM para confirmar que tiene valores correctos. EEPROM.write(4,consigna); EEPROM.write(5,consigna); // almacenamos los valores 2 veces EEPROM.write(6,tiempo); EEPROM.write(7,tiempo); // almacenamos los valores 2 veces EEPROM.write(8,kp); EEPROM.write(9,kp); // almacenamos los valores 2 veces EEPROM.write(10,kd); EEPROM.write(11,kd); // almacenamos los valores 2 veces EEPROM.write(12,ki); EEPROM.write(13,ki); // almacenamos los valores 2 veces EEPROM.write(14,intensidad); EEPROM.write(15,intensidad); // almacenamos los valores 2 veces}

Page 30: Liquid Crystal

LCD & Keypad Shield Quickstart Guide

The 16x2 LCD And Keypad Shield is very simple to use because it's fully compatible with the Arduino "LiquidCrystal" library. You can initialise the LCD and display messages on it with just a few lines of code, but it also gives you the flexibility to do more advanced projects such as display menu items and select them using the buttons.

Power RequirementsThe LCD & Keypad Shield requires a good 5V power supply to ensure the backlight fully illuminates and the display contrast is high, and if you power your Arduino from USB with the LCD Shield attached you may experience a voltage drop over the USB cable. If you have trouble with display contrast or backlight brightness, try attaching a power supply of around 7 to 9Vdc to the 2.1mm DC jack on the Arduino. A typical symptom in an undervoltage situation is that one line of the LCD will show pale rectangles in place of the characters, and the other line will show nothing at all. The Arduino may even continue running normally because it's quite happy at just 4V or so, but the LCD & Keypad Shield won't function.

Library RequirementsAll the hard work of interfacing with the LCD Shield is handled by the LiquidCrystal library, which is included as part of the official Arduino distribution. You can check whether you have it installed by starting up the IDE and looking under Files -> Examples -> LiquidCrystal. If it exists, you're good to go.

Minimal Display ExampleTo start up the LCD and display a message, open a new sketch in the Arduino IDE and paste in the following code:

#include <Wire.h>#include <LiquidCrystal.h>

LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );

void setup(){  lcd.begin(16, 2);  lcd.print("hello, world!");}

void loop(){

Page 31: Liquid Crystal

        // your main loop code here...}

Reading The ButtonsThe LCD Shield includes 5 buttons designed for use as navigational or control input. The buttons are arranged in a handy pattern and referred to as UP, DOWN, LEFT, RIGHT, and SELECT, but of course it's totally up to your sketch to decide what to do when any particular button is pressed.

All the buttons are connected to a single analog input, A0, using a chain of resistors that causes a different reference voltage to be applied to A0 depending on which button is pressed. This section of the shield schematic shows the input buttons and associated resistors:

As you can see, if no button is being pressed the voltage on A0 will be pulled all the way up to 5V by the 2K resistor called R6. In that situation none of the other resistors have any effect at all, and the analog reading on A0 will be hard on the upper limit of 1023. Therefore if you perform an analogRead() call on A0 and it returns 1023 (or any value above about 1000) you know that no buttons are being pressed.

Now consider what happens if the "DOWN" button is pressed. Now A0 is being presented with a voltage that is divided between the 2K resistor that is trying to pull it up to 5V, and the 330R and 620R resistors in series (totaling 950R) that are trying to pull it down to 0V. The voltage presented

Page 32: Liquid Crystal

to A0 in that case is about 1.61V, which means if you perform an analogRead() on A0 it will return a value of about 329. So if you read a value of about 329 from A0 you know the "DOWN" button is being pressed.

The same principle applies for the other buttons, with the voltages and equivalent analogRead() values shown on the schematic above.

This is a neat way to provide a whole set of input buttons while only using up one of the I/O pins on your Arduino, leaving more pins free for use in your project.

Complex ExampleThe extensive example below combines a number of techniques to demonstrate how to show messages on the LCD, read from the buttons, and change the display message depending on which buttons are pressed.

/*  Example code for the Freetronics LCD & Keypad Shield:       http://www.freetronics.com/products/lcd-keypad-shield     by Marc Alexander, 7 September 2011  This example code is in the public domain.     ---------------------------------------------------------------------     This program demonstrates button detection, LCD text/number printing,  and LCD backlight control on the Freetronics LCD & Keypad Shield, connected to an Arduino board.     After powerup, the screen looks like this:           ------------------        |Freetronics 16x2|        |Btn:          0 | <- This time value counts up the number of seconds since reset (overflows at 99)        ------------------   When a button is pressed, a label appears for it:           ------------------        |Freetronics 16x2|        |Btn:RIGHT     0 |        ------------------       Labels are LEFT, UP, DOWN, RIGHT and SELECT-FLASH.       SELECT-FLASH makes the LCD backlight flash off and on when held down.       Pins used by LCD & Keypad Shield:       A0: Buttons, analog input from voltage ladder    D4: LCD bit 4    D5: LCD bit 5

Page 33: Liquid Crystal

    D6: LCD bit 6    D7: LCD bit 7    D8: LCD RS    D9: LCD E    D3: LCD Backlight (high = on, also has pullup high so default is on)     ADC voltages for the 5 buttons on analog input pin A0:       RIGHT:  0.00V :   0 @ 8bit ;   0 @ 10 bit    UP:     0.71V :  36 @ 8bit ; 145 @ 10 bit    DOWN:   1.61V :  82 @ 8bit ; 329 @ 10 bit    LEFT:   2.47V : 126 @ 8bit ; 505 @ 10 bit    SELECT: 3.62V : 185 @ 8bit ; 741 @ 10 bit*//*--------------------------------------------------------------------------------------  Includes--------------------------------------------------------------------------------------*/#include <Wire.h>#include <LiquidCrystal.h>   // include LCD library/*--------------------------------------------------------------------------------------  Defines--------------------------------------------------------------------------------------*/// Pins in use#define BUTTON_ADC_PIN           A0   // A0 is the button ADC input#define LCD_BACKLIGHT_PIN         3   // D3 controls LCD backlight// ADC readings expected for the 5 buttons on the ADC input#define RIGHT_10BIT_ADC           0   // right#define UP_10BIT_ADC            145   // up#define DOWN_10BIT_ADC          329   // down#define LEFT_10BIT_ADC          505   // left#define SELECT_10BIT_ADC        741   // right#define BUTTONHYSTERESIS         10   // hysteresis for valid button sensing window//return values for ReadButtons()#define BUTTON_NONE               0   // #define BUTTON_RIGHT              1   // #define BUTTON_UP                 2   // #define BUTTON_DOWN               3   // #define BUTTON_LEFT               4   // #define BUTTON_SELECT             5   // //some example macros with friendly labels for LCD backlight/pin control, tested and can be swapped into the example code as you like#define LCD_BACKLIGHT_OFF()     digitalWrite( LCD_BACKLIGHT_PIN, LOW )#define LCD_BACKLIGHT_ON()      digitalWrite( LCD_BACKLIGHT_PIN, HIGH )#define LCD_BACKLIGHT(state)     { if( state ){digitalWrite( LCD_BACKLIGHT_PIN, HIGH );}else{digitalWrite( LCD_BACKLIGHT_PIN, LOW );} }/*--------------------------------------------------------------------------------------  Variables--------------------------------------------------------------------------------------*/byte buttonJustPressed  = false;         //this will be true after a ReadButtons() call if triggeredbyte buttonJustReleased = false;         //this will be true after a ReadButtons() call if triggeredbyte buttonWas          = BUTTON_NONE;   //used by ReadButtons() for detection of button events/*--------------------------------------------------------------------------------------  Init the LCD library with the LCD pins to be used--------------------------------------------------------------------------------------*/

Page 34: Liquid Crystal

LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );   //Pins for the freetronics 16x2 LCD shield. LCD: ( RS, E, LCD-D4, LCD-D5, LCD-D6, LCD-D7 )/*--------------------------------------------------------------------------------------  setup()  Called by the Arduino framework once, before the main loop begins--------------------------------------------------------------------------------------*/void setup(){    //button adc input   pinMode( BUTTON_ADC_PIN, INPUT );         //ensure A0 is an input   digitalWrite( BUTTON_ADC_PIN, LOW );       //ensure pullup is off on A0    //lcd backlight control   digitalWrite( LCD_BACKLIGHT_PIN, HIGH );   //backlight control pin D3 is high (on)   pinMode( LCD_BACKLIGHT_PIN, OUTPUT );     //D3 is an output    //set up the LCD number of columns and rows:     lcd.begin( 16, 2 );    //Print some initial text to the LCD.    lcd.setCursor( 0, 0 );   //top left    //          1234567890123456    lcd.print( "Freetronics 16x2" );    //    lcd.setCursor( 0, 1 );   //bottom left    //          1234567890123456    lcd.print( "Btn:" );}/*--------------------------------------------------------------------------------------  loop()  Arduino main loop--------------------------------------------------------------------------------------*/void loop(){   byte button;   byte timestamp;       //get the latest button pressed, also the buttonJustPressed, buttonJustReleased flags   button = ReadButtons();    //blank the demo text line if a new button is pressed or released, ready for a new label to be written    if( buttonJustPressed || buttonJustReleased )    {      lcd.setCursor( 4, 1 );      lcd.print( "             " );    }    //show text label for the button pressed   switch( button )    {      case BUTTON_NONE:      {         break;      }      case BUTTON_RIGHT:      {          lcd.setCursor( 4, 1 );          lcd.print( "RIGHT" );

Page 35: Liquid Crystal

         break;      }      case BUTTON_UP:      {          lcd.setCursor( 4, 1 );          lcd.print( "UP" );         break;      }      case BUTTON_DOWN:      {          lcd.setCursor( 4, 1 );          lcd.print( "DOWN" );         break;      }      case BUTTON_LEFT:      {        lcd.setCursor( 4, 1 );        lcd.print( "LEFT" );        break;      }     case BUTTON_SELECT:      {        lcd.setCursor( 4, 1 );        lcd.print( "SELECT-FLASH" );                     //SELECT is a special case, it pulses the LCD backlight off and on for demo        digitalWrite( LCD_BACKLIGHT_PIN, LOW );        delay( 150 );        digitalWrite( LCD_BACKLIGHT_PIN, HIGH );   //leave the backlight on at exit        delay( 150 );                 /* an example of LCD backlight control via macros with nice labels        LCD_BACKLIGHT_OFF();        delay( 150 );        LCD_BACKLIGHT_ON();   //leave the backlight on at exit        delay( 150 );        */                 /*        // an example of LCD backlight control via a macro with nice label, called with a value        LCD_BACKLIGHT(false);        delay( 150 );        LCD_BACKLIGHT(true);   //leave the backlight on at exit        delay( 150 );        */                 break;      }      default:      {        break;      }    }    // print the number of seconds since reset (two digits only)

Page 36: Liquid Crystal

    timestamp = ( (millis() / 1000) % 100 );   //"% 100" is the remainder of a divide-by-100, which keeps the value as 0-99 even as the result goes over 100    lcd.setCursor( 14, 1 );    if( timestamp <= 9 )      lcd.print( " " );   //quick trick to right-justify this 2 digit value when it's a single digit    lcd.print( timestamp, DEC );/*      //debug/test display of the adc reading for the button input voltage pin.    lcd.setCursor(12, 0);    lcd.print( "     " );           //quick hack to blank over default left-justification from lcd.print()    lcd.setCursor(12, 0);         //note the value will be flickering/faint on the LCD    lcd.print( analogRead( BUTTON_ADC_PIN ) );*/    //clear the buttonJustPressed or buttonJustReleased flags, they've already done their job now.    if( buttonJustPressed )      buttonJustPressed = false;    if( buttonJustReleased )      buttonJustReleased = false;}/*--------------------------------------------------------------------------------------  ReadButtons()  Detect the button pressed and return the value  Uses global values buttonWas, buttonJustPressed, buttonJustReleased.--------------------------------------------------------------------------------------*/byte ReadButtons(){   unsigned int buttonVoltage;   byte button = BUTTON_NONE;   // return no button pressed if the below checks don't write to btn       //read the button ADC pin voltage   buttonVoltage = analogRead( BUTTON_ADC_PIN );    //sense if the voltage falls within valid voltage windows    if( buttonVoltage < ( RIGHT_10BIT_ADC + BUTTONHYSTERESIS ) )    {      button = BUTTON_RIGHT;    }   else if(   buttonVoltage >= ( UP_10BIT_ADC - BUTTONHYSTERESIS )           && buttonVoltage <= ( UP_10BIT_ADC + BUTTONHYSTERESIS ) )    {      button = BUTTON_UP;    }   else if(   buttonVoltage >= ( DOWN_10BIT_ADC - BUTTONHYSTERESIS )           && buttonVoltage <= ( DOWN_10BIT_ADC + BUTTONHYSTERESIS ) )    {      button = BUTTON_DOWN;    }   else if(   buttonVoltage >= ( LEFT_10BIT_ADC - BUTTONHYSTERESIS )           && buttonVoltage <= ( LEFT_10BIT_ADC + BUTTONHYSTERESIS ) )    {      button = BUTTON_LEFT;    }   else if(   buttonVoltage >= ( SELECT_10BIT_ADC - BUTTONHYSTERESIS )           && buttonVoltage <= ( SELECT_10BIT_ADC + BUTTONHYSTERESIS ) )    {

Page 37: Liquid Crystal

      button = BUTTON_SELECT;    }    //handle button flags for just pressed and just released events    if( ( buttonWas == BUTTON_NONE ) && ( button != BUTTON_NONE ) )    {      //the button was just pressed, set buttonJustPressed, this can optionally be used to trigger a once-off action for a button press event      //it's the duty of the receiver to clear these flags if it wants to detect a new button change event      buttonJustPressed  = true;      buttonJustReleased = false;    }    if( ( buttonWas != BUTTON_NONE ) && ( button == BUTTON_NONE ) )    {      buttonJustPressed  = false;      buttonJustReleased = true;    }       //save the latest button value, for change event detection next time round   buttonWas = button;       return( button );}

Page 38: Liquid Crystal

Arduino LCD Keypad Shield

This is a 16x2 LCD and Keypad shield for Arduino Uno, Diecimila, Duemilanove and Freeduino boards.

Blue Backlight with white words uses 4 Bit Arduino LCD Library Left, Right, Up, Down and Select buttons Screen contrast adjustment Arduino Reset button

The board uses different pins to the Arduino example sketches, so to make the display work, use the following sequence of pins when starting the library:

LiquidCrystal lcd(8,9,4,5,6,7); 

The buttons are connected to only one analog input pin through resistors to give a different voltage for each button, thus saving on input/output pins. Reading the buttons is easy and example code is shown below

Pin Connections

Pin FunctionAnalog 0 Buttons (select, up, right, down and left)Digital 4 DB4Digital 5 DB5Digital 6 DB6Digital 7 DB7Digital 8 RS (Data or Signal Display Selection)Digital 9 Enable   Note: Do not use pin Digital 10 when this board is plugged in 

// include the library code:#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pinsLiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() {  // set up the LCD's number of columns and rows:  lcd.begin(16, 2);  // Print a message to the LCD.  lcd.setCursor(0,0);  lcd.print("LCD Key Shield");  lcd.setCursor(0,1);  lcd.print("Press Key:");}

void loop() {  int x;  x = analogRead (0);  lcd.setCursor(10,1);  if (x < 100) {    lcd.print ("Right ");  }  else if (x < 200) {    lcd.print ("Up ");  }

Page 39: Liquid Crystal

  else if (x < 400){    lcd.print ("Down ");  }  else if (x < 600){    lcd.print ("Left ");  }  else if (x < 800){    lcd.print ("Select");  }}

Page 40: Liquid Crystal