.NET Micro Framework includes reach graphics capabilities with WPF-like libraries, and quite a few high end development boards (Tahoe II, ChipworkX, or FEZ Cobra to name a few) include fancy graphic TFT screens, often with touch input thrown in as well. But this comes at a significantly higher costs, and requires a speedy CPU. Thus it might seem that if you are using a much cheaper board such as Netduino or one of FEZ family, you are doomed to rely on blinking LEDs only. Not quite so. In most scenarios an alphanumeric LCD might be a cheap alternative (or if you have higher budget you might consider using an OLED screen that also works with Netduino).
For a larger project I’m working on I plan to use an alphanumeric LCD to display all sorts of status information. Practically all popular LCDs are controlled by a HD44780 compatible parallel interface chipset. There is wide range of these screens available in various combinations of backlight and text color. The common size is 16x2 characters (16 columns in 2 rows). Take a look at the wide selection of LCDs available from SparkFun. I got mine from local electronics store that has very cool looking combination white text on blue background.
When you buy the LCD take notice if you get the 5V or 3V3 version. I’m sure both work fine with Netduino (which uses 3V3 logic) but make sure to wire them to correct power source pin.
These LCDs are quite easy to wire and program. If you look at the above picture notice the 16pin header on top of the display. The HD44780 chipset uses parallel interface for data communication and supports 8bit and 4bit modes. In the former case it will use at least 10 digital output pins from the microcontroller, in the later at least 6. The R/W pin (read write) bit can be permanently wired to ground. You can find the wiring instructions in the examples for the Arduino Liquid Crystal library – it will work the same way on the Netduino. To avoid soldering you can also try to use the DFRobot LCD Keypad Shield for Arduino, and I learned via twitter that Mr. Kogoro Kotobuki (@kotobuki), is designing a similar LCD shield that appears to work great with Netduino. I was told it’s a prototype and not yet sold, but it looks very nice (see one more photo and the schematics).
However if we take the direct approach, the LCD will use at least six of available digital pins. If you use a microcontroller that exposes a massive number of IO ports (like FEZ Rhino or upcoming FEZ Panda) this might be okay, but in case of Netduino or similar board that has only a handful of digital pins this might be not suitable. In this case you might want to multiplex the output over fewer lines. In my previous post I already talked about using shift registers to work around such situation and in this case we can reduce the number of outputs to only three.
Another alternative could be to buy a Serial Enabled LCD. Usually they include as special daughter board on the back (hence called a “backpack”) that has a MCU responsible for translating the UART communication to the interface of the LCD. So if you can sacrifice one of the UART ports on the Netduino this might be a good option, but they usually cost about $10 more than regular LCDs. You can also buy the serial backpack alone, for example the one from Sparkfun or the LCD117 Serial LCD Kit from Modern Devices.
For my project I will be using the same 74HC595 shift register that I used in my earlier demo. Pavel Bánský already demonstrated how to do this on .NET Micro Framework devices. In his first post he shows how to interface LCD with 3 wires using the 4094 shift register, and then in the second post he added support for an I2C 8-bit port extender. I have modified and extended his library to include functionality available in the Arduino LiquidCrystal library.
Pavel introduced a nice abstraction in his implementation to separate the LCD high level functions from underlying transport interface into separate classes. Thus the constructor of top level class LiquidCrystal requires you to provide an instance of a class implementing the ILiquidCrystalTransferProvider interface. This enables to use this library with all the methods of communication described above. In the source code you will already find an GpioLiquidCrystalTransferProvider and Shifter74Hc595LiquidCrystalTransferProvider for the 74HC595 shift register. Later I’m going to add support for the I2C port expander. I got a nice LCD backpack from JeeLabs shop that uses the MCP23008 chip but I don’t know yet how much different it is from Pavel’s PCF8574P. In preparation for this some common bit handling code is already abstracted in the BaseShifterLiquidCrystalTransferProvicer class.
Here you can see the wiring I used:
Notice that because this time I’m going to use SPI interface the serial data is connected to pin 11 (MOSI) and pin clock is connected to pin 13 (SPCK). Pin 10 is connected to the latch pin, and in the code it is passed as Slave Select pin to the SPIConfiguration object. Since we are going to use seven outputs from the shift register the one remaining output is connected via 2N2222A transistor to control the LCD backlight. This allows us to turn the backlight on or off from code. Finally the 10K potentiometer is used to control the display contrast.
Photo on the right shows the backpack I created for my LCD (I’ll cut the board later along the marked lines). Notice that because the board will be mounted “upside down” the outputs from the shift register to LCD are reversed, but it’s easy to correct it in the code (Shifter74Hc595LiquidCrystalTransferProvider constructor has the optional BitOrder option).
Below you can find a list of methods exposed by the LiquidCrystal class:
- Begin(columns, lines) - Use this method to initialize the LCD. Specifies the dimensions (width and height) of the display.
- Clear() - Clears the LCD screen and positions the cursor in the upper-left corner.
- Home() - Positions the cursor in the upper-left of the LCD.
- SetCursorPosition(column, row) - Position the LCD cursor; that is, set the location at which subsequent text written to the LCD will be displayed.
- ScrollDisplayLeft() - Scrolls the contents of the display (text and cursor) one space to the left.
- ScrollDisplayRight() - Scrolls the contents of the display (text and cursor) one space to the right.
- Write(text) - Writes a text to the LCD.
- Write(buffer, offset, count) - Writes a specified number of bytes to the display using data from a buffer.
- WriteByte(data) - Sends one data byte to the display.
- CreateChar(location, charmap)
And its properties:
- Backlight - Turns the LCD backlight on or off.
- BlinkCursor - Display or hide the blinking block cursor at the position to which the next character will be written.
- ShowCursor - Display or hide the LCD cursor: an underscore (line) at the position to which the next character will be written.
- Visible - Turns the LCD display on or off. This will restore the text (and cursor) that was on the display.
- Encoding - Get or set the encoding used to map the string into bytes codes that are sent LCD. UTF8 is used by default.
Finally let’s look at the sample code. Here is a simple “hello world” demo:
public static void Main()
// create the transfer provider
var lcdProvider = new Shifter74Hc595LiquidCrystalTransferProvider(SPI_Devices.SPI1,
// create the LCD interface
var lcd = new LiquidCrystal(lcdProvider);
// set up the LCD's number of columns and rows:
// Print a message to the LCD.
// set the cursor to column 0, line 1
// print the number of seconds since reset:
lcd.Write((Utility.GetMachineTime().Ticks / 10000).ToString());
You can download the source code for this project below. Please keep in mind that not all functions are implemented yet, and some other are not tested.
Eric D. Burdo figured out how to use this library with LCD from Seedstudio Electronic Brick Starter Kit
. The connections were a little tricky but he shows the proper pin assignment for the GpioLiquidCrystalTransferProvider in his blog post
. Thanks for sharing!
Update 2010-09-22: The library is now available on CodePlex at http://microliquidcrystal.codeplex.com/