BLE USB dongle throughput measurement
March 22, 2022Introduction
Here we will describe two quick ways of measuring the data throughput of the BleuIO Dongle.
For both examples we are going to need a BleuIO Dongle, another Bluetooth device (like another Bleuio Dongle) and a computer with Python (minimum version: 3.6) installed.
For the first measurement example, measuring the BLE data throughput, you will need one of the following supported development kits from Nordic Semiconductor:
- nRF52840 DK (PCA10056)
- nRF52840 Dongle (PCA10059)
- nRF52833 DK (PCA10100)
- nRF52 DK (PCA10040)
- nRF51 DK (PCA10028)
- nRF51 Dongle (PCA10031)
The first measurement example is the actual BLE data throughput. For this we will use a BleuIO Dongle and Wireshark. (For help on how to setup Wireshark and requirements go to this link: https://infocenter.nordicsemi.com/topic/ug_sniffer_ble/UG/sniffer_ble/intro.html ).
We will also utilize a simple python script that sends a set amount of data. For this measurement you can ignore the throughput print at the end of the script.
The second measurement example is for measuring the actual data being transferred over the USB as a Virtual COM port (via the CDC protocol).
We will be using the same simple script that will send a set amount of data and time when the transfer starts and then stops. Then divide the amount of data with the time the transfer took to get the throughput.
Notice : Interference can be caused by other wireless networks, other 2.4 GHz frequency devices, and high voltage devices that generate electromagnetic interference. This have impact on the measurement of throughput. To avoid interference, select wireless free space or use a shield box.
Instructions for BLE data throughput
- For best result place the nRF Dev Kit between the BleuIO Dongle and your target device.
- Open Wireshark and double-click the ‘nRF Sniffer for Bluetooth LE’.
- Make sure the target Bluetooth device is advertising and find in the the scroll-down list.
- Choose ‘IO/Data’ under the ‘Analysis’ menu tab.
- Click the ‘+’ button to add new graphs. Add ‘bytes per seconds’ and/or ‘bit per seconds’.
- Modify the script by filling in the relevant information into the variables ‘your_com_port’, ‘target_mac_addr’ and ‘write_handle’.
- Run the python script.
- You can now observe the graph showing the BLE Data throughput!
Instructions for USB port data throughput
This is the second measurement example for measuring the actual point to point data transfer between the two USB ports.
- Connect the dongle to your computer. (Look up the COM port your dongle uses and paste it in the script in the variable ‘your_com_port’)
- Scan (Using AT+GAPSCAN) after the device you wish to send the data to. Copy the mac address of the device into the script in the variable ‘target_mac_addr’.
- Connect to the device and look up the handle of the characteristic you want to write to and paste into the script in the variable ‘write_handle’.
- Finally just run python script and the throughput will be displayed at the end!
The script
import datetime
import serial
import time
import string
import random
connecting_to_dongle = True
trying_to_connect = False
# Change this to the com port your dongle is connected to.
your_com_port = "COM20"
# Change this to the mac address of your target device.
target_mac_addr = "[0]40:48:FD:E5:2C:F2"
# Change this to the handle of the characteristic on your target device.
write_handle = "0011"
# You can experiment with the packet length, increasing or decreasing it and see how that effect the throughput
packet_length = 150
# 1 Megabytes = 1000000 Bytes
file_size = 0.5 * 1000000
end_when = file_size / packet_length
send_counter = 0
# Random data string generator
def random_data_generator(size=packet_length, chars=string.digits + string.digits):
return "".join(random.choice(chars) for _ in range(size))
print("Connecting to dongle...")
while connecting_to_dongle:
try:
console = serial.Serial(
port=your_com_port,
baudrate=115200,
parity="N",
stopbits=1,
bytesize=8,
timeout=0,
)
if console.is_open.__bool__():
connecting_to_dongle = False
except:
print("Dongle not connected. Please reconnect Dongle.")
time.sleep(5)
print("Connected to Dongle.")
console.write(str.encode("AT+GAPDISCONNECT\r"))
start = input("Press Enter to start.\n\r>> ")
console.write(str.encode("ATE0\r"))
console.write(str.encode("AT+DUAL\r"))
connected = "0"
while connected == "0":
time.sleep(0.5)
if not trying_to_connect:
# change to Mac address of the device you want to connect to
console.write(str.encode("AT+GAPCONNECT=" + target_mac_addr + "\r"))
trying_to_connect = True
dongle_output2 = console.read(console.in_waiting)
time.sleep(2)
print("Trying to connect to Peripheral...")
if not dongle_output2.isspace():
if dongle_output2.decode().__contains__("\r\nCONNECTED."):
connected = "1"
print("Connected!")
time.sleep(8)
if dongle_output2.decode().__contains__("\r\nDISCONNECTED."):
connected = "0"
print("Disconnected!")
trying_to_connect = False
dongle_output2 = " "
start2 = input("Press Enter to sending.\n\r>> ")
start_time = time.mktime(datetime.datetime.today().timetuple())
console.write(
str.encode(
"AT+GATTCWRITEWRB=" + write_handle + " " + random_data_generator() + "\r"
)
)
while 1:
dongle_output = console.read(console.in_waiting)
if send_counter > end_when:
end_time = time.mktime(datetime.datetime.today().timetuple())
break
# Change to the handle of the characteristic you want to write to
if "handle_evt_gattc_write_completed" in str(dongle_output):
console.write(
str.encode(
"AT+GATTCWRITEWR=" + write_handle + " " + random_data_generator() + "\r"
)
)
send_counter = send_counter + 1
try:
if not dongle_output.decode() == "":
print(dongle_output.decode())
except:
print(dongle_output)
time_elapsed = end_time - start_time
time.sleep(0.1)
print("*" * 25)
print("Transfer Complete in: " + str(time_elapsed) + " seconds")
print(str(packet_length * send_counter) + "bytes sent.")
print("*" * 25)
print(
"Throughput via USB (Virtual COM port): "
+ str((packet_length * send_counter) / time_elapsed)
+ " Bytes per seconds"
)
print("*" * 25)