Posts Tagged ‘Raspberry Pi’

Cool Music

I purchased some Klipsch AW-400 outdoor speakers for a good price and mounted them on my garage (which is a separate building.) To drive them, I bought a HifiBerry AMP+ and a Raspberry Pi 3B+. I’d been using Max2Play for music streaming but came across Volumio and I prefer it. The web interface is so much better. Also, it makes it really easy to share the USB hard drive I use as a media server on another Raspberry Pi.

Volumio works fine right out of the box and the set up instructions on their site are very easy to follow. The problem I have is that since I live in the desert and have my Raspberry Pi on a shelf high in my garage, it overheats occasionally. I bought heat sinks for it but that didn’t solve the heat problem.

My solution was that I bought a USB powered fan on a goose neck. I got this one but any USB-powered fan, NOT one that charges a battery via USB, will work. I suppose I could just let the fan blow in the Raspberry Pi constantly, but where’s the fun in that? I figured that if I can read the temp, I turn the fan on and off as needed. Yes I can. Yes I did and here’s how.

I found that the CPU temperature is stored in /sys/class/thermal/thermal_zone0/temp as milidegrees Celsius, which means 45000 is 45° C.

I found uhubctl at GitHub which allows Linux in some applications to control some smart USB hubs. Fortunately, a RPi 3B+ is the right application and its USB ports are the right kind of smart USB hubs. To get it to work, it has to be download and compile first.

Volumio ships as a fairly stripped down version of Debian. To add the missing standard software, run:

sudo apt-get update && sudo apt-get -y upgrade

Next, install gcc, make, and a USB library:

sudo apt-get install gcc
sudo apt-get install make
sudo apt-get install libusb-1.0

To download the uhubctl command, we need to install git:

sudo apt-get install git

At this point we should be able to download and compile uhubctl:

git clone git://
cd uhubctl

uhubctl is now ready to use. Next we need to find which port the fan is plugged in to. To list the ports run:

sudo ./uhubctl

You should see an output something like:

Current status for hub 1-1.1
  Port 1: 0503 power highspeed enable connect [0424:7800]
  Port 2: 0100 power
  Port 3: 0100 power
Current status for hub 1-1 [0424:2514]
  Port 1: 0503 power highspeed enable connect [0424:2514]
  Port 2: 0100 power
  Port 3: 0100 power
  Port 4: 0100 power
Current status for hub 1 [1d6b:0002 Linux 4.19.118-v7+ dwc_otg_hcd DWC OTG Controller 3f980000.usb]

In this case, my fan is plugged into hub 1-1 port 2 but it doesn’t show up.

To turn the right port off, you need to be specific about which hub and which port. Plug in the fan, and hunt for it by turning ports off one at a time till the fan stops.

The command to turn off my fan is:

sudo ./uhubctl -l 1-1 -p 2 -a off

To turn it back on:

sudo ./uhubctl -l 1-1 -p 2 -a on

And to get the current status:

sudo ./uhubctl -l 1-1 -p 2

Experiment with it and make sure you can control your fan. Next, we’ll create a script to switch the port on or off depending on the temperature of the CPU:

sudo nano

Copy and paste this code:

# This is where the raw cpu temp is stored
# Could use vcgencmd measure_temp but it returns
#   a formatted string. Messy.
# This is the limit I set. Change as necessary
# To find which port your fan is plugged in run:
#  sudo ./uhubctl May need to experiment turning
#  them off to find it.
port_state=$(sudo /home/volumio/uhubctl/uhubctl -l 1-1 -p 2)
if [ $cpu -gt $limit ]; then
# We're overtemp. Turn on fan if necessary
  if [ $(expr substr + "$port_state" 79 6) == "off" ]
  # Port was off, turn it on
    echo "Overtemp: CPU raw temp is $cpu 'C at $(date)"
    /home/volumio/uhubctl/uhubctl -l 1-1 -p 2 -a on
    printf " -----\n"
# We're undertemp. Turn fan off if necessary
  if [ $(expr substr + "$port_state" 79 6) == "power" ]
  # Fan is on, turn that baby off
     echo "Undertemp: CPU raw temp is $cpu 'C at $(date)"
     /home/volumio/uhubctl/uhubctl -l 1-1 -p 2 -a off
    printf " -----\n"

