Problemas extraños con LCD (compatible con HD44780)

He estado tratando de interactuar con una pantalla compatible con HD44780 (16x2) durante algunas horas, pero me he encontrado con algunos problemas de comportamiento extraños que no puedo resolver.

Mi configuración:

  • Estoy usando la pantalla LCD en modo de 4 bits (los cuatro bits superiores, D4-D7, como en todas las guías que he encontrado, el orden es correcto, lo he comprobado varias veces).
  • La pantalla LCD está funcionando con un suministro regulado de 5v. (He probado 3.3v, mismo resultado, menos contraste)
  • La línea R/W está conectada a tierra con una resistencia desplegable (fija en el modo de escritura).
  • El contraste lo establece un potenciómetro y puedo ver una línea de cuadrados al inicio.
  • Estoy usando tiempos muy lentos (~200ms esperar - habilitar alto - ~200ms - cambiar datos - ~200ms - habilitar bajo)

Mi secuencia de inicio:

(con RS bajo)

  • 0x03 - (tres veces) (enviado como un nibble/byte)
  • 0x02: habilitar el modo de cuatro bits (enviado como un nibble/byte)
  • 0x28 - Conjunto de funciones (2 líneas, 4 bits) (enviado como dos nibbles, ms nibble primero)
  • 0x01 - Clear (enviado como dos mordiscos)
  • 0x06: establece el modo de entrada (aumenta el cursor al escribir, no cambia la visualización) (se envía como dos nibbles)
  • 0x08 - Pantalla, cursor y parpadeo apagados (enviado como dos nibbles)
  • 0x0F - Pantalla, cursor y parpadeo (enviado como dos nibbles)

Aquí, algunas cosas no suceden como se esperaba:

  • El modo de dos líneas no parece habilitarse (no hay cuadrados de fondo oscuro en la segunda línea, no se escriben caracteres allí)
  • claro no pasa
  • El cursor está en el tercer cuadrado en lugar del primero al final de esta secuencia de inicio

A continuación intento escribir algunos caracteres con RS alto, enviando 2 nibbles por carácter.

Aquí también, tengo un comportamiento extraño: en lugar de escribir 1 carácter por 2 mordiscos, escribe 2 (uno por mordisco). Hice que pasara por los caracteres 0-15 y obtuve símbolos aleatorios (por ejemplo, barra oblicua) y caracteres japoneses. Todos ellos son de lugares aleatorios en la tabla de caracteres, principalmente la fila inferior, no en ningún orden normal, pero siempre se imprimen los mismos caracteres en el mismo orden.

Mi pregunta: Realmente me he quedado sin ideas para arreglar esto. ¿Me estoy perdiendo algo obvio? ¿Qué problemas podría tener y cómo puedo depurar más?

Editar: esto es lo que veo en mi pantalla después de iniciar, puede ser útilLCD después de inicializar

Edición 2:

Mi código principal:

GPIOPin lcdEnablePin = PIN_B(11);
GPIOPin lcdRSPin = PIN_B(10);
GPIOPin lcdDataPins[] = {PIN_E(2), PIN_E(3), PIN_E(4), PIN_E(5)};

//Set all pins as outputs
GPIO::pinModeDigital(lcdEnablePin, 1);
GPIO::pinModeDigital(lcdRSPin, 1);
for(int i = 0; i < 4; i++)
 GPIO::pinModeDigital(lcdDataPins[i], 1);

GPIO::writePinDigital(lcdRSPin, 0); //Instruction register
lcdSendData4(lcdEnablePin, lcdDataPins, 2); //Enable 4 bit
lcdSendData8(lcdEnablePin, lcdDataPins, 40); //Function set, 2 line
lcdSendData8(lcdEnablePin, lcdDataPins, 1); //Clear and return home
lcdSendData8(lcdEnablePin, lcdDataPins, 2); //Entry Mode, Increment cursor position, No display shift
lcdSendData8(lcdEnablePin, lcdDataPins, 8); //All off
lcdSendData8(lcdEnablePin, lcdDataPins, 15); //All on

GPIO::writePinDigital(lcdRSPin, 1); //Data register
for(int i = 0; i < 16; i++) //Write test data, 4 bit because that's what seemed to work
 lcdSendData4(lcdEnablePin, lcdDataPins, i);

Mis funciones SendData:

void lcdSendData4(GPIOPin lcdEnablePin, GPIOPin lcdDataPins[], char data)
{
 simpleBusy();

 //Set enable high
 GPIO::writePinDigital(lcdEnablePin, 1);

 simpleBusy();

 //Write data
 for(int i = 0; i < 4; i++)
  GPIO::writePinDigital(lcdDataPins[i], data & (1 << i));

 simpleBusy();

 //Falling edge
 GPIO::writePinDigital(lcdEnablePin, 0);
}

