Using Firmware Display features

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.


Firmware 10.1 released

Firmware 10.1 released

You may have noticed that the output of drivers has decreased to a crawl recently. Well basically, there have been no new drivers released for a while.

This does not mean that we have not been doing some exciting things behind the scenes.

We have been quietly working on the firmware to add some new features and to squeeze every last available byte of User Memory to achieve some significant performance results.

One of the most exciting new feature is the support of native graphics in the firmware. With this new feature, one can simply use standard NetMF Graphics methods to render to a display that is attached to a MBN main board.

Since the graphics methods are being done natively and not in managed code, we can expect screen draws at a rate magnitudes above of what can be achieved in managed code.

For instance, with a MBN Quail main board hosting a OLED-C click, one can achieve a full screen flush at more than 53 frames per second (it depends on what is drawn on the bitmap, of course). While doing the same with the MBN managed only driver for the OLED-C Click, the frame rate drops to a mere 1 – 2 frames per second. That is a 5, 300 % increase in performance.

Currently we have support for the following diplay offerings:

  • ILI9163 – 128 x 128 TFT LCD
  • ILI9341 – 240 x 320 TFT LCD
  • SEPS114A – 96 x 96 OLEd (a.k.a. OLED-C Click)
  • ST7565 – 128 x 64 Graphic Monochrome LCD
  • ST7735 – 128 x 160 TFT LCd (a.k.a. GHI N18 or generic)
  • ST7735R – 128 x160 TFT LCD (a.k.a. GHI N18 or generic with Blue/Red Color Space swapped)

We have also added support for orientation : 0°, 90°, 180° and 270° when available. There are absolutely no drop in framerate when the displays is rotated.

Another very nice feature is that you can use different kinds of display simultaneously ! You can then have a B&W ST7565 display and a bigger ILI9341 both displaying different information, at your will. Again, there is no loss in speed.

Last nice feature about native graphics is that you can use small bitmaps and draw them on a bigger display without declaring the whole bitmap.
For example, on the ILI9341, a full-screen bitmap would be 240x320x2 bytes long, which gives 153.600 bytes eaten ! And there is still no program code involved…

With our Flush() feature, you can for example declare a 100×100 bitmap and draw it at (100,200). It is only a 20K bitmap that will not interfere much with your code. And of course, such a small bitmap will be faster to display 😉


Another new feature added to the firmware is the ability to retrieve the processor unique ID. This will allow you too identify your board in code. The native method GetProcessorUniqueID(int[] id) will populate a three (3) integer array with the unique ID of the STM32F427 processor on the MBN main board.

For instance, I got the following values for two separate MBN Quail main boards:

  • 2162726, 825512217, 960049969
  • 4390951, 808734986, 942814261

With this feature it is now possible to uniquely identify a single board if the need arises.

As far as the memory footprint, the original stock firmware left 172, 368 or 168.3K bytes of available memory for user code. We have been able to squeeze all of these enhancements into the firmware and only loose a few bytes of available memory. The new memory footprint is 171, 528 or 167.5K for user code. All this amazing stuff while keeping the memory footprint relatively the same.

We hope you will enjoy those new features ! There are many demo videos on the forum, so that you can see what it is all about :,248.0.html

The firmware can be found on the Download page and the how-to to update it on the Quail board can be found here.

MBN Virtual Sockets

MBN Virtual Sockets

One of MikroBUS.NET great features is what we proudly call Virtual Sockets. In this document, we will tell you what it can do for you and how to use it with you Quail board.

Maybe I should start at the end, though… Because how to use it will not be long ! But the list of what it can do for you will be (much) longer. Here is a simple code sample :

That’s all :)

As you can see, it is pretty simple. And I can assure you that every example we will see in this article will be as simple as this one.
So you may wonder how such a simple thing can be powerful or even useful. I will tell you that just after introducing the concept of sockets that we use on the Quail board.

On the Quail board, we are using 4 MikroBUS sockets. Each pin on a socket has a pre-defined function : PWM, INT, SPI and so on. Each Click board built by MikroElektronika is using this pre-defined assignment.
But pre-defined does not mean “fixed” and the pin labeled “INT” (for example) can be assigned to a standard OutputPort or an InputPort. The fact that the assignment is pre-defined, though, allows us to plug a Click board on any socket, without any restriction. It can even allow two or more Click boards to be stacked, if they do not use the same pins (see the Relay Click driver demo video for an example).

Our drivers (available on the Download page of the website) are all using a Hardware.Socket in their constructor. You simply have to pass the socket you have plugged the board in to the constructor.

This gives code like this one :

Since the drivers are 100% pure NETMF, they are easily reusable for non Click boards. But then you might ask : how can I wire it to the Quail and which socket will I pass to the constructor ?

