The μLCD 32PT is a nice TFT display from the Australians at 4DSystems. I have found two in an old box - perfect for Recycling Thursday !
The legacy documentation is here (GFX flavour).
So it's time to spin up a Windows VM and try to make something useful out of this !
The μLCD 32PT has two modes: SGC and GFX. From 4D directly : "The architecture of the base PICASO chip is such that it can be reconfigured to operate in 2 distinctively different ways. To configure the device, a PmmC (Personality Module Micro-Code) is downloaded via its serial port. There are 2 types of PmmC available for PICASO."
SGC (Slave Graphics Controller)
In this mode, the module is 'ready to go' by simply connecting it to the serial port of your favourite micro-controller, and sending serial commands to it.
GFX (Stand-Alone Graphics Controller)
In this mode, the module is then like a microprocessor which you program, using the 4DGL language (very similar to C), to control the internal graphics and external interfaces. It does not need an external microprocessor, just power.
We know SGC works (done that before), so let's try GFX (standalone) and see if we can do something nice and fun with that.
Let's create a flappy-bird-like game !
Setting the correct mode
Since the SGC mode is the default mode, we need to reprogram the microcode to use the GFX mode.
To do this, we will use the PmmC Loader (Windows application) and obviously, we'll need a programming cable like this one from 4DSystems.
The GFX microcode can be downloaded directly from the legacy product page of the uLCD (GFX mode), on the Downloads tab (you're looking for the
Just in case, here are the direct links to the two microcode flavours are :
- SGC : uLCD-32PT-I-SGC-R22.PmmC
- GFX (the one we want) : uLCD-32PT-I-GFX-R32.PmmC
Once you have all that installed, launch the PmmC Loader and choose the correct file :
Click Load, and it's done under a minute.
Compiling an example
We'll first assess that the module is correctly working by compiling and writing an example.
You have to install the legacy 4D Workshop IDE
This should work as expected (I tested on a Windows 7 virtual machine).
When you run the Workshop software, you have to select the correct platform : uLCD-32PT_GFX2 in the "Platform" select, and choose the correct COM port (here, COM3).
You can now compile and load any sample to see if it is working correctly.
Compiling a 4DVisi example
The IDE has a visual editor that allows to create richer interfaces using the 4DVisi format. This is quite powerful to create graphical programs, but it necessitates a bit more work to compile and run;
You need a micro SD card to copy support files that are then used by the program when it's running on the screen. The micro SD card must be formatted in FAT16 (so, a max of 4Gb).
There is a tool provided by the 4D IDE (Called RMPET) that can achieve that on Windows, and if you're on a Mac, I suggest that you use the
When it's done, you need to copy compiled assets (
.dat files to the SD card. When you build a solution that uses the 4DVisi format, you will be prompted to do so at the end of the compilation. Just select the drive your SD card is attached to, and click OK.
If you are on a VM like me, it gets a bit more complicated since it's quite unpractical to mount a SD card from the host system. In this case, you have to locate the two files, and manually copy them to the SD card.
Once it's done, insert the SD card into your 4D screen, then recompile and click on 'No, thanks' when it asks to copy the file. Tada !
Your code should now work and the assets should be correctly used.
On to something interesting
Now that everything works as expected, time to create a game !
We are not going to use the 4DVisi mode because it's not really needed I think, for a simple program like a flappy bird game, and it's a bit more hassle that needed for the assets. So we'll recreate the assets with code and simplify them heavily instead.
(TL,DR; The code is here and open source, as usual)
The 4D Graphics Language is a bit like C but not really like it. It's not really practical, to be honest, but it's usable.
There is a reference manual here so you can dive into the language and its subtelties (
next .. Wait, what ?).
PICASO Internal functions
Of course we'll use the internal functions of the PICASO chip to access the display, the storage, etc ...
The API is documented here.
We'll take a very naive approach for this game with a very simple loop :
- handle touch events
- detect eventual collisions
- draw the background
- draw the obstacles (that we will move along the X axis)
- draw the bird in the correct position
Beforehand we'll display a very simple splash screen, and we the user loses, we'll just show the score.
I won't use any assets (ie bitmaps) but rather redraw everything in a very simplist way.
I have copied the bird pixel art and translated that to GFX functions (in
calcBirdPosition()). This is a really simple approach. I've simplified the animation and created only two frames : one with the wing up, one down.
As for the "Mario tubes", they are simple rectangles, that I have very naively lighted from the left of the screen. One light and on dark column of pixels do the trick.
The display has a 16-bit depth so a tool like this will come in handy to convert 24 bit colors to 16 bit colors :
It's basic. The bird is falling at constant acceleration (kind of), and a touch makes it "jump" to a few pixels up his position.
The obstacles (3 maximum at the same time) appear from the right of the screen and scroll to the left.
The collision detection is very simple, I just verify that the bird coordinates do no overlap the tubes, or the bottom of the screen.
The Y+ axis is downward when the FTDI plug is at the top of the display by the way
Saving the score on the µSD card
There is no EEPROM on the µLCD-32PT as far as I can tell, so to keep the score across power cycles, we need to write it down on the SD card.
We'll keep it simple and save the score in a TXT file at the root of the disk (
On the device I have here, the SD card is somehow not very robust. I cannot mount the file system at times, and sometimes it works. I guess this may be due to the fact that the board has been sitting in a cupboard above my desk for quite a long time, not protected, and that the SD cards are quite old too.
So that's it !
Grab the code on my Github here and enjoy !