DIY Bluetooth MIDI Bridge

This page describes a project to create a device which can connect together USB MIDI gear and make them available to an iOS device over Bluetooth MIDI. The project can be made from any Raspberry Pi model that supports Wi-Fi and Bluetooth.

If you have multiple hardware MIDI devices, you've probably connected them to a USB hub and then to your iOS Device through the Apple USB Camera Connection kit. This little box will allow you to un-tether the iPad or iPhone so that it can send to and receive from any device over BLE MIDI instead. It has the added advantage that it automatically sets up routing between all devices so that they can all talk to each other. (It's up to you to manage channels and ensure there are no MIDI loops.)

The project is described in detail by its designer, Neuma Studio here: Raspberry Pi as USB/Bluetooth MIDI Host. I'm only adding a few details and a simple extension to view the device status via web browser here.

Here are a couple of pictures of my device. The first has an attached miniature display, which I decided I didn't really need. The second shows a web-based view of the connected devices that I added to the original project to be able to easily see what's going on without the LCD display.

One would need some deep Linux configuration skills to make this project were it not for the excellent step-by-step instructions in the article. But if you are able to follow directions carefully anyone can do this.


  • Any Raspberry Pi with Bluetooth Low Energy (BLE) capability. I used a Raspberry Pi Zero W for its low cost and tiny form factor, but higher-end devices may perform better and have the added advantage of multiple USB ports, meaning you can plug devices directly into them without the need for a hub.
  • Power supply for the Pi. This can be an official power supply, USB charger with appropriate wattage and appropriate cable with enough wattage, or a battery bank with appropriate cable. You'll need to figure out what works, but I recommend getting an “official” power source, at least to start out. The ones with a power switch are the handiest.
  • (Recommended) Case to protect the Pi. I recommend a clear case or at least one with a clear top so that the LED that shows it's powered on is visible.
  • One or both:
    • A computer with an “ssh” terminal to connect to the Pi. This is built-in with a Mac. PC's require a program such as PuTTY. Using this option will make things much easier as you will be able to cut and paste from the instructions in the article rather than typing everything!
    • A USB keyboard and HDMI monitor with the appropriate adapter (mini or micro HDMI) for your device. This makes it easier to troubleshoot if you have problems getting the Pi hooked up to your Wi-Fi network, or if something else goes wrong. But it's not needed if you can get ssh access working.
  • A USB hub (and Micro USB adapter for the Pi Zero W) if needed to connect multiple devices.
  • A Micro-SD reader for your PC or Mac.


As mentioned earlier, there is a lot of deep Linux configuration going on here. Compiling programs, editing system level commands and working in at least two different programming languages. But, if you can follow directions carefully and check your work each step of the way, you don't need to understand any of what you're doing. 8-)

If you look at the article and simply freak out … well, check the Easy Instructions for a simpler method that should “just work”. Really. Just burn the image to an SD card, plug it in, power on, and plug your devices in. They should all connect, and you should see the device available in your available Bluetooth connections in AUM or other host. You won't have visibility to confirm devices are connected, but generally that's not needed anyway.

The Neuma Studio article details the project better than I ever could. I will only be covering a few extra bits of information from my own experience, and the added web server page I created for viewing the device status.

There are a lot of instructions on the net for ways to burn Raspberry Pi OS images. I've found the simplest is to install using the official Raspberry Pi OS Imager. Select Raspberry Pi OS (Other) > Raspberry Pi OS Lite (32-bit). After installation you'll need to remove and re-insert the SD card to gain access to the “boot” partition to set up WiFi and terminal (SSH) access.

By design this is a “headless” device, meaning that it operates without a monitor, keyboard, and mouse. Why? Because this is a single-purpose device that you don't need to interact with (unless something goes wrong), and not installing all the graphical user interface elements reduces the needed processing power significantly.

You can connect a USB keyboard and an HDMI monitor or TV with the appropriate adaptor for your chosen Pi model. This is useful if the thing doesn't seem to be booting or connecting to your network. A far better way is to connect via “ssh” using a desktop computer. It's more complicated to set up, but will save a ton of time and mistakes by letting you copy and paste from the instructions.

Network Connection

To use ssh, you will first need to get your device connected to your network. If the device has an ethernet port and you can connect to your home router, then you're good to go. If not, you need to set up WiFi before booting your device. Follow the directions under PREPARING THE MICROSD CARD in the article.

If you don't know how to create or edit a file in the “boot” volume of the micro-sd card:

  • On MacOS: press <cmd><space> to bring up the search box, then type terminal<enter>. This will get you to a command prompt. Then, to create the wpa_supplicant.conf file you can type nano /Volumes/boot/wpa_supplicant.conf to create the file and open an editor. When done editing press <control-s>, then <control-x>, which should save the file and return you to the command prompt. Next, to create the ssh file, type touch /Volumes/boot/ssh.
  • On Windows: There is an excellent article here: that should tell you everything you need to know.

Access to the Command Line

If you've managed to get connected to your network, the next challenge is ssh access.

  • On a Mac you should be able to connect by typing ssh pi@raspberrypi.local into a terminal window (see above). If the device is found, the password is: raspberry.
  • On a PC you can use the free PuTTY program. Hopefully connecting to pi@raspberrypi.local will work.
  • In some cases finding the device by name won't work. I highly suggest this article in that case:

Yes! You are finally ready now to carefully follow the excellent step-by-step guide. If you plan to add the web-page status display, it's slightly easier if you skip the ENABLING READ-ONLY MODE steps for now. If you're not sure, then go ahead with these steps though. It's only a little more trouble to work around.

I purchased an LCD display and got it working. However, this resulted in a more fragile device and didn't add that much capability (other than looking hella cool). I decided not to keep it. I decided instead to implement a simple web-based display.

With the web status display you can see which devices are connected, and can also force a reconnection between all devices. Generally this isn't needed, but it's helpful if something doesn't seem to be working right. We use the lightweight Nginx web server for this.

Install Nginx Web Server

  1. Access the device using SSH.
  2. If you enabled the Read-Only file system, then make it Read-Write with the command rw.
  3. Follow the directions on this page: However, you do not need to do the first step “Install the Python package” and the last steps starting with: “As an example, let's create a Python CGI script.”

Add the Web Content

Assuming you're still logged in from the previous steps, execute the following commands, one step at a time, checking to be sure there are no error messages:

cd /var/www/html
sudo rm index*.html
sudo wget -O
sudo unzip

The output from the last command should look like this:

pi@raspberrypi(rw):/var/www/html$ ls  index.html  styles.css


cd /usr/lib/cgi-bin
sudo wget -O
sudo unzip
sudo chmod +x *.py
ls -l 

The output of the last command should look like this:

pi@raspberrypi(rw):/usr/lib/cgi-bin$ ls -l
total 12
-rw-r--r-- 1 root root 1149 Oct 31  2020
-rwxr-xr-x 1 root root 1117 Oct 24 16:37
-rwxr-xr-x 1 root root  321 Oct 24 16:31
Permission Changes

Create the file that gives the web server permission to run some needed commands. Type sudo nano /etc/sudoers.d/010_www-data-nopasswd and paste the following into the file:

www-data ALL=(ALL) NOPASSWD: /usr/bin/aconnect
www-data ALL=(ALL) NOPASSWD: /usr/local/bin/connectall.rb

Press <ctrl-s> <ctrl-x> to save and exit.

Another permissions modification: Type sudo nano /etc/group, then find the line that begins with audio: and make it look exactly like this:


Remember to type <ctrl-s><ctrl-x> when done.

You probably also want to change the time zone on the device since the web display shows the last refresh time. Enter sudo raspi-config, then go to Localization Options > Change Time Zone.

If the Read-Only file system modification hasn't been applied, you should now be able to reboot the device, then go to http://raspberrypi.local from an iOS device to see the status displayed. Otherwise, see below.

If Read-Only File System is in Use

Since Nginx requires log files and the Read-Only mod changed the log directory two more steps are needed. First, add a line into /etc/fstab for a new temporary file system. Type sudo nano /etc/fstab and add a line exactly like the last one below. Then press <ctrl-s> <ctrl-x> to save and exit. Be careful! Don't touch anything else in the file or your system may not boot.

proc            /proc           proc    defaults          0       0
PARTUUID=8ea4fe3d-01  /boot           vfat    defaults,ro          0       2
PARTUUID=8ea4fe3d-02  /               ext4    defaults,ro,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that

  tmpfs           /tmp             tmpfs   nosuid,nodev         0       0
  tmpfs           /var/log         tmpfs   nosuid,nodev         0       0
  tmpfs           /var/tmp         tmpfs   nosuid,nodev         0       0
  tmpfs           /var/lib/dhcpcd5 tmpfs   nosuid,nodev         0       0
  tmpfs           /var/log/nginx   tmpfs   nosuid,nodev         0       0

(Optional) Turn off logging to keep from filling up the temporary file system. Run sudo nano /etc/nginx/nginx.conf. Find the two log setting lines and comment them out by placing a “#” mark before them. Then press <ctrl-s> <ctrl-x> to save and exit.

        # access_log /var/log/nginx/access.log;
        # error_log /var/log/nginx/error.log;

Lastly, invoke the ro command and then sudo reboot. If all went well, the web page should still display when you go to http://raspberrypi.local.

If Read-Only File System is Not in Use

(Optional) If all is working, this might be a good time to follow the directions under ENABLING READ-ONLY MODE in the article. This will help protect the SD card from becoming corrupted when turning off the device. Keep in mind that from the time you do this, a rw command will need to be executed if any changes are made in the device, and certain app major app installations (such as the web-page modification above) require troubleshooting and extra setup to make work. So only do this if you're really ready to lock things down.

That's it! I know this is a long and possibly intimidating article. It's not all as hard as it seems if you take your time. It's a cool and potentially very useful device. I hope you have fun with it if you decide to take it on!

Please contact me if you find errors or omissions in this document. Likewise, please don't hesitate to contact me if you run into questions or problems. The Audiobus Forum topic for this can be found here:

You can also PM @wim on the Audiobus forum if you prefer. 8-)

  • diy_bluetooth_midi_bridge.txt
  • Last modified: 2020/11/05 06:33
  • by wim