void lcdSendData8(GPIOPin lcdEnablePin, GPIOPin lcdDataPins[], char data)
{
 lcdSendData4(lcdEnablePin, lcdDataPins, data >> 4); //Send MSB
 lcdSendData4(lcdEnablePin, lcdDataPins, data); //Send LSB
}
¿Tienes una espera suficientemente larga antes de empezar a escribir? ¿Y qué valor tiene la resistencia "pull down"?
¿Seguiste el tiempo en la hoja de datos?
Sphero: La resistencia es de 1k
Ignacio: No tengo una hoja de datos para mi LCD en particular, pero los retrasos que estoy usando están muy por encima de los tiempos máximos especificados en la hoja de datos HD44780. Como dije en la pregunta, paso alrededor de ~ 200 ms con habilitar alto, ~ 200 ms mientras se escriben los datos y ~ 200 ms después del borde descendente de la habilitación.
¿Está seguro de que los primeros tres 0x03 no habilitan el modo de 8 bits? En la hoja de datos parece haber cierta ambigüedad entre las páginas 42 y 46.
Esta hoja de datos tiene un buen diagrama de flujo en la página 14 (etiquetado como 12), y dice que solo se necesita 0x02 0x02 0x08.
También probé sin los 0x03 y lamentablemente no hizo ninguna diferencia. He leído que el modo solo se puede configurar una vez, pero también he leído que esta secuencia de 0x03 es un "restablecimiento completo" especial. También intenté cortar físicamente la energía a la pantalla, luego volver a conectarla y esperar un poco antes de comenzar la secuencia de inicio, para asegurarme de que la primera instrucción que recibe es el modo de 4 bits establecido, tampoco ayudó. Gracias a todos por sus sugerencias hasta ahora.
He agregado una imagen para mostrar lo que sucede después de que finaliza init. La salida siempre es exactamente así.
Los personajes no son aleatorios en absoluto. Todos tienen cuatro bits inferiores en 1 1 1 1. Diría que está en modo de 8 bits y el nibble inferior se detecta desde el aire. Intente tocar los pads D[0..3] con el dedo y vea si los caracteres cambian.
¡Al fin algo funcionó! Intenté conectar a tierra uno de los pines de datos adicionales y todos los caracteres cambiaron. :) Lo interesante es que el orden no es exactamente el mismo que en el mapa de caracteres. Así que ahora la pregunta es, ¿cómo me aseguro de entrar en el modo de 4 bits?
Tal vez podría agregar su código fuente, podría haber algún problema con el tiempo y el formato de los datos
Agregué fuente. También mirando esta página intenté agregar un menú desplegable de 10k en habilitar para evitar que se active accidentalmente, no ayudó. Mañana intentaré volver a soldar todas las conexiones, por si acaso.
Hombre, no puedo encontrar palabras para describir lo tonto que me siento en este momento. Miré mis conexiones una vez más y noté que D6 y D5 se intercambiaron al pasar de mi tablero a la pantalla LCD. Ahora todo funciona bien. Gracias a todos por sus sugerencias, perdón por la confusión. Venny: debe agregar su reconocimiento de los caracteres que tienen el mismo mordisco superior como respuesta para que yo lo acepte.

Respuestas (4)

En algunos modelos, debe enviar los comandos de configuración inicial varias veces. Además, algunos modelos que tengo consumen energía de manera agresiva y pulsada, así que tenga un condensador grande cerca de la fuente de alimentación (+ -) de la pantalla LCD para evitar el ruido del riel de alimentación.

No has mencionado la línea E hasta ahora.

E debe ser bajo, luego presentar datos, configurar E alto y luego bajo, etc.

Bienvenido al foro! Y sí, lo hizo. Está en la quinta viñeta (línea 11).
Sí, como se menciona en la pregunta, eso es lo que hago, con retrasos de 200 ms entre cada paso.

¿Ha permitido los retrasos necesarios para la inicialización? La hoja de datos dice que debe esperar más de 4,1 ms después de enviar el primer 0x3.

Bienvenido a EE.SE. Somos un tipo de sitio de preguntas y respuestas en lugar de un foro. Ha publicado una respuesta que sería más adecuada como comentario a la pregunta. En el futuro, trate de tener en cuenta que las respuestas son para una asistencia más grande y más involucrada.
@Funkyguy IIRC StackExchange no permite que los usuarios con menos de 15 puntos de representación comenten, solo respondan. Chamod probablemente hizo todo lo que el sitio le permitió en ese momento. (eso no fue hace mucho tiempo en mi caso :)

Una vez obtuve una pantalla con un comportamiento similar. Necesitaba configurarlo en modo de 8 bits tres veces y una vez más configurarlo en modo de 4 bits para llevarlo "realmente" al modo de 4 bits. Esta fue la única forma en que conseguí que funcionara en modo de 4 bits. Tal vez esto ayude.

Cuando la pantalla está en el modo de 4 bits, lo único que distingue entre la mitad superior e inferior de cada transacción es si ha habido un número par o impar de transacciones desde que la pantalla se cambió al modo de 4 bits. Cambiar a 8 bits y luego regresar permite que el software y la pantalla se sincronicen entre sí.