How to Play Prayer Adhan Automatically on a Raspberry Pi with a Bluetooth Speaker

Written by

in

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.

  1. Choose Raspberry Pi Zero 2 W as the device
  2. Choose Raspberry Pi OS Lite (64-bit) as the OS โ€” no desktop needed for this
  3. Choose your SD card
  4. 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
  5. 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 trust command 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 ADT to 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.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *