Netduino, GDI and a playable Invaders-like game...
Today's Hardware Friday post takes us to another .Net Micro Framework/Netduino developer who's been on knocking out a bunch of great articles and projects...
C9'ers, this is Mario Vernari. Mario Vernari, this is C9'ers...
This is my second attempt of making an hardware abstraction against a limited UI which can be connected to a Netduino. Most of the times, you can drive a character LCD module or something like that, but no complex displays unless some native library or hardware helper will come in rescue. That's because they require a lot of resources, such as RAM as well as CPU speed. However, until you write apps in managed C# on a Netduino, both of them are very limited.
That's the way I considered only very simple displays, and -why not?- the nice led matrix presented in my previous article.
I don't think to have discovered anything new: I took "inspiration" by the old Windows GDI (Win 98 and earlier), mixed with some elegancy of the newer GDI+ (XP). By the way, GDI+ is the one exposed by the .Net Winforms APIs. Instead, the challenge was to create the very minimum to be able to (literally) play with, without forgetting a decent performance.
Step-by-step usage of library with the Sure Electronics led-matrix.
The library usage should be pretty straightforward. However, a basic knowledge of the Windows GDI/GDI+ and/or Winforms Graphics will help a lot. I don’t teach here anything about it, because it is very well explained in many places, and there are thousands of good examples.
Instead, here I just want to show you how to proceed, step-by-step, for a very basic app. As a minimal example, this app won’t have any animation, but creates only static images on the display. Animations aren’t particularly different, but it require a bit of ability on manage the graphics at best, due the limited performance.
Here we go!
There's nothing special behind it: the process is exactly the same as drawing a static composition, but the sequence of frames is performed many times in a second. The deal is managing the drawing composition on every frame in the quickest way, that require a pretty good knowledge of the library and the framework itself.
Frame rendering: choosing an approach.
There are two approaches on how manage the animation.
The first way is running all the rendering in a tight endless-loop, so that the frame rendering sequence will be as fast as possible. The actual frame rate is not known a priori, but it varies upon the amount of work to be done for the graphics composition. Thus, when a frame is relatively simple, the frame rate will be high. Instead, when the composition is rather complex, you'll experience a poor, jerky animation.
Another way is constraining the frame rate at a certain value (e.g. 20 frames per second). This should ensure the same animation quality in any context, but requires a much more careful development of the composition. In fact, you must be sure that, in any case, no composition will take longer than the maximum allowed (in the example of 20 fps, no longer than 50ms).
I'd prefer the latter, but there are pros and cons in both of them.
Although you may choose the best approach you'll like, you have to deal with short timings of composition in any case. This is the only real task to deal with.
To measure the framing time, I used a simple trick. An OutputPort is taken high on the very beginning of the composition, then pulled low at the end. The high-level duration is measured with the scope (or any logic analyzer), and gives an approximate time of the task.
The bouncing-balls example.
This tutorial will cover an example on how to animate one or more "balls", each one actually drawn as a framed rectangle, and bouncing against the virtual bounds of the display viewport.
The program is structured to animate an array of "Ball" instances, thus you can experience how long takes animating just one or a series of them. A similar project is also interesting for inspecting what and where can be optimized.
Let's start back from a generic application, as seen in this article.
In this post I will show how the GDI library for Netduino can be used for a generic LCD character module (typically HD44780 driven).
The library abstracts the physical layer pretty well, although it’s rather hard to ignore the huge differences between a colored led-matrix and a back-and-white display.
First off, as said, the colors are just two: black and white. Better: blank and shaded, because there are LCDs which displays dark dots on a bright background, but also other models which displays bright dots on a dark background. To mimic the blending as in the led-matrix case, I considered the “Black” as blank (inactive) and the “White” as shaded (active).
Secondly, this kind of LCD module is structured as a character-matrix, so it has an intrinsic ability to display a character. For the led-matrix there’s a font-oriented character generator, which compose the character pattern using the display’s dots.
Thirdly, in a character-oriented LCD module, you cannot target a single “pixel” (meant as a single dot of a character). The “pixels” are something inaccessible from the outside interface, which understands the “character-entity” only, instead.
The hardware and the “old” LCD Boost library.
This project actually replaces the old LcdBoost library, but just for the software side. The hardware is still the same, because it works fine and it’s very fast compared to other solutions.
So, before dealing with the step-by-step tutorial, you should wire up the hardware. Here follows the Fritzing board-view of the circuit.
This is not the very first time an Invaders game has been developed for the .Net Micro Framework (check here), but it should be the very first developed for a Netduino-sized board.
The goal of this post is not give you a game, rather demonstrating how is simple create a pretty complex application using the GDI library for Netduino. Moreover, the good performance of the library as well as the physical layer (driver and hardware) yields the ability to control both a led-matrix and a LCD module at same time.
Of course, for the game to be playable, we also need a minimal controller. A simple sound generation is also provided.
How it's made?
I won't go deeper in the details of the app, because any good programmer can put his/hers hands on it. Instead, I'll go to describe the circuit structure, which is far form being complex.
All the hardware is composed of the following "components":
- a Netduino (Plus) 2;
- a Sure Electronics led-matrix module (introduced here);
- any common LCD character-module (I used a 4x20 one);
- three pushbuttons as the game-controller;
- some parts for the sound generation (optional);
- a good 5VDC power supply (I used a LM7805).
Hardware, code and some space-invaders... Looks like you've got some fun stuff to play with this weekend, don't you?