I have noticed that there are lots of topics about classic Bluetooth connect to Arduino and send data to Raspberry Pi by creating virtual port (using rfcomm
)
I have tried this method for BLE Device. However I found that it can not create the virtual serial port for BLE device (saying Host is down).
I know someone uses the bluepy
to read the characteristic or UUID of the BLE device, but I dont know how it works (if it’s working?)
I wonder if there are any methods to connect the Arduino to Raspberry Pi through BLE and send data to the Raspberry Pi.
My project is to build four slave Arduino UNO boards with BLE (HC08) and one master Raspberry Pi board. The reason using BLE is because the distance from each slave to the master Raspberry Pi 3B+ is more than 10 meter far. Each slave has a laser receiver which sense laser beam, when the beam is blocked and the slave will send a signal to the master Raspberry Pi board.
Any helps would be appreciated, and sorry for my poor english.
-
What is the MCU are you using with HC08?Sohan Arafat– Sohan Arafat2020年06月14日 19:37:15 +00:00Commented Jun 14, 2020 at 19:37
-
I am connecting a arduino uno with HC08(by arduino cable) and sending signal to my rpi3b+Vincent Yu– Vincent Yu2020年06月15日 12:01:13 +00:00Commented Jun 15, 2020 at 12:01
1 Answer 1
According to: https://drive.google.com/file/d/0B4urklB65vaCcmFqOGRFWV9IR2s/view
The UUID's used by this module are:
Service: "0000ffe0-0000-1000-8000-00805f9b34fb"
Characteristic: "0000ffe1-0000-1000-8000-00805f9b34fb"
The easiest way to test this on the Raspberry Pi is to use the command line tool: "bluetoothctl".
Once you have launched the bluetoothctl tool, type "help" to get all the commands.
The basic ones to get you started will be "scan on", "scan off", "pair <mac_addr>", "connect <mac_addr>, "disconnect".
Pairing with the HC-08 module is a one-off setup, and I would do that with Bluetoothctl. To connect after that and write to the device, I would use the documented DBus API.
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/adapter-api.txt
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/device-api.txt
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/gatt-api.txt
It looks like you want to do the Central Role and if you want to use Python there is the pydbus library which will help you greatly: https://pypi.org/project/pydbus/
Some useful things to know to get you started:
- The DBus service for bluez is called 'org.bluez'
- The Bluetooth adapter on a Raspberry Pi is normally '/org/bluez/hci0' DBus object path.
- The DBus Object path to a device is the adapter path plus the mac address prepended by 'dev_' and the semi-colons replaced with underscores. i.e. 'DE:82:35:E7:43:BE' would be found at '/org/bluez/hci0/dev_DE_82_35_E7_43_BE'
I don't have an HC-08 module so I've done an example connect, read, and write using a micro:bit. It should be fairly similar for you, you will need to change mac address and characteristic UUID.
import pydbus
bus = pydbus.SystemBus()
adapter = bus.get('org.bluez', '/org/bluez/hci0')
dev = bus.get('org.bluez', '/org/bluez/hci0/dev_DE_82_35_E7_43_BE')
# Get commands and properties available
print(dir(adapter))
print(dir(dev))
# Connect to the device if you have already paired the Raspberry Pi with it
dev.Connect()
To read and write you need to find the path to the characteristic which is a little more work. Typically you know the UUID of the characteristic you are interested in so to get the value from button A on a BBC micro:bit it would be:
mngr = bus.get('org.bluez', '/')
def get_characteristic_path(device_path, uuid):
mng_objs = mngr.GetManagedObjects()
for path in mng_objs:
chr_uuid = mng_objs[path].get('org.bluez.GattCharacteristic1', {}).get('UUID')
if path.startswith(device_path) and chr_uuid == uuid:
return path
char_path = get_characteristic_path(dev._path, 'e95dda90-251d-470a-a062-fa1922dfa9a8')
btn = bus.get('org.bluez', char_path)
btn.ReadValue({})
# [0]
Writing to a characteristic is similar. Here is an example of reading and writing to the Temperature Period on a BBC micro:bit
tmp_period_path = get_characteristic_path(dev._path, 'e95d1b25-251d-470a-a062-fa1922dfa9a8')
tmp_period = bus.get('org.bluez', tmp_period_path)
tmp_period.ReadValue({})
# Result is:
# [232, 3]
# To get it as an integer:
int.from_bytes(tmp_period.ReadValue({}), byteorder='little')
# 1000
# To write and new value of 1500
new_value = 1500
tmp_period.WriteValue(new_value.to_bytes(2, byteorder='little'), {})
tmp_period.ReadValue({})
# [220, 5]