Issue
I am collecting pressure sensor data from 4 Arduino Nano 33 ble to a raspberry pi 4. I am able to receive the data from all the sensors. Now, I want to send this received data to another Raspberry Pi 4 using BLE communication in real-time such that the first Raspberry Pi acts as a repeater. I searched but could not find a suitable approach or solution to implement this. The first Raspberry Pi could act as a peripheral/client sending all the received sensor data and the second raspberry pi could act as a central/server to receive all the sensor data which can be further displayed on web interfaces or stored in a database.
I tried connecting initially with one Arduino and sending its data over raspberry Pi. I have written the code for Raspberry Pi Client and Server using Bluedot library in Python.
Raspberry Pi 4 Client code
import sys
import time
from bluepy import btle
from bluedot.btcomm import BluetoothClient
from signal import pause
def data_3():
mac_adrs3 = 'f3:9a:9a:e8:54:5c'
print("Connecting..")
tp3_sense = btle.Peripheral(mac_adrs3)
print("Discovering Services..")
_=tp3_sense.services
tire3_sensing_service = tp3_sense.getServiceByUUID("2b7537ab-8899-4359-a78a-096e076a4605")
print("Discovering characteristics..")
_= tire3_sensing_service.getCharacteristics()
return tire3_sensing_service
def byte_array_to_int(value):
value = bytearray(value)
value = int.from_bytes(value, byteorder='little')
return value
def byte_array_to_char(value):
value = value.decode("utf-8")
return value
def decimal_exponent_two(value):
return value/100
def decimal_exponent_one(value):
return value/10
def pascals_to_kilopascals(value):
return value / 1000
def read_pressure3(service3):
pres3_char = service3.getCharacteristics("9c30d6b2-e3d3-4eae-8641-425a36d550ec")[0]
pres3 = pres3_char.read()
pres3 = byte_array_to_int(pres3)
#pres3 = decimal_exponent_one(pres3)
#pres3 = pascals_to_kilopascals(pres3)
print(f"Barometric pressure 3 : {round(pres3,2)} kPa")
return pres3
def read_temperature3(service3):
temp3_char = service3.getCharacteristics("e986145c-ead6-41a7-9718-d2b0b4834a11")[0]
temp3 = temp3_char.read()
temp3 = byte_array_to_int(temp3)
#temp3 = decimal_exponent_two(temp3)
print(f"temperature 3 : {round(temp3,2)} C")
return temp3
def loop():
c = data_3()
while True:
time.sleep(1.0)
print("\n")
read_temperature3(c)
read_pressure3(c)
t3 = read_temperature3(c)
p3 = read_pressure3(c)
r = BluetoothClient("DC:A6:32:4C:9D:ED", data_received_callback=None, port=2)
r.send(f"temp 3 : {t3} ")
r.send("\n")
r.send(f"pressure 3 : {p3} ")
#pause()
#time.sleep(1.0)
def main():
loop()
if __name__ == "__main__":
main()
Raspberry Pi Server code
from bluedot.btcomm import BluetoothServer
from signal import pause
def data_received(data):
print(data)
s.send(data)
s = BluetoothServer(data_received)
pause()
I am able to receive two readings and after that the client disconnects with the below error.
pi@raspberrypi:~/Desktop/rpible $ python3 onearduino_senddata.py
Connecting..
Discovering Services..
Discovering characteristics..
temperature 3 : 0 C
Barometric pressure 3 : 100 kPa
temperature 3 : 0 C
Barometric pressure 3 : 100 kPa
Traceback (most recent call last):
File "onearduino_senddata.py", line 83, in <module>
main()
File "onearduino_senddata.py", line 80, in main
loop()
File "onearduino_senddata.py", line 70, in loop
r = BluetoothClient("DC:A6:32:4C:9D:ED", data_received_callback=None, port=2)
File "/usr/local/lib/python3.7/dist-packages/bluedot/btcomm.py", line 567, in __init__
self.connect()
File "/usr/local/lib/python3.7/dist-packages/bluedot/btcomm.py", line 660, in connect
self._client_sock.connect((server_mac, self._port))
OSError: [Errno 16] Device or resource busy
please help to solve this issue.
Solution
Found the solution.
Create the client once outside the while loop and then the data transfer happens.
updated loop function.
def loop():
c = data_3()
//create the client connection here
r = BluetoothClient("DC:A6:32:4C:9D:ED", data_received_callback=None)
while True:
time.sleep(1.0)
print("\n")
t3 = read_temperature3(c)
p3 = read_pressure3(c)
r.send(f"temp 3 : {t3} ")
r.send("\n")
r.send(f"pressure 3 : {p3} ")
Answered By - Abhishek