GLCD’s Gráficos con PCD8544.
INTRODUCCIÓN.
Como me diría a mi mismo, «Bienvenida la novedad que, nos brinda la posibilidad de aprender nuevas técnicas» y lo ratifico. Ya que, esta es la página de inicio sobre los LCD gráficos, donde aprender, algunas cosas sobre, la forma de presentar datos de una forma más profesional, si cabe. Eso espero.
Actualmente tenemos a nuestro alcance, en el mercado una serie de componentes que hasta no hace mucho tiempo, eran dispositivos con los que especular. Sin embargo, las tecnologías en su imparable avance, han puesto a nuestro alcance entre otras, las pantallas graficas LCD que pueden sernos de gran utilidad, para nuestros proyectos.
Otro sitio, a parte del comercio, donde podemos localizar alguna de estas pantallas graficas, puede ser, procedente de un viejo teléfono móvil o celular. En concreto, he podido conseguir desguazar una de estas LCD, perteneciente a un Nokia3310. Tal vez, usted tenga un móvil de este tipo o quizás de un familiar o amigo y con un poco de cuidado y mucha paciencia, acabará obteniendo un LCD en condiciones de hacerlo trabajar.
No es fácil, pero puede intentarlo, si yo lo hice, usted, también puede. La verdad es que lo más sencillo es aprovechar la pantalla y poco más, ya que, la tarjeta o placa, es bastante compleja de reciclar. Algunos modelos, vienen con una cinta de conexión plana, este tipo, es más sencillo de aprovechar, ya que si llevamos cuidado, al separar la LCD con la cinta de la placa, podremos soldar con facilidad a nuestro proyecto.
Han quedado atrás, los tiempos en que mostrábamos los datos con fríos ‘números’, no teníamos medios con los que mostrar de forma gráfica los datos. Pero esto, últimamente ha cambiado, ahora, podremos mostrar los gráficos que mejor expresen los datos. Por ese motivo, utilizaremos ejemplos de utilidades, las cuales se apoyan en este tipo de LCD, para mostrar distintos datos y gráficos, debido a que con esta pantalla, es bastante fácil, controlar vía puerto serie, los datos que necesitamos enviarle a la LCD.
Si usted se decide a adquirir un LCD, puede encontrar una gran variedad de suministradores, procure asegurarse que, la que adquiere tiene garantías, ya se que son económicas, sin embargo, no debe aceptar productos sin garantías. En la plataforma de Arduino, puede encontrar las librerías que soportan este tipo de pantallas LCD.
LA PANTALLA LCD.
En este tutorial, veremos cómo proceder para hacer que nuestra LCD, funcione y podamos presentar los datos por medio de esta pequeña pantalla. La pantalla es monocromática de 84×48 píxeles y ha retroiluminación LED para una visibilidad bajo la luz. Como ya he mencionado, la podemos adquirir en los comercios del ramos o por LCD Nokia en eBay o en Sparkfun, los podemos encontrar en una gama de posibilidades y muy económicos, o desguazando un celular viejo. Yo, voy a apoyarme en una muestra que dispongo de un viejo móvil Nokia 3310 que, andaba perdido por el cajón. Algunos ejemplos, los presentaré con una pantalla Nokia 5110 que adquirí.
El lector, puede utilizar cualquier otro LCD que tenga disponible un controlador PCD8544, son muchos los modelos disponibles, naturalmente deberá realizar ciertos cambios, dependiendo del modelo para adaptar las E/S, al que vaya a utilizar.
Pero!. Ni se le ocurra conectar el LCD directamente a un microcontrolador de 5V como el Arduino. El LCD es un dispositivo de 3,3V. Sin embargo, sí podremos conectarlo directamente a dispositivos como el Arduino Pro y Pro Mini 3,3V.
Fig. 3
La pantalla de los teléfonos celulares Nokia 3310 y el 5110, utiliza el circuito controlador PCD8544 de Philips cuyas características se pueden estudiar en este enlace. Este circuito está diseñado para funcionar sólo a 3,3V y tienen niveles de comunicación 3V, así que, para los microcontroladores de 5V como Arduino, se requiere un desplazador de nivel lógico (de lo contrario se puede dañar fácilmente la pantalla), este tema se verá mas adelante.
Sistema de coordenadas.
Este tipo de pantallas monocromáticas tienen una densidad de 84×48 píxeles que cubren la totalidad de la misma. Pixel. Es (acrónimo del inglés picture element), un ‘elemento de imagen’, es la menor unidad homogénea en color que forma parte de una imagen digital, ya sea esta una fotografía, un fotograma de vídeo o un gráfico. Los bloques que componen una imagen digital, son tratados por sus coordenadas horizontal (X) y verticales (Y), justo lo contrario al sistema de coordenadas cartesianas estándar, de las matemáticas, pero, es una práctica establecida en muchos sistemas gráficos por ordenador desde los principios de los escáneres gráficos que, trabajaban de arriba a abajo.
Fig. 4
Además, a diferencia del sistema de coordenadas cartesianas matemática, aquí los puntos, tienen dimensión que, siempre son un píxel entero, «lleno» con ancho y alto. Las coordenadas, siempre se expresan en unidades de píxel, no existe una escala implícita a una medida del mundo real como milímetros o en pulgadas, y el tamaño de un gráfico que se muestra será una función de la distancia entre puntos que la pantalla específica o densidad de píxeles.
Para aclarar la semántica que se sigue sobre pixeles en las pantallas monocromáticas (de un solo color), los colores siempre se especifican simplemente como 1 (set, encendido) o 0 (claro, apagado), es específicos para el tipo de pantalla. Digamos que, por lo general, en referencia con una pantalla de LEDs, un pixel «set», se ilumina mientras que con una pantalla LCD reflectante, un píxel «set» es generalmente oscuro.
CARACTERÍSTICAS.
Este LCD que, utilizaban para el teléfono móvil Nokia 5110 o el 3310 (con unas pequeñas diferencias entre sí que, veremos más adelante). Todas las funciones necesarias para la visualización se proporcionan en un solo chip, incluyendo la generación de on-chip de alimentación LCD y tensiones de polarización, lo que resulta en un mínimo de componentes externos y bajo consumo de energía. Tiene muchas cosas interesantes este LCD: precio bajo, de fácil interfaz a través del puerto SPI, puede soportar gráficos y texto y consume poca intensidad sobre 200uA. Como se aprecia en las imágenes anteriores, el área activa de 30x22mm, permite una exposición bastante decente de los datos.
Fig. 5
Utiliza la interfaz de comunicaciones serie, con el procesador principal, número de líneas de la señal de interfaz muy reducido, sólo 8 líneas de señales, incluyendo la alimentación y GND. Soporta diferentes tipos de MCU, tales como el Arduino, AVR, del PIC, STM32, STC MSP430 y otros. Velocidad de transferencia de hasta 4 Mbps, la velocidad máxima que puede escribir datos en la pantalla, sin tiempo de espera.
El oscilador en el chip, proporciona la señal de reloj para el sistema de visualización. No se requieren componentes externos y la entrada de OSC, debe estar conectada a VDD. Una señal de reloj externa, si se utiliza, está conectada a esta entrada. En el caso de que usted se decida a utilizar una LCD de un viejo móvil, le voy a dar unos consejos: El peine de conexionado, puede ser de elastómero o por contactos metálicos, en ambos casos, tiene un espaciado de 1’15mm, fíjese en la posición de las patillas que, nos permiten dos opciones:
- ) Trazar unas pistas sobre la placa PCB, si es el caso, con el ancho de 1,15mm y una longitud de 1’00cm. o
- ) Soldar directamente (ponga atención), al punto de contacto, con sumo cuidado, los cables muy finos, para su conexión.
El proyecto que decida realizar, puede funcionar con una tensión de alimentación máxima de 4’8V, la podemos obtener de baterías recargables (4×1’2V), que convierte su manejo en independiente y fácil.
Nota: NO USE DIRECTAMENTE PILAS ALCALINAS DE 1’5V (4×1’5V=6V), quemará el LCD y el microcontrolador, salvo que añada un regulador LF33CV o similar, para reducir la tensión a 3’3V. Esta que sigue, es una prueba de mi experiencia.
ASIGNACIÓN DE PINES ENTRE UN LCD 3310 Y UN LCD 5110.
En la tabla de abajo, hago una comparativa entre un conector de 8pines, con los 8 cables procedentes del Nokia3310 (al que se han soldado con mucho cuidado) y las 8 salidas del Nokia5110.
Fig. 7
Sencillo desplazador de nivel lógico.
Si usted está utilizando, un sistema Arduino Pro (microcontrolador 3,3V), puede omitir el desplazador de nivel. Como venimos repitiendo el LCD funciona a 3,3V por lo que tendrá que utilizar un chip para cambiar de nivel para trabajar con un microcontrolador de 5V.
Amplificador no inversorMuchos dispositivos que se pueden utilizar con un Arduino, requieren una fuente de alimentación de 3,3V. Este, es también el caso del Nokia 5110 o 3310. Con la ayuda del conocido circuito CD4050, podemos desplazar el nivel de tensión. Este circuito integrado de 16 patillas, tiene la particularidad en su alimentación que, se corresponde con: el VCC está en la patilla 1 y el GND en la patilla 8. Consta de 6 amplificadores no-inversores, como el mostrado. De modo que la mejor y más económica forma de trabajar con el LCD es, utilizar un simple cambiador de nivel.
El Nokia 5110 es una pantalla LCD gráfica básica para muchas aplicaciones. Gracias a la fijación interna de la PCD8544 podemos utilizar un simple cambiador de nivel, con cuatro resistencias limitadoras de corriente de 10k, que pueden hacer el trabajo. Cuando una línea de control LCD es alta, la corriente a través del resistor 10kΩ es de sólo 40uA, por lo que, es inofensivo. Sin estas resistencias, pueden aparecer grietas en la pantalla LCD. El esquemático que sigue, muestra el conexionado de la pantalla junto al desplazador de nivel CD4050.
En el supuesto de adquirir una pantalla Nokia 5110 con el PCD8544, decida que lado superior/inferior soldar la tira de 8 pines que suele traer. Una vez decidido, para evitar deformaciones al soldar la tira, inserte la tira de 8 pines, en un protoboard y suelde la tira de 8 pines al lado elegido. Los números de los pines vienen indicados en la propia PCB.
La pantalla de un nokia3310 de reciclaje, tiene 8 pines, el pin 1 está situado a la izquierda (vista, desde detrás de la pantalla), con cables diminutos se podrían soldar directamente a los pines metálicos. Recomendación: para mayor seguridad, diseñe una placa de circuito (con pistas de 1’15mm a un conector de 2’5mm) por su cuenta debido a que la placa de circuito apenas puede ser reciclada.
También, puede realizar un convertidor de paso de 1,15mm a 2.5mm con una pequeña PCB, como se puede ver arriba, observe que el PCB, se ha trazado en espejo, de modo que lo puede girar sin perjuicio para su uso. Para hacer más fácil el conexionado de la pantalla al circuito impreso o PCB, he creado un conector conversor de paso de 1’15mm a 2’5mm que es el estándar, lo puede descargar desde aquí.
Una aplicación sencilla.
El controlador del PCD8544, puede funcionar a 5V. Gracias al reductor interno del PCD8544, se puede utilizar un cambiador de nivel lógico simple, con cuatro resistencias limitadoras de corriente de 10KΩ, la corriente a través de estas resistencias es de sólo 40uA, por lo que es inofensivo. Sin estas resistencias, pueden aparecer grietas en la pantalla LCD.
Este ejemplo, naturalmente, puede realizarse con un ATmega8 y unos pocos componentes a su alrededor, al que se le ha añadido un conector ISP para su programación in-situ. Un ejemplo, se muestra en la figura siguiente:
La lista de componentes es la siguiente:
- 3 resistencias pueden ser de 10KΩ
- 1 resistencias de 1KΩ
- 3 diodos pueden servir con el 1N4148 o el 1N4001, para reducir la tensión del Atmega8.
- 3 pulsadores normalmente abiertos
- 1 cristal de cuarzo de 16MHz
- 2 condensadores de 22pf
- 1 dido LED de color.
- 1 tira de pines de 8 (para el LCD) y 1 de 4 pines (para las entradas)
- 2 tiras dobles de 3 pines (1 para el ISP y 1 para la alimentación) y 1 tira de 2 para alimentación.
El microcontrolador que podemos utilizar es un ATmega8 y unos pocos componentes, como veremos en el esquema, con una tensión de alimentación de 3’3V. Usted es libre de, utilizar otro modelo de microcontrolador. Sin embargo, en esta práctica he utilizado el Arduino habitual para pruebas.
LCD test.
El siguiente es el código de la primera prueba:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
/* lcd_test.pde Este código tiene características adicionales incluyendo una función de posicionamiento XY en la pantalla y una función Dibuja la linea de Nokia 3310 LCD Se modificó a partir del original http://playground.arduino.cc/Code/PCD8544 */ // Mods by V. García // Funciona bien. 15/05/2013. #define PIN_DC 2 // LCD Dat/Com. Pin 5 #define PIN_SCE 3 // LCD CS .... Pin 3 #define PIN_SDIN 4 // LCD SPIDat . Pin 6 #define PIN_RESET 5 // LCD RST .... Pin 1 #define PIN_SCLK 6 // LCD SPIClk . Pin 4 // LCD Gnd .... Pin 2 // LCD Vcc .... Pin 8 // LCD Vlcd ... Pin 7 #define LCD_C LOW #define LCD_D HIGH #define LCD_X 84 #define LCD_Y 48 #define LCD_CMD 0 int a = 0; static const byte ASCII[][5] = { {0x00, 0x00, 0x00, 0x00, 0x00} // 20 ,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 ! ,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 " ,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 # ,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $ ,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 % ,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 & ,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 ' ,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 ( ,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 ) ,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a * ,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b + ,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c , ,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d - ,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e . ,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f / ,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0 ,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1 ,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2 ,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3 ,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4 ,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5 ,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6 ,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7 ,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8 ,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9 ,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a : ,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ; ,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c < ,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d = ,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e > ,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ? ,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @ ,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A ,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B ,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C ,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D ,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E ,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F ,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G ,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H ,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I ,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J ,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K ,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L ,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M ,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N ,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O ,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P ,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q ,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R ,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S ,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T ,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U ,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V ,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W ,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X ,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y ,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z ,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [ ,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥ ,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ] ,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^ ,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _ ,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 ` ,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a ,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b ,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c ,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d ,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e ,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f ,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g ,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h ,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i ,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j ,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k ,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l ,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m ,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n ,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o ,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p ,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q ,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r ,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s ,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t ,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u ,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v ,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w ,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x ,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y ,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z ,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b { ,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c | ,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d } ,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ← ,{0x00, 0x06, 0x09, 0x09, 0x06} // 7f → }; void LcdCharacter(char character) { LcdWrite(LCD_D, 0x00); for (int index = 0; index < 5; index++) { cdWrite(LCD_D, ASCII[character - 0x20][index]); } LcdWrite(LCD_D, 0x00); } void LcdClear(void) { for (int index = 0; index < LCD_X * LCD_Y / 8; index++) { LcdWrite(LCD_D, 0x00); } } void LcdInitialise(void) { pinMode(PIN_SCE, OUTPUT); pinMode(PIN_RESET, OUTPUT); pinMode(PIN_DC, OUTPUT); pinMode(PIN_SDIN, OUTPUT); pinMode(PIN_SCLK, OUTPUT); digitalWrite(PIN_RESET, LOW); // delay(1); digitalWrite(PIN_RESET, HIGH); LcdWrite( LCD_CMD, 0x21 ); // LCD Extended Commands. LcdWrite( LCD_CMD, 0xBf ); // Set LCD Vop (Contrast). //B1 LcdWrite( LCD_CMD, 0x04 ); // Set Temp coefficent. //0x04 LcdWrite( LCD_CMD, 0x14 ); // LCD bias mode 1:48. //0x13 LcdWrite( LCD_CMD, 0x0C ); // LCD in 0x0C normal mode. 0x0d for inverse LcdWrite(LCD_C, 0x20); LcdWrite(LCD_C, 0x0C); } void LcdString(char *characters) { while (*characters) { LcdCharacter(*characters++); } } void LcdWrite(byte dc, byte data) { digitalWrite(PIN_DC, dc); digitalWrite(PIN_SCE, LOW); shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data); digitalWrite(PIN_SCE, HIGH); } // gotoXY routine to position cursor // x - range: 0 to 84 // y - range: 0 to 5 void gotoXY(int x, int y) { LcdWrite( 0, 0x80 | x); // Column. LcdWrite( 0, 0x40 | y); // Row. } void drawLine(void) { unsigned char j; for(j=0; j< 84; j++) { // top gotoXY (j,0); LcdWrite (10,0x01); // } for(j=0; j< 84; j++) { //Bottom gotoXY (j,5); LcdWrite (10,0x80); // } for(j=0; j< 6; j++) { // Right gotoXY (83,j); LcdWrite (10,0xff); // } for(j=0; j< 6; j++) {// Left gotoXY (0,j); LcdWrite (10,0xff); // } } void setup(void) { LcdInitialise(); LcdClear(); } void loop(void) { // Muestra algunas animaciones sencillas de caracteres // int a,b; char Str[20]; //15 /* // Dibujar un cuadro for(b=1020; b>0; b--) { drawLine(); for(a=0; a<=5 ; a++) */ { gotoXY(8,2); //gotoXY(4,1); // Poner el texto en el recuadro LcdString ("TestDisplay"); gotoXY(7,3); LcdString ("Este ejemplo"); gotoXY(3,4); LcdString ("funciona bien"); gotoXY(0,5); LcdString (" "); gotoXY(0,6); LcdString (" "); gotoXY(24,1); LcdCharacter(' '); LcdCharacter('H'); LcdCharacter('O'); LcdCharacter('L'); LcdCharacter('A'); LcdCharacter('!'); LcdCharacter(' '); LcdCharacter('='); // gotoXY(10,6); LcdCharacter('_'); // Dibujar + en esta posición gotoXY(10,1); LcdCharacter('='); delay(500); gotoXY(24,1); LcdCharacter(' '); LcdCharacter('h'); LcdCharacter('o'); LcdCharacter('l'); LcdCharacter('a'); LcdCharacter('!'); LcdCharacter(' '); LcdCharacter('-'); // Dibujar - en esta posición gotoXY(10,6); LcdCharacter('_'); // gotoXY(10,6); LcdCharacter('='); delay(500); LcdClear(); } } |
El ejemplo, presenta unas palabras de saludo que muestra en mayúsculas y en minúsculas, simplemente para demostrar que funciona la pantalla. Si usted está utilizando una pantalla diferente, puede que el resultado se presente con alguna diferencia, eso es debido a la propia pantalla, como se muestra en las imágenes de abajo.
En el ejemplo anterior, he observado que existe una ligera diferencia entre las dos pantallas, me refiero a que el LCD 3310, muestra un ancho de visualización mayor que el LCD 5110, lo que repercute en los datos mostrados incluso en los gráficos. Los gráficos mostrados en el Nokia 3310 (reciclado), son mostrados en pantalla, ocupando menor espacio, como que, los pixeles son de menor tamaño. Al menos esto es lo que ocurre en la pantalla LCD 5110 que he recibido.
Trazando un rectángulo que ocupe toda la superficie del LCD 5110, en el Nokia 3310, se muestra con un espacio a la derecha de dos letras mayúsculas y abajo de 2 líneas. Es decir, el equivalente a 2 columnas y 2 filas.
La siguiente es la segunda prueba, en la que se ha modificado algunas rutina y añadido otras, para darle una posibilidad más al lector que decida llevar a cabo los ejercicios.
LCD test2.
El siguiente es el código de la segunda prueba, algo más completo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 |
/* lcd_test2.pde Este Código tiene características adicionales incluyendo una función de posicionamiento XY en la pantalla y una función Dibuja la linea de Nokia 3310 LCD Se modificó a partir del original http://playground.arduino.cc/Code/PCD8544 */ // Espero que le funcione a usted// // Mods by V. García. 15/05/2013. // #define PIN_DC 2 // LCD Dat/Com. Pin 5 #define PIN_SCE 3 // LCD CS .... Pin 3 #define PIN_SDIN 4 // LCD SPIDat . Pin 6 #define PIN_RESET 5 // LCD RST .... Pin 1 #define PIN_SCLK 6 // LCD SPIClk . Pin 4 // LCD Gnd .... Pin 2 // LCD Vcc .... Pin 8 // LCD Vlcd ... Pin 7 #define LCD_C LOW #define LCD_D HIGH #define LCD_X 84 #define LCD_Y 48 #define LCD_CMD 0 int progress = 0; int prev_prog = 0; int pixels[85][6] = {{0}}; int a = 0; static const byte ASCII[][5] ={ {0x00, 0x00, 0x00, 0x00, 0x00} // 20 ,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 ! ,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 " ,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 # ,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $ ,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 % ,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 & ,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 ' ,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 ( ,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 ) ,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a * ,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b + ,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c , ,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d - ,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e . ,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f / ,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0 ,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1 ,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2 ,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3 ,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4 ,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5 ,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6 ,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7 ,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8 ,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9 ,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a : ,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ; ,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c < ,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d = ,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e > ,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ? ,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @ ,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A ,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B ,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C ,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D ,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E ,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F ,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G ,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H ,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I ,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J ,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K ,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L ,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M ,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N ,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O ,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P ,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q ,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R ,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S ,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T ,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U ,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V ,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W ,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X ,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y ,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z ,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [ ,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥ ,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ] ,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^ ,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _ ,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 ` ,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a ,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b ,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c ,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d ,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e ,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f ,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g ,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h ,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i ,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j ,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k ,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l ,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m ,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n ,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o ,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p ,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q ,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r ,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s ,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t ,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u ,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v ,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w ,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x ,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y ,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z ,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b { ,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c | ,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d } ,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ← ,{0x00, 0x06, 0x09, 0x09, 0x06} // 7f → ,{0x00, 0x00, 0x7D, 0x00, 0x00} // 80 ¡ }; void LcdCharacter(char character) { LcdWrite(LCD_D, 0x00); for (int index = 0; index < 5; index++) { LcdWrite(LCD_D, ASCII[character - 0x20][index]); } LcdWrite(LCD_D, 0x00); } void LcdClear(void) { for (int index = 0; index < LCD_X * LCD_Y / 8; index++) { LcdWrite(LCD_D, 0x00); } } void LcdInitialise(void) { pinMode(PIN_SCE, OUTPUT); pinMode(PIN_RESET, OUTPUT); pinMode(PIN_DC, OUTPUT); pinMode(PIN_SDIN, OUTPUT); pinMode(PIN_SCLK, OUTPUT); digitalWrite(PIN_RESET, LOW); delay(1); digitalWrite(PIN_RESET, HIGH); LcdWrite( LCD_CMD, 0x21 ); // LCD Extended Commands. LcdWrite( LCD_CMD, 0xB9 ); // Set LCD Vop (Contrast). //B1 LcdWrite( LCD_CMD, 0x04 ); // Set Temp coefficent. //0x04 LcdWrite( LCD_CMD, 0x14 ); // LCD bias mode 1:48. //0x13 LcdWrite( LCD_CMD, 0x0C ); // LCD in 0x0C normal mode. 0x0d for inverse LcdWrite(LCD_C, 0x20); LcdWrite(LCD_C, 0x0C); } void LcdString(char *characters) { while (*characters) { LcdCharacter(*characters++); } } void LcdWrite(byte dc, byte data) { digitalWrite(PIN_DC, dc); digitalWrite(PIN_SCE, LOW); shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data); digitalWrite(PIN_SCE, HIGH); } // gotoXY routine to position cursor // x - range: 0 to 84 // y - range: 0 to 5 void gotoXY(int x, int y) { LcdWrite( 0, 0x80 | x); // Column. LcdWrite( 0, 0x40 | y); // Row. } // *************** // Enable or disable a specific pixel // x: 0 to 84, y: 0 to 48 void setPixel(int x, int y, int d) { if (x > 84 || y > 48) { return; } // The LCD has 6 rows, with 8 pixels per row. // 'y_mod' is the row that the pixel is in. // 'y_pix' is the pixel in that row we want to enable/disable int y_mod = (int)(y >> 3); // >>3 divides by 8 int y_pix = (y-(y_mod << 3));// < < 3 multiplies by 8 int val = 1 << y_pix; /// We have to keep track of which pixels are on/off in order to // write the correct character out to the LCD. if (d){ pixels[x][y_mod] |= val; } else { pixels[x][y_mod] &= ~val; } // Write the updated pixel out to the LCD // TODO Check if the pixel is already in the state requested, // if so, don't write to LCD. gotoXY(x,y_mod); LcdWrite (1,pixels[x][y_mod]); } void drawLine(int x1, int y1, int x2, int y2) { } // Draw a horizontal line of width w from x,y void drawHorizontalLine(int x, int y, int w){ drawHorizontalLineXY(x,x+w,y); } // Draw a horizontal line between x1 and x2 at row y void drawHorizontalLineXY(int x1, int x2, int y){ for (int i=x1;i<=x2;i++) { setPixel(i,y,1); } } // Draw a vertical line of height h from x,y void drawVerticalLine(int x, int y, int h){ drawVerticalLineXY(y,y+h,x); } // Draw a vertical line from y1 to y2 on column x void drawVerticalLineXY(int y1, int y2, int x){ for (int i=y1;i<=y2;i++) { setPixel(x,i,1); } } void clearPixels() { for (int x=0;x<83;x++) { for(int y=0;y<47;y++) { pixels[x][y] = 0; } } } // Draw a rectangle of width w and height h from x,y void drawRect(int x, int y, int w, int h) { drawHorizontalLineXY(x,x+w,y); drawHorizontalLineXY(x,x+w,y+h); drawVerticalLineXY(y,y+h,x); drawVerticalLineXY(y,y+h,x+w); } void initProgressBar() { LcdClear(); clearPixels(); drawRect(10,21, 64, 5); } void setProgressBar(int value) { int startValue = ((float)prev_prog/100.0)*64; int newValue = ((float)value/100.0)*64; if (newValue < startValue) { startValue = 0; } int pb_x = 10; int pb_y = 21; for (int i=startValue;i<newValue;i++) { drawVerticalLine(pb_x+i,pb_y,5); } prev_prog = value; } // ******** ***** void setup(void) { LcdInitialise(); initProgressBar(); while (progress < 100) { progress++; setProgressBar(progress); delay(25); } LcdClear(); clearPixels(); } void loop(void) { // Muestra algunas animaciones sencillas de caracteres int a,b; char Str[20]; //15 { gotoXY(4,0); //gotoXY(4,1); // Poner el texto en el recuadro LcdString ("TestDisplay"); gotoXY(0,1); LcdString ("Este ejemplo"); gotoXY(0,2); LcdString ("LCDtest.pde"); gotoXY(0,3); LcdString ("funciona "); gotoXY(22,4); LcdString (" bien "); gotoXY(0,5); LcdString ("0123456789AB"); } } |
En este ejemplo, he añadido una barra de progreso que precede a unas palabras con el fin de rellenar la superficie de la pantalla.
Con la seguridad de que a usted le ha funcionado bien, doy por terminado este tutorial de inicio en la aventura de las LCDs. En caso de tener alguna consulta que hacer, no dude en plantearla en: admin(^aT^)hispavila(^dOt^)com.
Exención de responsabilidad:
Este es un software y hardware experimental. Úselo bajo su propio riesgo. El software y hardware presentado en estas páginas aunque ha sido probado por el mantenedor/desarrollador de estas paginas, no se hace responsable bajo ninguna circunstancia por los daños de hardware o software, pérdida de datos o cualquier otro daño directo o indirecto, como resultado del uso de este software o hardware. Ni del mal uso que usted haga con él.
Si usted no está de acuerdo con estas condiciones, no podrá utilizar o distribuir más este software o utilizar cualquiera plantillas para piezas para la construcción que aquí se presenta.
Muy interesantes todos los temas en su pagina.
Muy buena para aprender
Gracias
Hola Jesus Antonio.
Gracias por tus palabras.