The firmware v10.1 has added native displays support to the MBN boards (Quail, Tuatara and Dalmatian). Here is a brief how-to to get you started with the few (but powerful) features newly added.

We will first need to create a Visual Studio NETMF project. A console application is fine but you may also use the MBN application template as well.

Next important thing is to reference the needed assemblies. Here is a screenshot of the minimal assemblies needed : Display.dll, Microsoft.SPOT.Graphics and Microsoft.SPOT.Hardware. If you have chosen the MBN application template, the MikroBusNet assembly has already been added to the project.

ScreenShot 411

 

Serious things will now begin ! Let’s add the first lines of code :

The Populate() method is telling to the firmware that it will be using a ST7735 display on the socket #2. It also has a Backlight pin connected to the Rst pin of socket 2. While you are entering the code in VS, you may notice that there is a ST7735R display. You will use it if you notice that your display has Blue and Red channels swapped.

If you did not choose the MBN application template to create your program, then the Hardware.SocketTwo type will not exist. You can then use the standard Cpu.Pin type instead :

Note : the Populate() method sets the current display where every Flush() will be transferred. We will see later how to use more than one display if needed.

Then, we clear the display on socket 2. The Clear() method does not use any bitmap : it really clears the display. The parameter is the socket number on which the display is connected.

Finally, and since the ST7735 has a backlight, we need to turn it on if we want to see something :)
This is done by using the standard NETMF Utility.Backlight() method. This method will use the current display settings to set the backlight on/off. If you have more than one display and need to turn the backlight on on another display, you will need to use the MBNDisplay.Select() method before calling Utility.Backlight(). See below for the MBNDisplay.Select() usage.
If you have only one display, then you do not need to bother and simply call the Backlight() method.

So far, so good : we have a display and its backlight has been turned on. What else ?

Well, let’s add some nice graphics and display them :

As you can see, we are using standard NETMF graphics methods. The ST7735 has a 128×160 resolution, so we have created a bitmap of this size and drawn a pretty white rectangle on it.

The bitmap is rendered on the display when you Flush() it. By default, a Flush() without any parameter will flush the complete bitmap on the display, starting at display coordinates (0,0). We will see later that we can change this behaviour.

If we want to rotate the display (not the bitmap), we can use the MBNDisplay.SetOrientation() method :

The SetOrientation() method will use the display ability of rotating its content. Allowed angles are 0°, 90°, 180° and 270°. Other values are simply ignored.
If the display does not support an angle, it is ignored as well. For example, the ST7565 display only supports 0° and 180°.

One should care at the bitmap size, though : in the example, since we rotate the display 90° clockwise, the bitmap needs to be 160×128 (and not 128×160).

 

Now imagine you have an ILI9341 display… If you create a 240×320 bitmap, you will certainly get out of memory since NETMF will eat up roughly 153K for the bitmap (240x320x2 bytes exactly). So even if you have enough memory at startup with Quail (around 170KB), you may quickly run out of memory as soon as you add your custom code.
How can we solve this while still using standard NETMF methods ? Easy :)

We have changed the behaviour of the Flush(x,y,width,height) method. When you use the overload with parameters, they are interpreted in a different way :
x,y : they represent the coordinates on the display where the bitmap will be flushed.
width, height : the width and height of the bitmap to be flushed. Important : width and height have to be exactly the same as the bitmap you have created.

Here is an example :

We first create a “small” bitmap and draw a nice rectangle on it.

Then we tell the firmware to draw that bitmap at screen coordinates (80,64). And, while we are at it, we also want it to be displayed at screen coordinates (0,64) :)
The important point here is that you have created a 64×64 bitmap and then passed that information to the Flush() method by setting the width parameter to 64 and height parameter to 64.

So, as you can see, you can perfectly create small bitmaps that will not consume much memory while still being able to draw on a big display like the ILI9341. And, btw, flushing small bitmaps is way faster than flushing a full-screen one !

 

Last thing we have to see is another useful feature if you need more than one display attached to your board. You can have for example a nice ILI9341 that display data analysis result, while a ST7735 would display other informations.

To achieve this, we will be using the MBNDisplay.Select() method. Please see the following code :

We start by populating socket #2 with the ST7735 and then draw a rectangle on it. Much like what we have seen at the beginning of this how-to.

Then, we populate another socket (socket #1) with another display type.
An important point, here : support for multiple display is only available for different kinds of displays. You can mix ST7735, ILI9163, ILI9341 for example, but not two ST7735 or two ILI9163. Support for many displays of the same kind may come later if there are needs for this but it is not planned in a near future.

Again, we clear the screen by calling MBNDisplay() with the socket number and now create a 128×128 bitmap. As seen in the previous example, and because we are not using a full-screen bitmap, we flush it at screen coordinates (100,0).

Then we create another small bitmap (64×64) and here we are using the MBNDisplay.Select() method to tell the firmware on which display the next call to Flush() will go. In the example, we select the ST7735 display (socket 2) and flush the 64×64 bitmap at screen coordinates (0,0).
Then we select the ILI9341 (socket 1) and flush the same bitmap at screen coordinates (20,30). I have used the same bitmap here for the example but you could have used another dedicated bitmap for each display, of course.

That’s all. I think that it is pretty simple to use as we tried to not add too much specific methods and instead use standard NETMF one. Here is a little summary of the important things to remember :

– The Populate() method is mandatory to use a display. The display is “selected” by default once “populated”.
MBNDisplay.Select() is not necessary if you have only one display attached.
Flush() without any parameter needs a bitmap whose size is the same as the display resolution.
Flush(x,y,width,height) is flushing at screen coordinates (not bitmap coordinates) and width/height have to be the same as the bitmap’s dimensions.
Flush() and Flush(x,y,width,height) are using the currently selected display.

 

Thank you for reading. If you have any question regarding the usage of those feature, do not hesitate to ask for help on the forum.