HD44780 LCD Module driver for Windows 10 IoT

This is my first post about Windows 10 IoT and small computers (embedded) after some experiences in the past with the .Net MicroFramework (Netduino, in essence).

I must say that this Windows 10 is finally a small masterpiece, or “everything you ever asked and none never responded you”. The programming way is easy but very flexible, although still many bricks are missing (in development).

The source code on GitHub

Here is a very simple experiment, a bit vintage, of driving a common alphanumeric LCD module (HD44780-based) with a Raspberry PI 2 and Windows 10 IoT.


The project isn’t anything new, but rather kinda “refresh” of another of mine where the Netduino board was used (see below). Someone of you may wonder “why” still using a so-old LCD module when several graphics are available on the market. Well, my first answer is: “why not?”. As said, this project hasn’t any specific purpose (although many of you may dig into their “miracles box” and pull out an “almost useless” LCD module). The aim is to test how hard is to drive something well known.


Some credits…

I can’t miss to mention Laurent Ellerbach, who gave me some inspiration (and motivation) on pursuing those hacking/funny activities.


The hardware.

All you need is very easy to find:

  • Raspberry PI2 (with Windows 10 IoT installed)
  • any suitable HD44780 LCD display module (mine is a 4×20)
  • 74HC595 shift-register
  • 220 Ohms resistor (only if you need the backlight)
  • 10k Ohms trimpot (22k or 47k are fine the same)

For sake of simplicity, I won’t detail how to set up the Raspberry, but there are many articles which describe very well that. I followed the Microsoft site and everything went fine, except for the suggested SD minimum size: I found that a 8GB won’t work. Simply consider a 16GB.




The software.

I wanted to publish the project keeping the sources simpler as possible. A similar application won’t have sense in a complex hardware (full-featured TFT displays and HDMI monitors perform way better than this module). The general guideline is: if you find convenient to connect a LCD module to a RPI, then make it working in minutes.

Since the LCD module’s capabilities are very limited, I embraced the idea to expose the APIs as it were a kind of “Console”. Just a “write” and something more, where a background task should manage the physical transfer by itself.

The project contains two different demo:

  1. a basic one, where some strings’ content is reflected on the display;
  2. a slightly more complex demo, which gets a bunch of RSS news from the BBC.uk channel, and rotates the titles on the screen.


Basic demo.

    class BasicDemo

        public async Task RunAsync()
            //write a static string
                "This is a basic demo",
                new Point(0, 0)

            int n = 0;
            while (true)
                //display a simple counter
                    new Point(0, 1)

                //display current time and date
                var now = DateTime.Now;
                    now.ToString("T") + "   ",
                    new Point(0, 2)

                    now.ToString("M") + "   ",
                    new Point(0, 3)

                await Task.Delay(1000);




RSS demo.

    class RssDemo

        public async Task RunAsync()
            //write a static string
                "Getting RSS...",
                new Point(0, 0)

            //get the latest news using a normal HTTP GET request
            var http = new HttpClient();
            var endpoint = new Uri("http://feeds.bbci.co.uk/news/rss.xml");

            var srss = await http.GetStringAsync(endpoint);
            var xrss = XDocument.Parse(srss);

            //extract the news items, and sort them by date-time descending
            var xnews = xrss.Root
                .OrderByDescending(_ => (DateTime)_.Element("pubDate"))

            int n = 0;
            while (true)
                * Loop the news as one per page

                //the first row is for the publication date-time
                var dt = (DateTime)xnews[n].Element("pubDate");
                    new Point(0, 0)

                //the three other rows are for the title
                var title = (string)xnews[n].Element("title");
                title = title + new string(' ', 60);

                for (int row = 0; row < 3; row++)
                        title.Substring(row * 20, 20),
                        new Point(0, row + 1)

                //wait some seconds before flipping page
                n = (n + 1) % xnews.Count;
                await Task.Delay(3000);





You may wonder how well performs the driver. Well, there are two stages involved in the displaying process:

  1. the calls from the main application to the driver;
  2. the physical data transfer.

Any invokation by the main app involves always the cache: no matter how many calls are made, because everything is hosted in memory. For this reason, any manipulation is irrelevant in terms of performance impact. However, a fixed rate (typically 200ms) there’s a cache dump to the LCD screen, that is: the physical data transfer though the SPI.

How long takes the entire screen dump via SPI?

The circuit is very simple, thus there’s no way to take the transfer faster than the machine execution speed. Even adjusting the SPI clock rate, the resulting duration won’t change notably. Please, bear in mind that a too high SPI clock rate could face signal degradation due the wire length. I used a perfect 1 MHz value, and you can see from the below screenshot that the total transfer duration is less than 30ms.


If you are interested in a faster way to dump the data via SPI, I suggest to read the following section which requires a decent knowledge about electronics.


The old “LCD Boost” library.

The original project was tailored for the .Net MicroFramework (Netduino) and many things were optimized for speed reasons. Moreover, the NetMF had some leaky problems mostly due to the super squeezed CLR, thus many solutions were solved as it were a low-level device.

Here are some links to the original articles of mine:

Very fast SPI-to-parallel interface for Netduino

LcdBoost library for Netduino

The GDI library for Netduino targets a LCD module.

A playable Invaders-like game with a Netduino Plus 2.


Netduino + FT800 Eve = MicroWPF

The spare time is few, but step by step the target is getting closer.
It’s a been I’ve started playing around the FTDI FT800 Eve board, and it must admit it is awesome. If you need a quick solution to add a small touch display to your *duino board, the Eve is something you should consider.

EVE image

You know, I love Netduino and C#. That’s because I chose to play with the display using Netduino (Plus 2), and honestly I’d expected a pretty bad performance. Instead, the graphic engine of the Eve can be easily driven via SPI from any board. That is, the SPI on Netduino is fast, very fast.

My goal is creating a small library for helping many users to create small and funny home/hobby projects with the Netduino and the Eve display boards. Since I love the classic WPF, how could I avoid to inspire from them?

Micro WPF

