Downloading acceleration data logs

We are trying to make a basic app where we log accelerometer data onto the board and then tries to empty the log once every minute.
We have looked at the free fall example app and modified that and also the example app that comes with the Android API.
It works for a few times to download the logs but after some downloads the app start throwing exceptions and no more data is being correctly downloaded. 
Most often there is a NoSuchElementException but sometimes out of memory and null pointer exceptions in the DefaultMetaWearBoard class.
To reproduce: Start the example app in the Android API, click connect, turn on accelerometer, click download. After a few downloads the app start throwing exceptions. Anyone else experiencing these issues?

Background task reported an error
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear: java.util.concurrent.ExecutionException: java.util.NoSuchElementException
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at java.util.concurrent.FutureTask.report(FutureTask.java:93)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at java.util.concurrent.FutureTask.get(FutureTask.java:163)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at com.mbientlab.metawear.MetaWearBleService$3.run(MetaWearBleService.java:1126)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at java.util.Timer$TimerImpl.run(Timer.java:284)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:  Caused by: java.util.NoSuchElementException
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at java.util.LinkedList.removeFirstImpl(LinkedList.java:689)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at java.util.LinkedList.removeFirst(LinkedList.java:676)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at java.util.LinkedList.poll(LinkedList.java:895)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at com.mbientlab.metawear.impl.DefaultMetaWearBoard$VariableLoggable.processLogMessage(DefaultMetaWearBoard.java:543)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at com.mbientlab.metawear.impl.DefaultMetaWearBoard.processLogData(DefaultMetaWearBoard.java:2686)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at com.mbientlab.metawear.impl.DefaultMetaWearBoard.access$4500(DefaultMetaWearBoard.java:70)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at com.mbientlab.metawear.impl.DefaultMetaWearBoard$6.process(DefaultMetaWearBoard.java:2372)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at com.mbientlab.metawear.impl.DefaultMetaWearBoard.receivedResponse(DefaultMetaWearBoard.java:3026)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at com.mbientlab.metawear.MetaWearBleService$2$6.run(MetaWearBleService.java:909)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
10-13 14:48:39.112 17044-17068/com.mbientlab.metawear.test E/MetaWear:     at java.lang.Thread.run(Thread.java:841)