If you’re using a different hub, you may need to change

  if [ $(expr substr + "$port_state" 55 6) == "off" ]

What it is saying is to start at character 55 and read the following 6 characters. If you use hub 1-1.1, that will throw that number off. To find it, I used the following command and adjusted the first number till I got “power” or “off” with no space in front of it.

port_state=$(sudo /home/volumio/uhubctl/uhubctl -l 1-1 -p 2) && echo $(expr substr + "$port_state" 55 6)

I set the limit to 70° C because the overtemp warning happens at 80° C. Adjust the limit as you see fit.

To make the script executable, run

sudo chmod 755

Now test the script. Change the limit to make it turn on the fan and then change it back to turn it off. Make sure it works. To run the script:

sudo ./

If you don’t use sudo, uhubctl won’t work correctly. Once you’re satisfied with the script, we need to add a cron job to execute it every five minutes. Like I said, Volumio is pretty stripped down, so we need to install cron:

sudo apt-get install cron

Add the script to the cron jobs:

sudo crontab -e

If you don’t use sudo, you’ll only add the script for the user and we need root access for this thing to work.

Add the following line to the bottom of the file:

*/5 * * * * /home/volumio/uhubctl/ >> /home/volumio/log.txt

I included the log file because I want to see that it works. The way the script is written, it will only produce output when it turns the fan on or off so the log file won’t fill up too quickly.

If you want to make sure the cron jobs are working, you can also add:

* * * * * echo “crontest $(date) $(whoami)” >> /tmp/crontest.txt

Don’t forget to remove it or it will create a pretty big log file in a few days.

That should do it. My experience has been that the fan cools the RPI down pretty quickly. Here’s an example of my log file:

Overtemp: CPU raw temp is 70370 'C at Sun Jun 24 22:45:01 PDT 2018
Current status for hub 1-1 [0424:2514, USB 2.00, 4 ports]
  Port 2: 0000 off
Sent power on request
New status for hub 1-1 [0424:2514, USB 2.00, 4 ports]
  Port 2: 0100 power
Undertemp: CPU raw temp is 49388 'C at Sun Jun 24 22:50:01 PDT 2018
Current status for hub 1-1 [0424:2514, USB 2.00, 4 ports]
  Port 2: 0100 power
Sent power off request
New status for hub 1-1 [0424:2514, USB 2.00, 4 ports]
  Port 2: 0000 off
Overtemp: CPU raw temp is 70370 'C at Mon Jun 25 15:40:01 PDT 2018
Current status for hub 1-1 [0424:2514, USB 2.00, 4 ports]
  Port 2: 0000 off
Sent power on request
New status for hub 1-1 [0424:2514, USB 2.00, 4 ports]
  Port 2: 0100 power
Undertemp: CPU raw temp is 52616 'C at Mon Jun 25 15:45:01 PDT 2018
Current status for hub 1-1 [0424:2514, USB 2.00, 4 ports]
  Port 2: 0100 power
Sent power off request
New status for hub 1-1 [0424:2514, USB 2.00, 4 ports]
  Port 2: 0000 off

You can see that it overheated at 70.3° C, kicked the fan on and in 5 minutes when it ran again, the temperature was down to 49.3° C so it turned it back off. While the outside temp remains high, it does oscillate on and off but we’re doing that well below the overheat limit so we should be good.

Raspberry Airplay

My next Raspberry Pi project was to stream music to my stereo system. Since I’m all Apple at home, I decided I need something that uses Apple’s Airplay and the Raspberry Pi seemed the natural choice.

After some research, I learned (unsurprisingly) that the earphone jack on the RPi would be insufficient. It just doesn’t have a high enough bit rate DAC (Digital/Analog Converter) driving it. The first option I explored was to use an external USB DAC. There are some fine ones but they are expensive and bulky. I have to admit though, some of the tube-based DACs look pretty good and I’m sure the sound is impressive but they are cost prohibitive. What to do?

