Skip to main content

8 posts tagged with "docusaurus"

View All Tags

eInk Spectra build guide

· 13 min read
Marius Andra
Maintainer of FrameOS

I've just released a new video build guide, which covers the FrameOS case maker, and the new full color e-ink Spectra lineup from both Waveshare and Pimoroni.

Intro

What follows is the video transcript.

To make a frame like this you'll need four things: the panel, the controller, the case and the software.

In this video I'm going to going to cover all four, and then we'll build a few sample frames together.

Panel

First the panel.

Where I live I have easy access to e-ink panels from two manufacturers: Pimoroni in the UK and Waveshare in China... I can buy directly from them, or from their numerous resellers on Amazon.

Waveshare makes many different panels, most imporantly their latest 6-color e-ink spectra lineup, available in three different sizes. their panels are basically pure glass, and come with a separate little board that you attach to your controller, either through the 40 pin interface, or with the included cables.

Pimoroni's panels also use the e-ink spectra technology, but packaged differently. The panel is glued to a thick PCB, with all the chips on the other side. This makes it much stronger, but also thicker and with larger bezels. The 40pin connector is soldered onto the board, and they also included four clicky buttons for fun and profit. We'll make use of those later.

Controller

Next, the controller.

Technically you could go with a microcontroller such as the ESP32. Those chips are powerful enough to download an image from the internet, and show it on the screen. sadly that's about all they can do. with just 16MB of storage and around half a megabyte of RAM, you're very limited to what you can do on device. your frame effectively becomes a dumb terminal, dependent on a web server to show anything.

That can be a good thing - if someone steals your frame, you can remotely disable it, and they won't have more than the last image on the screen.

I, however went with something else: the Rapberry Pi Zero W2.

With half a gigabyte of RAM and four 64bit ARM Cortex-A53 cores clocked at 1GHz, it's a beast, relatively speaking. it's comparable to a budget Android smartphone from 2014. That means it can store a lot more data, and we can run everything locally on device.

The downside is that it consumes a lot more power: a full watt when idling, so you won't be powering it with a battery. that was never my plan, as batteries are annoying, even if only have to change them once per month.

Case

Third, the case.

Tired of redesigning the same thing over and over again, I learned OpenSCAD and built a tool simply called "The Case Maker". It lets you customize and print out a case for your frame. Choose a template to get started, and modify the parameters to fit your needs. Once done, hit render, download the STL and print away. You'll also need a few 6mm M2 screws, and as many M2x4x3.5 heat set inserts.

The most important parameter to configure in the case maker is the case depth. This determines how much space is left inside for your electronics. The smallest I've gone is 6mm with Waveshare panels. This gives a total thickness of just 1cm, but requires a lot of soldering. You can probably get away with a 9mm case depth if you're using a right angled gpio headers, but even that is not guaranteed, so always measure your components.

For the easiest setup you'll want a Pimoroni panel and a case with a 12mm depth to fit the attached raspberry. For the slimmest setup you'll want a Waveshare panel with a 6mm case depth and a lot of janky soldering. It all depends on your skill level, and how much time you want to put into it.

There are a few other features in the case maker:

  • You can of course modify the various dimensions
  • You can add or remove screws as needed.
  • You can add a print-in-place kickstand
  • You can add a USB cutout
  • You can add various holes for hanging it on the wall
  • You can place an SD card adapter in either the kickstand's leg or in the USB cutout, more on that later
  • You can add pins to hold your raspberry in place, complete with cooling holes
  • You can add even more cooling holes elsewhere on the back
  • You can add as many side buttons as you want.

... and you can print all of this both vertically and horizontally, so for those of you Bambu Lab users complaining that you can't print a case for a 13" frame with your X1C... well, yes, yes you can. Just print it upright. It may warp and require some post processing, but it's doable.

If I have one tip here it's this: print the cover of the case first, and then print the rest. Make sure your expensive piece of glass fits perfectly in there. If not, adjust the dimensions and try again. This one tip could save you a lot of money, as it's very easy to break these panels.

Software

Finally, let's talk software.

I will of course be using FrameOS, which is an open source project I built specifically for controlling e-ink displays around my house.

The first step is to install the FrameOS backend, which is usually done via docker. You use the backend to deploy software onto the frames via SSH. Once a frame is connected - and more on this in a bit - you can choose from any of these ready made scenes, and then hit "deploy".

