Skip to content

Instantly share code, notes, and snippets.

@Quasimondo
Last active March 1, 2024 09:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Quasimondo/e47a5be0c2fa9a3ef80c433e3ee2aead to your computer and use it in GitHub Desktop.
Save Quasimondo/e47a5be0c2fa9a3ef80c433e3ee2aead to your computer and use it in GitHub Desktop.
Writing directly to the Raspberry PI framebuffer from Python (no GUI or X required)
# After a lot of searching and false or complicated leads I found this brilliant method
# that allows to use a numpy array to get direct read/write access to the rpi framebuffer
# https://stackoverflow.com/questions/58772943/how-to-show-an-image-direct-from-memory-on-rpi
# I thought it is worth sharing again since so it might someone else some research time
#
# The only caveat is that you will have to run this as root (sudo python yourscript.py),
# But you can get around this if you add the current user to the "video" group like this:
# usermod -a -G video [user]
# source: https://medium.com/@avik.das/writing-gui-applications-on-the-raspberry-pi-without-a-desktop-environment-8f8f840d9867
#
# in order to clear the cursor you probably also have to add the user to the tty group
# usermod -a -G tty [user]
# Potentially also to the dialout group (not so sure about that, but I did it before I realized that a reboot is required)
# usermod -a -G dialout [user]
# IMPORTANT you will have to reboot once for this to take effect
import numpy as np
import os
# this turns off the cursor blink:
os.system ("TERM=linux setterm -foreground black -clear all >/dev/tty0")
# this is the frambuffer for analog video output - note that this is a 16 bit RGB
# other setups will likely have a different format and dimensions which you can check with
# fbset -fb /dev/fb0
buf = np.memmap('/dev/fb0', dtype='uint16',mode='w+', shape=(576,720))
# fill with white
buf[:] = 0xffff
for x in range(720):
# create random noise (16 bit RGB)
b = np.random.randint(0x10000,size=(576,720),dtype="uint16")
# make vertical line at x black
b[:,x]=0
# push to screen
buf[:] = b
# turn on the cursor again:
os.system("TERM=linux setterm -foreground white -clear all >/dev/tty0")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment