Posts for 2025 February

Homeboard: eInk display

Post by Nico Brailovsky @ 2025-02-23 | Permalink | Leave a comment

What's better than one display? Two displays, of course.

When I see a picture in my Homeboard, I often remember when and where I took it (photos are, after all, a form of exomemory), but not always. In wwwslide, my home slideshow service, I workaround this with a QR code: a small QR code is displayed in a corner of the image, and I can scan it to read the metadata of the picture being displayed. This is a good solution, but I'm not entirely happy with it.

Today, I added an eInk display to my Homeboard project. I can show picture metadata (and maybe even a QR code!) without taking up valuable picture real-estate. I chose an eInk display because they are easy to source and work with, relatively cheap, and require very little power (Homeboard is powered by PoE). Some day, I'm hoping to use it as an extra low-power mechanism to show actual homeboard info (a clock? weather? price of memecoins? The options are endless!)

I couldn't get all of the manufacturer's examples to work (especially the partial refresh), but it works well enough to display a thing rendered with Cairo. The original manufacturer's examples had a custom rendering library which was quite unnecessary; my version of lib-eInk gets rid of all the custom rendering code, and uses Cairo to create graphics. Here's an example:

struct EInkDisplay display = eink_init();
cairo_t cr = eink_get_cairo(display);
// Get display's surface
cairo_surface_t *surface = cairo_get_target(cr);
const size_t width = cairo_image_surface_get_width(surface);
const size_t height = cairo_image_surface_get_height(surface);
// Configure "pen"
cairo_set_source_rgba(cr, 0, 0, 0, 1);
cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size(cr, 20);
// Calculate text position
cairo_text_extents_t extents;
cairo_text_extents(cr, "Hola mundo", &extents);
double x = (width - extents.width) / 2 - extents.x_bearing;
double y = (height - extents.height) / 2 - extents.y_bearing;
// Draw
cairo_move_to(cr, x, y);
cairo_show_text(cr, text);
eink_render(display);
eink_delete(display);

Github repo here.


Sidenote: my multiline code rendering seems to be eating pointers for breakfast, so struct S* may be rendered as struct S. I should fix this.


Homeboard V1, bootstrap V2

Post by Nico Brailovsky @ 2025-02-16 | Permalink | Leave a comment

With ~most~ some of the bugs fixed in the industrial design, it's time to setup a second Homeboard. That way I can experiment on one, while the other shows pretty pictures. Because my computer is also a new install, it's now a good opportunity to document the full bootstrap process from an almost brand new and clean Ubuntu 24.04.

Bootstrap a new devenv

Bootstrap the OS

This article has been updated to work, but the gist of it is:

dtoverlay=vc4-kms-v3d
gpu_mem=128

Build things

Build harder things

Install services

The homeboard doesn't do much nowadays, only show images; once you reached this point, and if things build and run, your build environment and target are ready to use. Just a few more arcane spells and we're done:

The target should be ready for production, in only about 30 simple steps!

Appendix: it hangs!


Homeboard: Industrial Design (bonus: Inkscape)

Post by Nico Brailovsky @ 2025-02-09 | Permalink | Leave a comment

My Homeboard project has officially left its cardboard pizza phase. Almost:

The 2 or 3 pixels above show the first "industrial design" of the homeboard. Or at least the parts that "work". It's hanging from a wall, like a real picture frame. Unfortunately it has bugs, and all its guts are hanging from the top.

I spent some time working on a mount, cut with a laser engraver. The mount has two main pieces: a frame for the display, and a horizontal mount that can be hanged from a hook in the wall. The vertical display frame slots into the horizontal mount, meaning there is no flimsy glue holding expensive equipment: gravity does the job. There are some screws and Ls to give it a nice shape, but the main stress between the hook in the wall and the display is supported by the material strength, not by glue. All the cool electronics fit in a small box on top of the horizontal mount. Or at least that's the idea.

As nice as my design is, it has bugs: You can see in the picture I forgot to consider that wires, especially fat cables such as HDMIs, have physical properties, such as bend radius. Without a slot for wiring, the electronics that fit nicely on the top box in my drawing, actually protrude from the top. The ribbon cable was mirrored in my drawing, meaning a weird 180-degree twist was needed to fit the screen to the main board. The box itself doesn't lock, because the "teeth" are slightly misaligned. And the screw holes for the Raspberry Pi are about a quarter mm out of alignment.

Attached to this post is my SVG design, with theoretical bug-fixes for the problems (version 3, if anyone is counting). I haven't tried printing it yet, and I wouldn't be surprised if V4 is required too.

Image above shows the outline; clicking on it should open the original svg, which is probably mostly blank because vector laser cuts have 0.001mm strokes. Download and open with Inkscape to see it (you may need to change the view mode to outline, too).

Bonus: misc Inkscape tips

My experience with anything that has colors is zero, and I had to spend time learning how Inkscape works to build the design above. Seeing a mechanical design you have in your head come to life with a laser cutter is incredibly rewarding, and I can see myself embarking in more ambitious designs some day, when I have more free time. Here's a list of things I learned and should remember next time I'm using Inkscape: