[PyQt] How to communicate with a BLE device with PyQt5?

Dennis Jensen djensen at pgcontrols.com
Tue Nov 12 16:18:46 GMT 2019


I am going to guess that perhaps the issues you are having here are 
similar to the some of the issues the RPI group I work with are having 
however I only help them with python-pyqt stuff in relation to the RPI 
they are dealing with the specific issues related to communicating with 
the devices -- shoot me a friend request on Discord `DenniO#8137` if you 
would be interested in chatting with these guys

On 11/12/2019 8:50 AM, s.achterop at rug.nl wrote:
>
> Hello List,
>
> Maybe not for this list, but I don't know a better one:(
>
> I try to create an app using PyQt5/QML software to talk to the Bluno m0.
> This is an Arduino compatible clone with a CC2540 chip from TI for BLE.
> The current state of the app can be found on 
> https://github.com/SietseAchterop/Bluno_pyqt5
> It is derived from a Python port of the lowenergyscanner app from 
> qtconnectivity.
> It also contains an arduino sketch, test3.ino, for the Bluno m0 and a 
> Linux python script, blunoTerminal.py, that works, using the bluepy 
> library.
>
> The problem I have is with reading and writing characteristics that 
> come with Bluetooth low energy.
> Beforehand I have to mention that the Bluno is not properly conforming 
> to the BLE specs, meaning that it does not have the Client 
> Characteristic Configuration Descriptor (CCCD, 0x2902) for the 
> characteristic we use.
> Notify is on per default, so it can notify without using a CCCD, as 
> exemplified by apps on linux, android and iOS.
>
> But I do not get response from the device in my app, which is running 
> on Debian/Buster with PyQt5 (5.13.2)
>
> After connecting and retrieving the services and characteristic I try 
> to communinate with the DBF1 characteristic named 'Serial'.
> Calling WriteCharacteristic works, I can see the data arriving at the 
> device. And the device does send something back, but I cannot read it.
> The only thing readCharacteristic yields is the FIRST character of the 
> string send.
>
> Here some code snippets from main.py:
>
> self.currentService.characteristicWritten.connect(self.writtenToBluno)
>         self.currentService.error.connect(self.errorBluno)
> self.currentService.characteristicChanged.connect(self.charChanged)
> self.currentService.characteristicRead.connect(self.charRead)
>
> Here the callbacks are set for reading, writing and changing the 
> characteristic.
> When pushing a "Send" button a command is created and sendtoBluno is 
> called to write to DBF1:
>
>     def sendtoBluno(self, charinfo):
>         c = self.currentCharacteristic.getCharacteristic()
>         self.currentService.writeCharacteristic(c, charinfo.encode(), 
> QtBt.QLowEnergyService.WriteMode.WriteWithResponse)
>
> And finally the callbacks:
>
>     @pyqtSlot(QtBt.QLowEnergyCharacteristic, QByteArray)
>     def writtenToBluno(self, c, result):
>         print(f'Written callback {c.uuid()}   {result}')
>
>     @pyqtSlot(QtBt.QLowEnergyCharacteristic, QByteArray)
>     def charChanged(self, c, result):
>         print(f'Changed callback {c}   {result}')
>
>     @pyqtSlot(QtBt.QLowEnergyCharacteristic, QByteArray)
>     def charRead(self, c, result):
>         print(f'Read callback {c}   {result}')
>         self.blresult = result
>         self.characChanged.emit()
>
>     @pyqtSlot(QtBt.QLowEnergyService.ServiceError)
>     def errorBluno(self, e):
>         print(f'errorBluno {e}')
>
> When, in the app, the command hello is entered and send to the bluno, 
> the following is shown.
>
>    setCommand to hello
>    Written callback 
> PyQt5.QtCore.QUuid('{0000dfb1-0000-1000-8000-00805f9b34fb}') b'hello\r'
>
> The '\r' is added in the code, needed to get a response from the Bluno.
> When I later push the "Read" button, the following function is called 
> to read DBF1
>
>   @pyqtSlot()
>     def dddd(self):
>         c = self.currentCharacteristic.getCharacteristic()
>         self.currentService.readCharacteristic(c)
>
> The response then is:
>
>    Read callback <PyQt5.QtBluetooth.QLowEnergyCharacteristic object at 
> 0x7f62277fb798>   b'h'
>
> I use the separate Read button because I don't understand how reading 
> from a characteristic works. The Qt documentation states that you have 
> to read readCharacteristic and set a connect a signal. But if data is 
> send on a regular basis, will that one call to readCharacteristic do 
> and will the signal be used throughout?
>
> Back to the app. The writtenToBluno callback shows the data that was 
> send. Ok, but not very useful.
> The charRead callback ONLY shows the first character of the string, 
> also when the Read button is called more often.
> I would have expected the response 'ack', with is what the bluno did 
> send back.
>
> The question is, why does the read not yield the data send from the 
> Bluno.
> The basic assumption is that when I do a writeCharacteristic that, 
> when the bluno sends something back, that data should be retrievable 
> by using readCharacteristic.
>
> Hopefully can someone point me in the right direction.
>   Thanks in advance,
>                  Sietse
>
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt


More information about the PyQt mailing list