If you know WPF, many concepts would come easier. Otherwise, I recommend to take a look to the documentation, tutorials and whatever you want. Even if you don’t harm with a PC, rather with the Windows Store/Phone APIs, the approach here isn’t too far from.
The “WPF” term for a simple Netduino is clearly abused. Here is just the visual approach, the XAML-like approach to create the UI, and -yes- the same ability to create your own controls: MeasureOverride and ArrangeOverride.
That’s not all.
If you have any visual application in mind with Netduino+Eve (e.g. a climate control, IoT client, etc), then probably you’d need some kind of navigation service across several pages. That’s the most modern UI experience, on every device: PC, tablets, and phones.

I still don’t write what the library will offer, because it’s just something made for fun: for helping hobbists and even students working with a UI on a such small board as Netduino is.
For sure, there are NOT (nor in the future):

  • data binding
  • XAML parsing (the tree has to be created programmatically)
  • styling
  • the remaining 99.99% of regular WPF…

An example of layout

The most versatile yet complex layout control is the Grid, but it seems working fine.
Let’s take this sample XAML:

<Page x:Class="WpfApplication2.Page1"
      d:DesignHeight="300" d:DesignWidth="300"

            <ColumnDefinition Width="150" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />

            <RowDefinition Height="*" />
            <RowDefinition Height="2*" />
            <RowDefinition Height="Auto" />







On the regular WPF the result is the following:


Now, let’s see how to write the same thing on Netduino:

    public class DemoPage2 : PageBase
        protected override void OnCreate(FT800Device dc)
            var btn_prev = new WidgetButton() { Margin = new Thickness(10, 5), Text = "Prev" };
            btn_prev.Click += new EventHandler(btn_prev_Click);

            var btn_next = new WidgetButton() { Margin = new Thickness(10, 5), Text = "Next" };
            btn_next.Click += new EventHandler(btn_next_Click);
            btn_next.HAlign = HorizontalAlignment.Center;

            var grid = new WidgetGridContainer();
            grid.Name = "GRID";

            grid.AddColumnDefinition(1, GridUnitType.Star);
            grid.AddColumnDefinition(1, GridUnitType.Auto);

            grid.AddRowDefinition(1, GridUnitType.Star);
            grid.AddRowDefinition(2, GridUnitType.Star);
            grid.AddRowDefinition(1, GridUnitType.Auto);

                var ctr = new WidgetStackContainer();
                ctr.Name = "R0C0";
                ctr.Background = Colors.Blue;
                grid.SetRowCol(ctr, 0, 0);

                var ctr = new WidgetStackContainer();
                ctr.Name = "R0C1";
                ctr.Background = Colors.DarkGreen;
                grid.SetRowCol(ctr, 0, 1);
                var ctr = new WidgetStackContainer();
                ctr.Name = "R0C2";
                ctr.Background = Colors.Red;
                grid.SetRowCol(ctr, 0, 2);

                    new WidgetButton() { Name = "B0", Margin = new Thickness(10, 5) }
                var ctr = new WidgetStackContainer();
                ctr.Name = "R1C0";
                ctr.Background = Colors.LightPink;
                grid.SetRowCol(ctr, 1, 0, 1, 2);
                var ctr = new WidgetStackContainer();
                ctr.Name = "R2C1";
                ctr.Background = Colors.MediumSlateBlue;
                grid.SetRowCol(ctr, 2, 1, 1, 2);


            this.Content = grid;

        void btn_prev_Click(object sender, EventArgs e)

        void btn_next_Click(object sender, EventArgs e)
            NavigationService.Instance.Navigate(new DemoPage3());

That leads the following snapshot:

My Snapshot5

NOTE: by live the display shows the colors correctly. However, the picture taken renders a bad result.

Widgets, widgets, widgets…

The Eve board is very well designed, because it’s plenty of useful widgets. I don’t believe you’d need something different from the provided.
At the moment of writing, the Netduino library supports:

  • (normal) Button
  • ToggleButton
  • TextBlock
  • Slider
  • Dial

and, as for the layout control:

  • StackPanel
  • Grid

As long the spare time helps me, I will try to add some other useful component as the TextBox and the Image.

Yet some screens generated by the Netduino and the FT800 Eve board.

My Snapshot4

My Snapshot3

My Snapshot7

Source code

I will release a beta release soon.

An example of an hardware problem and how to solve it

This post was not planned, in the sense that the main article is expected on the real working project (coming soon), not on the problems related. However, this is a typical case of hardware malfunction (due to a insufficient design redundancy), and it thought it was useful to show. I realized that most users not having a good practice in electronics, get discouraged when they try to replicate a circuit and that does not work as expected. They first wonder about the “logical equivalency” of the schematic/wiring, but that does not seem a good reason for make it working.
Electronics is physics, I mean a small part of. So, the world is not working differently when we talk about electrons spinning or a logic chip connected to a micro-controller. However, the main task done for years by scientists is to simplify, to model, to minimize interaction between “electronic parts”, so that the design will become easier yet reliable.


In this post I want to describe what happened to me yesterday, when I was trying to make the circuit working, but it did not wanted to. All my attention was payed on the software (written by me), on possible bugs in the new Netduino Plus 2, and even about some wrong wiring. None of these areas was the right one, but the most unsuspected component.


The goal of the project is interfacing a Sure Electronics Led-matrix board to the Netduino Plus 2 with a minimal external hardware. By the way, the board can be SPI-driven with a couple more of signals. All I need is some pull-up resistor, just because the STM32 MCU used by the Netduino Plus 2 does not embed them as the Atmel does.
So far, so well.

Yesterday the C# software driver was completed and worked well…ehm, bad…or well?…Hard to say how…
According to the Sure Electronics datasheet, as well as the Holtek HT1632 datasheet, my driver running on the Netduino produced the waveform correctly. Every single pattern, command, and data have been checked on the scope, and looked fine. However, the leds on the board were not lighting at all, or -at most- randomly colorized.


I had a suspect on the board itself, but I refused it because I mumbled:

…these boards are sold worldwide in thousands units: how can be not working?

