Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

SparkFun SerLCD class


  • Please log in to reply
25 replies to this topic

#1 Niels R.

Niels R.

    Member

  • Members
  • PipPip
  • 28 posts

Posted 17 August 2010 - 06:24 PM

Hey,

I've quickly written a simple class to use these LCD's using NETMF. I'm using the SerLCD from SparkFun (both 2x16 and 4x20) for a small project.

Be aware that this is a quick implementation to get me started real quick. Not everything is tested and there is probably a lot of code improvement possible. I hope this might be a starting point for some people.

Please don't start bashing my coding style and please... post improvements and corrections!

Kind regards,
Niels R.

using System;
using System.IO.Ports;

namespace LXIT.Hardware
{
    public sealed class SerLCD
    {
        public enum Direction { Left, Right }

        public enum DisplayType { C16L2, C16L4, C20L2, C20L4 }

        public enum Status { On, Off }


        private readonly SerialPort _serialPort;

        private readonly DisplayType _displayType;


        public SerLCD(string portName) : this(portName, DisplayType.C16L2)
        {}

        public SerLCD(string portName, DisplayType displayType)
        {
            // Defaults for SerialPort are the same as the settings for the LCD, but I'll set them explicitly
            _serialPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);

            _displayType = displayType;
        }

        public void ClearDisplay()
        {
            Write(new byte[] { 0xFE, 0x01 });
        }

        public void MoveCursor(Direction direction)
        {
            MoveCursor(direction, 1);
        }

        public void MoveCursor(Direction direction, int times)
        {
            byte command;

            switch (direction)
            {
                case Direction.Left: command = 0x10; break;
                case Direction.Right: command = 0x14; break;
                default: return;
            }

            for (int i = 0; i < times; i++)
            {
                Write(new byte[] { 0xFE, command });
            }
        }

        public void Open()
        {
            if (!_serialPort.IsOpen)
                _serialPort.Open();
        }

        public void SaveAsSplashScreen()
        {
            Write(new byte[] { 0x7C, 0x0A });
        }

        public void Scroll(Direction direction)
        {
            Scroll(direction, 1);
        }

        public void Scroll(Direction direction, int times)
        {
            byte command;

            switch (direction)
            {
                case Direction.Left: command = 0x18; break;
                case Direction.Right: command = 0x1C; break;
                default: return;
            }

            for (int i = 0; i < times; i++)
            {
                Write(new byte[] { 0xFE, command });
            }
        }

        public void SetBlinkingBoxCursor(Status status)
        {
            byte command;

            switch (status)
            {
                case Status.On: command = 0x0D; break;
                case Status.Off: command = 0x0C; break;
                default: return;
            }

            Write(new byte[] { 0xFE, command });
        }

        public void SetBrightness(int brightness)
        {
            if (brightness < 128 || brightness > 157)
                throw new ArgumentOutOfRangeException("brightness", "Value of brightness must be between 128-157.");

            Write(new byte[] { 0x7C, (byte)brightness });
        }

        public void SetCursorPosition(int line, int column)
        {
            if ((_displayType == DisplayType.C16L2 || _displayType == DisplayType.C16L4) && (column < 1 || column > 16))
                throw new ArgumentOutOfRangeException("column", "Column number must be between 1 and 16.");

            if ((_displayType == DisplayType.C20L2 || _displayType == DisplayType.C20L4) && (column < 1 || column > 20))
                throw new ArgumentOutOfRangeException("column", "Column number must be between 1 and 20.");

            if ((_displayType == DisplayType.C16L2 || _displayType == DisplayType.C20L2) && (line < 1 || line > 2))
                throw new ArgumentOutOfRangeException("line", "Line number must be 1 or 2.");

            if ((_displayType == DisplayType.C16L4 || _displayType == DisplayType.C20L4) && (line < 1 || line > 4))
                throw new ArgumentOutOfRangeException("line", "Line number must be between 1 and 4.");

            int[] startPos16 = { 0, 64, 16, 80 };
            int[] startPos20 = { 0, 64, 20, 84 };
            int charPos;

            switch (_displayType)
            {
                case DisplayType.C16L2:
                case DisplayType.C16L4:
                    charPos = startPos16[line - 1] + (column - 1);
                    break;
                case DisplayType.C20L2:
                case DisplayType.C20L4:
                    charPos = startPos20[line - 1] + (column - 1);
                    break;
                default:
                    return;
            }

            Write(new byte[] { 0xFE, (byte)(charPos + 0x80) });
        }

