I wanted the Adhan to play in my house at the right times every day without having to remember to open an app. No phone propped up against the wall, no relying on a smart speaker subscription, no touching anything. Just the call to prayer, five times a day, handled.
A Raspberry Pi Zero 2 W turned out to be the answer. It’s an $18 computer roughly the size of a stick of gum. It runs 24/7, uses almost no power, connects to a Bluetooth speaker, and once it’s set up you genuinely forget it’s there. I’ve been running this setup for months and it has not missed a prayer time.
Getting there took some troubleshooting. The Bluetooth audio stack on Pi OS is not plug-and-play, and I hit a few walls. This guide covers everything I did, including the parts that didn’t work and what actually fixed them.
๐ Last Updated July 2026. Tested on Raspberry Pi OS 2026-06-18, based on Debian 13 “Trixie” with Linux kernel 6.18 LTS. That’s the current stable release from the Raspberry Pi Imager.
What You’ll Need
- Raspberry Pi Zero 2 W (~$18 CAD)
- MicroSD card (8GB or more)
- Micro USB power adapter (5V 2.5A)
- Bluetooth speaker
- WiFi connection
- A computer for the initial setup
Why Pi Zero 2 W? It has built-in WiFi and Bluetooth, costs less than a fast food meal, and draws so little power you can leave it plugged in permanently without thinking about it. For a single-purpose device like this, it’s the right call.
Step 1 โ Flash Raspberry Pi OS to Your SD Card
Download the Raspberry Pi Imager on your computer and open it.
- Choose Raspberry Pi Zero 2 W as the device
- Choose Raspberry Pi OS Lite (64-bit) as the OS โ no desktop needed for this
- Choose your SD card
- Click Edit Settings before writing and fill in:
- A hostname (I used
nanobot) - A username and password โ write these down
- Your WiFi name and password
- SSH enabled, under the Services tab
- A hostname (I used
- Click Save then Write
Put the SD card in the Pi, plug it in, and give it about a minute to boot.
Trixie note: The Imager now defaults to Raspberry Pi OS based on Debian 13 “Trixie.” That’s what this guide is written for.
Step 2 โ Connect to Your Pi
You don’t need a monitor. Two options:
Option A โ Raspberry Pi Connect (what I use)
Go to connect.raspberrypi.com, make a free account, and link your Pi. Then click Remote Terminal and you have a full terminal in your browser โ from anywhere in the world, no router port-forwarding needed.
Option B โ SSH
If you’re on the same network, open Terminal (Mac/Linux) or PuTTY (Windows) and run:
ssh yourusername@nanobot.local
Step 3 โ Update Everything First
Before anything else, run a full update. Skip this and you’ll hit weird dependency issues later.
sudo apt update && sudo apt upgrade -y
It takes a few minutes. Let it finish.
Step 4 โ Unblock Bluetooth (Trixie Only)
This tripped me up. On Trixie, the Bluetooth radio can be blocked at the hardware level by default. Your speaker simply won’t show up during scanning if you skip this.
sudo rfkill unblock bluetooth
sudo systemctl restart bluetooth
One-time fix. You won’t need to run it again.
Step 5 โ Install Required Packages
sudo apt install -y git python3 python3-pip bluez bluez-alsa-utils sox
That installs Git to download PiPrayer, Python to run the prayer calculator, the Bluetooth audio stack, and Sox for audio conversion.
Step 6 โ Disable PipeWire
This is the step that took me the most time to figure out. Trixie runs PipeWire as the default audio system, and on the Pi Zero 2 W it flat-out fights with Bluetooth audio. Both systems try to grab the Bluetooth device and they cancel each other out. No PipeWire, no problem.
systemctl --user stop pipewire.socket pipewire-pulse.socket wireplumber
systemctl --user disable pipewire.socket pipewire-pulse.socket wireplumber
sudo reboot
The Pi reboots. Reconnect after 30-60 seconds.
Don’t skip this. I spent a long time debugging why the Bluetooth speaker kept failing to produce audio. This was the reason every time.
Step 7 โ Start BlueALSA
After the reboot, enable BlueALSA as the audio backend:
sudo systemctl enable bluealsa
sudo systemctl start bluealsa
Step 8 โ Pair Your Bluetooth Speaker
Put the speaker in pairing mode, then:
bluetoothctl
Type these one at a time. Don’t paste them all together:
power on
agent on
scan on
Wait for your speaker to appear. If you see a wall of MAC addresses and don’t know which is yours, type devices to see the names alongside them.
Once you spot it, run these (swap in your actual MAC address):
pair B8:D3:A2:03:7A:77
trust B8:D3:A2:03:7A:77
connect B8:D3:A2:03:7A:77
exit
The
trustcommand matters. Without it, the Pi won’t auto-reconnect to the speaker after a reboot.
Step 9 โ Verify Audio is Working
Check that BlueALSA sees the speaker:
bluealsa-aplay -l
Your speaker should appear. Then play a test sound (use your MAC address):
aplay -D bluealsa:DEV=B8:D3:A2:03:7A:77,PROFILE=a2dp /usr/share/sounds/alsa/Front_Center.wav
If you hear something, you’re past the hard part.
Step 10 โ Set the Speaker as Default Audio (Optional)
If you want every audio command to use the Bluetooth speaker automatically without specifying it each time:
nano ~/.asoundrc
Paste this with your MAC address:
defaults.bluealsa.interface "hci0"
defaults.bluealsa.device "B8:D3:A2:03:7A:77"
defaults.bluealsa.profile "a2dp"
Save with Ctrl+X, Y, Enter.
Step 11 โ Stop the Speaker from Disconnecting
Left alone, the Pi’s Bluetooth goes into power saving mode and drops the connection after a while. Here’s the fix.
Part A โ Turn on AutoEnable
sudo nano /etc/bluetooth/main.conf
Find this line:
#AutoEnable=true
Remove the # so it reads:
AutoEnable=true
Save and exit.
Part B โ Add a Reconnect Script
This runs every 5 minutes and reconnects the speaker if it dropped:
nano ~/piprayer/reconnect-bt.sh
Paste this (your MAC address):
#!/bin/bash
STATUS=$(bluetoothctl info B8:D3:A2:03:7A:77 | grep "Connected: yes")
if [ -z "$STATUS" ]; then
bluetoothctl connect B8:D3:A2:03:7A:77
fi
Make it executable:
chmod +x ~/piprayer/reconnect-bt.sh
Part C โ Add it to Cron
crontab -e
Add this line:
*/5 * * * * /home/admin/piprayer/reconnect-bt.sh
Save and exit. Now even if the speaker disconnects, it comes back on its own within 5 minutes.
Step 12 โ Download PiPrayer
PiPrayer is a free open-source tool that calculates prayer times from GPS coordinates and plays an Adhan recording at each one. Exactly what we need.
cd ~
git clone https://github.com/kamranzafar/piprayer.git
cd piprayer
pip3 install configparser --break-system-packages
Step 13 โ Fix the Audio Quality
The Adhan files that come with PiPrayer are recorded at 8000 Hz. Over Bluetooth, they sound rough. This converts all 15 recordings to 44100 Hz stereo in one shot:
cd ~/piprayer/media
for f in azaan-*.wav; do sox "$f" -r 44100 -c 2 "tmp_$f" && mv "tmp_$f" "$f"; done
Takes about 2 minutes. The difference in sound quality is noticeable.
Step 14 โ Update the Play Script
PiPrayer’s built-in script uses PulseAudio to play sound. Since we’re using BlueALSA, we need to change one line:
nano ~/piprayer/play-azaan.sh
Find:
paplay $(dirname "$0")/media/azaan-"$1".wav
Replace with (your MAC address):
aplay -D bluealsa:DEV=B8:D3:A2:03:7A:77,PROFILE=a2dp $(dirname "$0")/media/azaan-"$1".wav
Save and exit.
Step 15 โ Set Your Location
Create the config file PiPrayer reads for your location and calculation method:
nano ~/piprayer/.piprayer
Paste this and update the coordinates and offset for your city:
[Default]
lat = 44.6505
lng = -63.5977
gmt-offset = -3
dst = 0
method = ISNA
asr-time = Standard
prayers = Fajr:0, Dhuhr:0, Asr:0, Maghrib:0, Isha:0
Save and exit.
Finding your coordinates: Search “your city name coordinates” on Google.
GMT offset: Atlantic is -3 in summer and -4 in winter. Eastern: -4/-5. Central: -5/-6. Mountain: -6/-7. Pacific: -7/-8.
Calculation method: ISNA is standard for Canada and the US. Other options: MWL, Egypt, Karachi, Makkah. Use whatever your local mosque follows.
Step 16 โ Match Your Mosque’s Times (Optional)
Calculated times don’t always line up exactly with what your mosque publishes. You can apply a minute offset to each prayer to match. First, check what the calculator gives you:
cd ~/piprayer
python3 piprayer.py .piprayer
Compare that against Muslim Pro or your mosque’s schedule. If Maghrib is 8 minutes off, update the config:
prayers = Fajr:0, Dhuhr:0, Asr:0, Maghrib:8, Isha:0
Negative numbers subtract minutes. Re-run the command above to confirm.
Step 17 โ Pick Your Adhan
PiPrayer comes with 15 different recordings. Try a few:
bash ~/piprayer/play-azaan.sh 1
Change the number at the end to try others (1 through 15). Pick your favourite before moving on.
Step 18 โ Set Up the Automatic Schedule
This is the step that makes it all run itself. Replace the 1 with whichever Adhan number you chose:
cd ~/piprayer
export XDG_RUNTIME_DIR=/run/user/1000
bash setup-piprayer.sh 1
Check that the schedule looks right:
crontab -l
You should see five prayer entries plus a line at 1:00 AM that recalculates times for the next day. Something like:
## PI PRAYER ##
55 03 * * * export XDG_RUNTIME_DIR=/run/user/1000 && /home/admin/piprayer/play-azaan.sh 1 #fajr
11 13 * * * export XDG_RUNTIME_DIR=/run/user/1000 && /home/admin/piprayer/play-azaan.sh 1 #dhuhr
17 17 * * * export XDG_RUNTIME_DIR=/run/user/1000 && /home/admin/piprayer/play-azaan.sh 1 #asr
44 20 * * * export XDG_RUNTIME_DIR=/run/user/1000 && /home/admin/piprayer/play-azaan.sh 1 #maghrib
27 22 * * * export XDG_RUNTIME_DIR=/run/user/1000 && /home/admin/piprayer/play-azaan.sh 1 #isha
0 1 * * * export XDG_RUNTIME_DIR=/run/user/1000 && /home/admin/piprayer/setup-piprayer.sh 1
## PI PRAYER ##
Step 19 โ Handle Daylight Saving Automatically
Twice a year the clocks change and the GMT offset needs to update. This script does it for you every night so you never have to think about it:
nano ~/piprayer/update-offset.sh
Paste this (update the timezone code and offsets for your region):
#!/bin/bash
CONFIG=~/piprayer/.piprayer
IS_DST=$(date +%Z)
if [ "$IS_DST" = "ADT" ]; then
sed -i 's/gmt-offset = .*/gmt-offset = -3/' "$CONFIG"
else
sed -i 's/gmt-offset = .*/gmt-offset = -4/' "$CONFIG"
fi
Make it executable:
chmod +x ~/piprayer/update-offset.sh
Add it to cron, just before the 1 AM recalculation:
crontab -e
Add this at the very top:
50 0 * * * /home/admin/piprayer/update-offset.sh
Save and exit.
For other timezones: Change
ADTto your summer abbreviation (EDT, CDT, MDT, PDT) and update the offset values.
Step 20 โ Final Reboot
Reboot and confirm everything comes back up on its own:
sudo reboot
Wait a minute after it boots, then test:
bash ~/piprayer/play-azaan.sh 1
If the Adhan plays through the speaker, you’re done.
What the Pi Does Every Day
- 12:50 AM โ Checks the timezone and updates the GMT offset if DST changed
- 1:00 AM โ Recalculates tomorrow’s five prayer times based on your coordinates
- Every 5 minutes โ Checks if the Bluetooth speaker is connected and reconnects if not
- Fajr, Dhuhr, Asr, Maghrib, Isha โ Adhan plays at the correct local time
No apps. No subscriptions. No touching anything. It just works.
Troubleshooting
Speaker not showing up during scan: Almost certainly the rfkill issue. Run sudo rfkill unblock bluetooth and sudo systemctl restart bluetooth, then try scanning again. That’s Step 4 โ go back and check.
Speaker connects but no sound: Make sure PipeWire is still disabled. Run systemctl --user status pipewire and if it’s active, re-run the disable commands from Step 6.
Speaker disconnects after a while: Check that the reconnect script from Step 11 is in your crontab (crontab -l) and that AutoEnable is set to true in /etc/bluetooth/main.conf.
Prayer times off by an hour: Your gmt-offset is wrong. Check what timezone your Pi thinks it’s in with date, then update the offset in ~/piprayer/.piprayer to match.
Audio sounds bad: You probably skipped Step 13. Run those sox commands now and the quality will improve immediately.
Cron not running: Run echo $XDG_RUNTIME_DIR and confirm it returns /run/user/1000. If your user ID is different, update the cron entries to match.
Optional Upgrades
Switch Adhan recording: Run bash setup-piprayer.sh 5 with any number from 1 to 15. The cron schedule updates automatically.
Use your own recording: Convert any MP3 to WAV first:
sox your-adhan.mp3 -r 44100 -c 2 ~/piprayer/media/azaan-16.wav
Then run bash setup-piprayer.sh 16.
Add Pi-hole: The Pi Zero 2 W handles both the prayer clock and Pi-hole (network-wide ad blocking) without breaking a sweat. Two useful things on one $18 device. See pi-hole.net for setup.
SSH from anywhere: Raspberry Pi Connect handles browser access already. For SSH from your phone, Tailscale is the easiest option:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
Install Tailscale on your phone and your Pi shows up like it’s on your local network, from anywhere.
If something in here saved you time, pass it along. And if you hit a problem that’s not covered, drop it in the comments and I’ll take a look.
Leave a Reply