Embedded systems often need a small display. The programming required to support that distracts from the main focus of the project. IO pins are also costly. The simplest possible method of adding a display is desirable. Having a low cost separate processor to manage the display with an easy to load firmware and a simple command set seems like a good idea. A single serial tx pin (and rx if a touch screen is used) should be enough. Instead of using binary commands and supplying a library of code in every language, a simple human readable text command format can be used.
The general format is a series of commands which are just a number and the first letter off a command or attribute. e.g. L for Line, c or C for Color.
It ends up a bit like a g-code. But postfix at least for now. e.g. not X10, but 10x.
| Commands | Attributes | Description |
|---|---|---|
Zero |
Clear the display, erase all groups and areas | |
O |
x y diameter color | A filled in circle |
Point |
x y P [x y P ...] | Just a way to save a list of points |
Line |
color width | A series of lines from 'P'oints. (can't enclose group id) |
Shape |
x y P [x y P ...] | A closed series of lines forming a shape. |
Rect |
x y width height | A filled in rectangle (use Path for outlines) |
Text |
x y color height | Text. The characters are placed between the T and the attribues |
Map |
pixel data | See below |
Arc |
x y diameter begin end color | An arc or non-filled circle |
Graph |
x y w h , series | Plots a graph of points |
| Attributes | Description |
|---|---|
id |
Specify a group by setting the ID number |
x |
0 to display width |
y |
0 to display length |
width |
+ integer |
height |
+ integer |
diameter |
0 to minimum of display width and height |
# |
set radix (default hex) for this number |
, |
pushes integer onto a series |
Color |
RGB 565 value, use # for hex but only w/uppercase C to end |
begin |
Starting arc degrees 0-360 |
end |
Ending arc degrees 0-360 |
Font? |
" |
100x 100y P 200x 100y P #ffffC L
Draw a line from 100,100 to 200,100 colored white. It starts with a Point at 100,100 and another at 200x100 with a color setting of ffff (RGB all fully on) which is in hex (#) and then with all that set up, we can draw the Line. Note that we use C instead of c to set the color so that hex c is possible.
1i 10x 20y 40h 50w #f800C R
Sets up a clickable filled rectangle. It's clickable because it's in a Group which starts with the Id of 1. The Rect goes from 10, 20 and is 50 wide and 40 hight, and a red fill Color.
A click in that area sends a "1" back to the host.
Multiple objects can be part of a single group, just set the same id for each one.
2i 100x 35y 25d #07e0C O
A 25 pixel diameter green filled in circle at 100,35 in group 2.
A live example with test code is available at:
https://wokwi.com/projects/446578045170487297
press the green play button (hopefully it won't have to compile) and then you can enter
strings at the lower right for the interpreter. e.g:
1i 10x 100y 10h 50w #f800C R
to add a 10 by 50 pixel red rectangle at 10, 100. Please note that the sim is VERY MUCH
slower than the real hardware. Click on any object with an id, and it will send back a
message. Those messages could easily be in whatever data format you like.
The original fonts via GFX are a bit sad, but they have been expanded of late. 'f' to set the font face. 'd' could be re-used as direction. 's' for size.
10x 80y 255C 1s "ABC""DE" T
Prints ABC"DE at 10,80 in a blue double size font.
Size is automatically increased by 1 because the size parameter in GFX is 1 based.
Direction is increased by the TFT_DIRECTION define modulus 4 to make portrait the default.
Quotes can be included by double quoting. e.g. "" puts a " in the string.
Each set of points (called a series) is added using the 'G' opcode. So unlike the other shaps, Graphs are specified over and over as new data comes in. The other attributes can be set once and re-used as long as other shapes don't need them in the mean time, but they must be correct.
10x20y400w200h 1,2,3,4G 1,3,3,3G 1,4,3,2G 1,5,3,1G
Draws a graph of 4 values, with 4 series.
The spacing between the lines is based on the height divided by the number of values; so it is very important to always provide the same number of values with each series.
Arcs are not supported by the GFX library, so a series of lines or pixels would need to be drawn to support that.
Map (aka Mat ala OpenCV) is for transfering pixel data. Combined with the radix setting (#) to change base and we can do things like a binary map from 10,20 for a zero with a dot in the middle. Most commands send with a cr, this one needs an empty line, e.g. cr cr.
10x20y2#
00110000
01001000
10000100
10110100
10000100
01001000
00110000
M
which is the same as
10x20y #30 48 84 B4 84 48 30 M
Radix 1 is a special binary format using # and to be a clearer image than 0 and 1.
10x20y1#
##
# #
# #
# ## #
# #
# #
##
M
Unused letters: J K N Q U V
-
"Why not Nextron, et all?" This is open source, and simple; it doesn't require libraries or binary commands. Simple. FOSS. Cheap. At this points, it's basically a minimum viable project, and I would welcome anyones help / forks / pull requests / etc...
-
"Why not LVGL?" because it's complex. But I would love for you to add that.
-
"Why not put the command letter first?" the things I love about postfix is that it makes tiny interpreters like the one I implemented there REALLY simple... and simple code is (perhaps) harder to mess up while not being THAT much harder to use. Right? No? Ok...
-
"Why Pi Pico?" super easy to use e.g. drop a UF2 on the Pi Pico in USB mode, connect some wires, send easy to remember human readable commands.
Used letters: ABCDEFGHILMOPRSTWYXZ