        public void SetDisplay(Status status)
        {
            byte command;

            switch (status)
            {
                case Status.On: command = 0x0C; break;
                case Status.Off: command = 0x08; break;
                default: return;
            }

            Write(new byte[] { 0xFE, command });
        }

        public void SetDisplayType(DisplayType displayType)
        {
            switch (displayType)
            {
                case DisplayType.C16L2:
                    Write(new byte[]{0x7C, 0x04}); // 16 characters
                    Write(new byte[]{0x7C, 0x06}); // 2 lines
                    break;
                case DisplayType.C16L4:
                    Write(new byte[]{0x7C, 0x04}); // 16 characters
                    Write(new byte[]{0x7C, 0x05}); // 4 lines
                    break;
                case DisplayType.C20L2:
                    Write(new byte[]{0x7C, 0x03}); // 20 characters
                    Write(new byte[]{0x7C, 0x06}); // 2 lines
                    break;
                case DisplayType.C20L4:
                    Write(new byte[]{0x7C, 0x03}); // 20 characters
                    Write(new byte[]{0x7C, 0x05}); // 4 lines
                    break;
            }
        }

        public void SetUnderlineCursor(Status status)
        {
            byte command;

            switch (status)
            {
                case Status.On: command = 0x0E; break;
                case Status.Off: command = 0x0C; break;
                default: return;
            }

            Write(new byte[] { 0xFE, command });
        }

        public void ToggleSplashScreen()
        {
            Write(new byte[] { 0x7C, 0x09 });
        }

        public void Write(byte buffer)
        {
            Write(new[] { buffer });
        }

        public void Write(byte[] buffer)
        {
            Open();

            _serialPort.Write(buffer, 0, buffer.Length);
        }

        public void Write(char character)
        {
            Write((byte)character);
        }

        public void Write(string text)
        {
            byte[] buffer = new byte[text.Length];

            for (int i = 0; i < text.Length; i++)
            {
                buffer[i] = (byte)text[i];
            }

            Write(buffer);
        }
    }
}


#2 Charles

Charles

    Advanced Member

  • Members
  • PipPipPip
  • 192 posts

Posted 08 October 2010 - 12:08 AM

Thanks for you contribution! I will probably be using something like this eventually and I really appreciate having this example to start with! Thanks again!

#3 Niels R.

Niels R.

    Member

  • Members
  • PipPip
  • 28 posts

Posted 11 October 2010 - 09:16 AM

Thanks for you contribution! I will probably be using something like this eventually and I really appreciate having this example to start with!

Thanks again!

I hope you can use it. It definitely can use some optimization, but I think it's a quick and easy start.

I'm refactoring the class later, so you might want to check for a new version in a few weeks.

Cheers,
Niels

#4 Marius

Marius

    Advanced Member

  • Members
  • PipPipPip
  • 59 posts
  • LocationCenturion RSA

Posted 23 October 2010 - 05:43 AM

Hi Niels, I am also a newby to this environment. I have not programmed for about 10 years and I have not used C#. So a big learning curve for me. Do you have some example code of how you implemented this class?
If at first you don't succeed, then try and try again.

#5 Niels R.

Niels R.

    Member

  • Members
  • PipPip
  • 28 posts

Posted 23 October 2010 - 10:07 AM

Hey Marius, I'll prep you a sample project but you'll have to wait until Monday. I'm not around my PC this weekend. Kind regards, Niels R.

#6 Marius

Marius

    Advanced Member

  • Members
  • PipPipPip
  • 59 posts
  • LocationCenturion RSA

Posted 23 October 2010 - 09:26 PM

Thanks Niels, I will check on Monday.
If at first you don't succeed, then try and try again.

