How can I estimate the power consumption of a BLE module? - ios

I'm writing an iOS app for a device with a BLE module that advertises a few bytes of data on a consistent basis while it's connected. We are trying to estimate the power consumption of the BLE module so we can estimate the battery life for the device. I've scoured SO and Google looking for the appropriate way to estimate this, but I'm coming up empty. Is there a way to take the number of bytes that are being sent, multiplied by the frequency with which the data is sent and come up with a rough approximation of power consumption?

A typical BLE SoC (i.e. a all-in-one Application + Radio chip) typically consumes:
A few hundreds nA while in deep sleep,
2 to 10 µA while a RTC tracks time (needed between radio events while advertising or connected),
10 to 30 mA while CPU or Radio runs (computing data, TX, RX). RX and TX power consumption is roughly the same.
Life of a BLE peripheral basically consists of 3 main states:
Be idle (not advertising, not connected). Most people will tell your device is off. Unless it has a physical power switch, it still consumes a few hundred nanoamps though.
Advertise (before a connection takes place). Peripheral needs to be running approximatively 5 ms every 50 ms. This is the time when your device actually uses most power because advertising requires to send many packets, frequently. Average power consumption is in the 1-10 mA range.
Be connected. Here, consumption is application-dependant. If application is mostly idle, peripheral is required to wakeup periodically and must send a packet each time in order to keep the connection alive. Even if the peripheral has nothing useful to send, an empty packet is still sent. Side effect: that means low duty cycle applications basically transmit packets for free.
So to actually answer you question:
length of your payload is not a problem (as long as you keep your packets shorts): we're talking about transmitting during 1 µs more per bit, while the rest of the handling (waking up, receiving master packet, etc. kept us awake during at least 200 µs);
what you actually call "continuous" is the key point. Is it 5 Hz ? 200 Hz ? 3 kHz ?
Let's say we send data at a 5 Hz rate. Power estimate will be around 5 connection events every second, roughly 2 ms CPU + Radio per connection event, so 10 ms running every second. Average consumption: 200 µA (.01 * 20 mA + .99 * 5 µA)
This calculation does not take some parameters into account though:
You should add consumption from your sensors (Gyro/Accelerometers can eat a few mA),
You should consider on-board communication (i2c, SPI, etc),
If your design actually uses two chips (one for the application talking to a radio module), consumption will roughly double.

Related

ESP32: Store and Send data via BLE frequently

I'm developing a sensor based on the ESP32-DevKit board where I sense vibration from an accelerometer. The application/sensor goal is to store the accelerometer data for 20s and then send all the data through BLE.
I'm currently using the ESP32 ADC (12 bit) for a fast sampling rate (10-100KHz) to get an accurate signal. The next step is to store this signal, but it will take as size almost 2MB, so I don't know if I can store it in the ESP32 and send it later via BLE (packet by packet), therefore a lot of tasks will end up degrading the process time and Energy.
The main points are :
Fast sampling rate / accurate signal.
Sending data to phone with the lowest energy possible.
using ESP32-S2 to Store 2MB data and resend it to Phone app.
Is there any possibility of doing what I want to?
When storing the signal, have you considered compressing the data? If the accelerometer readings are very similar to the previous reading, then just storing the difference might save a lot of space, especially if you use a variable length format.
I have a project where I save GPS data, but because it is comparatively slow moving boats, the difference between two coordinates (every second or so) will be very small, so no point storing the full coordinates.

Speed issue while trying to read/write BLE characteristic second time

I have an external BLE device, in which I can read/write the data up to 500-800 bytes.
I'm writing by chunks sized to 200 bytes, and the reading is limited on the BLE device side by 20 bytes per packet.
After I connected and do some operation (read / writeWithResponse) - it takes approx. 1 sec, but every operation after that takes up to 1 min, e.g. while I'm reading, transferring every packet takes about 2 seconds.
If I disconnect and connect to the device, only the first operation is fast.
The code is pretty simple - I just splitting data (in case of writing) and sending it by chunks. Every next chunk is sending just after I receive callback didWriteValueForCharacteristic:.
How can I improve the speed? Do you have suggestions: why only the first operation with BLE module is fast?

IOS BLE packet loss

