RadioGlobe is an internet radio player originally by Jude Pullen (Hey Jude), Donald Robson and Peter Milne.
A globe is used to locate radio stations by moving a cursor which scans for stations in the area around large cities. Once a city is found, you can select playable stations displayed on the LCD screen using the jog wheel.
Full details of how to 3D print and build RadioGlobe were published on Instructables and DesignSpark. It runs on a Raspberry Pi with the Open Source code written in Python and is available on GitHub under the Apache License 2.0. The music player is based on VLC and uses pulseaudio.
See CONTRIBUTING.md for how to submit code changes.
RadioGlobe python packages have been tested on a Raspberry Pi 4 model B with 4MB RAM and a powered speaker connected to the audio jack. Bluetooth speakers are supported, tested with a UE Boom 2.
Most of the installation is handled for you with an installation script install.sh. It does the bare minimum to get RadioGlobe up and running. This is in case you have a non-standard setup. It assumes you have a working system based on Raspberry Pi OS Lite that you can SSH into remotely and can play audio through the audio jack.
SPI and I2C interfaces are required for the electronics and setting auto-login for the default user for use with the audio. You can do this with raspi-conf.
If you want to use a BT speaker, you can configure it with bluetoothctl.
Get your Raspberry Pi up and running.
Flash Raspberry Pi OS Lite to a 16GB SD card using Raspberry Pi Imager from the Raspberry Pi Other section. Tested on Trixie. Raspberry Pi OS installation
Note: Use OS Customisations to set the hostname to radioglobe, default user to radioglobe, optional WiFi, timezone and SSH access. If you don't do this here, you will have a hard time getting SSH access!
Insert the SD card, power on the system and let the Pi connect to your network, either via an Ethernet cable (Best) or via WiFi. It can take a couple of minutes on first boot. Use your routers admin page to find the Raspberry Pi hostname and IP address. From your PC / Laptop (Windows / Mac / Linux) open a terminal and login remotely:
ssh radioglobe@radioglobe.local
Bring your system up-to-date:
sudo apt update
sudo apt full-upgrade
sudo apt install git
sudo reboot
Once logged in, open raspi-config as root and setup the interfaces and auto-login:
sudo raspi-config
- Enable
SPIinInterfacing Options- used by the encoders. - Enable
I2CinInterfacing Options- used by the LCD display. - Enable
Auto LogininSystem Options, chooseConsole Auto Loginrequired for pulseaudio sound server. - Reboot
Install Git and download the RadioGlobe source from GitHub. Check out the latest version tag, for example v0.6.0, using the development repo as documented below:
cd ~
sudo apt install git
git clone https://github.com/milnepe/RadioGlobe
cd RadioGlobe
git fetch --tags
git checkout v0.6.0
The installation script install.sh will pull in all the software packages (quite a few), create a Python virtual environment, and install the RadioGlobe Python package into that venv (the project uses a src/ layout). The installer also installs and enables a systemd user service to start RadioGlobe on startup.
The startup template service services/radioglobe.service assumes RadioGlobe is installed into /opt/radioglobe (the installer creates the venv and installs the package there). If you change the install directory you will need to edit the template accordingly.
You can run the installer multiple times if you have any issues.
cd RadioGlobe
bash -x install.sh
install.sh does not reboot automatically — reboot manually once it completes:
sudo reboot
This is required, not just recommended: the dial's kernel rotary-encoder device-tree overlay (added to /boot/firmware/config.txt by install.sh) only takes effect after a reboot. If all went well RadioGlobe will start with the welcome screen after about 30 seconds.
For development and repeated device updates, the repository includes a Makefile that builds a wheel and deploys it to the device.
From the repo root on your development machine:
make build
This generates a wheel in dist/ and writes the resolved package version into VERSION.
To upload and install the built wheel on the remote device:
make deploy
To force-reinstall the exact built wheel into an existing device venv and verify the installed version matches the local build:
make force-deploy
To inspect the version currently installed on the target device:
make device-version
Use install.sh for the first-time device setup or when the device needs the full OS and service installation. Use make deploy / make force-deploy for iterative code updates once the device is already provisioned.
When starting for the first time the encoders need calibrating. Set the reticule cross-hairs to the intersection of the 0 latitude and 0 longitude lines. Now press and hold the middle button until the LED flashes GREEN and the display shows Calibrated.
The system retains the calibration, along with the current station/city selection, in ~/cache/radioglobe.json so you only need to do this once. You can re-calibrate at any time.
Once calibrated, move the reticule near to a large city, for example London GB (51.51N, 0.13W). When a city is close, the LED will flash RED and the first station should start playing. You can change stations using the jog wheel. Set the volume up or down with the top and bottom buttons.
It is important to shut the Pi down correctly so that the SD card is not corrupted. Press and hold the Jog wheel until the shutdown message appears, then press the middle button to shut down. Wait more than 10 seconds before disconnecting the power.
If you have an existing system based on an earlier Raspberry Pi OS release you can try upgrading to Trixie. This may not work depending on how much custom config you have on your system.
Make a copy of your stations.json file if you have made any custom changes to this. It can be copied back to the new installation.
Follow the above from Step 5.
Once RadioGlobe is working with powered speakers you can try adding Bluetooth speakers or headphones. These can be setup with bluetoothctl.
Note: on Trixie we've seen intermittent A2DP pairing failures with some speakers (pairing appears to succeed momentarily then drops before an audio connection is established). If pairing doesn't stick first time, power-cycle the speaker, remove the device (bluetoothctl remove <MAC>) and try again.
Check that pulseaudio is active and running - you may see some failures listed but they can be mostly be ignored:
systemctl --user status pulseaudio
Start bluetoothctl as the default user - the prompt will change to [bluetooth]#:
bluetoothctl
Turn scanning on - the Pi will start scanning for bluetooth devices:
scan on
Now turn on your BT speaker and set it to pairing mode - making sure that no other device is connected to it. It should show up in the list of devices with the MAC address and name of the device, for example:
...
[CHG] Device 88:C6:30:1A:22:10 RSSI: -41
[CHG] Device 88:C6:30:1A:22:10 TxPower: 4
[CHG] Device 88:C6:30:1A:22:10 Name: UE BOOM 2
[CHG] Device 88:C6:30:1A:22:10 Alias: UE BOOM 2
[CHG] Device 88:C6:30:1A:22:10 Class: 0x00240418
[CHG] Device 88:C6:30:1A:22:10 Icon: audio-headphones
[CHG] Device 88:C6:30:1A:22:10 Modalias: bluetooth:v000ApFFFFdFFFF
...
Once you have the DT MAC and name turn off scanning:
scan off
Now pair the speaker using the MAC address:
pair 88:C6:30:1A:22:10
Trust the device so you don't have to do this again after a reboot:
trust 88:C6:30:1A:22:10
Now you should be able to connect to the speaker:
connect 88:C6:30:1A:22:10
If the process is successful, the audio should switch to output from your BT speaker!
When starting RadioGlobe it is best to have your BT speaker off and turn it on once RadioGlobe has started up fully.
App-behaviour settings (volume levels, display/LED timing, search sensitivity) are in radio_config.py. You can change these to suit your setup. GPIO pin numbers and other single-component hardware settings live as private constants in their respective modules instead — e.g. button pins in radioglobe/hal/buttons.py, LED pins in radioglobe/hal/rgb_led.py, the I2C address in radioglobe/hal/display.py — see ARCHITECTURE.md §8 for the full list if you're wiring up different hardware.
Audio code is now in radioglobe/streaming/python_vlc_streaming.py which uses python-vlc. This module can handle station URLs that are plain media formats and also media play lists. This was not the case with the older cvlc player.
To take advantage of pulseaudio it is important to have a logged in user and RadioGlobe must be started as the default user. This will start pulseaudio in a secure way and allow automatic detection of your output devices.
Audio has been tested on Trixie.
Note that radio stations change their URLs all the time so a URL may be out-of-date. You can update this by editing the stations.json file. Save a copy first! Some stations go off-line in their night time, depending on your timezone. Try back later or you can remove them from stations.json.
If things are not working the first step is to make sure that your Pi is setup and up-to-date and you have followed the steps above carefully. We recommend to start with a powered speaker connected to the audio jack first, before moving on to Bluetooth speakers, which are more problematic.
- Check OS release is Trixie - this is what we have tested on
cat /etc/os-release
...
VERSION_CODENAME=trixie
...
- Check the system is up-to-date - if not go to Step 3.
sudo apt update
...
All packages are up to date.
- Check SPI and I2C modules have loaded:
lsmod | grep spi
spidev 16384 0
spi_bcm2835 20480 0
lsmod | grep i2c
i2c_dev 16384 2
i2c_bcm2835 16384 1
i2c_brcmstb 12288 0
- Check that you enabled auto-login in
raspi-config- see Step 4. If the Pi only boots when you SSH in you probably forgot to do this! - Re-run the install script as the default user and check for any failures:
bash -x install.sh
- The startup script must be in
/etc/systemd/user/radioglobe.serviceso that it can be started as the default user. - Check the journal as default user - there is a lot of logging if it is set to DEBUG in
radio_config.pywhich should show up most issues. Don't forget to use the --user param and don't run as root.
journalctl --user-unit=radioglobe.service -b
- If all else fails
Turn it off and on again- usesudo poweroff:)
You can always post an issue on GitHub and we will try to help but we also have other things to do!
- Install UV on your development host
- Clone the repo:
git clone https://github.com/milnepe/RadioGlobe.git
- Checkout your own branch:
cd RadioGlobe
git checkout -b mybranch
- Create a virtual environment - this must be compatible with the version of python on the RPi:
uv venv --python 3.11
source .venv/bin/activate
- Initialise the project:
uv init --no-workspace
- Add dependencies.
python-vlc,liquidcrystal-i2c,spidevandsmbusare Pi-hardware-only and belong in thepiextra (seepyproject.toml's[project.optional-dependencies]), not the base dependencies — the core package and unit test suite don't need them.lgpio/rpi-lgpio(which providedRPi.GPIO) are no longer needed at all —dial.py/buttons.py/rgb_led.pyare all kernel-driven (evdev/sysfs) rather than talking to GPIO pins directly:
uv add --dev pytest
uv add --optional pi python-vlc
uv add --optional pi "liquidcrystal-i2c @ git+https://github.com/pl31/python-liquidcrystal_i2c.git"
uv add --optional pi spidev smbus
- Test UV:
uv run hello.py
Hello from radioglobe!