I found HifiBerry. They have a few choices of DACs that plug right into the GPIO (general purpose I/O) port on the Pi. They also sell cases that hold the Pi and DAC very nicely. I found the HifiBerry DAC I wanted on Amazon, added the case and Pi 3 B to my cart but found that ordering a bundle straight from HifiBerry was about $20 cheaper. I already owned a spare MicroSD card an power cord so the project cost me around $100.

I decided on the DAC+ Standard. I didn’t need the DAC+ Pro with its gold plated RCA connectors because I don’t think they make a difference. But some real audiophiles will disagree.

Ordering a bundle from HifiBerry was a bit confusing. What comes with the bundles and what do I need to add? Turns out you need to pick your package and customize everything. For me, I selected the DAC+ Bundle and added the DAC+ Standard, the HifiBerry Universal case, and the Raspberry Pi 3B. If you need a power supply you might find one cheaper elsewhere. If you don’t have an adapter to plug the SD card into your computer, you will need one and HifiBerry’s seems a reasonable price.

If you buy from HifiBerry, the order ships from Switzerland so expect some delay. Shipping information from Switzerland to JFK was provided but once it hit JFK, shipping info disappeared. Since I didn’t get a notification that it was stuck in customs I decided to wait. Ten days later it showed up via USPS. So if time is important, you might pay more and get it from Amazon.

Instructions below the fold…

Read On…

Raspberry Pi as Apple Time Capsule

USE AT YOUR OWN RISK: I’m going to leave these instructions here but until hfsprogs, hfsutils, and hfsplus get updated to support journaling, this option will not work. I picked up a Mac Mini for $200 on eBay and I’m switching over. Good luck.

NOTE: On December 11th, 2019, this post was extensively updated.

NOTA BENE: (12/23/19) Since the last update I’ve run into an issue I don’t seem to be able to solve.

[NOT] RESOLVED: (1/11/2020) It looks like I fixed it. I was having reliability issues with the hard drive. It appears that the RPI can’t handle hard drives better than 3TB and mine was 6 so I partitioned it. Also discovered some better ways to do some things so I’m updating the instructions again.

NOT SO FAST: The RPI drivers must be 32 bit so the largest hard drive they can address is 3 TB. Got it. But, they do not support Mac OS Extended (Journaled) drives and that remains the problem. Time Machine will back up to them but from what I can tell, you can only use Time Machine once to restore from them and then the drive formatting gets scrambled. I tried using drivers from Paragon Software but they won’t run on the ARM architecture the RPI uses.

I’ll skip the obvious stuff about having to own a Raspberry Pi and external hard drive and how to set up the Pi since the first two should be obvious and the third you can find 1,000 other places. Instead I’ll just cut to the chase. This worked for me on a Raspberry Pi 2 and a 3 as well.