This is where Virtual Sockets come in handy !

Now it time to take a real example with a Quail and a Devantech LCD03 in I2C mode. The Quail board exposes I2C on each socket, of course, but on screw terminals as well (along with 3.3V, 5V and ground).
So we will use the screw terminals to wire the LCD : power to 3.3V & GND and I2C to… SCL/SDA :)








Once it is wired, you can open Visual Studio and create a new MBN application project. This is not really mandatory and a NETMF project would work, but the MBN template is referencing the MBN core and prepares a nice source for you.
Next, you will have to download the LCD03 driver from our site and add the source code to your project (*). In the generated program.cs, replace BarGraphClick with DevantechLcd03.

You should then have something like this :

The LCD03 driver then needs a socket and the I2C address of the module. But… it is not wired to a socket but to screw terminals !

No problem, just create a Virtual Socket with the needed information :

What did we do ?

First, we create the socket instance, with the “new” keyword, then we assign I2C pins to this socket. Here, we are using I2C, which is a bus. So, every socket on the Quail board is connected to the same bus, hence the same pins.
This is why we have used the I2C pins assigned to SocketOne. We could have used SocketTwo as well. And you do not even need to know what are the underlying processor pins !

And we are done !

We can now enhance this program so that it is displaying something :







As you can see, this is very simple.

Now, let’s imagine that this LCD has a on/off feature for the backlight that you can wire externally (this is not the case of the Devantech LCD03). We will wire it on a pin exposed on the screw terminals : PE5
We decide to connect it to the Rst pin in the socket. We could have chosen the INT pin as well, or any other non-bus pin.


Now, let’s take another example that will be using Quail and the GHI Gadgeteer ENC28J network module.
We already have a driver for this module as it is using the same chip as MikroElektronika ETH Click board. So software is not a problem.
But wait ! The GHI module is not a Click module !? We have the solution with one of our G-Adapters, the one labeled Type-S (for SPI). Those adapters permit the use of Gadgeteer modules on the Quail board in a very easy way.

The hardware will then look like this, with the G-Adapter on socket 3 on Quail :










But on the backside on the G-Adapter, we can see that the Gadgeteer pin 5 (INT pin of the ENC28) is not connected to the MikroBUS INT pin but to the AN pin :(










Virtual Socket will solve that problem in less time than it takes to write this blog post :) Remember, we have plugged the G-Adapter on socket 3. This will then give :

As you can see, there is not need for hardware “green wire” or driver’s modification.


Finally, here are two examples, with more pins used and with the modules on a breadboard wired to the screw terminals of the Quail.

This first example is using GHi’s Character display, which is a Serial LCD :

You can see a demo video of such a character display connected to our Dalmatian board (2 MikroBUS sockets) via a G-Adapter type XY. The video is demonstrating the GPS3 Click driver :


The last example is using MikroElektronika UV Click, which is a SPI module.

On the Quail board, the screw terminals expose SPI3, like sockets 3 & 4. Hence the use of the SocketThree pins definition. We do not have to know what the underlying real pins are (PC11, PC12, PC10 respectively if you really want to know :) )

If you wanted to put the real pins, it would look like this :


Now we are at the end of this topic. I hope you are not sleeping :) And that you better understand the power of Virtual Sockets.

To summarize, I would say that : if you have the MBN driver for your module, then no matter if it is Gadgeteer, custom module or MikroE Click board, you will be able to easily use it on a MBN board ! Dalmatian, Tuatara and Quail are all able to use this nice feature.


Thank you for reading.


(*) We do not deliver complete compiled DLLs with full of useless stuff. We provide each driver’s source code so that you include only what you need.

MBN Core v2.2 released

MBN Core v2.2 released


this is the latest revision of the MBN Core assembly.


It contains a fix for problems encountered with SPI bus and some more cosmetical/internal changes.

The file can be found on the Download page or you can download it with this direct link : 


Previously downloadable version should be considered as buggy and useless.


Gadgeteer drivers

Gadgeteer drivers

We have added a new category of drivers for use with Gadgeteer modules.

Since we now have some G-Adapters, the next obvious thing that could come was drivers for Gadgeteer modules. And since it is very easy to code such drivers, thanks to our Virtual Sockets and/or templates, it will not take long to have more and more drivers for such modules.

How do you use them ? Easy : take your module, see which type it is (U, I, P, XY and so on), plug the appropriate G-Adapter on any socket on the Quail (for example), download our driver and run the sample code provided. That’s all !

We are beginning with only 3 modules but you can expect more in the next few weeks !

As usual, you can find the drivers on our Download page by selecting the “Gadgeteer modules” category.

Please note that the drivers has been coded by MBN and as such does not imply any endorsement from GHI Electronics, who is selling Gadgeteer modules.