Comments

  • edited October 2015
    Are you using Marshmallow by chance?  A fix has been pushed to the GitHub repo.


    Also, the logger is not meant for recording high frequency data, such as acceleration data; the sheer volume of data will quickly consume all the flash memory.  You should think about what you want to do with the acceleration data and log processed data rather than raw data.
  • Hrm..actually the previous fix leads to another race condition.  I'll have to rework how the logger handles the data.
  • interesting discussion. I have a similar problem - every 60 seconds I would like to log accelerometer data for 15 seconds (with 12.5 Hz frequency) and then download it. I does work a couple of cycles with downloads performed to the very last entry point but then notifications just stop, no onProgressUpdates called.
  • We are using android 4.4.2
  • edited October 2015
    It should also be noted that the logger cannot do garbage collection while the ble connection is active.  If you are maintaining connection throughout your logging, then you will eventually use all the log entries despite starting multiple log downloads.  This also raises the question of why you are logging data when you have an active connection that can directly stream to your device.


  • Hi Eric -

    Is there any example, app note, etc. that shows how to stream or log either the sum or average - instead of raw accelerometer and gyro data. Especially if you want to analyze the x, y, z values PRIOR to and AFTER an event (e.g. RMS>Threshold).

    As you correctly pointed out in multiple posts - both streaming and logging raw accelerometer and gyro data for high frequency application have issues (BLE/storage). It would be helpful for everyone who may be doing high frequency apps (>50Hz) if there is an example showing how to stream/log processed data PRIOR to and AFTER a triggering event.

    Also, the logger is not meant for recording high frequency data, such as
    acceleration data; the sheer volume of data will quickly consume all
    the flash memory.  You should think about what you want to do with the acceleration data and log processed data rather than raw data.
  • Hi Eric.

    The following scenario I think is very common and I think should be supported:

    1. Acceleration data is to be continuously measured and all data points needs to be delivered to the application since heavy calculations are needed that aren't feasible on the board.
    2. The board can't be connected to the phone/tablet at all time since the board moves out of connection range.
    3. The battery life needs to last for weeks.
    4. In our application we would also need to have a trigger on fall detection, so if a fall is detected the application needs to be notified directly (in case the board is in connection range)

    How should such a use-case be built?

    We currently split the accelerometer data into raw logging and one stream that only triggers on fall. The app works for around a minute, then it starts crashing as above. 

    Should it be designed in some other way?
    If I understand correctly, streaming of raw accelerometer data is not feasible since data will be lost if the board is not connected and also it will drain the battery since the Bluetooth is on all the time?

    Logging would then be needed and downloading of logs should be performed regularly for the user to feel somewhat that it's semi live, every 1 or 5 minutes. Should the connection be turned on/off all the time for this to work? Then the triggering of fall detection will not work for the stream if the board is in off state?
    How is the internal sleep mode of the Bluetooth triggered?

    Many questions here but looks like other people have similar use cases so would be great to shed some light on this.
  • Yes, I will write up some demo code to show how to do that

    What exactly are you using the MetaWear for?  I am curious as to what your use case is.

    For your scenario, the best way I can think of is to have the board alternate between streaming and logging depending on the connection state.  The firmware currently does not support this configuration but we are working on adding a feature where you can program the board to react to a change in the connection state.

    The battery the MetaWear R variants is only 100mah.  You can attach a higher mah battery if you need to continuously run the accelerometer for weeks.
  • Thanks Eric.

    We are using the meta wear accelerometer data as input for machine learning algorithms to find and train on different motion patterns. That is why we would like as much data as possible for the input.

    If we run in streaming mode, don't we drain a lot of the battery since the Bluetooth need a lot of energy?
    Can you develop some function where you can download and empty the logs while still connected and also functions to be able to compress the log data (with less resolution, like 1 byte per axis) to be able to store more onto the board memory?
  • Thank you so much Eric. Looking forward to your solution. In our experiments, the number of process required for each individual axis (Accel x, y, z & Gyro x, y, z) to save prior event data was large. I am sure there is a much elegant way to do this. 
  • edited October 2015
    We have talked about both features you mentioned but at the moment, they are considered nice to have features.  
  • Similar to others, we are looking to log accelerometer and gyro data (for sport) at 100hz for approx 2hr and then download the data from the device for further processing using other applications such as matlab, R, python etc.. Thus the some of the onboard processing methods are no applicable and raw data is needed.
  • Thanks Eric!
    The new patch works great! No more crashes.

    However, it feels quite strange that we need to do disconnect and then connect again to garbage collect the logs.. even though we have emptied the data from them..
  • You have to erase a flash memory memory chunk before you can reuse it and you can't erase while the connection is active.  The only way around this is to have external flash memory separate from the SoC.
  • We do have an option for extended NOR FLASH memory on the board but it doesn't come standard on the dev boards.

    We could make it available as a standard board feature, maybe a MetaWearRSUPER next year if there is enough demand for it.

  • The NOR FLASH sounds interesting. Is it possible to use that also on the upcoming metawear C or is the memory already larger on that board?
  • edited October 2015
    I vote for the NOR Flash. I have working code to download accelerometer data every few seconds at 200Hz, but it's based on the previous API. I have yet to get it working with the new API. The need to disconnect and reconnect makes my app fairly unstable. Client is looking at 200 units/yr if that makes any difference :)
  • edited October 2015
    @sonalideo
    No, MetaWear C has the same memory capacity as the R boards

    If your customer is considering purchasing at that quantity and requires some variant of the vanilla board, then he should take a look at our services (http://mbientlab.com/services/) and contact us directly at "hello at mbientlab dot com" to see what we can do for him.

    You can try this code to see if it works for you.

    ```
    final byte sampleSize= 16;
    final String streamKey= "x_axis_event_data";
    accelModule.routeData().fromXAxis()
            .process(new Sample(sampleSize))
            .process(streamKey, new Passthrough(Passthrough.Mode.COUNT, (short) 0))
    .commit();
    switchModule.routeData().fromSensor().monitor(new ActivityHandler() {
        @Override
        public void onSignalActive(Map<String, DataProcessor> processors, DataToken token) {
            processors.get(streamKey).setState(new Passthrough.State((short) (sampleSize * 2)));
        }
    }).commit();
    ```
    What this does is use the sample filter to store the previous N samples from an event (in this case, the switch toggling) and uses the passthrough filter to allow the next N samples after the event through.  There is something acting funny in the firmware when using the sample processor at high freq but in the meantime, you can this chain with a lower freq, such as 25Hz or 12.5Hz.
  • Thank you Eric.
    This is sort of what we were trying also. Is there a limit on the number of process you can have on board [remember seeing something about it on a doc, but can't find it now]?

     We tried this with both 100Hz (what we need) and 50 Hz without success. Will try with 12.5 and see if we can get the data we need - and then wait for firmware update for higher frequencies.

    Thank you again for looking into this --
    Vinod
This discussion has been closed.