However, today I checked the board correctness against its schematic.
The first yet easy component to check was the mapper for enabling the HT1632 led-controllers. There are four controllers on my board, which is 16 rows by 32 columns, bi-color led-matrix. The mapper is a normal 74HC164 shift-register, similar but simpler than the famous 74HC595.
The software driver clocks the 74HC164 so that only one HT1632 is enabled at once. Basically the driver issues a logic “zero” to the shift-register input, then shifts once: this will move the zero to the first register output, while all the remaining are “one”. This enables only the first controller, and the driver feeds it with the matrix data. Every further clock should issue a logic “one”, so that the logic “zero” is “moving” forward on the register’s outputs, and the other controllers are enabled.

The 74HC164 used for enabling the led controllers.
The 74HC164 used for enabling the led controllers.

What made me shocking is the wrong output state of the register. Although the clocks were issued correctly, as well as the input data, the outputs were completely wrong, most of the times enabling more controllers at once. That was a very good reason for the leds lighting randomly!
So, my move was to inspect what made the shift-register shifting unexpectedly. To do that, I placed the first scope probe on the 74HC164 output activating badly, and the second probe on the same chip clock. At first glance there was no reason for the output getting low, because there was no clock edges. However, something must happen, because the 74HC164 actually shifts the data.
The 74HC164 clock (above) and its first output going low.
The 74HC164 clock (above) and the data input fed into.

The first output of the shift-register, which correctly goes low along a whole clock period.
The first output of the shift-register, which correctly goes low along a whole clock period.
The shifter's second output going low earlier than the second clock pulse.
The shifter’s second output going low earlier than the second clock pulse.
The clock generated by the Netduino is perfectly flat upon the output falling: that's suspect!
The clock generated by the Netduino is perfectly flat upon the output falling: that’s suspect!

The driver timings are around several milliseconds: even the new Netduino can’t reach microseconds pulses. By the way, the external logic does not care about milliseconds, and it works even on nanoseconds events.

The actual clock by the 74HC164 pin shows a small glitch shorter than 100nS.
The actual clock by the 74HC164 pin shows a small glitch shorter than 100nS.

I scaled the scope time-base up to sub-microseconds timings, and…GOTCHA!…a subtle pulse was causing the improper shifting.
Now, I didn’t know exactly where that pulse is originated, nor the very best way to avoid it. By the way, it had to cut off, otherwise the board won’t worked. Two guesses: stray capacitance (e.g. PCB tracking too tight), and/or bad grounding (e.g. leds’ current leads voltage drops).

The solution.

The easier way to cut a spike off is placing a small 1nF capacitor across the signal and ground (assuming the grounding is good).

The 1nF capacitor added to the board.
The 1nF capacitor added to the board.

The funny thing is that the capacitor was considered by design, but not mounted (at least on my board). I wonder why the Sure Electronics Engineers missed it.

The 74HC164 second output shows perfectly after the capacitor insertion.
The 74HC164 second output shows perfectly after the capacitor insertion.


I know, it’s frustrating.
Most of the users having fun with Netduino are programmers, and they can’t accept that does not exist “copy-and-paste” for hardware. Well, it can be applied if the circuit model has enough redundancy so that most of the undesired effects and interactions can be ignored.
So, please, don’t trash your long awaited hardware project just because it does not work at first time. Dig, dig, and dig again. Also remember that a logic analyzer can’t replace a scope, but a scope most of the time can.

Led-matrix controller driven via SPI


Time ago, Stanislav -a Netduino community user- posted a problem on how to drive a 6-by-4 led-matrix using its Netduino. After some experiment, he got stuck with the circuit, because a matrix must be multiplexed, and that’s not easy to solve.
Here is the link to the forum thread.


If you read the message exchange on the thread, then you’ll collect easily a list of constraints. Here they are:

  • the leds have been already assembled (i.e. only the multiplex driver is needed)
  • the overall price should fall within 10 Euro
  • must be handcrafted, thus no use of small parts (e.g. SMDs)
  • the multiplex should not stop its cycling as the Netduino stops (avoid leds burnout)
  • the circuit should avoid complicate wiring, so that the PCB can get pretty easy
  • reliable enough
  • finally, Stanislav asked to learn how to design such a circuit

It was clear that Netduino only wasn’t enough to drive a 6×4 led-matrix. First off, for the inability to give enough current for the leds, and secondly for the relative slowness of the managed code running into.


The problem in depth.

Light up a led is very simple. Starting from the power supply, as parameter you have the current flowing through the led, then calculating the resistor to put in series. A led needs from few mA (SMDs), to several hundreds of mA (or even more) for the high-power class.
Let’s face the multiplex problem thinking to a normal discrete-led which needs 10 mA for a normal brightness.

So, what is a multiplex?
The multiplexing is a technique for driving many loads (e.g. leds), using a relatively low number of wires. Thinking to a 6×4 led-matrix, instead having 24 wires (one for each led), the multiplex-way needs only 6+4 = 10 wires at all. The trick is enabling one column at once, and issuing the related row pattern. If this process is fast enough, our eyes can’t perceive the scanning.
Now, let’s focus on a single column of four leds: the scan process cycles over, but each column is enabled only at 25% (i.e. 1/4) of the total cycle-time. It means that to yield the same brightness as the led was lit with 10 mA, we should raise it of a factor of 4, thus 40 mA. This current is off the upper limit achievable by a normal logic chip.
By the way 40 mA is probably above the led’s limit. However, the current is flowing only for a quarter of the cycle, so there’s no warm up in the *average*. We only should take care to *avoid* any cycle break, otherwise the 40 mA will flow for a too long time, and the led blows.
That’s not all. When a column is enabled, there are 6 leds composing it, and they might be all on (worst case). So, the total current flowing is 40 mA x 6 = 240 mA.
How much is the current of each row, instead? A row drives only the led at where the column is enabled, but at 25% duty, of course. It means the 40 mA seen above.


My solution.

