Calibration and Firmware Update Issues!
Hi there,
I been trying to add the functionalities that came with the new update (Firmware 1.4.1, Android API v3.5.0) to my Metawear Android app. There are two main problems that I cannot figure.
----> The calibration method that retrieves the sensor fusion calibration states does not work, instead, the method just disconnects the MetaMotion R device immediately. The following are the method I use to retrieve the calibration and Android Studio's printed log.
private void calibrate() {
Log.i("Calibration", "Start");
final SensorFusionBosch fusionModule = connection.board.getModule(SensorFusionBosch.class);
fusionModule.readCalibrationStateAsync().continueWith(new Continuation<SensorFusionBosch.CalibrationState, Void>() {
@Override
public Void then(Task<SensorFusionBosch.CalibrationState> task) {
Log.i("Calibration", task.getResult().accelerometer.toString());
Log.i("Calibration", task.getResult().gyroscope.toString());
Log.i("Calibration", task.getResult().magnetometer.toString());
Log.i("Calibration", task.getResult().toString());
return null;
}
});
}
……
I/Calibration: Start
D/BluetoothGatt: onClientConnectionState() - status=8 clientIf=6 device=D2:5D:E0:63:F0:C0
D/BluetoothGatt: refresh() - device: D2:5D:E0:63:F0:C0
D/BluetoothGatt: close()
D/BluetoothGatt: unregisterApp() - mClientIf=6
I/D2:5D:E0:63:F0:C0: Disconnected
……
----> The update firmware method does the job but I am not sure if that is how it supposed to work. When I use the update method it always end with "DFU service destroyed" and disconnecting the device. The first time I use the method on a Metamotion R device with Firmware v1.3.7, it ends by turning into metaboot mode with Firmware v0.2.2. The second time I use the method on the same device it remains in metaboot mode but goes to firmware 0.3.1. The third time it updates fully to firmware 1.4.1. The following are the method I use to update the device and Android Studio's printed log.
private void updateFirmware(final Context context, final Class<? extends DfuBaseService> dfuServiceClass) {
showDialog("Updating firmware...");
Log.i("--------------", "1");
Capture<List<File>> files = new Capture<>();
connection.board.downloadFirmwareUpdateFilesAsync().onSuccessTask(new Continuation<List<File>, Task<Void>>() {
@Override
public Task<Void> then(Task<List<File>> task) throws Exception {
Log.i("--------------", "2");
files.set(task.getResult());
if (connection.board.inMetaBootMode()) { return null; }
return connection.board.getModule(Debug.class).jumpToBootloaderAsync();
}
}).onSuccessTask(new Continuation<Void, Task<Void>>() {
@Override
public Task<Void> then(Task<Void> ignored) throws Exception {
Log.i("--------------", "3");
Task<Void> task = Task.forResult(null);
for(final File f: files.get()) {
task = task.onSuccessTask(new Continuation<Void, Task<Void>>() {
@Override
public Task<Void> then(Task<Void> ignored2) throws Exception {
Log.i("--------------", "4");
return Task.delay(1000);
}
}).onSuccessTask(new Continuation<Void, Task<Void>>() {
@Override
public Task<Void> then(Task<Void> ignored2) throws Exception {
Log.i("--------------", "5");
dfuTaskSource = new TaskCompletionSource<>();
DfuServiceInitiator starter = new DfuServiceInitiator(connection.board.getMacAddress())
.setKeepBond(false)
.setForceDfu(true);
int i = f.getName().lastIndexOf('.');
String extension = f.getName().substring(i + 1);
if (extension.equals("hex") || extension.equals("bin")) {
starter.setBinOrHex(DfuBaseService.TYPE_APPLICATION, f.getAbsolutePath());
} else {
starter.setZip(f.getAbsolutePath());
}
starter.start(context, dfuServiceClass);
Log.i("--------------", "6");
return dfuTaskSource.getTask();
}
});
}
return task;
}
}).continueWith(new Continuation<Void, Void>() {
@Override
public Void then(Task<Void> task) throws Exception {
Log.i("--------------", "7");
if (task.isFaulted()) {
closeDialog("firmware update failed");
Log.i("Firmware update", "Failed", task.getError());
}
else if (task.isCancelled()) {
closeDialog("firmware update cancelled");
Log.i("Firmware update", "Cancelled");
}
else {
closeDialog("firmware update successful");
}
return null;
}
});
}
Comments
When is the
calibrate
function called? What code is executed before calling said function?The sample DFU code in the Android documentation should iterate through the list of files to upload with 1 function call. It is extracted from the MetaBase app so some mistakes were probably introduced during the refactoring. I'll double check the code.
Hi Eric,
The activity simply starts by connecting to the device. Code for connecting...
After the activity displays the new fragment, the activity retrieves the Battery level and RSSI data. Code...
Then the user can click a button in the new fragment to call the calibration method, calibration().
Here is the Android Studio's log...
The last line in the log is printed when an unexpected disconnection occurs.
Configure and start the sensor fusion algorithm before you read the calibration state.
Thanks! works perfectly. Is it normal to get the states as “unreliable” on most sensors? and is there a way to calibrate the sensors to make them more accurate?
Regarding the update firmware method, is there a way to make it all in one step?
Thanks,
Amr
Read the documentation:
https://mbientlab.com/androiddocs/3/sensor_fusion.html#calibration
About the firmware update, quoting myself from my previous post