Hardware:
- Arduino (s)
- cc2541 – BLE module(s) for Arduino
- Raspberry Pi
- Bluetooth 4.0 USB dongle for raspberry pi
Software:
Code:
from bluepy.btle import Scanner, DefaultDelegate, Peripheral | |
import threading | |
class NotificationDelegate(DefaultDelegate): | |
def __init__(self, number): | |
DefaultDelegate.__init__(self) | |
self.number = number | |
def handleNotification(self, cHandle, data): | |
print 'Notification:\nConnection:'+str(self.number)+'\nHandler:'+str(cHandle)+'\nMsg:'+data | |
bt_addrs = ['00:15:83:00:45:98', '00:15:83:00:86:72'] | |
connections = [] | |
connection_threads = [] | |
scanner = Scanner(0) | |
class ConnectionHandlerThread (threading.Thread): | |
def __init__(self, connection_index): | |
threading.Thread.__init__(self) | |
self.connection_index = connection_index | |
def run(self): | |
connection = connections[self.connection_index] | |
connection.setDelegate(NotificationDelegate(self.connection_index)) | |
while True: | |
if connection.waitForNotifications(1): | |
connection.writeCharacteristic(37, 'Thank you for the notification!') | |
while True: | |
print'Connected: '+str(len(connection_threads)) | |
print 'Scanning…' | |
devices = scanner.scan(2) | |
for d in devices: | |
print(d.addr) | |
if d.addr in bt_addrs: | |
p = Peripheral(d) | |
connections.append(p) | |
t = ConnectionHandlerThread(len(connections)–1) | |
t.start() | |
connection_threads.append(t) |
Arduino Code can be seen in:
http://blog.blecentral.com/2015/05/05/hm-10-peripheral/
Explanation:
The main thread of the program keeps scanning the existing unconnected Bluetooth devices using the Scanner object.
If the devices have address existing in the bt_arrs array, we start a connection with it by initiating the Peripheral object and add it into the connections array.
To avoid the searching being blocked by the communication of each connection, every connection will be handled by a separate ConnectionHandler Thread.
Within the connection thread, the communications between the Pi and the Arduino(s) are handled by using waitForNotification and writeCharacteristic function of the bluepy library.
Why do we write data to handler 37?:
By looking at the documentation of the BLE module, we know that both data sending from and to the BLE module are stored in the same places (20 Bytes). Therefore by observing the data sent from the BLE module, we know the data should be written to Handler 37.
The output below is showing 1 Arduino with 2 BLE modules and the Arduino is doing:
- send count via BLE modules #0
- count ++
- send count via BLE modules #1
- count ++
- and loop
From the output of the program, we can see
- It is continuously scanning devices
- It is able to communicate with Connection 0 & Connection 1.
- All notifications are from handler 37.
Hello Anthony, thank you for posting this project! I’m currently trying to make my raspberry Pi to communicate with some iBeacons (and change some parameters, such as Minor, Major,etc.).
To starting understand how the communication works, I tried to run the code of this project in my raspberry, after installing bluepy, and I’m getting the following error:
pi@raspberrypi:~ $ sudo python code.py
Connected: 0
Scanning…
Traceback (most recent call last):
File “code.py”, line 33, in
devices = scanner.scan(2)
File “/home/pi/Desktop/bluepy/btle.py”, line 631, in scan
self.start()
File “/home/pi/Desktop/bluepy/btle.py”, line 568, in start
self._startHelper(iface=self.iface)
File “/home/pi/Desktop/bluepy/btle.py”, line 210, in _startHelper
universal_newlines=True)
File “/usr/lib/python2.7/subprocess.py”, line 710, in __init__
errread, errwrite)
File “/usr/lib/python2.7/subprocess.py”, line 1335, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Do you have any clue about what could be causing this error?
Thank you.
LikeLike
Hi Paul,
May be you can try scan your bluetooth device using command line first,
https://fixmynix.com/bluetooth-in-linux-with-bluez-and-hcitool/
LikeLike
So with this would I be able to control multiple arduinos via ble from a rasberry pi 3b
LikeLike
I have not tested on a Pi 3b.
I wrote this post when I was doing a course project, at the end, I was able to connect 4 Arduino from a Pi 2.
LikeLike
Bryan did you get it working with the pi 3 bs?
LikeLike
Is there a way to send messages to each client via Bluetooth?
LikeLiked by 1 person
Hi Reevid. Sure you can send messages from the Pi to the Arduinos with connection.writeCharacteristic. Note that, I have used a multi-threading approach, the connection(one Ardiuno) variable actually comes from a list of connections (many Ardiuno).
LikeLike
Hello. I wonder if you can help me. I have a code using bluepy.btle. The device that sends information through a serial / bluetooth module (at-09) masters sensor data at a speed of 9600 bits / s to my computer that is able to receive this information and save it to a file. Until then, OK! The problem is that since the amount of data is too large, a baud rate of 9600 bits / s generates a bottleneck in data transmission, and it takes a long time for the whole file to be sent. So I made the device that sends the information through the serial / bluetooth module send information at a higher speed, at 38400 bits / s. The problem is that the method that receives the information via bluetooth (handleNotification (self, cHandle, data)) can not keep up with, and generates a kind of “sub-sampling” of the data, so that not all of them arrive correctly. In this way, I believe that this problem can occur because of the following problem: The buffer of the receiving method is populated quickly, and in this way, the values are being overwritten before going to main memory. Would you know how to solve this, if that’s the case, if you ever had a problem or know how to solve it? I did not find anything about this problem in the forums. Thank you so much.
LikeLiked by 1 person
Hi, I got your point. Unfortunately, I have only worked on small data. I haven’t tested on the speed. I have done some tricks (start string, end string) to avoid messing up messages from different devices.
LikeLike