← home

How to connect HC-05 to Linux PC

Bluetooth on Linux has always been a headache for me. As I expected connecting HC-05 module to my laptop wasn't any better. In this note I want to describe how to configure and connect HC-05 Bluetooth module to the Linux PC.

Playing with these cheap (about 3$) Bluetooth modules I wrote a small application which can help to diagnose and configure them. In this article I use Arduino Nano (atmega328p) and classical HC-05 with a linear power regulator. There is no need to solder anything complicated - only one little wire πŸ˜€.

HC-05 Bluetooth module

Image is taken from www.laskarduino.cz

Firstly, let me describe this Arduino app. I can't say that it is reliable but it is simpler than doing everything by hand.

HCTOOLS - HC-05 Configuration tool

This application can be used on most of the Arduinos starting from Arduino Nano. You can download it from the Github. I used platformio as a development environment so if you are familiar with it you know what to do (look into platformio.ini). If not, you can use classical Arduino IDE. To do so, you need to:

  1. Copy content of src/main.cpp into Arduino IDE
  2. Install SoftwareSerial and SimpleCLI libraries with library manager
  3. Upload the sketch.

The application provides "shell"-like interface to work with HC-05 module. It has following commands/features:

To use it firstly you need to connect your Arduino and HC-05 module together.

Hardware Setup. The Arduino will need to control power to the HC-05 module and be able to set HIGH/LOW state on the pin 34 (or PIO11). This is required due to the way HC-05 is switched to AT mode. Firstly, Arduino powers off the module then it sets pin 34 into HIGH state and turns power on. After this HC-05 boot into AT mode.

Schematics of connection of HC-05 Bluetooth module and Arduino

The transistor can be any PNP transistor from your Arduino kit. Make sure that it is PNP by googling its datasheet. I used 2N3906. The resistor also can vary. It is needed to limit current going through the base of the transistor. I picked 1000 Ohm one. I suppose that anything around 500 - 1500 Ohm would work.

Let's try this out! Connect Arduino and HC-05 as shown in the schematics above and flash the application to the Arduino (with platformio or Arduino IDE). Then open serial monitor. You should see something like this:

HCTOOLS. Version: 1.0 (f0341d1)
# 

By default application assumes that module has baudrate set to 38400 (the default baudrate in AT mode). If you changed it previously then change it in the application as well and re-upload it.

Type help into the application shell to see all the available commands.

Back to PC

So, after you set name for your module and configure it as a slave you can try to setup wireless connection. Install Bluetooth stack:

$ sudo apt-get install bluez bluez-utils

Next, lets check if kernel module is installed and loaded. For some chips it will be enough to have btusb loaded but for other chips (like my Broadcom) you will need to find and install appropriate driver. You can check if btusb is loaded into the kernel by the following command:

$ lsmod | grep btusb
btusb                  65536  0
btrtl                  24576  1 btusb
btbcm                  16384  1 btusb
btintel                32768  1 btusb
bluetooth             675840  5 btrtl,btintel,btbcm,btusb

Note: In case you also have Broadcom chip I would recommend to look into this instruction. It seems to be a common solution.

If there is nothing in the output you should try to install general Bluetooth driver:

$ sudo apt-get install btusb

If it won't work try to find driver for your particular device. You can find out some information about name of your Bluetooth chip with following commands:

$ lsusb | grep Bluetooth
... output is hidden ...
$ dmesg | grep Bluetooth
... output is hidden ...

After driver is installed and kernel module is loaded start and enable Bluetooth service:

$ sudo systemctl enable bluetooth.service
$ sudo systemctl start bluetooth.service

Check that service successfully started:

$ sudo systemctl status bluetooth.service
    ● bluetooth.service - Bluetooth service
     Loaded: loaded (/usr/lib/systemd/system/bluetooth.service; disabled; vendor preset: disabled)
     Active: active (running) since Thu 2020-02-20 19:35:07 CET; 23h ago
       Docs: man:bluetoothd(8)
   Main PID: 779 (bluetoothd)
      Tasks: 1 (limit: 6990)
     Memory: 2.7M
     CGroup: /system.slice/bluetooth.service
             └─779 /usr/lib/bluetooth/bluetoothd

