How to display PyGame framebuffer using systemd service? - python-3.x

I have created an ambilight clone as a personal learning project. It uses USB webcam to capture required RGB data from TV; it is currently fully functional. My problem is that my RasPi is currently headless and I would like to be able to show stuff on HDMI output; e.g. fill the screen with RGB(0,255,0) which is used for finding the TV screen from the webcam image.
Currently, I am using a class called Hdmi. It uses PyGame surfarray which allows to show NumPy arrays on framebuffer. This works just fine when running the code using "sudo $(which python) webcambilight.py". But when using system, apparently there is no surface. It doesn't give any errors; it just stops running. If I remove the Hdmi class, everything works.
This narrows the problem down to this piece of code:
os.putenv('SDL_FBDEV', '/dev/fb0')
os.putenv('SDL_VIDEODRIVER', 'fbcon')
pygame.display.init()
I am not very experienced with Linux, but my understanding is that there is no fb0 when running from systemd? I know that services are usually for things that run in the background. But this is a special case. I want to launch the service automatically when the device is turned on. Ideally I would never have to log into the device using SSH.
Based on another question/answer on StackOverflow, I've tried this code in .service file.
Environment="DISPLAY=:0"
Environment="XAUTHORITY=/home/pi/.Xauthority"
This didn't help, which I think is because I have no display. Fb0 and fbcon are not really on display=:0, right?
My .service file's contents are currently:
[Unit]
Description=Webcambilight
After=network.target
[Service]
Type=idle
WorkingDirectory=/home/pi/webcambilight
ExecStart=/home/pi/.virtualenvs/py3cv4/bin/python -u webcambilight.py
[Install]
WantedBy=multi-user.target
NOTE! This works just fine when Hdmi is not on use. But I would love to use it. Now, if I accidentally move my webcam or my TV, I will have to either open YouTube using TV and play a video of greenscreen and then press calibration button on my raspberry (which is a GPIO push button).
What I would want to do is change input to HDMI 4, which is connected to RasPi. Then, by pressing the GPIO calibration button, my Hdmi class would fill the whole 1920x1080 framebuffer with (0,255,0).
Sooo.. any ideas on accessing framebuffer (/dev/fb0?) while running the systemd service?
The full code of Hdmi class is at: https://github.com/sourander/webcambilight/blob/master/wambilight/hdmi.py

Apparently, this fixes it. The systemd is sending hangup signal for reasons beyond my Linux-knowledge.
import signal
def handler(signum, frame):
pass
signal.signal(signal.SIGHUP, handler)

Related

How to set default audio output on Raspberry Pi to hdmi?

if I execute:
speaker-test -D plughw:1,0 -t wav , sound gets played over the hdmi cable, as it is supposed to.
But if I type speaker-test -t wav , no sound gets played over the hdmi cable, so I guess the issue is the default output device.
Here is a list of what I've already tried:
change the output device in the top left corner on the Desktop
execute amixer cset numid=3 2 in the console
uncomment those 2 lines in the config:
hdmi_drive=2
hdmi_force_hotplug=1
change to those 2 lines in the alsa.conf file:
defaults.ctl.card 1
defaults.pcm.card 1 (also tried with 2 instead of 1)
My goal is to later play sound over a browser, but chrome seems to only be able to output sound over the default audio output device, so I guess I somehow need to change it.
I am a noob, so please tell if me if you need more informations and how to get them.
If anyone has some hits on how to solve this issue, I'd be really grateful
had the same problem (PI 4, Bullseye).
what helped was:
sudo raspi-config
1. System options
S2. Audio
Select HDMI Option (In my case it was HDMI 2, because default output was on HDMI 1)
After that default output worked. Everything else (changing config.txt or alsa.conf) wasn't necessary in my case.
reference: Raspberry Pi Configuration
At the time I tried to get into the configuratioms via
sudo raspi-config
as #reallyATypo suggested, but it seemed to be broken somehow. Even navigating into it on the desktop environment didn't work...
Since there were those weird things going on with the os and there wasn't much data on the RasPi anyways, I decided to set up an entirely new os on the same SD card. On there the default configurations seemed to be already correct and there also was no problem anymore with the os.
Thank you all for answering :)
Idk if that is the right thing to do, but I'm gonna set my answer as a workig one in order to close the issue

