Eagle Jones, PhD, CEO, RealityCap
In our previous post, we discussed the performance of the iPhone 5S accelerometer, based on the data available from public sources such as Chipworks and the manufacturer spec sheets. We now have sample calibration code available for developers on Github, which we describe at the end of this post. First, we’d like to provide an update on our understanding of the root cause of these issues.
Yesterday we heard from an electronics engineer named Diego Caraballo, who pointed out a key detail. The Chipworks photo of the part in question shows a marking of “361 LP”. Bosch tells us how to decode this marking in its spec sheets: the three digits (361) correspond to a production run, the first letter (L) corresponds to a part code, and the second letter (P) identifies the subcontractor or plant in which the part was produced. Diego pointed out that not only does the part code of “L” not correspond to the BMA220 (which has a part code of “2”), but it does not correspond to any of the MEMS accelerometers listed publicly by Bosch.
A number of people have also pointed out that the BMA220 only has 6 bits of resolution. In the iPhone 5S, we’ve experimentally verified that the accelerometer has a range of +/-8g. If the BMA220 were really used, the minimum increment two different measurements would be a massive 1/4g (16/(2^6)). This would be dramatically worse resolution than previous devices, and anecdotally inconsistent with the performance we’ve seen from the 5S accelerometer to date. To test this, we analyzed data collected from the 5S accelerometer, and found the minimum increment between measurements is roughly .000015g. It turns out that the exact value of this step size goes into 16 (the range of the sensor) 1,048,576, or 2^20 times. The data we’re getting from the iPhone 5S accelerometer actually has a resolution of 20 bits.
Given the difference in markings and resolution, we can be pretty certain that Chipworks was wrong, and the accelerometer in the iPhone 5S is not the BMA220. It also doesn’t correspond to any other publicly available Bosch part; the resolution is higher than any listed on Bosch’s site and the marking is not consistent.
Thus the conclusion that the bias observed in 5S accelerometer readings is due to the specs of the part may or may not be correct. This mysterious accelerometer could still have a relatively large bias range; the parts that Bosch does offer today all have at least a +/-50mg bias range, still significantly more than the +/-20mg of the previous ST part. Or it could be that Bosch is providing a part with an extremely low bias range, but something in Apple’s manufacturing process is causing (or failing to correct for) the bias we see. For example, the performance cited by the ST part assumes MSL3 preconditioning.
In any case, we are seeing significant bias from the iPhone 5S accelerometer measurements, so what can developers do to make their apps work? Since the bias is more or less constant, a simple one-time calibration process can correct for it. There are several ways to approach this, but we find it most straightforward to ask the user to place their device on a flat, level surface. We then capture accelerometer data over a period of time (to smooth out any vibration or noise in the measurements). This data can be averaged or filtered in a variety of ways; in our example we implement a simple low-pass filter. The resulting vector corresponds to the dual contributions of gravity and bias. We subtract off the contribution of gravity, providing the bias for all three axes of the accelerometer. You can find the source on Github.
There are two important assumptions implicit to this approach:
- The user doesn’t move the device during calibration. Small vibrations or bumps will be smoothed out by filtering, but larger disturbances could cause problems.
- The surface is closer to flat than the existing bias of the device. Therefore, on older devices where the bias range is closer to +/-1 degree, this calibration could actually make things worse.
Overall, this approach is very similar in principle to simply zeroing out a known measurement. In fairness to Apple, this can be accomplished in their compass / level app by simply tapping the screen when the device is on a flat surface.