I'm writing an IOS/iPhone app that communicates with an sp-10c imu via bluetooth low energy. The packets I am receiving were originally 61 bytes long, but I have shortened them to 38 bytes so that the packet is sent in the minimum number of notifications.
I have no control over the actual programming of the sp-10c, but they do give me control of some of the settings. I can change what all info I receive (accelerations, gyros quaternions, etc) and thereby change the packet size, and I can also change the transmission interval (by 10 millisecond intervals). I have read a lot of the questions and answers on here related to this subject, but the only solutions I have seen require having programming control over the peripheral device, which I do not have.
I have also read Apple's handbook on this, which states that the minimum interval should be 20 ms. If I could reliably get entire packets at 50 hz, that would work for my needs. Anything less is pretty much worthless. My problem is that I'm getting intervals of massive packet loss at the 20ms interval (there are times when 40 or more packets are lost, and this happens regularly). I really don't see reliable results until I slow it down to an interval of 60 ms or more, which, as I said, is worthless. (I am trying to sense a sharp change in acceleration that lasts about 20 - 40ms)
Most of the questions and answers on here are somewhat dated, but I saw where someone said that things may have gotten worse as far as the BLE connection + Apple devices go. It has been suggested that classic bluetooth is the only way to go when large amounts of throughput are needed, but the sp-10c does not offer classic bluetooth as an option.
My questions are:
Is this the normal behavior for a ble connection with apple devices?
Has anyone had any success getting reliable ble notifications at 20ms with longer packets?
Should I give up now and try to find an imu with classic bluetooth?
I guess what I'm really getting at is this: Am I doing something wrong, or is this just par for the ble/iPhone course?
Would it help to try and limit the packet to less than 20 bytes so it is received in one notification?

Flurry / Google Analytics / Localytics bandwidth consumption on iOS

I'm choosing an analytics service for my iOS app. I want to track quite a lot of events and the app I'm developing is going to be used outdoors, so there will be no wi-fi connection available, and even the cellular connectivity can be of a poor quality.
Analytics is the only thing that requires network connectivity in my app. Recently I've checked how much traffic it consumes, and it consumes much more than I've expected. That was about 500KB for Google Analytics and about 2MB for Flurry, and that's just for a 2-minute long session with a few hundred events. It seems very inefficient to me. (Flurry logs a little bit more parameters, but definitely not 4 times more.)
I wonder — have anybody compared other popular analytics solutions for their bandwidth consumption? Which one is the slimmest one?
Thank you
If you don't need real time data (and you probably don't with outdoor app), you can get the best network compression for Analytics by dispatching more hits at once to benefit from batching and compression. To do that set the dispatch interval to 30 minutes. The maximum size of uncompressed hit that analytics will accept is about 8k so you should be sending less then that. With compression that would bring it down to ~25% of the original size for individual hit assuming mostly ascii data. To generate 500k of data you should be sending few hundred hits individually. With batching and compression the hits will shrink down more efficiently. Usually batch of 20 hits will compress to less then 10% of the uncompressed size or about 800 bytes per hit at most. For further network savings just send less data per event or fewer events. Btw, Analytics has a rate limit of 60 tokens that are replenished at a rate of 1 hit every 2 seconds. If you are sending few hundred events in short period of time your data is likely getting rate limited.
https://developers.google.com/analytics/devguides/collection/ios/limits-quotas#ios_sdk

How to synchronize event on more than one iOS device?

I would like to synchronize (within .05 seconds) an event in the future on more than one iOS device, whether or not those devices have network access at that future time.
To do this, I believe I'll need to sync to a common clock between these devices, and the best way would be to get a precise time from an NTP server(s). I've looked at iOS-NTP, but the description says that that it determines time with 1 second accuracy, and that doesn't quite do it for me.
One alternative is to get the (accurate?) timestamp from a GPS clock, but I'm not sure that the devices will always have the ability to get a GPS signal.
Any other suggestions?
iOS doesn't give you low level access to the GPS hardware, so you can't use that method.
If the devices are close to each other, you can establish a peer to peer wireless connection using GameKit. That should give you around 35ms latency with bluetooth, and the latency should be consistent so you could measure it a few times to get the clocks in sync.
If they're not close together... then I would setup a server and use that as the "real" time. With several calls you should be able to measure the latency between the device and the server, then calculate the clock offset with reasonable accuracy.
If possible use UDP instead of TCP, that way network congestion will drop packets instead of delaying them.
You'll need to keep on re-calculating the offset though, since iOS devices change their clock frequently (I think it's part of the 3G/LTE network protocol? Jumping from one cell tower to another might update the clock).

Resources