Unable to detect usb camera

I am trying to use 5 usb cameras on ubuntu 18.04.1 LTS in python using opencv.
Individually they all work fine, but as I connect them all together the following happens:
Mostly all cameras are successfully detected in start and are listed in lsusb as well as ls /dev/video*, but as I try to use them through my code in python one of these 5 cameras disappear and error like VIDEOIO ERROR: V4L: index 0 is not correct! is printed.A nd after that either ls /dev/video* does not show that camera or the camera name e.g. video0 is automatically changed to e.g. video6. i know if we restart PC the device names are changed but in this case I am not rebooting.
Sometimes the cameras are enlisted in both lsusb as well as in ls /dev/video* but while using select timeout appears.
Let me know if you need further information.
1.Try first to show video streams from all cameras with ffmpeg (or ffplay): https://trac.ffmpeg.org/wiki/Capture/Webcam#Linux
Or with gstreamer.
2. OpenCV can capture video from webcam with any backend (ifit was comliled with it): https://docs.opencv.org/3.4/d4/d15/group__videoio__flags__base.html#ga023786be1ee68a9105bf2e48c700294d
For example: cv.CAP_V4L2, cv.CAP_GSTREAMER, cv.CAP_FFMPEG etc

How to disable a Virtual Terminal in Yocto Linux

Would anyone know how to disable the virtual terminals in linux? I am using Yocto, Morty version on an i.MX6 processor. Even though our base distribution is Yocto, unfortunately we have diverged from building it with recipes, so this is more of a straight linux question than Yocto…
To give some detail as to my problem: It is for an embedded device that has an HDMI port - when I attach a terminal to the HDMI port it shows the Linux Penguin logo, a getty service and blanks out after 600 seconds. I just want to use the hdmi port as an output with nothing displayed on the output and I want it to stay on all the time.
I have found that the hdmi port maps to /dev/tty1 – when I type: echo “asdfasdf” > /dev/tty1 I see the characters output to the monitor.
Here are a few things I have tried to no avail – a lot of these are not needed if I can figure out how to disable it as a virtual terminal…
• I figured out how to disable the getty service but a cursor still blinks. I don’t even want a cursor to show
• I have tried to disable the display of the penguins by disabling the LOGO in the kernel config parameters - I commented anything with LOGO out:
CONFIG_LOGO=y
CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_VGA16=y
CONFIG_LOGO_LINUX_CLUT224=y
To no avail. The logo still shows : .
• The fact that it blanks after 600 seconds is console blanking – I can see it set to 600 in the file: /sys/module/kernel/parameters/consoleblank. When I issue the command: echo -e '\033[9;0]'>/dev/tty1
It sets the console blanking to 0 and wakes the terminal. Being able to wake the console up is limited success but I would like to disable the virtual terminal altogether…
• I tried commenting out any virtual terminal defines in the config file to no avail:
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_CONSOLE_SLEEP=y
CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
Everything I have read suggests that /dev/tty1 is a virtual terminal or console. From what I read about the VT option, disabling the CONFIG_VT should do it:
VT — Virtual terminal Say yes here to get support for terminal devices
with display and keyboard devices. These are called "virtual" because
you can run several virtual terminals (also called virtual consoles)
on one physical terminal. You need at least one virtual terminal
device in order to make use of your keyboard and monitor. Therefore,
only people configuring an embedded system would want to say no here
in order to save some memory; the only way to log into such a system
is then via a serial or network connection. Virtual terminals are
useful because, for example, one virtual terminal can display system
messages and warnings, another one can be used for a text-mode user
session, and a third could run an X session, all in parallel.
Switching between virtual terminals is done with certain key
combinations, usually Alt-function key. If you are unsure, say yes, or
else you won't be able to do much with your Linux system.
But for some reason it doesn’t do anything!
• I found this thread; https://askubuntu.com/questions/357039/how-do-i-disable-virtual-consoles-tty1-6 among others, but none are much help since my distribution does not have any of the directories in the solutions offered in this thread or any others I have found. For instance I do not have a /etc/events.d nor do I have a /etc/default/console-setup file nor do I have a /etc/init directory… I imagine the reason for this is that my distribution uses systemd and the solutions are SysV based init maybe?
Disabling the logo or console blanking would not be necessary if I could just figure out how to disable that port as a terminal…
So does anyone have pointers or things I could try? I am relatively new (returning after 10 years - I worked with DNX 10 years ago v2.6 and it seems everything I knew about init is fairly obsolete lol) to linux so I am sure I am missing a lot…
Thanks,
- Chuck
I think I found the answer to my question. This is actually a frame buffer console documented here: Documentation/fb/fbcon.txt. From the documentation:
The framebuffer console (fbcon), as its name implies, is a text
console running on top of the framebuffer device. It has the
functionality of any standard text console driver, such as the VGA
console, with the added features that can be attributed to the
graphical nature of the framebuffer.
Commenting out the line
CONFIG_FRAMEBUFFER_CONSOLE=y
In the configuration file located in /arch/arm/configs will disable it.
Also this part of the documentation shows you how to disable it at runtime:
So, how do we unbind fbcon from the console? Part of the answer is in
Documentation/console/console.txt. To summarize:
Echo a value to the bind file that represents the framebuffer console
driver. So assuming vtcon1 represents fbcon, then:
echo 1 > sys/class/vtconsole/vtcon1/bind - attach framebuffer console
to
console layer echo 0 > sys/class/vtconsole/vtcon1/bind - detach framebuffer console from
console layer
When I issue the echo 0 command, the cursor stops blinking and starts blinking again when I issue the echo 1 command.
I think there is another way of doing it as well by modifying the Yocto build environment by putting the USE_VT="0" in the OpenEmbedded machine config file. The "USE_VT" variable is referenced by the sysvinit-inittab recipe. This answer was given to me from the Yocto Linux mailing list - but I have not tested it since we have diverged from Yocto...