To solve this problem, I see three ways:

  1. using any small micro-controller (e.g. AVR, STM8, etc), then creating a program for both multiplexing the matrix, and for communicating with the Netduino. However, this solution still has the current limitation problem, and easily could take the overall cost over 10 Euro.
  2. using an ASIC, such as the AS1108: this way probably keep the cost within the limit, but can’t get the current higher than the chip’s max-rating.
  3. creating the circuit in the “classic-way”, using simple logic gates that you can buy everywhere for fews Euro. This solution seems having only the fault on the low compactness. However, there are tricks to minimize the hardware, and the compactness didn’t seem a constraint.

My choice was for the third option, for several reasons: it’s easy to create, it teaches how to design a led-matrix driver, it’s also cheap. I’d add it’s also pretty flexible, because you could change some component upon the leds current. It’s even modular: can create (theoretically) as many rows and columns as you wish, by simply adding a stage.
I had an old 7×5 led-matrix display: not so good, IMHO. It requires about 10 mA to light a led, but the brightness isn’t so high. Even raising the current to 20-25 mA, there’s no significantly better shining. I have several modern leds, and they should fit much better a similar project, because with as little as 5 mA they shine a lot more than my matrix. However, I used it for a faster prototyping.
In my circuit I also reversed the rows/columns role, but that does not change anything about the concept. It’s only for my convenience.


How it works.

The circuit is based on the famous shift-register 74HC595. A single register holds one-column pattern, that is 7 leds. Since we can chain several shift-register, I chained 5 of them: one for each row. The software for loading via SPI a bit stream into the chained registers is trivial, but there are several libraries such as the Stefan’s “Bit-shift shizzle”.
The Netduino has only one task: shift the whole stream of bits into the five registers, by using the SPI.
Afterward, the trick is playing with the /OE input of each register: when this line is high, all the register’s outputs are completely “detached” from the circuit. That is, we can parallel all the outputs, and enable one register a time leveraging the /OE behavior.

NOTE: the circuit shows only three registers for clarity.

The /OE signals should be cycled. To do that, I used a simple clock generator (NE555), and a 4017 (or 74HC4017), which is a Johnson counter.
The NE555 generates a square-wave of about 500 Hz, which feeds the counter. The 4017 simply puts high one of its outputs at once: every clock edge the next output is pulled high, as a natural 10-sequence. This sequence is also used for the column’s cycle, because the registers enabling must be synchronized with the proper led-column activation. Since the matrix is composed by 5 columns, the 4017 sequence must be shorten to that quantity. To achieve this, simply wire the 6th output to the counter reset: as soon the sequence hits the 6th output, its logic high also resets the counter taking the first output high immediately.

Both the shift-registers circuit, and the sequencer requires no particular difficulty.
The complex section is the real leds driver, which has to amplify the current (possibly wasting almost no power).
There are two cases of led-matrix pattern: common-cathode or common-anode. To clarify, let’s take the columns as reference: either the column lines represent the leds’ cathode, or the leds’ anode instead.

My display is a common-cathode, and the Stanislav case is about a common-anode, instead.


The led driver for columns sharing the cathodes.

The following circuits targets the current amplification for both columns- and rows-lines.

NOTE: the circuit shows only few rows/cols for clarity.

The row signals are coming directly from the 74HC595 outputs, which aren’t powerful enough to drive the leds. Thus a PNP-transistor (I used BC640) for each row is used for amplifying the signal. The PNP is wired as common-emitter, so that the registers have to set the output low to activate the led-row.
The ultimate goal for these transistors is taking them to the saturation: that’s for minimizing the voltage drop across the emitter-collector. More voltage available for the leds, and lesser power waste on the transistor themselves.
Notice that I didn’t used any resistor in series to the transistors base. That’s because I wanted to maximize the current through the base, so that the saturation will be guaranteed. The register stress is relative, because -yes- the current is above the chip’s rating, but also that is for a short period in a cycle. We should always bear in mind the *average* behavior.

For the columns the amplification circuit is more complex.
That’s because every column transistor should saturate flowing a current of 350 mA (or more). It worth noting that my matrix is 7×5, so that the column current is 7 x 50 mA = 350 mA (see the above calculation).
The BC639 NPN-transistor is the dual of the BC640, and it’s rated up to 1 A (continuous). Its hFE (current amplification ratio) is rated at about 25 when the collector current is about 500 mA. That means a base current greater than 500 / 25 = 20 mA, to ensure the saturation. This value is very close to the upper limit achievable by the 74HC4017, and furthermore the drop C-E looks still pretty high. The BC639 specs indicate a VCE = 0.5V @ Ic=500 mA and Ib=50 mA. All that imply another stage for pre-amplification.
The pre-amplification stage is a common-collector pattern: simple, yet good for taking the current higher. Please, also notice that the transistor pair are NOT connected as Darlington. The Darlington fault is that you cannot take it to the saturation, and we want that instead.
I used a 1k Ohms resistor for the final-stage-base, which is fine for a column current up to 500 mA. However, you could take this value lower (e.g. 330 Ohms) whereas the required column current should be greater.

You know, this driver is designed for taking the columns to the ground in order to light the leds. So, when the 74HC4017 output is high (just one at once), the related transistor-pair stage shorts the column line to the ground.
But…remember? We also need to enable the related shift-register, so that the bits pattern will be issued against the rows. The same column signal is also used for activating the /OE of the 74HC595. Since when the column is not active there’s also nothing taking the /OE high, there’s an additional pullup (2.2k Ohms) to achieve that. However, the presence of this pullup doesn’t involve the matrix behavior in any way.


The led driver for columns sharing the anodes.

This is the case of Stanislav, and the circuit looks a little simpler than the above.

The considerations about the current flowing through the transistors are the same as before. The only difference is in the polarity, which has to be reversed.


Power supply.

NOTE: this section is very important. An improper wiring may lead to an unexpected or quirky behavior of the circuit.

There are three sections involved in the whole project: the Netduino, the logic (shift-registers and the sequencer), and the drivers (rows’ and columns’). All the grounding must be carefully shared: the logic can be powered from the Netduino +5V supply, but the driver can’t.
The drivers (i.e. the leds) need a lot of power, which must be supplied separately.
You should observe this pattern for supplying the various power sources:

