UPDATE 8/27/2022: These instructions have a odd issue with Ubiquiti Unifi wireless AP roaming handoffs. I am currently investigating. If you have a normal Wi-Fi network with only one access point this is not a issue.
This is the updated CabCam software package running UV4L. It operates similarly to MJPEG Streamer but it has a WebGUI for on the fly changes and it generally runs better with less bandwidth useage. If you have already setup the hardware for your CabCam skip to step 3 for the updated software. JMRI’s WebThrottle with video will be the next post.

Overview
We describe how to set up a small computer to stream cab view video from an HO locomotive. This allows remote operation of trains at local or remote layouts, optionally connecting it to video conferencing software like Google Meet or Zoom.
Goals
- Easy to set up and maintain.
- Easy to access the cab view via a URL or via conference software eg. Zoom or Meet.
- Distribute the setup to others for the betterment of the hobby.
- Provide a low latency video stream to enable remote control via Engine Driver/WiThrottle
- Keep the hardware within HO NMRA clearances.
- Use commonly available components and open-source software where possible.
Implementation
Hardware: We are using one Raspberry Pi Zero W 2 per CabCam car. The original Zero works as well but is slower.
Camera: The Pi Zero Spy Camera works well for our purposes.
Software: The project uses Raspian Buster running UV4L conference streaming software on the CabCam car. This streams video from a URL on the local network. The video can be viewed locally or streamed to conference software via OBS and the OBS VirtualCam feature. This software runs Raspberry Pi OS Bullseye(Debian 11) 32bit.
Power: The Juiceb0x Zero is a “hat” for the Pi Zero. While the Pi Zero WH comes with the required header already installed, soldering is required to install header pins on the Juiceb0x Zero board.
Rolling Stock: The easiest approach is build a mounting sled out of styrene as shown below. With a little bit more work the setup can be installed inside a dummy engine, too.
How To
This section describes the setup in more detail. Some familiarity with Raspberry Pi and respective software management is helpful.
1. Gathering the hardware
You will need for the self contained unit.
- Raspberry Pi Zero 2 W
- Juiceb0x Zero
- 160 Degree Pi Zero Camera
- 2×20 header pins 0.1in
- 3.7V Li-Ion battery 2000 mA or larger
- SDHC card 4GB or larger
- Male 2×20 header
- USB charger with microUSB charging cable
For the cheaper unit running a battery bank:
Small Battery Power Bank Amazon has some as well.
160 Degree Pi Zero Camera
SDHC card 8GB or larger
USB charger with microUSB charging cable
2. Setting up the hardware
Solder the male header to the Pi Zero 2. Connect the camera to the Pi Zero 2 W. Solder the header pins to the Juiceb0x Zero per the instructions that come with it and attach it to the Pi Zero 2. Connect the battery to the Juiceb0x Zero. Connect the USB charger to the Juiceb0x Zero to charge the battery.
Never connect power to the USB ports of the Pi Zero 2 W while the Juiceb0x Zero is attached.
For the cheaper version you need plug in the camera then plug the USB micro cable into the power bank and then into Pi Zero. Be mindful of your NMRA gauge, if you need to you can build a sled to hold the Pi Zero on its side so the USB cable is vertical.
3. Burning the image and setting up the software. Those skipping to this step, do this on a second SD card so you don’t mess up your MJPEG Streamer install.
Head over to the Raspberry Pi Foundations website and download the Raspberry Pi Imager and install and run it.
Once open you will be presented with the option to CHOOSE OS, click this and select Raspberry Pi OS(other) and select Raspberry Pi OS Lite(32-bit). Once that is chosen click the gear icon on the main page.
Check Set hostname and set your hostname to whatever you want. I generally chose cabcam# where # is the number of the camera on the layout, eg cabcam1, cabcam2 etc. You want to then mark on the camera hardware which one it is.
Check Enable SSH which automatically checks use password authentication. Below that you can set the username and password. Make sure you write these down or otherwise remember them or you will be making yourself a new image.
Check Configure wireless LAN and set your SSID(Network name) and Password for the wireless network you are going to be using. This MUST be a 2.4ghz network for the Pi Zero W and 2 W. Set your Wireless LAN country to your country abbreviation.
Check Set locale settings and find your time zone. Then if you use a different keyboard layout than US, go ahead and set that.
Optional: Uncheck enable telemetry.
Click SAVE
Click CHOOSE STORAGE and choose your SD card from the options. Then click WRITE. Once the image is written eject your SD card and place it in your Pi. Power the Pi on and give it a few minutes.
4. Logging in to the Pi
Find the IP address your Pi is using via your router and log in using ssh. You may get away with just typing cabcam#.local
Use the credentials you set in step 3.
On a Mac use Terminal. On Windows use PuTTY (you may have to download it) and put in the IP of your Pi in the Hostname block. Try cabcam.local if you can’t find the IP. When you connect use the credentials you set in step 3.
Windows 1909 and up can use the command prompt with the command shh username@ipadressofpi to connect now so you don’t need putty.
On many networks the following also works:
ssh username@cabcam.local
5. Configuring the Pi
Once on the Pi command line type
sudo rpi-update and update the firmware.
echo /opt/vc/lib/ | sudo tee /etc/ld.so.conf.d/vc.conf
sudo ldconfig
sudo raspi-config
to enter the configuration page for the Pi. Arrow down to 3 Interface Options and open I1 Legacy Camera. Follow the prompts to enable legacy camera drivers so we can use UV4L. Exit the config utility.
6. Install UV4L.
Now we are going to configure the software to allow us to stream the cab POV and you can configure the settings you want.
First run the following command to add the UV4L repo to your install.
curl https://www.linux-projects.org/listing/uv4l_repo/lpkey.asc | sudo apt-key add –
echo “deb https://www.linux-projects.org/listing/uv4l_repo/raspbian/stretch stretch main” | sudo tee /etc/apt/sources.list.d/uv4l.listing/uv4l_repo/lpkey
Then run sudo apt-get update, then run sudo apt-get upgrade and accept any prompts.
Run the following accepting any prompts.
sudo apt-get install uv4l uv4l-raspicam
sudo apt-get install uv4l-raspicam-extras
sudo apt-get install uv4l-server
Now you are going to configure UV4L
sudo nano /etc/uv4l/uv4l-raspicam.conf
Set resolution to 640×480 20fps quality to 8(no joke it works great). You can increase this if you are only streaming localy over wifi.
I don’t suggest going much higher if you are going over the internet due to low upload speeds.
You may need to set rotation to flip the camera if your Pi camera is on its side, it goes by degrees so rotation = 180 will flip the image around 180 degrees.
Also find the following and uncomment them.
server-option = –connection-timeout=15
server-option = –enable-keepalive=yes
server-option = –keepalive-timeout=7
and make sure server-option = –max-streams=5 is uncommented and =5. The newer UV4L holds on to connections a little too long.
Run sudo reboot
Now it is time to test the stream.
Open a browser and head to http://IPofPi:8080/
Click MJPEG/Stills Stream and you should see the stream from your camera. If not turn off the Pi and check your cable seating. That is the issue 99% of the time.

