Main Site Documentation

HD44780 strange behaviour on FEZ Cerbuino Bee


#1

Hi,

I attached the HD44780 (with display) to my Cerbuino Bee… Writing Hello World
to the display
void ProgramStarted()
{
Debug.Print(“Program Started”);
led7r.Animate(200, true, true, true);
LCD.Clear();
LCD.PrintString(“Hello WORLD”);
}
gives some odd chacarcters (see image)

(i tried on all three connectors \ the Display works fine m my Spider)

any ideas ?

bert


#2

I think cerbuino is too fast for the display. This is good news!

We will update the driver with some delays.


#3

What is the firmware version on your board?


#4

@ Gus - @ Steven
Would the Cerberun not have the same problem (speed)> I thought the innerworks of cerberus and Cerbuino-bee are the same…
i put the latest firmwart on both (the same "Tinybooter 4.2.0.1 " LCD has problems on the bee, not on the cerberus


#5

They should be identical. Have you tried a different socket?


#6

@ Gus -
yes all 3 of them…


#7

I am having this same issue on the Cerbuino bee on the current firmware.
has this bee fixed?
i have tried all three sockets.


#8

I think a little delay is needed


#9

Will you be updating the driver to do this soon?
or where do you think the delay needs to be?


#10

@ Gus you are right. i added 1 ms sleeps between each write in the Putc and the SendCmd functions and it works like a champ


#11

Can you try to sleep 0?
Thread.Sleep(0);


#12

it works with Thread.Sleep(0); also


#13

Can you please post your code showing where you added the delay? We are nto able to repro this on our end.


#14

Putc and SendCmd is where i added the delays

using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;

using System.Threading;

namespace Gadgeteer.Modules.GHIElectronics
{
    /// <summary>
    /// A simple character display module for Microsoft .NET Gadgeteer
    /// </summary>
    /// <example>
    /// <para>The following example uses a <see cref="Display_HD44780"/> object to display "Hello World" on the character display. 
    /// First, we clear the screen and set the cursor to the top left corner.
    /// Then, we display our desired text to the screen.
    /// </para>
    /// <code>
    /// using System;
    /// using System.Collections;
    /// using System.Threading;
    /// using Microsoft.SPOT;
    /// using Microsoft.SPOT.Presentation;
    /// using Microsoft.SPOT.Presentation.Controls;
    /// using Microsoft.SPOT.Presentation.Media;
    /// using Microsoft.SPOT.Touch;
    ///
    /// using Gadgeteer.Networking;
    /// using GT = Gadgeteer;
    /// using GTM = Gadgeteer.Modules;
    /// using Gadgeteer.Modules.GHIElectronics;
    ///
    /// namespace TestApp
    /// {
    ///     public partial class Program
    ///     {
    ///         void ProgramStarted()
    ///         {
    ///             display_HD44780.Clear();
    ///             display_HD44780.CursorHome();
    ///
    ///             display_HD44780.PrintString("Hello World");
    ///
    ///             Debug.Print("Program Started");
    ///         }
    ///     }
    /// }
    /// </code>
    /// </example>
    public class Display_HD44780 : GTM.Module
    {
        private GT.Interfaces.DigitalOutput LCD_RS;
        private GT.Interfaces.DigitalOutput LCD_E;

        private GT.Interfaces.DigitalOutput LCD_D4;
        private GT.Interfaces.DigitalOutput LCD_D5;
        private GT.Interfaces.DigitalOutput LCD_D6;
        private GT.Interfaces.DigitalOutput LCD_D7;

        private GT.Interfaces.DigitalOutput BackLight;

        const byte DISP_ON = 0xC;    //Turn visible LCD on
        const byte CLR_DISP = 1;      //Clear display
        const byte CUR_HOME = 2;      //Move cursor home and clear screen memory
        const byte SET_CURSOR = 0x80;   //SET_CURSOR + X : Sets cursor position to X

        // Note: A constructor summary is auto-generated by the doc builder.
        /// <summary></summary>
        /// <param name="socketNumber">The socket that this module is plugged in to.</param>
        public Display_HD44780(int socketNumber)
        {
            // This finds the Socket instance from the user-specified socket number.  
            // This will generate user-friendly error messages if the socket is invalid.
            // If there is more than one socket on this module, then instead of "null" for the last parameter, 
            // put text that identifies the socket to the user (e.g. "S" if there is a socket type S)
            Socket socket = Socket.GetSocket(socketNumber, true, this, null);
            socket.EnsureTypeIsSupported('Y', this);

            LCD_RS = new GT.Interfaces.DigitalOutput(socket, GT.Socket.Pin.Four, false, null);
            LCD_E = new GT.Interfaces.DigitalOutput(socket, GT.Socket.Pin.Three, false, null);
            LCD_D4 = new GT.Interfaces.DigitalOutput(socket, GT.Socket.Pin.Five, false, null);
            LCD_D5 = new GT.Interfaces.DigitalOutput(socket, GT.Socket.Pin.Seven, false, null);
            LCD_D6 = new GT.Interfaces.DigitalOutput(socket, GT.Socket.Pin.Nine, false, null);
            LCD_D7 = new GT.Interfaces.DigitalOutput(socket, GT.Socket.Pin.Six, false, null);

            BackLight = new GT.Interfaces.DigitalOutput(socket, GT.Socket.Pin.Eight, true, null);

            Initialize();
        }

        /// <summary>
        /// This function will enable the display, clean it, and enter 4-bit mode.
        /// </summary>
        public void Initialize()
        {
            LCD_RS.Write(false);

            // 4 bit data communication
            Thread.Sleep(50);

            LCD_D7.Write(false);
            LCD_D6.Write(false);
            LCD_D5.Write(true);
            LCD_D4.Write(true);

            LCD_E.Write(true);
            LCD_E.Write(false);

            Thread.Sleep(50);

            LCD_D7.Write(false);
            LCD_D6.Write(false);
            LCD_D5.Write(true);
            LCD_D4.Write(true);

            LCD_E.Write(true);
            LCD_E.Write(false);

            Thread.Sleep(50);

            LCD_D7.Write(false);
            LCD_D6.Write(false);
            LCD_D5.Write(true);
            LCD_D4.Write(true);

            LCD_E.Write(true);
            LCD_E.Write(false);

            Thread.Sleep(50);

            LCD_D7.Write(false);
            LCD_D6.Write(false);
            LCD_D5.Write(true);
            LCD_D4.Write(false);

            LCD_E.Write(true);
            LCD_E.Write(false);

            SendCmd(DISP_ON);
            SendCmd(CLR_DISP);
        }

        ///<summary>
        /// Sends an LCD command.
        /// </summary>
        private void SendCmd(byte c)
        {
            LCD_RS.Write(false); //set LCD to data mode

            LCD_D7.Write((c & 0x80) != 0); Thread.Sleep(0);
            LCD_D6.Write((c & 0x40) != 0); Thread.Sleep(0);
            LCD_D5.Write((c & 0x20) != 0); Thread.Sleep(0);
            LCD_D4.Write((c & 0x10) != 0); Thread.Sleep(0);
            LCD_E.Write(true); Thread.Sleep(0); LCD_E.Write(false); //Toggle the Enable Pin
            Thread.Sleep(0);
            LCD_D7.Write((c & 0x08) != 0); Thread.Sleep(0);
            LCD_D6.Write((c & 0x04) != 0); Thread.Sleep(0);
            LCD_D5.Write((c & 0x02) != 0); Thread.Sleep(0);
            LCD_D4.Write((c & 0x01) != 0); Thread.Sleep(0);
            LCD_E.Write(true); Thread.Sleep(0); LCD_E.Write(false); //Toggle the Enable Pin

            Thread.Sleep(1);

            LCD_RS.Write(true); //set LCD to data mode
        }

        /// <summary>
        /// Prints the passed in string to the screen at the current cursor position. Note: This function will move the cursor position after.
        /// </summary>
        /// <param name="str">The string to print.</param>
        public void PrintString(string str)
        {
            for (int i = 0; i < str.Length; i++)
                Putc((byte)str[i]);
        }

        /// <summary>
        /// Sends an ASCII character to the LCD at the current cursor position. Note: This function will move the cursor position after.
        /// </summary>
        /// <param name="c">The character to display.</param>
        public void Putc(byte c)
        {
            LCD_D7.Write((c & 0x80) != 0);
            Thread.Sleep(0);
            LCD_D6.Write((c & 0x40) != 0);
            Thread.Sleep(0);
            LCD_D5.Write((c & 0x20) != 0);
            Thread.Sleep(0);
            LCD_D4.Write((c & 0x10) != 0);
            Thread.Sleep(0);
            LCD_E.Write(true);
            Thread.Sleep(0); 
            LCD_E.Write(false); //Toggle the Enable Pin
            Thread.Sleep(0);
            LCD_D7.Write((c & 0x08) != 0); Thread.Sleep(0);
            LCD_D6.Write((c & 0x04) != 0); Thread.Sleep(0);
            LCD_D5.Write((c & 0x02) != 0); Thread.Sleep(0);
            LCD_D4.Write((c & 0x01) != 0); Thread.Sleep(0);
            LCD_E.Write(true); Thread.Sleep(0); LCD_E.Write(false); //Toggle the Enable Pin
            Thread.Sleep(0);
        }

        /// <summary>
        /// Clears the screen.
        /// </summary>
        public void Clear()
        {
            SendCmd(CLR_DISP);
        }

        /// <summary>
        /// Places the cursor at the top left of the screen.
        /// </summary>
        public void CursorHome()
        {
            SendCmd(CUR_HOME);
        }

        /// <summary>
        /// Set the cursor to the passed in position.
        /// </summary>
        /// <param name="row">Row of the desired cursor position.</param>
        /// <param name="col">Column of the desired cursor position.</param>
        public virtual void SetCursor(byte row, byte col)
        {
            byte[] row_offsets = new byte[4] { 0x00, 0x40, 0x14, 0x54 };
            SendCmd((byte)(SET_CURSOR | row_offsets[row] | col));
        }

        ///// <summary>
        ///// Turns the backlight on.
        ///// </summary>
        //public void TurnBacklightOn()
        //{
        //    BackLight.Write(true);
        //}

        ///// <summary>
        ///// Turns the backlight off.
        ///// </summary>
        //public void ShutBacklightOff()
        //{
        //    BackLight.Write(false);
        //}

        /// <summary>
        /// Sets the module's backlight to the passed in value.
        /// </summary>
        /// <param name="bOn">True for backlight enabled, false for disabled.</param>
        public void SetBacklight(bool bOn)
        {
            BackLight.Write(bOn);
        }
    }
}



#15

Hello,
Would it be possible to have a plan to connect the LCD to the board ?
I started with Cerbuino.
thank you.


#16

@ Matheo1010 - what do you mean?

Welcome to the community