The circuit should be created along two sections: the logic and the drivers.
The two grounds (Netduino’s and leds’ power) should be joined in the middle point between the two sections. So, the two current loops are kept separated.
As stated, the positive leads of the two supplies must be not connected together.



As stated in the beginning, the circuit is clearly modular.
The 74HC595 offers up to 8 outputs (i.e. rows), so you can add a transistor and a led strip with ease. Since the registers are already chained, it’s also not hard to double-chain them, and reach 16 rows or even more.
Pretty the same consideration for the columns: the 74HC4017 yields up to 10 outputs (i.e. columns). Just add a transistor-pair stage, and the leds.
In this case is a bit more difficult to expand the column outputs over ten, but it’s not impossible at all. I’ll avoid any description over here, unless explicitly requested.
Modularity yields a relatively easy wiring of the PCB, or any other concrete solution.


The prototype.

NOTE: the circuit scans the led-matrix automatically, also when the Netduino is halted or even detached. This should prevent over-current through the leds, and facilitates the debugging of the software application.

Here are some pictures about the prototype built over two (!) bread-boards.

The whole prototype seen from above.


Detail of the 5×7 led-matrix


Detail of the five shift-registers (74HC595) chained.


Detail of the clock generator, and the 74HC4017 (i.e. the column scanning)


Detail of the seven rows’ drivers (BC640)


Detail of the five columns’ drivers (2 x BC639)


The demo program.

