I am trying to evaluate the suitability of some different wireless interfaces for our project on 2xRaspberry Pi 4 and currently I’m evaluating Bluetooth Low Energy. Therefore I have written an Central and Peripheral device application with the Qt framework (5.15). In my case the latency time between messages is important, because of some security aspects. The message size of each command is around 80-100 Bytes. In one of my tests I have sent 80 Bytes commands every 80ms. Ideally the messages should be received on the other device in 80ms interval as well. For the LAN (TCP) interface this test works well.
For Bluetooth Low Energy I observed that messages, which are sent from Peripheral to Central work quite good and I measured no big delay. Different results I got for the Central to Peripheral direction. Here, I have received the messages in the interval of 100ms to 150ms really exactly. It seems that there couldn’t be a very big magic behind it, so is there any plausible explanation for this? I tested it with a Python script as well and I observed the same results. So it seems that the Qt implementation shouldn’t be the problem.
During research I found out, that the connection interval may influence this, but in Qt the QLowEnergyConnectionParameterRequest (QLowEnergyConnectionParameters Class | Qt Bluetooth 5.15.4) doesn’t work for me. Is there any command, where I can set the connection interval for test purposes at the command line on Linux?
Kind regards,
BenFR
It is possible that your code is slower from central to peripheral because WRITE is used instead of WRITE WITHOUT RESPONSE. The difference is that WRITE waits for an acknowledgement, therefore slowing the communication down, while WRITE WITHOUT RESPONSE is very much like how notifications/indications work in that there's no ACK at the ATT layer. You can change this by changing the write mode of your application and ensuring that the peripheral's characteristic supports WriteNoResponse.
Regarding changing the connection interval, the change needs to be accepted from the remote side in order for it to take effect. In other words, if you are requesting the connection parameter change from the peripheral, then the central needs to have code to receive this connection parameter change request and accept it.
Have a look at the links below for more information:-
How does BLE parameter negotiation work
Understand BLE connection intervals and events
The different types of BLE write
Related
I'm currently working on a research project which revolves around me getting to know the transfer speeds of BLE in a simple setting. To be specific, I'll be working with an Arduino Nano 33 BLE board. I'm well aware that BLE v5 is capable of reaching speeds of up to 1Mb/s (Mega-bits/s) but is unrealistic in real-world applications. Are there any resources that I can get the transfer speeds of BLE? If not, I'm guessing I will have to work with an experimental setup for finding the speeds for my specific use-case. Thank you in advance!
The Bluetooth Radio on the Arduino Nano 33 BLE is built into the NRF52840 MCU.
More information on the Radio is found here:
https://infocenter.nordicsemi.com/topic/ps_nrf52840/radio.html?cp=4_0_0_5_19
There are definitely ways to determine real throughput of this peripheral, you just need a packet sniffer (link below) or have a transmitter/receiver board-to-board setup.
Packet Sniffer:
https://www.nordicsemi.com/Products/Development-tools/nRF-Sniffer-for-Bluetooth-LE
The board-to-board setup will have the relay serially send the number of packets received to a PC for analysis. You could configure the relay board to send the number of packets received within a certain interval (using the Timers in the NRF52840 with <microsecond precision).
If your project changes and you no longer need to use BLE and you would like to increase throughput to ~1.5Mbps, I developed and tested a working configuration of the NRF52840's Radio on the Arduino Nano 33 BLE. Link below.
https://forum.arduino.cc/t/stream-binary-data-from-arduino-nano-33-ble-to-pc-via-ble/917206
I'm trying to build a small program that reads the BLE beacons around my devices and parses the ones that I'm interested in to publish on MQTT. I'm using Raspberry Pis to run the code, I develop using my mac. The language is JS (Node 10.x), my Pis are running latest Buster, that is Bluez 5.50 and a fork of Noble to interface with the bluetooth layer.
For some reason, on one of the Pis that I moved to an open area (in order to get clear readings), I only receive the Scan Response Packets. I never receive the Advertisement Packet. I do sometimes receive the Advertisement packet for one of the device that is quite far away, making me suspect that signal comes in play here. From the Pis in the network cabinet (small Faraday cage) I do get inconsistently both packets every now and then (reason for dedicating a Pi in an open location).
Is there any way to force Bluez to always receive the Advertisement packet? Is there a bug somehow or a feature that I am not using properly?
EDIT
I installed tshark to monitor closely, and I do see the advertisement packet reaching my device. This means that BlueZ is ignoring them. Is there some complete documentation on how to use bluetoothctl and how to configure the bluetooth deamon/tool in order for these packets to be read?
After many days investigating, I manage to get the desired result for my project. I first thought of using the bluewalker project to access the raw packets. With this you can scan in passive mode, meaning only the advertising packet is retrieved.
By looking more in depth into noble project, the one I actually use to interface with, there is a workaround to scan in passive mode (https://github.com/noble/noble/issues/701), but also a variable to capture both advertising and response packets: NOBLE_REPORT_ALL_HCI_EVENTS. Setting this to 1 will give me exactly what I need, both the scan request which contains the data that changes more frequently, and the scan response that contains more data, such as min/max 24h values. And as a matter of fact, combining this setting with duplicates=false seems to give me only the scan request data, just like in passive mode.
Question still opened:
Having this, I still don't know how to use bluetoothctl to display both scan request data along with the scan response. Nor did I find a way to force the scan mode to passive. I could investigate more hcitool hciconfig, but they are deprecated (although every article on the internet refers to them).
As I understand it, Bluetooth Low Energy communication can be established with or without pairing. This is in the context of mobile development, Android more specifically but I believe iOS is more or less the same.
Are there instances where one would choose one over the other? And what would be the purpose? What is technically considered paired communication and what is considered unpaired communication?
I've dabbled around for a bit on the differences and have even made a few demo only apps related to BLE but I haven't found a clear explanation if what I am doing is actually considered paired or not.
Edit:
The reason I ask the question is that I believe I am looking to encrypt unpaired BLE connections. In some cases, and essentially my main use case, a mobile device may want to connect to several different peripherals randomly at different times throughout the day and the process of physically accepting a pair request seems unnecessary and quite time consuming. By 'randomly' I mean I am walking by one if I have a dozen scattered around my apartment and I personally don't know exactly which one without physically checking. I don't what to walk in the room the first time and have to manually pair each device, that would be insane if I had 100 devices. Note that these devices don't necessarily have to be connected at the same time, but could. Also note that I understand this isn't generally the main use case of the typical peripheral to mobile use case.
Here are a few differences:
If you bond the devices, the link will become encrypted, so it becomes more secure. So "paired" communication basically means the link is encrypted plus the device "knows" what it talks to.
The remote device also learns your phone's IRK (identity resolving key), which can be used to identify the phone later on. By default, the phone rotates the Bluetooth Device Address every 15 minutes or so. Without knowing the IRK, the peripheral can't identify the phone.
A good thing if the devices are bonded, is that the GATT db of the remote device gets cached, which means upon next connection, you don't have to wait a long time for service discovery to complete.
On Android, connecting by Bluetooth Device Address without first scanning is broken since the API lacks the "address type" bit (public/random address). If Android "guesses" wrong, you will connect to the wrong device and therefore fail. However if devices are bonded, the address type is stored and looked up based upon Bluetooth Device Address, which makes it work as expected. So if you plan to automatically connect to your peripherals in the background upon boot for example, it's a good idea to bond the devices.
A small detail is that Client Characteristic Configuration Descriptor values should also be stored by the GATT server and restored once the bonded device reconnects so it doesn't have to rewrite the descriptor value.
Some Bluetooth profiles needs bonding, for example HID (at least on iOS and Android).
I have a small BLE beacon which is configured to send iBeacon packets every 1000ms.
In my usecase i want to detect the signal on multiple recievers every time it is sent. However the detection is not reliable no matter which receiving device and software i use (phone, computer, raspberry). The signal is sometimes detected after 2 seconds, another time 5, 6 or whatever. It seems like there is no pattern behind it.
Also it seems that sometimes the signal is received on one receiver but not on the others while definetly being in range! Also the area i am testing in is not "problematic".
What could be the problem?
Not 100% of beacon packets transmitted are ever received. There are a number of reasons for this, including radio noise, packet collisions and channel hopping. That said, the typical detection rate in a quiet radio environment is around 90 percent.
If you are seeing a much lower rate than this on multiple receivers I would check the transmitter. First, use one of.your devices to transmit a software beacon (Android and iOS have free apps like Locate Beacon that do this.) If you get a higher detection rate with a different device transmitting, the issue may be your transmitter.
A few possible issues with it:
Bad antenna sending out a very weak signal. (Measure the received RSSI when you do get a detection and verify it is over -60 dBm)
Weak transmitter power setting. See if you can configure this higher.
Advertising on wrong channels
Advertising is stopped before packet can go out. Try to leave the advertiser on for at least 2x the transmission rate to ensure at least on packet gets out.
I assume you use a large enough scan window for your scan interval so your receiver radio is actually turned on most of the time.
You could try to send advertising packets of the type ADV_NONCONN_IND (non-connectable and no scan response packet). That way if the receiver radio scans with 100% duty it should see the packet.
Otherwise if you use normal ADV_IND packets, then at least Android always waits for the SCAN_RSP packet before it sends anything to the scanning app. But if the are multiple scanners nearby, your peripheral can only respond to a single scanner's SCAN_REQ for each advertising packet. To avoid collisions of SCAN_REQ packets in the air, Bluetooth controllers also back off if they don't get a SCAN_RSP in return. If you use a BLE sniffer you can see all three kinds of packets and what happens when you have multiple scanners nearby.
Read the BLE Link Layer part of the Bluetooth Core specification for more details.
I'm posting for the first time in this forum and English is not my first language so sorry for any mistakes ;) .
I'm trying to find out if it's possible to live stream audio using Bluetooth LE 4.X technology maintaining a very low latency. Namely below 10 ms. I'm trying to live stream a music instrument via bluetooth and the difference between the instant the instrument is played and the musician hears it should be negligible.
I'm asking in particular for the BLE because of what i saw in this page: https://en.m.wikipedia.org/wiki/Bluetooth_low_energy.
In the technical specifications it says: Latency (from a non-connected state) 6 ms. but i cant find where that value came from and even so i don't know if that is the value that I'm looking for.
Thanks! :)
BLE is specifically for sending small amounts of data with an emphasis on saving power by sacrificing speed. If you're concerned about speed and latency then you probably shouldn't be using BLE.
To answer your question, though, the latency is dependent on the connection interval. The connection interval is how long the two devices wait between transfers of data.
The 6ms the wikipedia page is talking about the length of time it takes to do the initial connection between the two devices (BLE is faster at making initial connections than "classic" Bluetooth because I think they made it simpler), but that isn't related to the latency during the regular usage after the connection is established.
Most Bluetooth 4.0 devices that support BLE also support regular Bluetooth, so I'd suggest using that if at all possible (since your concern is latency and not power consumption).