I found the instructions here. They are mostly right but now out dated so I’m going to summarize it, clean it up, and inject what I learned from my experience.

  1. I’m assuming you have your RPI up and running on your network and are ready to get Time Machine working. SSH into and let’s get it set up.
  2. Enter sudo apt-get update && sudo apt-get -y upgrade.
  3. We need netatalk to talk to Apple products over the network. Enter sudo apt-get install netatalk -y.
  4. It used to be that this would install an older version of netatalk but that has been up fixed. Verify you’re running the correct version by entering afpd -V (you don’t need sudo and that is a capital V). The first line after you enter that command should be something like: afpd 3.1.XX - Apple Filing Protocol (AFP) daemon of Netatalk
  5. Raspberry Pis can’t natively read Apple formatted disks so you’ll need to install software to allow them to. Enter sudo apt-get -y install hfsprogs hfsutils hfsplus to download and install them.
  6. Format your external hard drive. Plug it into the RPI and run sudo blkid to find it. You’ll need the address which looks like /dev/sdxy (where x and y are numbers depending on where you plugged it in). To format it run sudo mkfs.hfsplus -v Time\ Machine /dev/sdxy. This will format it as HFS+ which the Mac needs.
  7. You’ll need a directory to mount the external drive to. Create it by entering sudo mkdir -p /media/time_machine.
  8. We need to find the UUID of the drive so we mount the right one in the right place. Enter sudo blkid to list the devices. Find your drive in the list and copy the UUID. It is a bunch of numbers and letters between quotes, just copy the numbers and letters, not the quotes.
  9. To have Raspbian automatically mount it on boot, enter sudo nano /etc/fstab. There will already be a few entries in the file. Below them add the following all on one line:

    UUID="numbers and letters" hfsplus nofail,rw,user,auto 0 0

    No quotes around the numbers and letter!
  10. Enter sudo mount -a to mount the drive. It looks at the fstab file you just edited for what should be mounted where.
  11. Next, enter sudo chmod 777 /media/time_machine. This will set permissions on your external drive to drwxrwxrwx.
  12. To verify that the hard drive mounted correctly enter:
    cd /media/time_machine
    sudo touch test

    If that worked, there will be a file named test. That means we’re ready to continue. If you got a message that says the system is read only, you’ll need to troubleshoot that. Take a look at the bottom of this post for some tips.
  13. We need those programs that enable us to talk to Apple products to run every time the RPI boots so we’ll add those two commands to the linux version of autoexec.bat (for those old enough to remember MS-DOS.) Enter:
    sudo nano ~/.bashrc
    Add the following two lines to the end of the file:
    sudo service avahi-daemon start
    sudo service netatalk start
  14. To make sure that the RPI is visible to your Mac’s Time Machine, enter sudo nano /etc/nsswitch.conf and in that file, look for the line that starts with hosts: files mdns4_minimal. Add a space to the end of that line and add mdns4 mdns.
  15. Enter sudo nano /etc/avahi/services/afpd.service This will probably be a new, empty file. Add the following, where it says [Tab], don’t type it, just press Tab.

    [Tab] %h
    [Tab] [Tab] _afpovertcp._tcp
    [Tab] [Tab] 548
    [Tab] [Tab] _device-info._tcp
    [Tab] [Tab] 0
    [Tab] [Tab] model=TimeCapsule
  16. Enter sudo nano /etc/netatalk/afp.conf and under the [Global] heading, add mimic model = TimeCapsule6,106. Then add this to the end of the file:
    [Time Machine 6TB]
    path = /media/time_machine
    time machine = yes
  17. Enter sudo reboot. Give it a few minutes to come back up.

If everything worked, you should see your Raspberry Pi in the Finder under Shared in the left column. Go ahead and connect to it with your Raspberry Pi username and the password. After that launch Time Machine preferences and select the disk. You should see Time Machine 6TB listed. Select that and let it Time Machine do its magic. This will take a while since this is an initial back up.


I had a few hiccups along the way and here’s what I learned.

In the past when I tried to do this, I was using an outdated version of netatalk. Make sure you’re using netatalk 3 or better. If you use the outdated version, you’ll get an error in Time Machine about sparesebundle and it will have error(null) which is not at all helpful.

Something I have encountered is that if the Pi shuts down improperly, sometimes the external hard drive will mount as read only. Here’s how I’ve fixed it:

  1. SSH into the Pi.
  2. Unmount the drive using sudo umount /dev/sda2 (If you don’t remember the drive number, type mount and look for it.)
  3. Unplug the drive and plug it into your Mac.
  4. On the Mac, launch Disk Utility. Be patient. It tooks a moment before the drive shows because it is running a disk repair.
  5. Eject the disk and put it back on the RPI.
  6. Mount it with sudo mount -a
  7. Try it again.

If you have to format your external hard drive because it became corrupted, plug it into your Mac and do the initial Time Machine back up. After that, don’t forget to run sudo chmod 777 /Volumes/Time\ Machine && ls -l /Volumes in the terminal to change the permissions. If you don’t Time Machine won’t be able to use the drive.

It appears that if the Pi is using DHCP, when the IP address is refreshed, you’ll get a error because Time Machine can’t find the drive. If you connect, not via an IP address but using the host name of the RPI, that’s better. Otherwise, you should statically set the IP address of the RPI.

In step 17 above, we named the drive Time Machine 6TB but you can name it whatever by changing that line. This is just the title and doesn’t fix the size of the drive.