#7 Niels R.

Niels R.

    Member

  • Members
  • PipPip
  • 28 posts

Posted 25 October 2010 - 10:29 AM

A simple Program class that creates a SerLCD instance (default size = 16x2) on COM1 and writes some stuff to it:

The "largeLcd" instance isn't used, it's just an example of instantiating another size of SerLCD.

using System.Threading;
using SecretLabs.NETMF.Hardware.Netduino;

namespace SerLcdExample
{
    public class Program
    {
        public static void Main()
        {
            // Create instance for a SparkFun SerLCD 16x2
            SerLCD smallLcd = new SerLCD(SerialPorts.COM1);

            // Create instance for a SparkFun SerLCD 20x4 - Not being used...
            SerLCD largeLcd = new SerLCD(SerialPorts.COM2, SerLCD.DisplayType.C20L4);

            // Now start playing with these LCD's
            smallLcd.ClearDisplay();
            smallLcd.SetCursorPosition(1, 6);
            smallLcd.Write("Hello");
            smallLcd.SetCursorPosition(2, 6);
            smallLcd.Write("World!");

            // Wait 2 seconds
            Thread.Sleep(2000);

            // Clear screen
            smallLcd.ClearDisplay();
            smallLcd.Write("Goodbye World...");

            // Wait 2 seconds
            Thread.Sleep(2000);

            // Turn the LCD off
            smallLcd.SetDisplay(SerLCD.Status.Off);

            // Wait 2 seconds
            Thread.Sleep(2000);

            // Turn the LCD back on
            smallLcd.SetDisplay(SerLCD.Status.On);
        }
    }
}


#8 Dezorian

Dezorian

    Member

  • Members
  • PipPip
  • 24 posts

Posted 20 January 2011 - 08:02 PM

Awesome library! Worked out of the box :) I found 2 other libraries that didn't work or weren't transparent or well coded. This is a very good base to work with. Well done! I'll post my version of the library when i have added features that I needed. Thanks for posting this to the forum!

#9 Dezorian

Dezorian

    Member

  • Members
  • PipPip
  • 24 posts

Posted 21 January 2011 - 03:21 PM

[edited to prevent this from being à double post]

I've added some comments and a Drawlines(string[] lines) method and will post my additions to the library when its finished.

Thanks again!

MODERATOR NOTE: Sorry for the delay approving your post. We've been getting a lot of spambots recently so we're temporarily approving first user posts. Also, welcome to the Netduino community!

#10 Carsten Dressler

Carsten Dressler

    Member

  • Members
  • PipPip
  • 20 posts

Posted 22 January 2011 - 03:40 AM

Did you have problems with the LCD printing garbage when the Netduino is powered up? I have my screen connected GND -> GND, + -> 3.3V, PX -> DIGITAL 2. When I power on the Netduino (both USB/Ext Power), the screen prints junk. If I unplug the PX connection, wait a couple seconds after power up, then plug the PX in; then it prints fine. Any idea?

#11 Dezorian

Dezorian

    Member

  • Members
  • PipPip
  • 24 posts

Posted 22 January 2011 - 10:04 AM

Did you have problems with the LCD printing garbage when the Netduino is powered up?

I have my screen connected GND -> GND, + -> 3.3V, PX -> DIGITAL 2.

When I power on the Netduino (both USB/Ext Power), the screen prints junk. If I unplug the PX connection, wait a couple seconds after power up, then plug the PX in; then it prints fine.

Any idea?


By Digital 2 i hope you mean D1? D1 and D3 are the TX pins. So you should connect the display to that. When my netduin starts with the display, you get to see "Sparkfun Display version xxx" or something like that,
Then my display would show a full screen of double pipes (||). But anyway, When I start the main thread and initialize the LCD display, ails do a clear screen to solve that problem.

Hope this will solve yours as well.

#12 Carsten Dressler

Carsten Dressler

    Member

  • Members
  • PipPip
  • 20 posts

Posted 22 January 2011 - 05:28 PM