FrameOS is built in Nim, a compiled language. That means it's fast to run, but it takes time to deploy. We'll now compile all these scenes into a binary, and then run that on the frame.

When you need something more complex than the included scenes, click "edit" and study how these scenes are built. There's always a "render" event that kicks off the whole thing, triggered at an interval. Then the blue "logic" nodes are executed, in the order that they're connected. Green "data nodes" fetch, transform or generate data, and also handle caching. Yellow "state nodes" are user provided input. Logic flows from left to right, data flows down. Pull from a handle to connect it to another handle, or to create a new node. You can also write quick nim code in code nodes with arguments, and you can edit the source behind whole apps. Save and check the "scene source" tab for syntax errors. When you're done, deploy your changes to the frame. If you run into issues, post on Github or ask the community on Discord for help.

Once a frame has been deployed, you can shut off the backend, though it's useful to keep it up and running to collect logs and other system metrics.

SD card

Next, let's set up the SD card.

If you haven't already, install the FrameOS backend. You can install it as a Home Assistant addon, or run it directly with docker. Either copy the oneliner, or run the various docker commands manually.

bash <(curl -fsSL https://frameos.net/install.sh)

Once up, sign up, go to settings and generate a new SSH key. copy the public key and save the changes.

Plug in your SD card and open the raspberry pi imager. Choose the latest 64 bit Raspberry Pi OS Lite version, select your sd card and then edit the customization settings.

Type in a hostname, enable SSH and paste in the public key you just genereated. Save it all and hit write.

Building the 13.3" Waveshare Spectra frame

Finally we're ready to build some frames

wWe'll start with this 13.3" panel from waveshare on medium difficulty.

Before we make any hardware modifications, let's verify that we can get something to render as is. To speed things up, I'm using a full Raspberry Pi 5 here. Attach the control board and the SD card, and power it on.

Go back to the FrameOS backend and add a new frame. Use the same hostname dot local you set earlier, and choose the right driver for your panel. In this case it's the waveshare 13.3"E 6-color spectra panel.

Now, install a few included scenes, and hit deploy.

If you're lucky, an image will appear on screen after a few minutes. If it's rotated, click "settings" and choose "rotation" - "90 degrees". Then redeploy.

You might be wondering what is this QR code. Well, it's something you can use to control the frame directly from the local network. You can disable it under settings if you don't need it.

Now let's switch from a bulky Pi 5 to a Zero W2.

Measuring things, the control board is the thickest piece at 9mm. a pi zero with right angled gpio headers less than that, making our final case depth 9mm.

Open the case maker, select the 13.3" waveshare case, and make sure the depth is at 9mm. as for the other options, we're going to add a USB charging port, and a SD card adapter to the left of it. we'll also add a thick border, as it gives the frame a more classic appearance.

Solder on the gpio header, and attach the wires according to the schematic from waveshare's wiki. plug it in and make sure everything still works.

Great success!

Now to power it, you could just plug a USB cable through the hole, attach the wires, and call it a day. However since we want a professional look, I'm going to use one of these female USB C connetors I found on Amazon. Solder on two cables, and connect them to your raspberry's 5v and ground pins as indicated.

To hold it in place, I'm going to use a bit of superglue. Use as little as possible, as it's very easy to get some in the port and get a cable permanently stuck there. An even better option than superglue is to use a 5 minute epoxy.

Sadly our USB C port will only work with a USB A to C cable, but that'll do for now. If you want to get true USB C to C power delivery to work, you'll need to solder a small 5.1kohm resistor between these two pads here. I tried and failed, so I guess this will have to do.

SD card

Finally, the SD card adapter. This part is strictly optional and quite hard to pull off. We'll be using one of those micro SD card adapters to extend the SD card slot, and make it easy to swap cards without opening up the case.

Cut out 8 identically sized cables, and then follow these schematics to wire them all together. Pretin the pins on both the raspberry and the adapter, and then do your best to not leave a mess. I'm using 24 gauge wires here.

The SD card is still a high speed bus, so it's very easy to mess something up and have it not work. tread with caution. I have about a 50% success rate here.

And there you have it, a gorgeous looking home made 13.3" full color e-ink picture frame.

Attach the heat set inserts to the frame's cover, and screw them in from the back. stop screwing when you encounter resistence --> too much and you'll either rip off the inserts, or punch through the plastic cover itself.

Buliding the 7.3" waveshare frame

Building a frame with the 7.3" waveshare panel is very similar. The one exception is that the control board is much thicker, at around 11mm this time. if you want to keep it as is, you'll need a bulkier case. we'll still use the right angled GPIO headers, and we'll skip the SD card adapter this time

We'll also add a print in place kickstand.

The installation process if very similar. follow the wiring diagram to connect the right cables to the right headers, add a USB charging port as described earlier, and you're good to go.

Unfortunately here I messed up the superglue, and got my USB cable stuck in the port. So I'm just going to hardwire the cable directly to the pi.

And there you have it. It's bulky and could use a better set of colors, but it works!

The slim 7.3" version is pretty similar, with a few key differences. First the control board. How do we slim it down? Our target is a 6mm case depth, as then the entire frame will be just 1cm in depth.

Somehow we're going to need to slim the control board down from 11mm to just 6. Looking at it, we have two things we can remove: the 40pin gpio connector, or the 8 pin connector on the other side. Removing the GPIO connector is hard. It's very easy to pull off copper from the PCB itself, rendering the entire thing useless. It also won't give us the clearance we need.

So instead, we'll be pulling off this other connector, and wiring the cables directly to the exposed pads. Next, instead of using a GPIO header on the raspberry, we'll solder the cables directly onto it.

We'll also add a GPIO button this time. figure out which pins on the button itself are "default off" or no contact, and solder them between the ground pin and a free GPIO port. I recommend GPIO 5 to start. we'll also add the USB C port as before, and use superglue to hold it all in place.

Close it up... and enjoy!

The Pimoroni panels

Finally, let's look at these two panels from Pimoroni.

They're a bit bigger than the ones from waveshare, but like I said earlier, they're much stronger as a result. You won't really notice the extra size in real life.

For the easiest build, choose the 12mm pimoroni case templates. Print it out, attach the panel and the raspberry, and you're basically done. You still need to power it, so either add a USB port like we did earlier, or then stick a cable through the hole and hook it up directly... and that's it.

Set up your frame with the right driver, and it should register the 4 gpio buttons automatically.

Now, you can still slim these builds, if you print a 6mm case, ditch the 40pin connector, and hardwire the raspberry directly onto those exposed connectors. Look at pimoroni's schematics or just use a tester to know which pin goes where... and don't forget about these four extra pins for the buttons.

It's a bit more work, the result might just be worth it. So good luck!

Outro

And there you have it.

There's a lot more we could cover, but those are the basic steps if you want to build a frame like this yourself.

Good luck, have fun, and I'll catch you all next time.

Join the community on discord, and have a great one!

The Case Maker

· One min read
Marius Andra
Maintainer of FrameOS

Case Maker

Introducing The FrameOS Case Maker!

When my new 6-color Spectra e-ink panels arrived, I had to make a case for them. Having just spent way too long on a case for the 12.48" panel, the propsect of doing it all over again wasn't very appealing. So I decided to tackle this problem once and for all.

I learned of Bambu Lab's Makerworld's Makerlab's Parametric Model Maker, and of OpenSCAD that powers it all. I also learned of the OpenSCAD playground, which seemed like a self-hosted version of Bambu's stuff.

A few days of modelling and coding later, and we now have this:

So go ahead, design and print a custom enclosure for your frame in the FrameOS Case Marker!

If you end up adjusting the parameters for a frame we don't yet have listed, submit a PR with your changes here: https://github.com/FrameOS/cases

FrameOS 2024 recap

· One min read
Marius Andra
Maintainer of FrameOS

Exactly 1 year ago I launched the FrameOS Nim rewrite.

Despite the early days, it was a great milestone. The following year brought many quality of life improvements - multiple scenes, external control, iCal support, state and data nodes, rich text, caching, timezones and a FastAPI backend rewrite - a lot of core features were added.

The FrameOS Home Assistant Addon is now ready. It makes installing FrameOS easier than ever before.

I also spent a lot of time 3D printing this year. After many prototypes, the build guide for the 12.48" 3-color e-paper display from WaveShare is finally here in the form of a YouTube video:

You can find the case itself on Printables.

What's in store for 2025 for FrameOS? You'll have to wait and see. The overall goal is to improve the experience. I'd like to make it easier to share scenes between users, work on adding many new apps, and to make the entire experience one that sparks joy.

Join the community on discord, and have a great one!

FrameOS Nim rewrite

· 3 min read
Marius Andra
Maintainer of FrameOS

FrameOS started its life as a Python app that displays an image on a Pimoroni eInk display that's connected to a Raspberry Pi Zero W:

... and a web interface to edit and deploy apps over SSH to said Raspberry Pi:

I wrote it in Python, as that's what the e-ink display drivers came in. It took 40 seconds to refresh the display, so speed of rendering was not a concern.

In the meanwhile, I had added another screen to my house, a cute little Pimoroni HyperPixel 2.1 Round to control the hot water in the bathroom:

I was able to get FrameOS running on it at 2 FPS. While that's enough to show a clock with just seconds, it won't be enough if I want to add a temperature slider or any other interactive elements.

While an eventual rewrite of FrameOS in a compiled language seemed inevitable (why not get the speed and efficiency gains?), seeing how this Python MVP was already getting usage in the wild, I decided to jump the gun and rewrite it all in Nim already now. Doing it later would have been painful for everyone.

But why nim?

What sold me on it were 1) it's features, 2) the praise in the Nim 2.0 HN post, 3) the fact that it definitely is used for real time graphics, and 4) the fact that it has a great graphics library called pixie that supports both SVG and font rendering out of the box.

