I built a custom ARM device based on the nRF52 SOC that handles BLE 5. I wrote a custom app in SWIFT/X-Code/IB using Core Bluetooth framework and am unable to stream data from the ARM device any faster than about 12 kbs. Using packet sniffers I can see that the ARM device sent all of the packets in realtime, but the iPhone doesn't read them any faster than a few times per second. On rare occasion the iPhone reads everything quickly. The Bluetooth connection negotiates to a 12-24 ms latency. I am using Nordic nRF52 SDK version 16. The iPhone is not connected to any other BLE devices at the time.
Has anyone else had this issue? If it is helpful, I can post the code used on the ARM device and the XCode code.
As your using the nordic board there are several things to check to "speed up the process". Firstly I assume you are sending via notifications. Secondly you need to know what forms your data rate. They are:
Number of bits per notification
Connection interval
Events per connection interval
Data communication type
Also you can queue up-several packets to store until they are sent via the notification(filling a buffer).
So some useful settings. First and foremost maximise the data you are sending per packet. E.g if you are sending 10 bytes of data send more, this will be limited to the maximum data size on the nordic board (247). Then increase the GAP length. So some settings I recommend to start are:
Go to sdk_config.h
Change NRF_SDH_BLE_GAP_EVENT_LENGTH to 400(think the default is 6)
Increase the MTU size to 247
Then run on the board, you will probably get an error saying change ram and start location. This will be printed to a terminal. You can do this by going:
Project
Options
Common
Press up arrow till under project
Linker
Section placement macros.
From there change your ram start and allocation variables to what is printed in the terminal / putty / debugger. Also not sure about the APIs for iphone apps but android has a function to set the bluetooth hardware into high power mode, this increased my throughput whilst transferring data, just disable it after data transfer. The APIs your using may have a similar function.
For reference code there is an example called maximum_throughput in the sdk, this should be a good reference point.
Related
Short version: Is it possible to dynamically change the advertisement data of an iOS device during run-time?
Long version: Ok, so here is the specific scenario: I have a BLE device scanning for advertisements, and number of devices that are advertising. Based on the received advertisement packets the central device, who is scanning, will open a lock. Now, I know that the advertisement packets can be copied by other devices; hence, authenticating the correct devices is an issue.
Our solution is to change the advertisement packets every now and then (say every minute) in a way that only the authenticated devices and the central device knows the pattern. However, in order to do this we need to be able to change our advertisement data dynamically.
I know that I can do this with BLE MCUs and I am fairly certain this is possible with Android devices since changing Advertisement data is allowed. Is this possible with iOS devices as well, i.e. can I dynamically change the advertisement data of an iOS device during run-time?
P.S. An easier solution would be to establish a connection, but I am also not certain if an iOS device can establish a connection when the application is in the Background?
I have an iBeacon device I'm working on and am wondering how often iOS monitors/checks/scans for iBeacons when asked to do so via a CoreLocation app? I'm wondering so I know how long to broadcast for my iBeacon is designed to not always be on.
I'm surprised I haven't been able to find this on the web (and of course Apple won't tell us)
Edit: I mean when the app itself is not running because the phone has been restart or the app is shut down.
There is no Apple documentation for this, but the following is what I have learned from lots of testing on iOS 7 and iOS 8 devices:
If the app gets one of the limited (30) bluetooth hardware detection slots, the Bluetooth chip will always be scanning for the beacon pattern. In theory one packet could trigger the detection, but in practice you may need several seconds of transmission to guarantee detection.
If the app does not get a hardware acceleration slot, the OS will perform a full scan every 15 minutes.
If you want to target phones that have hardware detection slots, the beacon could transmit for 5 seconds at any time appropriate for the use case. If you want to target apps without hardware acceleration slots, the beacon must transmit for 15 minutes to guarantee detection.
I am writing a Core Bluetooth App for IOS. It is connecting to a TI device With custom firmware. The firmware developer developed it to publish data 12 times a second. I am using the Notify Property to get the data, but it seems that we are grabbing the data 30 times per second. This is causing extra power consumption, and for specific reasons, I can't pull at my own rate I need to pull at the rate of the device is publishing.
The firmware developer created a Windows Application that doesn't have this problem without having a hard coded Read Rate. So it is On me to find the issue.
Does anyone have any recommendations?
For what you are describing, on your system the Swift side is just receiving notifications, so there is no control over the rate that your device is using to update that specific characteristic.
But, some devices may have a command on their own high level protocol to set the advertising interval. That's completely up to the manufacturer. If you think that the system is advertising at a different rate with that Windows app that you have mentioned, I would suggest to take a look to see if there is any initialization code that the app may be doing when it starts (thus setting the rate). But for that you will need the Windows app's source code, or at least the manufacturer's documentation about your device's protocol (if any).
Also, are you really sure that the updating rate when the device is connected to the Windows app is really lower than the one you are experimenting when connected your iOS app? How are you measuring that?
I'm writing an app which utilizes CoreMidi to exchange SysEx data with specific class-compliant USB-MIDI hardware.
I crosscompile the app for iOS and Mac, and on the Mac the MIDI data transfer rate is much higher than on iOS by default (can't be more specific for now, looks like more than twice as fast). This is both for sending data via MIDISend(3) and for reading data. Is there a way to ask the OS for the actual transfer rate, and to increase it on iOS?
The data I'm sending/receiving is in the order of MegaBytes, so this has a significant impact on the performance of my app.
Is there a USB transfer speed limitation in the OS or CoreMidi?
I'm developing an external device, this device has a large amount of data to be sent via Bluetooth to the iphone / ipad, but sends a very slow speed is only about 60kbps.
The device sends data to the PC speed is 256kbps, I think not because of device problems.
Who knows the iOS Bluetooth maximum speed is?
Information:
Use external accessory framework,
Bluetooth 2.0 + EDR
Thanks,
I know this is a bit late, but based on all the work I've been doing, the iDevice's are generally slower than PC/Android over Bluetooth. This is due to internal restrictions of the device, but also depending on how you're doing your data transfer (packet sizes, frequencies, latencies, packet overhead, buffer sizes, etc...), that could slow you down as well.
Another issue is that depending on the BT module you're using, I've seen HUGE variations (factor of 10) in how much data they can pass to iOS devices (even though they can all push to Androids at 300kbps).
When communicating with an iOS device, there is some additional overhead during packet handling and the protocols used, and if the BT firmware developer doesn't handle this correctly, you'll see performance implications. These numbers also change device to device and iOS version to iOS version.
To give you some concrete numbers, with one of my BT modules, here were my results (the highest I've seen so far):
iPad Mini running iOS 7.0.4 - 18,500-20,500 bytes/s
iPhone 5S running iOS 7.0.4 - 14,000-15,000 bytes/s
iPod Touch running iOS 7.0.4 - 16,000-17 000 bytes/s
iPod Touch running iOS 6.1.3 - 19,000-20,000 bytes/s
The last test there shows you that the iOS version itself can also have a large impact. Note, these were all done with the same BT module, 3-4 runs per test.
Edit: I added a bit more context here: http://www.sureshjoshi.com/embedded/bluetooth-classic-apple-french/