1

I would like to draw on a non-standard linux frame buffer with python. I have a Odroid C4 SBC running Ubuntu, with a 3.2 inch LCD screen hat. The LCD is 320x240 16-bit color. I do most of my interaction with a monitor connected through hdmi. The screen uses /dev/fb4 as it's framebuffer, and my monitor is on /dev/fb0. I can directly write to /dev/fb4 in different ways and and stuff shows up on the screen. I'd like to use python to draw simple text and images on the small screen but I'm not sure what modules to use and how to point them at /dev/fb4.

I have found various modules that let you draw to the main framebuffer, like pygame, but I haven't been able to find instructions on how to point them at a different framebuffer.

  • Welcome to [Stack Overflow.](https://stackoverflow.com/ "Stack Overflow")! Questions that ask for software/library recommendations are typically too broad and are not a good fit for this site because any answer is generally just an opinion.. Give a good read over [Where to Start](https://softwareengineering.meta.stackexchange.com/questions/6366/where-to-start/6367#6367), and [Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example "Minimal Reproducible Example") then edit your post. – itprorh66 May 29 '23 at 14:45
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community May 29 '23 at 23:52

1 Answers1

2

Here are some code snippets to help you create your own code.

import mmap # shared memory
import sys  # exit

fbN = 'fb4'   # device created by the device driver

# get width and height
f = open( f"/sys/class/graphics/{fbN}/virtual_size", "r")
wh = f.read()
wa,ha = xy.split( ',')
w = int( wa) # width
h = int( ha) # height
f.close

# get bits per pixel
f = open( f"/sys/class/graphics/{fbN}/bits_per_pixel", "r")
self.bpp = int( f.read())
if not self.bpp in (16,32):
  print( "Unsupported bpp")
  sys.exit()
f.close()

# open framebuffer and map it onto a python bytearray
  fbdev = open( f"/dev/{fbN}", mode='r+b') # open R/W
  fb = mmap.mmap( fbdev.fileno(), w * h * bpp//8, mmap.MAP_SHARED, mmap.PROT_WRITE|mmap.PROT_READ)

# example: write a pixel at position x,y
# the following code support 2 bpp: 32 bits (RGBA) and 16 bits (packed RGB)
x,y = 5,13
if bpp == 32:
  r,g,b,a = 40,80,120,80 # arbitrary color
  p = bytearray.fromhex( '%02x %02x %02x %02x' % ( b,g,r,a))
else:
  r,g,b,a = 10,20,30,1 # arbitrary color
  m = r<<12 + g<<5 + b # pack colors
  p = bytearray.fromhex( '%02x %02x' % ( m>>8, m&0xFF))
pos = (( y * w  + x) * len(p))
fb[pos:pos+len(p)] = p[:] # draw pixel

It's pretty easy to program your own text-to-pixel routine if you use a monospaced bitmapped font (look into /usr/share/consolefonts/). psf file format is documented in https://en.wikipedia.org/wiki/PC_Screen_Font

Note: writing to a framebuffer is a restricted operation. You must add your username to 'video' group.
If you need more info, please detail your question.
Have fun!

user3435121
  • 633
  • 4
  • 13