It's syntax is really friendly after just a bit of usage, it compiles really fast, it has great interop with C libraries, and did I mention it has a great graphics library?

If you imagine native-compiled type-annotated Python where nearly 100% of your code is business logic with no cruft, you're getting close to the Nim experience.

The closest thing to a useful SVG and font library in Python would have been pixie-python, but it's one version behind the nim version, and at this point, why bother with the extra layer of abstraction?

The other compiled languages I considered, like Rust, Zig, Mojo, and Go, all had their own issues, and none hit that sweet spot the way Nim did. Going deep into them would be a post of its own, so let's leave it for another time.

The rewrite

The rewrite was pretty straightforward. It of course took longer than expected, but after about a week of work, I now have something that is (almost) feature complete with the Python version that came before it, while being 10x as fast. 🔥🔥🔥

I also sneaked in a few new features: inline code snippets to override any value, and color fields.

Sadly the rewrite is not fully backwards compatible, as I took the opportunity to clean up some variable and other names. I ask for forgiveness, and hope the 10x wins in efficiency make it well worth it though. It's best to restart all scenes from scratch.

If you wish to remain on the old python version, make sure to stop using the latest docker tag, and instead pin to the last docker tag that starts with legacy-python-.

I hope you enjoy the new version, and I'm looking forward to seeing all the cool FrameOS apps in the wild. ❤️

The work is not done yet. The todo list keeps expanding.

FrameOS gains GPT4 support

· One min read
Marius Andra
Maintainer of FrameOS

You can now chat with GPT4 directly inside FrameOS when building apps:

ChatGPT and FrameOS

To enable this, simply set your OpenAI API key in the settings, and make sure you have access to GPT-4.

MVMVP milestone achievend.

· One min read
Marius Andra
Maintainer of FrameOS

The first phase of FrameOS development is complete. The MVMVP milestone has been achieved, making it feature complete for my own home use.

Walkthrough

You can now edit and deploy python code directly from FrameOS.

Why FrameOS?

· 2 min read
Marius Andra
Maintainer of FrameOS

About a year ago we moved to a new house. The light-to-switch situation downstairs was unbelievably inconsistent. To fix that, I placed little Zigbee switches behind every light toggle, and taped Philips Hue Dimmer switches over the old physical ones. Thus began my journey into smart homes.

A year later, the biggest first world problem I had was losing time running around the house, closing all windows, before rushing out to pick up the kids from school. There's not a lot of crime around here, but if they get you, it's by learning your patterns of forgetfulness.

The obvious answer was to install Zigbee sensors on all the windows, and put a small screen next the front door.

Turns out Raspberry Pi powered color e-ink displays are actually not that expensive, so that's what I went with:

However the software side of things was rubbish.

Enter FrameOS.

It's a piece of software that SSH-s into a Raspberry Pi, and installs python scripts which display an image in a loop.

It has also slowly scope creeped its way into a visual programming environment on sorts:

This project is fresh, so expect things to break. But if you're interested in trying it out, check out the installation instructions