Connect an Arduino to a Rasberry Pi via an HC-05 Bluetooth Module
Walk through of how to connect an HC-05 bluetooth module to a Raspbery Pi and setting up a service to automatically connect the device on startup and disconnect.
The £5 HC-05 Bluetooth Transcever Module is a popular choice for Arduino and Raspberry Pi projects however, it can be a touch fickle when it comes to connecting especially in the more recent iterations of Rasbperry Pi OS.
Add the serial port profile to the pi
To do this you need to edit the
dbus-org.bluez.service file. (Use
nano instead of
vim if you haven't used vim before.)
sudo vim /etc/systemd/system/dbus-org.bluez.service
[service] section you need to add the compatability flag (
-C)at the end of the
ExecStart line and then add
ExecStartPost=/usr/bin/sdptool add SP below it:
ExecStart=/usr/libexec/bluetooth/bluetoothd -C ExecStartPost=/usr/bin/sdptool add SP
Restart the services:
sudo systemctl daemon-reload sudo systemctl restart dbus-org.bluez.service
Pair and trust your device
The simplest way to do this is to run
bluetoothctl in interactive mode.
Assuming you didn't have any syntax errors in your file, this will change the prompt to
You'll be presented with a list of available bluetooth devices one of which should be:
00:00:00:00:00:00 HC-05 make a note of the address. If you can't see your device you might need to put it into pairing mode. Now run:
If your device has a PIN set you will be prompted to enter it. Once you've paired you need to run
to get out of bluetoothctl type
Test your connection
sudo rfcomm connect hci0 <00:00:00:00:00:00> <channel>
This is telling the internal bluetooth module (
hci0) to connect to your HC-05 module. If you don't specify a channel it will use 1. This should give you something like
connected /dev/rfcomm0 to 00:00:00:00:00:00 on channel 1 Press CTRL-C for hangup
If your bluetooth device is sending data you can trivially check this by running
cat /dev/rfcomm0 in a different terminal window.
NOTE: if you try to connect using
bluetoothctl you will get
Failed to connect: org.bluez.Error.NotAvailable.
Connect on boot
The neatest way to do this is to create a service.
sudo vim /etc/systemd/system/<connectbt>.service
Add the following:
[Unit] Description=Automatic connection to a bluetooth device After=bluetooth.target Requires=bluetooth.target [Service] User=root ExecStart=rfcomm connect hci0 <00:00:00:00:00:00> Restart=always RestartSec=20 [Install] WantedBy=multi-user.target
Reducing the restart interval from the default 100ms gives time for the user to turn the bluetooth device on in case they forget. If you don't do this you will hit the default
StartLimitBurst (5) and the service will terminate.
If you want to check for the device more frequently it would be prudent to set
StartLimitBurst in the
[Unit] section. Be careful to ensure that
Start your service:
sudo systemctl daemon-reload sudo systemctl start <connectbt>.service
Troubleshooting your script
If your service fails you can find the error message by running
journalctl -e -u <connectbt>
-edrops you in at the end of the pager output
-ulimits the logs to those from the specified unit
- if you don't want the whole output you can also add
-n <lines>to limit it to the last n lines
- If you want to check whether the service is connecting properly on failure you can add
-fto tail the log.
- Getting the Pi to connect to the module: https://forums.raspberrypi.com/viewtopic.php?p=947185#p947185
- rfcomm: https://www.tutorialspoint.com/unix_commands/rfcomm.htm
- Managing Bluetooth Devices on Linux Using bluetoothctl: https://www.makeuseof.com/manage-bluetooth-linux-with-bluetoothctl/
- Serial Bluetooth Communication: https://pirobotblog.wordpress.com/2016/12/22/serial-bluetooth-communication/
- How to Use journalctl to read Linux System Logs: https://www.howtogeek.com/499623/how-to-use-journalctl-to-read-linux-system-logs/
- Systemd Service Options: https://www.freedesktop.org/software/systemd/man/systemd.service.html#Options
- Systemd Unit Options: https://www.freedesktop.org/software/systemd/man/systemd.unit.html#[Unit] Section Options
Comments powered by Talkyard.