The Internet uplink bandwidth at SVL is quite limited. For cab control with remote operators we found that SD resolution is sufficient and limits bandwidth demand. We are using a frame rate of 20 images per second. The stream doesn’t get smoother turning this up.
The camera stream is set to startup on boot.
Put your CabCam car on the front of a train, and run the train while watching the video stream in the browser.
Bernhard wrote down some thoughts on camera placement and car choice on his blog.
9. What’s Next?
To stream the video to remote operators we use OBS with the built in Start Virtual Camera option, configured with CabCam feeds. This is connected to Google Meet and can even stream to Youtube Live. Other video conferencing software like Zoom, Duo, Skype, etc. can be used, too. Remote operators join the video conference and use Engine Driver or WiThrottle to control trains via JMRI over a VPN. You can also run your train all from JMRI’s WebThrottle which will be covered in the next post. OBS will be covered after that because the real star of this show is the WebThrottle.
10. Things to Consider.
If you plan to have multiple cameras you should look into making an image of your SD card so you can burn them to other SD cards without having to do all the above steps. I will leave it up to you to Google “imaging raspberry pi SD card for (insert OS here).” Once you have the image backed up and burned to a new SD card you should run sudo raspi-config and change your hostname to increment your camera name.
Variations
Hardware: While we are using a Raspberry Pi Zero 2 W, any Pi with built-in Wifi will work.
Camera: Any compatible Raspberry Pi camera can be made to work. Possible options are the official Pi camera, the spy cameras, or other compatible cameras available from e.g. Adafruit.
Power: The Zero2Go board is an alternative to the Juiceb0xZero. However, the Zero2Go can’t charge the battery. In either case, do not power the Pi from the onboard USB while the power solution board is attached.
Some people had success with using a small form-factor USB power bank connected to a Pi Zero without additional hardware.
Revisions
Over time we have made corrections to these instructions, or fine tuned settings. Below is a list of important revisions.
- 8/16/22 Added some information to make the CURL commands work in step 5.
Some sources:
Installation for ARM (Raspberry Pi)
the command curl https://www.linux-projects.org/listing/uv4l_repo/lpkey.asc | sudo apt-key add –
echo “deb https://www.linux-projects.org/listing/uv4l_repo/raspbian/stretch stretch main” | sudo tee /etc/apt/sources.list.d/uv4l.listing/uv4l_repo/lpkey fails with errors echo no such file or directory. and “deb https://www.linux-projects.org/listing/uv4l_repo/raspbian/stretch stretch main” no such file or directory.
LikeLike
It has been few weeks since I last ran this, its possible that UV4L got removed from that repo as it was updated recently. I am going to spin up a new install of Bullseye and see if that line is needed.
LikeLike
Seems there was a change last month, run the following to allow you to run the curl commands. I will update the main post.
sudo rpi-update
echo /opt/vc/lib/ | sudo tee /etc/ld.so.conf.d/vc.conf
sudo ldconfig
Taken from
LikeLike