force vlc to load ui on raspberry booted to cli

I've been googling for this all week, struggling to find a good solution.
I have a training video kiosk script that I've set up for my company, running on an intel NUC. to me, that feels like overkill, so I'm trying to get the script to run on a pi 3 model b to save a little on costs to deploy this thing.
my script works great from desktop, I've been able to get it to run on startup from the cli, & I can even load the videos with the dummy UI - the problem is that there's no sound, and when the video loads in the cli, it fills the screen with errors, then plays as text, like the picture below.
If I run it from desktop, it's fine (just really jittery)
is there a way to force vlc to load its interface without loading the desktop of raspian?
right now, when I call a video, the terminal line inputs like:
vlc-wrapper <file path> --play-and-exit --fullscreen -Idummy
video image
got it to load the video
from command line:
X & vlc <filepath>
also got it to run from python
import os.subprocess
subprocess.call(['xinit', '--', '/usr/bin/vlc-wrapper, '<filepath>'])

How can I determine touch screen device in a bash script?

I am trying out the eGalax touch screen driver for my touch screen, as an alternative to the evdev/xinput_calibrator combination.
The calibration tool that comes with the eGalax driver, TKCal, takes the device to which the touch screen is connected as a command line argument.
Now I would like to start the calibration tool from a bash script. Is there some smart way to determine the device within the script, instead of hard coding "/dev/hidraw0" as in this example:
TKCal /dev/hidraw0 Cal
I presume that I can't rely on the touch screen landing on hidraw0 every time, can I? If I run my software on a different system, with a mouse and a keyboard and touch screen, I guess I have to handle that the devices can be conneted to different hdrawX devices. Please correct me if I am wrong.
Thank you very much!
/Fredrik Israelsson
Try looking at /sys/class/hidraw/hidraw*/device/uevent.
The guys developing the eGalax drive told be to try a much simpler solution:
Write a udev rule that will map the touch screen to a device name of my choice.

Resources