I made a thing for RepRapFirmware micropython addon makers

Somewhat TL;DR :wink:
This is a Maker related Software project (at least the bit I’m discussing here is);

Years ago I made the PrintEye, which is a simple display device for RRF based printers (Duet3D and FlyRRF based controllers, plus others).

Although not much discussed here RRF has a strong following thanks to it’s use in the Duet range in industry, and is a very complex system these days with a thriving ‘Software Framework’ used to extend it. At the heart of this is the 'ObjectModel` which can represent all the individual devices that make up a ‘controller’ in a single data structure. This in turn can be accessed as JSON via any stream interface to the controller.

RRF 3.5 (currently in late beta) is a major release with some depreciations; one of which hits the mechanism my original PrintEye uses to get machine data. This change is basically forcing me to use the ObjectModel for PrintPy2040, a micropython based replacement.

I got a bit carried away in building my CPython based prototype (run on a PI3 plugged into my Duet2/wifi) and ended up making a complete serial ObjectModel synchronisation class that runs on both Cpython3 and microPython1. It provides a dictionary that mirrors (user selected) parts of the ObjectModel and can be refreshed as needed.

There is an associated logging loop that implements a robust loop to gather print/cnc/laser data and progress. The output of this is, in turn, is handled by a separate class so that it is easy to implement console/I2C/SPI/Whatever displays.

And a working microPython port running on the XIAO 2040 based printPy2040 that has NeoPixel mood lighting, but no display features yet.

I’m basically posting this here since I need to get it out of my system. Well over a month of work has gone into this so far and I need some air. Once I’ve mowed the grass etc I need to return to the ‘nice user display’ part of the project.

Which is another story; since you would have thought that microPython1+, with it’s internal framebuffer, would have some nice small display/mono font packs available… but it does not. No U8G2 equivalent.
My current project is aimed filling this hole; it’s half done. I have fonts, but need a better way of displaying them.


I previously used an I2C SSD1306 OLED display with MicroPython and framebuffer support with the ESp32. I did not gather what display you’re planning to use, though. (Depending on how your MicroPython is built, framebuffer and specific device drivers may or may not be included).

Yours seems like a cool project.

1 Like

Hi again,

I have been reading your code in github and I can see that you are indeed using SSD1306 and that your code’s comments link to framebuf — frame buffer manipulation — MicroPython latest documentation

There, different graphics primitives are available, like rectangle, line, ellipse, fill, etc.

Perhaps this can help: 14. Using a SSD1306 OLED display — MicroPython latest documentation

1 Like

Indeed I do, for now.

But I actually need to support two other screen (One is a 64K color ift LCD, and the other is an obscure ILxxxx chip where I may need to convert the current, ad-hoc, Arduino/C driver, sigh…)

So the plan is to use the existing FrameBuffer and blitting. The framebuffer.blit() function can handle conversion between framebuffer formats (and color mapping, transparency), so I’ll be focussed on that and hope to support any micropython.framebuffer compatible device.

I have spent some time thinking about this. There is a working demo using the writer class in the repo now, but the main README is sorta obsolete, my plans have evolved.

I hope the initial version can support horizontal justifying by default, and I’ll build the architecture to allow rotation but that probably wont be in the initial set.

The main problem with higher-resolution color displays is that they need a lot of RAM. One widely used display module with MicroPython is the Waveshare 1.8" SPI LCD TFT display based on the ILI9341 driver. If you need more RAM, then SPI RAM might be one solution.

I’m targeting small displays for my text class, the Writer class from micropython-font-to-py is much more suitable for larger displays, and my fonts are already compatible with it. Peters code is quite memory efficient but obviously your MCU needs enough HP for the attached device.

I do provide restricted font sets (eg just ascII and just numeric), to help the memory situation. But once you have a large color display all bets are off. Your Framebuffer will be the limiting factor.

Anyway; my goal is explicit; I want people with cheap, small, oled and lcd displays to have easy access to better fonts. If this is only ever used by educators to make their projects look more attractive I’ll consider it worthwhile.

NB: My code will be CreativeCommons Zero (no blame licence) and only open licenced fonts used.

I figured I should note whats up here:


This is generated using my own writer; there are four fonts there, one inverted and one with transparent background.

code to do this is basically (minus the display setup):

import mPyEZfont_u8g2_spleen_12x24_r
import mPyEZfont_u8g2_spleen_16x32_n
import mPyEZfont_u8g2_6x12_r
import mPyEZfont_u8g2_symb18_e

d0 = SSD1306_I2C(128, 64, i2c0, addr=0x3c)

font1 = ezFBstr(d0, mPyEZfont_u8g2_spleen_12x24_r)
font2 = ezFBstr(d0, mPyEZfont_u8g2_spleen_16x32_n, color=(1,0))
font3 = ezFBstr(d0, mPyEZfont_u8g2_6x12_r)
font4 = ezFBstr(d0, mPyEZfont_u8g2_symb18_e, color=(0,1,0))

d0.rect(0, 0, 127, 62, 1)
font1.write('Test', (0, 0))
font2.write('1.23', (56, 4))
font3.write('Hello\nWorld', (6, 32))
font4.write('bB1!%Z', (44, 32))

Look at dem.py in the dev branch if you want to play.

You need the ssd1396.py driver from there, it is extended so I can detect the colormap (or this can be supplied at font init if using something else)

Colors and transparency are working, I’m using the framebuffer .blit(...,transparantkey, palette) features to apply them so it should work on greyscale and 16bit displays too, though this is untested.

Newlines are supported, and text clips properly. (0,0) is top left of the padded string. documentation is NOT up to date…

I will work further on the positioning/alignment options. I also want to implement padding removal and rotation but these are not intended for the initial release, though there are features/stubs/comments in the code to help implement them later

1 Like