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.
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);
}
}
}
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!
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.
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);
}
}
}
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!
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!
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?
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.
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.
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?
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 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
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,
JeffLCD issues.jpg272.23KB77 downloads