Note: There should be - Active: active (running)

Now, after you install the driver reset your PC/laptop. It really has to be power reset (power off -> power on) because during reboot your drivers could still stay unloaded (you know just in case). After boot check output of dmesg it should be something similar to this:

$ dmesg | grep Bluetooth
[    5.493394] Bluetooth: Core ver 2.22
[    5.493415] Bluetooth: HCI device and connection manager initialized
[    5.493420] Bluetooth: HCI socket layer initialized
[    5.493422] Bluetooth: L2CAP socket layer initialized
[    5.493426] Bluetooth: SCO socket layer initialized
[    5.751843] Bluetooth: hci0: BCM: chip id 70
[    5.752829] Bluetooth: hci0: BCM: features 0x06
[    5.768841] Bluetooth: hci0: BCM43142A
[    5.769833] Bluetooth: hci0: BCM43142A0 (001.001.011) build 0000
[    6.489850] Bluetooth: hci0: BCM43142A0 (001.001.011) build 0215
[    6.505851] Bluetooth: hci0: Broadcom Bluetooth Device (43142)

Pairing PC with the HC-05 device

First of all, I always try to connect to the HC-05 with Android phone. I used Serial Bluetooth Terminal to connect and send some text to the module to check that it's alive. It is always a good sign that everything going well. So, in case you have one try that. Anyway, in the linux run bluetoothctl:

$ sudo bluetoothctl
 Agent registered
 [CHG] Controller 80:56:F2:E5:43:E6 Pairable: yes
[bluetooth]# 

Make power reset of the HC-05 module and then turn on Bluetooth scan of nearby devices on your PC:

[bluetooth]# power on
 Changing power on succeeded
[bluetooth]# scan on
 Discovery started
 [CHG] Controller 80:56:F2:E5:43:E6 Discovering: yes
 [CHG] Device 78:BD:BC:D3:D5:68 RSSI: -92
 [CHG] Device 78:BD:BC:D3:D5:68 Name: [TV] UE40J6272
 [CHG] Device 78:BD:BC:D3:D5:68 Alias: [TV] UE40J6272
 [CHG] Device 00:13:EF:00:03:04 RSSI: -59

The exact MAC address of the HC-05 can be obtained by the AT+ADDR? command in the atmode. See application aboveπŸ‘Œ.

After something like HC-05 (00:13:EF:00:03:04 in my case) has appeared on the screen you will need to make it trustworthy, pair it with your PC and try to connect to it. That can be done by the following commands trust <MAC>, pair <MAC> and connect <MAC> accordingly.

[bluetooth]# trust 00:13:EF:00:03:04
 [CHG] Device 00:13:EF:00:03:04 Trusted: yes
 Changing 00:13:EF:00:03:04 trust succeeded
[bluetooth]# pair 00:13:EF:00:03:04
 Attempting to pair with 00:13:EF:00:03:04
 Request PIN code
[agent] Enter PIN code: 1234
 [CHG] Device 00:13:EF:00:03:04 UUIDs: 00001101-0000-1000-8000-00805f9b34fb
 [CHG] Device 00:13:EF:00:03:04 ServicesResolved: yes
 [CHG] Device 00:13:EF:00:03:04 Paired: yes
 Pairing successful
[bluetooth]# set-alias mymodule
 [CHG] Device 00:13:EF:00:03:04 Alias: mymodule
 Changing mymodule succeeded
[bluetooth]# connect mymodule
 Device mymodule not available
 [CHG] Device 00:13:EF:00:03:04 ServicesResolved: no
 [CHG] Device 00:13:EF:00:03:04 Connected: no
 [CHG] Device 00:13:EF:00:03:04 Connected: yes
[mymodyle]# 

If you'd like to check if disconnect works:

[mymodule]# disconnect
 Attempting to disconnect from 00:13:EF:00:03:04
 Successful disconnected
 [CHG] Device 00:13:EF:00:03:04 Connected: no
[bluetooth]# 

Time to open serial monitor

The last step is to create serial port. The following command binds your Bluetooth device with rfcomm device (/dev/rmcomm0 in this case). It won't immediately connect to your HC-05 only when an application such as serial monitor will use it. More about RFCOMM protocol and devices.

Unfortunately, on some systems (e.g. Arch linux) rfcomm utility can be in status "deprecated" and won't be available in the official repository. Try to find instruction of how to install it on your particular system (See Arch Wiki).

$ sudo rfcomm bind rfcomm0 <MAC-OF-HC-05>

Now you should have serial port /dev/rmcomm0 which is attached to your Bluetooth device.

Let's test that it works. In another terminal open serial monitor attached to Arduino with HCTOOLS application and run echo command:

$ pio -e nano -t monitor
...some output is hidden...
--- Miniterm on /dev/ttyUSB0  115200,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
HCTOOLS. Version: 1.0
# echo
Echoing every received character. CTRL-D to stop it.

Try to open serial monitor on the rfcomm port and send something to the device:

$ pio device monitor -p /dev/rfcomm0 -b 115200
...long output is hidden...
--- Miniterm on /dev/ttyUSB0  115200,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
Hello

Now, if you send something to Arduino it will send it to HC-05 and then to your /dev/rfcomm0 port. If you will send something to the /dev/rfcomm0 with a newline it will send it back to you.

HC-05 Bluetooth module

That basically it. For convenience you can add a udev rule to have a nice name for your device instead of /dev/rfcomm0. The name is specified in the SYMLINK attribute. For example:

$ cat /etc/udev/rules.d/80-blueled.rules 
KERNEL=="rfcomm[0-9]", SUBSYSTEM=="tty", DRIVER=="", ATTR{channel}=="1", ATTR{address}=="00:13:ef:00:03:04", SYMLINK+="blueled"

As you can see there is attributes of particular device. These attributes can be found with following command:

$ sudo udevadm info --attribute-walk --name=rfcomm0
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/virtual/tty/rfcomm0':
    KERNEL=="rfcomm0"
    SUBSYSTEM=="tty"
    DRIVER==""
    ATTR{channel}=="1"
    ATTR{address}=="00:13:ef:00:03:04"

Now your device should be available under /dev/blueled path.

Troubleshooting HC-05

There is list of problems which I faced during my attempts to configure everything right.

  1. The following messages in response to rfcomm bind command probably means that you don't have kernel module for RFCOMM protocol. Try to load it sudo modprobe rfcomm. Also try to update the kernel.

    Can't open RFCOMM control socket: Protocol not supported

  2. If bluetoothctl shows No default controller available make sure that you have your driver installed and then run bluetoothctl with sudo (stackoverflow answer).

  3. It can happen that other application is using Bluetooth and by doing so it will occupy Bluetooth controller (in my case it was connman). You can unblock it by firstly stopping the suspected application and then running following command rfkill unblock all:

    $ sudo rfkill list
    0: tpacpi_bluetooth_sw: Bluetooth
        Soft blocked: no
        Hard blocked: no
    1: hci0: Bluetooth
        Soft blocked: yes
        Hard blocked: no
    5: phy3: Wireless LAN
        Soft blocked: no
        Hard blocked: no
    $ sudo rfkill unblock all
    $ sudo rfkill list
    ...
    1: hci0: Bluetooth
        Soft blocked: no
        Hard blocked: no
    ...
    

  4. As always power on/off helped in a few cases πŸ˜€.

  5. A lot of information about Bluetooth is available on the Arch Linux Wiki

References


HeyπŸ‘‹ I'm Andrey. In this blog I post my personal short tutorials or interesting technical notes. Over the day I work as a Software Engineer developing and testing Linux filesystems. I use free software mainly #NixOS #Neovim #Kitty. Btw I use NixOS. Subscribe for updates on:

telegram β€’ @alberand@mas.to β€’ twitter