Below is the source code used for the demo (see below). Nothing else is required.

    /// <summary>
    /// Sample application for testing the led-matrix driver
    /// </summary>
    /// <remarks>
    /// NOTE: it's important to bear in mind that the circuit
    /// uses a negative logic, thus a logic '1' means a led off.
    /// </remarks>
    public class Program
        //define the bit-buffer as mirror to the 'HC595 chain
        private static byte[] _buffer = new byte[5];

        //define some bit-masks, just for improving speed
        private static int[] _mask0 = new int[8] { 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F };
        private static int[] _mask1 = new int[8] { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };

        public static void Main()
            //fill the whole buffer with logic '1' (turn all the leds off)
            for (int i = 0; i < 5; i++)
                _buffer[i] = 0xFF;

            //defines the first SPI slave device with pin #10 as SS
            var cfg595 = new SPI.Configuration(
                Pins.GPIO_PIN_D10, // SS-pin
                false,             // SS-pin active state
                0,                 // The setup time for the SS port
                0,                 // The hold time for the SS port
                false,             // The idle state of the clock
                true,              // The sampling clock edge (this must be "true" for the 74HC595)
                1000,              // The SPI clock rate in KHz
                SPI_Devices.SPI1   // The used SPI bus (refers to a MOSI MISO and SCLK pinset)

            //open the SPI port
            using (var spi = new SPI(cfg595))
                //set the initial ball's position
                var ball1 = new Point();
                ball1.X = 2;
                ball1.Y = 5;

                //set the initial ball's speed
                var speed1 = new Point();
                speed1.X = 1;
                speed1.Y = 1;

                //endless loop
                while (true)
                    //clear the led where the ball now is
                    SetPixel(ref ball1, false);

                    //move the ball accordingly to its speed
                    ball1.X += speed1.X;
                    ball1.Y += speed1.Y;

                    //check for the display "walls"
                    //NOTE: it's a rect having width=5, and height=7
                    if (ball1.X > 4)
                        ball1.X = 4;
                        speed1.X = -1;
                    else if (ball1.X < 0)
                        ball1.X = 0;
                        speed1.X = 1;

                    if (ball1.Y > 6)
                        ball1.Y = 6;
                        speed1.Y = -1;
                    else if (ball1.Y < 0)
                        ball1.Y = 0;
                        speed1.Y = 1;

                    //light the led at the new ball's position
                    SetPixel(ref ball1, true);

                    //copy the bit-buffer to the 'HC595 chain

                    //wait a little

            //useless in this case, but better than missing it!

        /// <summary>
        /// Simple helper for setting the state of a pixel
        /// </summary>
        /// <param name="pt">The pixel coords</param>
        /// <param name="state">The desired led state (true=on)</param>
        /// <remarks>
        /// The "ref" yields better performance than
        /// passing two parameters (X,Y) separately
        /// </remarks>
        private static void SetPixel(
            ref Point pt, 
            bool state)
            if (state)
                //the led should be turned on,
                //then let's clear the related bit
                _buffer[pt.X] &= (byte)_mask0[pt.Y];
                //the led should be turned off,
                //then let's set the related bit
                _buffer[pt.X] |= (byte)_mask1[pt.Y];


    /// <summary>
    /// The basic point structure
    /// </summary>
    public struct Point
        public int X;
        public int Y;

Here is a short video demonstrating the circuit prototype.
The Netduino runs a small program for bouncing a ball.


Effect of long wiring on digital signals

It’s a very common question from the Netduino users. It’s about how to connect two or more boards/shields when they are relatively far each other.

The appliances and the mains.

It’s perhaps the habit to take the mains everywhere simply adding a piece of chord: the vacuum-cleaner works. Or else, during Christmas, when we have to plug half a dozen of light strings to the mains. No matter how we plug the cables: the Christmas tree is shining. We’ve only to take care of: (1) ensure a good mains connection, and (2) take care to avoid any false-contact which may cause overheat.
By the way, everything is working fine for several reasons:

  • the voltage is high enough, so that any small voltage drop will be insignificant;
  • the waveform of the mains is a wonderful sine, swinging at a very low frequency (50 or 60Hz);
  • but, of sure, the most important fact is that:

there’s no any information carried over the mains wiring, thus our appliance will “understand” just “go/no go”.

The digital signals.

Working on digital logic, microcontrollers and else, we need mostly transfer “information” from a block to another one. This “information” can be a simple bit high/low, but it can be much more complex (e.g. the SPI). The higher is the quantity of information, the harder is to protect it from errors.
It’s the famous “signal-to-noise ratio“, which impose a limit to the maximum quantity of information over a line when the noise has a certain level.
Here I won’t show you anything mathematical, instead I want to show you that not always the things are simple as they seem.

The experiment.

As base for the experiment, I created a simple circuit with my Netduino. Nothing special about it: it’s a circuit seen many times.
The Netduino SPI drives a 74HC595, which dirves a 7-segment display. The display itself has the only meaning to show a certain “pattern” to the observer (me). Of course, it’s much more simple to recognize a number, than a sequence of leds. That’s the way I’ve chosen a display over eight leds.
The Netduino runs a very simple program, which has to present sequentially the 16 digits of the hex-base. Each digit is held for 500ms, and the sequence is kept running forever.

    public class Program
        /// <summary>
        /// Segment pattern for the hex-digits
        /// </summary>
        static readonly int[] Digits = new int[16]
            0xBF,   //0

            0xE6,   //4

            0xFF,   //8

            0xB9,   //C

        public static void Main()
            //define the SPI configuration
            var config = new SPI.Configuration(
                Pins.GPIO_PIN_D10, // SS-pin
                false,             // SS-pin active state
                0,                 // The setup time for the SS port (not used)
                0,                 // The hold time for the SS port (not used)
                true,              // The idle state of the clock
                true,              // The sampling clock edge
                1000,              // The SPI clock rate in KHz
                SPI_Devices.SPI1   // The used SPI bus (refers to a MOSI MISO and SCLK pinset)

            //define a single-cell buffer used by the "Write" method
            int i = 0;
            byte[] buffer = new byte[1];

            //open the SPI port
            using (var spi = new SPI(config))
                while (true)
                    //issue the digit pointed by the index
                    buffer[0] = (byte)(Digits[i] ^ 0xFF);
                    i = (i + 1) & 0x0F;

                    //small delay


Note 1: The segment pattern follows the “standard” map used by the 7-seg displays. Bit #0 maps to segment “A”, whereas bit #7 maps to the decimal point.
Note 2: I used to make the DP on for the even digits, and off for the odds.
Note 3: The display I’ve used is a common-anode (toward +5V), so the activation logic is reversed. That’s explain the XOR-op.

I won’t change anything in the above program, other than the SPI clock rate, which is initially equals to 1 MHz (=1000). I would have used an higher clock rate (e.g. 10 MHz), but my scope has a limited bandwidth (100 MHz), and the waveform would not be shown as it is.
The target of the experiment is showing how the SPI signal is at the 74HC595 pins, upon several different wiring.

Tight wiring.

That’s the reference. Everything is wired very tight, keeping the wires as short as possible. Also the grounding (which is *very* important) is shared on the same bread-board, and the supply is given by the Netduino itself.

The circuit is working fine (tested up to 40 MHz of clock-rate, just for your information).

The waveform is perfectly squared: no noise, nor delays.
The upper trace is the SCLK, while the lower is the MOSI.

Shielded cable.

The second test is performed using a 2.5m (about 8 ft) of multi-pole shielded cable of good quality. The problem is about the SPI, which needs at least three signals (SCLK, MOSI, SS), plus ground. For a bidirectional data exchange we’d need another wire.
The circuit is still on the bread-board, but the Netduino is moved off the area. The supplies are separate: the Netduino is supplied via USB, which the HC595 circuit via a regulated power supply.
The ground is shared by connecting the cable shield to both sides.

Again, there’s a little distortion of the signals, but the data transfer is still reliable. The shielded cable works correctly, but I should have to “adapt” the wires at the HC595-side, by “terminating” each signal with a proper resistor. I didn’t for simplicity of comprehension.

The problem is the cost and the thickness of the cable.

Un-shielded cable.

The third test is performed using a 3m (about 10 ft) of multi-pole cable of poor quality. It’s cable for phones, burglar alarms, and similar wiring. Very cheap and thin (although the mine has only three wires: for the ground I’ve used another wire).
Again, the Netduino supply only itself, and the HC595 is supplied by a separate power.

The waveform is clearly getting worse, but the circuit still counting correctly.

The waveform shows rippled, thus it’s interesting to make an attempt by raising the clock rate.

Un-shielded cable at 2 MHz.

Doubling the clock-rate the result is getting even worse. However, the circuit seems still working fine.

Un-shielded cable at 5 MHz.

At 5 MHz the signals are almost unrecognizable, and -yes- the circuit is not working anymore. It displays strange patterns, sometime correct, but mostly randoms.

Effect of the noise on the un-shielded cable.

Let’s take the clock back to 1 MHz, but let’s try to see what happens when a noise-source is close to the cable.
For instance, we might think to another cable, close to the signals’ one, used for motors, inverters, or many others loads that involves “high-frequencies”.

In this case, I took the same shielded cable of the previous test, but I’ve used the shield as “emitter”. Basically, I’ve connected the shield to a square-wave generator (about 4 MHz), and I’ve let the cables over the un-shielded. There’s *NO* metallic connection, but for capacitive coupling (i.e. electrostatic) there’s an interference on the signals’ cable.

The resulting waveform by the HC595 is clearly showing how the noise “sums” to the useful signals.
Of course the circuit is not working!


The SPI is not a good way to transfer data on long wiring: too wires, too high clock rate. But I wanted to highlight you the effects of a long wiring on a relatively high speed.
Of sure I’d bet on the classic serial port (i.e. UART), which needs just two signals and ground. However, even the RS-232 interface cannot be used for lengths over 15m (50 ft).
For very long distances, the speed must get lowered, and the things are getting harder. However, there are many interesting ways to solve small projects without getting crazy.

LcdBoost library for Netduino


This article show a concrete application of the circuit presented in my previous post.
Although the hacking is something versatile, it has been focused on driving LCD modules in general.
Here is a presentation of a small yet powerful library to simplify the graphic management, even having few memory resources.


There’s almost no changes from the circuit shown in my past article: just some improvement, which has been tested over two-three different kinds of LCD modules. Every time, with no problems.

For my convenience, I created the circuit on a piece of proto-board. I know, it’s not the best solution I could do, but it seems working okay. It’s easy to connect, and it leaves the Netduino pins free for further extensions.

I just added a transistor more, to drive the LCD backlight, where available. Nothing special, but it came almost for free, because luckily on the same Netduino connector there’s a PWM output also.
By the way, there’s no power supply, and most of the LCDs are using the old, faithful, +5VDC. Thus, I used a dedicated connector, using the same pinout as the *duino like connector. It means almost nothing, but it’s worthwhile keeping almost the same pinout pattern, as for convention.
Moreover, this separate power connector yields to a dedicate power supply, instead of overloading the Netduino’s embedded regulator.


Having a very fast data transfer offers the possibility to structure the library better. Abstraction is asking often a little more of memory resources, but also yields to a better integration of modules. The result is somewhat amazing, at least for a managed device as Netduino is.

First off, I wanted to separate the two layers involved in the UI: the physical and the logical. The physical layer is meant as the “driver”, which actually knows how is the LCD module, its features, and much more. The logical layer should not know anything about the hardware, instead has to organize the user’s API at best, so the user will find comfortable interacting with any display.
Of course this is just the goal: we must bear in mind that never ever will achieve a WPF-like APIs.

Secondly, I wished to offer the APIs in two flavors. Okay, the library is actually the same, but the user can choose to access the display in a imperative-way, or in a declarative-way. However, you can mix all that: no exclusivity at all.

The imperative way is the most intuitive (really?), which came from our childhood. Most of the personal computer had no enough resources, and the “do this”/”do that” programming manner became the most famous. Both the code samples contained in my old post about LCD driving with SPI, are shaped in the imperative fashion.
The declarative way is much more powerful, elegant, and -I’d add- intuitive. Instead of polluting our code with specific actions, let’s declare a bunch of “object”, which we’ll interact with. Each object has its own properties, along with methods. Isn’t sounding familiar?
Further I’ll show a small example of using the LcdBoost library, taking advantage of its declarative APIs.

How is this library made?

As stated, the library is designed to be a “satellite” project to be linked to your own application. You shouldn’t copy-and-paste modules, which leads to errors, and misalignment.
The user interact normally with the logical layer, although it can access the specific physical layer wherever some custom chip-tailored function should be performed. For instance, often the LCD modules are based on the Hitachi HD44780 chip, which offers a character pattern customization. This feature is specific for that chip, thus should be accessed directly to the driver instance.
Also, the library is meant to be improved, and extended. Both the logical and the physical layers are structured to be easily extended. Physical drivers are pluggable, and the logical graphic entities are also pluggables.
At the moment of writing this post, there’s only support for character matrix LCD modules. I’d like to drive some dot-matrix module, but I’m not sure to be able to do it.

The imperative access consists in just three methods:

        /// <summary>
        /// Clear the entire screen
        /// </summary>
        public void Clear()
            // ...

        /// <summary>
        /// Set the starting (reference) position
        /// to be used by any further text operation
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void SetCursorPosition(
            int x,
            int y
            // ...

        /// <summary>
        /// Write a text string (as plain ASCII) on the video cache
        /// </summary>
        /// <param name="text">The string to be written</param>
        /// <remarks>
        /// The text starting reference has to be set by using the <see cref="SetCursorPosition"/>.
        /// After this call, the logical position is moved accordingly
        /// </remarks>
        public void Write(string text)
            // ...

It’s really the minimum, and -honestly- I would not care so much, in favor of the declarative APIs (which I’m proud of!)

Okay, I’m a big fan of WPF, thus I *tried* to mimic that approach. The problem is that WPF would require *TONS* of memory, plus several parts of the regular framework, not implemented in the .Net Micro Framework.
So, the declarative API allow to operate with objects, which must implement a common interface:

namespace Toolbox.NETMF.Hardware
    /// <summary>
    /// Fundamental interface for implementing any graphic element
    /// to be managed in the declarative-way by the LcdBoos library
    /// </summary>
    public interface ILcdBoostElement
        /// <summary>
        /// Indicates whether the graphic element is hidden or not
        /// </summary>
        bool IsHidden { get; }

        /// <summary>
        /// Renders the element's cache onto the video viewport
        /// </summary>
        /// <param name="cache">The target video cache to be filled</param>
        /// <param name="container">The parent container bounding rectangle</param>
        void Render(
            LcdBoostVideoCache cache,
            LcdBoostRect container

The library comes with just two “renderable” objects (so far):

It’s clearly limited to the character-matrix modules, but surely enough at first attempt.
Again, the LcdBoostElementCharPoint is a particular case of the more generic LcdBoostElementTextArea. It has been tailored for a single character entity, but is performing much better due the fewer calculations.


Well, I had hard time to believe my eyes: the rendering is blazing fast. The physical driver has been improved several times, always within a compromise of performance and readability.
I must admit that the only result I have are for character matrix display, all based on the Hitachi HD44780 chip. The “practical” result is that the slowest part is surely the LCD itself, but…I mean the *real* LCD: the crystals! It looks that the crystal inertia is so huge, that you can reach 2-3 fps. At this point, the Netduino speed is a minor problem.

Anyway, here is a couple of snapshots taken with the scope.
The first one shows the overall rendering process (logic arrangement, plus physical transfer), along the timer cycle (100ms). The high-level interval is the actual busy period.

The second picture (below) is showing the physical transfer time via SPI. Since my display is a 20×4 character matrix, the transfer is accomplished on two sequential steps. The overall transfer takes less than 20 ms.

NOTE: the timing of the pictures is based on the demo game presented below.

A simple demo game.

To be attractive, a sample should be something funny.
Here is a simple pong-like game. The game itself has no meaning: using a 20×4 display is still playable with difficulty.
The interesting thing is how readable is the code, and how simple is creating even complex tasks. I’d also add that a similar approach will probably improve both efficiency, and compactness of the resulting code.
Do you have ever programmed any XNA game?
Well, the concept is quite simple: declare your resources (e.g. bitmaps, sounds, etc), then add the game logic. All the life is hanging to a “loop” which renders the game scenery. Here is the same.
Just add your ILcdBoostElement-derived elements to an array, that will be you resource-bag to be rendered. Afterward, the actual rendering will be performed automatically within a timed loop.

namespace Toolbox.NETMF.Hardware
    /// <summary>
    /// A demo of a simple pong-like game
    /// </summary>
    /// <remarks>
    /// The aim of the demo is demonstrating how simpler is
    /// creating even pretty complex games, by taking advantage
    /// of the declarative approach, instead of the imperative one.
    /// The paddle is controlled by any numeric port
    /// NOTE: although this demo can work on any lcd size,
    /// has been tailored for a 20x4 char matrix LCD module
    /// </remarks>
    class DemoPong
        private const int BrickRows = 2;
        private const int BrickColumns = 16;
        private const int TotalBricks = BrickRows * BrickColumns;

        private const int AvailablePaddles = 5;

        private static LcdBoostElementCharPoint[][] _elem_bricks;
        private static LcdBoostElementTextArea _elem_paddle;
        private static LcdBoostElementTextArea _elem_score;
        private static LcdBoostElementTextArea _elem_paddles_left;
        private static LcdBoostElementCharPoint _elem_ball;
        private static LcdBoostElementTextArea _elem_gameover;

        private static Random _rnd;

        public static void Run(
            LcdBoostProxy lcd,
            NumericInput paddle)
            //init the random number generator using a pseudo random seed
            _rnd = new Random(DateTime.Now.Millisecond);

            //define an array for containing all the UI-elements
            var elements = new ILcdBoostElement[TotalBricks + 6];
            var elem_count = 0;

             * Allocates the resources to be used in the program
             * this is very similar to the "sprite" approach

            //right-side wall
            var wall = new LcdBoostElementTextArea();
            wall.Text = "||||";
            wall.Bounds.Left = 16;
            wall.Bounds.Top = 0;
            wall.Bounds.Width = 1;
            wall.Bounds.Height = 4;
            elements[elem_count++] = wall;

            // ...

             * Create a new session of game.
             * The session contains only the dynamic data used
             * by the game. The logic is meant to be outside.
             * That's much like a functional approach
            var session = new GameSession();

             * Master clock for the game refresh
             * Notice that the clock is handling the display refresh
             * at 10 fps, but the game logic has to be slowed down
             * because would be too fast to play
            int clock_counter = 0;
            var clock = new Timer(
                _ =>
                    //invoke the game logic

                    //refresh display


        /// <summary>
        /// The game logic
        /// </summary>
        /// <param name="session"></param>
        /// <param name="clock_counter"></param>
        private static void Worker(
            GameSession session,
            int clock_counter)
            //stop logic when there'are no more paddles left
            if (session.PaddlesLeft <= 0)

            //timer scaling to slow down the game logic
            if ((clock_counter & 0x07) != 0)

            //retrieve the current ball coords
            int x = _elem_ball.X;
            int y = _elem_ball.Y;

            // ...


        /// <summary>
        /// </summary>
        private class GameSession
            /// <summary>
            /// Overall score
            /// </summary>
            public int Score;

            /// <summary>
            /// Paddles left
            /// </summary>
            public int PaddlesLeft = AvailablePaddles;

            /// <summary>
            /// 2D vector defining the ball speed
            /// </summary>
            public readonly Vector BallSpeed = new Vector();

            /// <summary>
            /// Init for a new incoming ball
            /// </summary>
            public void NewBall()
                int n = _rnd.Next(10000);

                //gets the new ball position
                _elem_ball.X = 2 + n % 12;
                _elem_ball.Y = 0;

                //gets the new ball speed
                this.BallSpeed.DX = n < 5000 ? -1 : 1;
                this.BallSpeed.DY = 1;

                //update the paddles left box
                _elem_paddles_left.Text = "_" + this.PaddlesLeft.ToString() + "_";

        /// <summary>
        /// Simple class for defining a 2D vector
        /// </summary>
        private class Vector
            public int DX;
            public int DY;

            public void InvertX()
                this.DX = -this.DX;

            public void InvertY()
                this.DY = -this.DY;


As seen previously, in the performance section, the rendering loop is timed to refresh the display on every 100 ms, that is 10 fps. It’s fairly poor as it were a normal video game, but it’s indeed too fast to be playable. Thus, the logic update has been scaled down of a factor of 8.

The paddle controller deserves a word of mention.

The poor-man game controller

In any decent arcade game, the controller is an important component. However, I’m not going to produce video-consoles, nor focusing on the comparison on game controllers. I just needed a quick-and-dirty way to move the paddle for my pong-like game, but…I also realized that I hadn’t anything fitting the goal.
So, I took my bag of trashy stuffs, carefully collected by my (poor) dad, and I began digging. The most obvious thing is the last to be considered: why not a normal brushed motor? My dad had dozen of small motors, so I got one of them, probably originally built on a old tape-deck.
The circuit is somewhat ridiculous: just a 1/2 voltage divider, and the motor. Okay, I’ve seen that a capacitor is a good way to get the reading more stable.

The voltage divider just creates an halfway voltage, so that the working point for the ADC is about in the middle of the range. As stated, the capacitor yields more stability to this voltage point. Finally, the motor is connected from this voltage divider, and any Netduino analog input.
When you take the motor spinning by using fingers, it works actually as a dynamo, and produces a little voltage. This voltage can be either positive or negative respect to the voltage divider point. The software samples the analog input periodically, and converts the samples accordingly.

As long you don’t get the motor spinning fast, there’s no danger at all.


Once again, Netduino does it better.
It’s just another little piece of knowledge to get you working better with Netduino, and the .Net Micro Framework. Sometime the solution isn’t coming quickly as expected, but collecting experience helps a lot.

Future goals is hacking the new gaming console Netduino-based: the PIX-6T4, by Nwazet.

The library is part of the Cet Open Toolbox, and can be downloaded together with schematics and Fritzing diagrams.