Yes you are right. I meant Digital Pin 1. Forgot they started with 0 :S I am basically using the code from above. But it prints junk. Unless I unplug the PX during power up of the unit.

#13 Dezorian

Dezorian

    Member

  • Members
  • PipPip
  • 24 posts

Posted 23 January 2011 - 09:28 AM

Yes you are right. I meant Digital Pin 1. Forgot they started with 0 :S

I am basically using the code from above. But it prints junk. Unless I unplug the PX during power up of the unit.


Have you set the display type correctly? If you use the constructor with only the port property it will set the default display type. Maybe that's why you're getting that? Otherwise it seems like in the start section of your thread something is going wrong?

#14 Carsten Dressler

Carsten Dressler

    Member

  • Members
  • PipPip
  • 20 posts

Posted 24 January 2011 - 12:31 AM

Have you set the display type correctly? If you use the constructor with only the port property it will set the default display type. Maybe that's why you're getting that? Otherwise it seems like in the start section of your thread something is going wrong?


I just tried that and it didnt work either.

I am trying this SerLCD class on a Netduino Plus. Was thinking that its maybe the N+ causing the issue so I uploaded a test program on the regular Netduino but I got the same results.

When I first got the LCD it worked fine. Then I was building a enclosure for it, maybe I damanged it during the fitting process. I ordered another LCD, hopefully this one will work.

I will post the results.

Carsten

#15 Carsten Dressler

Carsten Dressler

    Member

  • Members
  • PipPip
  • 20 posts

Posted 27 January 2011 - 04:09 AM

I just wanted to point out that it was a bad LCD Module that I had. I got a new one and it works flawlessly. Thanks for all the suggestions. Carsten

#16 Dezorian

Dezorian

    Member

  • Members
  • PipPip
  • 24 posts

Posted 27 January 2011 - 09:46 AM

Thanks for the feedback! Saves us a lot of trouble when encountering the same issues. B)

#17 John Feeney

John Feeney

    Advanced Member

  • Members
  • PipPipPip
  • 55 posts
  • LocationAuburn, ON, Canada

Posted 03 July 2011 - 01:36 AM

I have a Netduino Plus I am getting an error that it does not recognize the word SerialPort The type or namesspace name 'SerialPort' could not be found (are you missing a using directive or an assembly reference) Here is the code down to the error using System; using System.IO.Ports; using Microsoft.SPOT.Hardware; using Microsoft.SPOT.IO; namespace npaTmp102 { class SerLCD { public enum Direction { Left, Right } public enum DisplayType { C16L2, C16L4, C20L2, C20L4 } public enum Status { On, Off } private readonly SerialPort _serialPort; As well as adding using System.IO.Ports -- do I also need to add something to my reference file? Thanks, John

#18 John Feeney

John Feeney

    Advanced Member

  • Members
  • PipPipPip
  • 55 posts
  • LocationAuburn, ON, Canada

Posted 03 July 2011 - 01:39 AM

As well as adding using System.IO.Ports -- do I also need to add something to my reference file?

Thanks, John


I found it about couple minutes later... I need to add the reference Microsoft.SPOT.Hardware.SerialPort

Thanks

#19 ItsDan

ItsDan

    Advanced Member

  • Members
  • PipPipPip
  • 101 posts

Posted 04 July 2011 - 01:25 PM

Nice, I have the LCD but of course the sample code all uses built in routines for the Arduino and provides no useful help.
Follow the adventures of the Box of Crappy Surplus

Total BOCS Traveled Distance: 9708 miles | States Visited: 5
Track the Box

#20 Jeffffff

Jeffffff

    New Member

  • Members
  • Pip
  • 2 posts

Posted 15 January 2012 - 02:09 AM

Hi, I am new to the Netduino and have just ordered the LCD that you recommended from sparkfun. I am trying get the code ready to use for when it arrives. I also am a newbie to the C# programing language. I have tried creating the class and the program from your examples. I am getting quite a few erros and I dont know how to correct them. Could you give some pointers on this? Atached is a screen shot of the errors when I try to build the solution. Thanks, JeffAttached File  LCD issues.jpg   272.23KB   77 downloads




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.