What are Framebuffers?

A framebuffer acts as a temporary "canvas" that sits inside of your computer's memory. Framebuffers are often used so that the program can draw the lines, points and other objects at different times, and then have everything displayed all at the same time. This reduces the amount of flicker you would otherwise see on your display when you're drawing at all different times.

For our LED Matrix display, drawing to the framebuffer is generally accomplished using the following steps:

  1. Erase the framebuffer so you're starting with a blank canvas.

  2. Draw what you want on the framebuffer — lines, rectangles, points, objects, etc.

  3. Display the framebuffer on the LED Matrix.

    For each LED on the LED Matrix (there are 64 of them), the framebuffer stores a number between 0 and 15. This number is the color of the LED — colors are shades of red:

    LED COLOR

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    As you can see, the higher the number, the darker/brighter that LED will be displayed as.

Framebuffer Functions

We've already seen the framebuffer point() function. It takes two parameters: x and y, which define which LED to light up using rectangular coordinates. As a reminder, x is the distance from the left side of the LED Matrix, starting at zero. And, y is the distance in from the bottom of the LED Matrix, also starting at zero.

The point() function (and all framebuffer drawing functions) can take an optional parameter that is the color, a number between 0 and 15, as we described above. To draw a point of a specific color (for example, medium red "8"), we can use:

We've also already seen the erase(), which erases the framebuffer. erase() can also take a color as a parameter, which will "erase" the screen with that color (meaning it will make every LED on the Matrix the indicated color).

The show() function displays whatever is in the framebuffer onto the LED. If you've written some code to draw something on the LED display and it does not appear, it's likely you've forgotten to call show().

A framebuffer can also let you know the width and height of the LED matrix display. This perhaps seems obvious — the width and height are always 8. But, in fact, you can build bigger displays with more than one LED matrix. If you do, the total width and height will be different (larger) than 8.

To print the width and height of the display that's hooked up:

Note that fb.width and fb.height above are not functions of a framebuffer, they are actually what are called attributes of the framebuffer. The difference is that they act just like variables, instead of like functions. You can tell they are not functions because functions always have () or (parameters) after them — attributes do not.

Finally, there are two additional functions for drawing lines and rectangles.

line(point_a, point_b) draws a line on a framebuffer from point_a to point_b. Each point is given as coordinates, (x,y). So, for example, to draw a line from the bottom middle to the upper right, you might use:

rect(origin, dimensions) draws a rectangle, where the bottom left corner is the origin, and the dimensions are given as (width,height). For example, to draw a rectangle with a bottom left corner at coordinates (1,1), with a width of 3 and with a height of 5, you could use:

Lines and rectangles support the color parameter, too. And don't forget to show() your lines and rectangles, or you won't see them on the display!

Examples

Here's a set of examples that all use the above framebuffer functions:

The above code just draws a point at the coordinates (0, 0). If we change line 5 (fb.point(0,0)) to use a different function and parameters, the output would look like:

Functions

LED Matrix

# Draw a point in the lower left corner
fb.point(0,0)

00000000
00000000
00000000
00000000
00000000
00000000
00000000
F0000000

# Draw a point in the upper right corner
fb.point(7,7)

0000000F
00000000
00000000
00000000
00000000
00000000
00000000
00000000

# Draw a diagonal line (forward slash)
fb.line((0,0), (7,7))

0000000F
000000F0
00000F00
0000F000
000F0000
00F00000
0F000000
F0000000

# Draw a diagonal line (backslash)
fb.line((0,7), (7,0))

F0000000
0F000000
00F00000
000F0000
0000F000
00000F00
000000F0
0000000F

# Draw an "X" (2 diagonal lines)
fb.line((0,0), (7,7))
fb.line((0,7), (7,0))

F000000F
0F0000F0
00F00F00
000FF000
000FF000
00F00F00
0F0000F0
F000000F

# Draw a "U" (3 lines)
fb.line((0,7), (0,0))
fb.line((0,0), (7,0))
fb.line((7,0), (7,7))

F000000F
F000000F
F000000F
F000000F
F000000F
F000000F
F000000F
FFFFFFFF

# Draw a rectangle from edge to edge
fb.rect((0,0), (8,8))

FFFFFFFF
F000000F
F000000F
F000000F
F000000F
F000000F
F000000F
FFFFFFFF

# Draw a rectangle in the upper left
fb.rect((0,4), (4,4))

FFFF0000
F00F0000
F00F0000
FFFF0000
00000000
00000000
00000000
00000000

# Draw a "U" (1 rectangle, 1 black line)
fb.rect((0,0), (8,8))
fb.line((1,7), (6,7), color=0)

F000000F
F000000F
F000000F
F000000F
F000000F
F000000F
F000000F
FFFFFFFF

# Draw a "Q"
fb.rect((0,1), (7,7))
fb.line((4,3), (7,0))

FFFFFFF0
F00000F0
F00000F0
F00000F0
F000F0F0
F0000FF0
FFFFFFF0
0000000F

# Draw 4 rectangles inside each other
# with each rectangle lighter in color
fb.rect((0,0), (8,8), color=15)
fb.rect((1,1), (6,6), color=11)
fb.rect((2,2), (4,4), color=7)
fb.rect((3,3), (2,2), color=3)

FFFFFFFF
FBBBBBBF
FB7777BF
FB7337BF
FB7337BF
FB7777BF
FBBBBBBF
FFFFFFFF