Save Logging Data to .csv and output

Are there any examples of saving Log data to CSV and outputting to local directory? I have tried so many different things, and I cannot get it to work with the sensor.

I have a button that starts the logging and a button that stops the logging and downloads the entries. However, every time I try to integrate normal CSV writing that would be done in Java, it does not work. I have not found any examples online that work with the sensor. Log.i messages say that logging has started/stopped/downloaded, etc.

If anyone has information/code samples they could share, I would appreciate it. I have been at this for 2 weeks and it's making me super frustrated that I can't find a good example for logging. (I have found streaming examples, but they don't seem to work with logging.)

Comments

  • For additional info - I used the Starter App (Android - Java) as to get going. Basic functionality is working as expected. My code for the Start / Stop / Info buttons is in the DeviceSetupActivityFragment.java. I tried to setup the CSV read / write similarly to this blog, which is out of date but should theoretically be easy to adapt. I feel like I am probably missing something obvious in the way the API works with Java, but I have no idea what. If anyone could point me to some code examples I would appreciate it. I have Googled, read Android docs, read the MBientlab docs and done the tutorials.

    My Buttons are in the onViewCreated method

    public class DeviceSetupActivityFragment extends Fragment implements ServiceConnection {
        public interface FragmentSettings {
            BluetoothDevice getBtDevice();
        }
    
    
        public DeviceSetupActivityFragment() {
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            Activity owner = getActivity();
            if (!(owner instanceof FragmentSettings)) {
                throw new ClassCastException("Owning activity must implement the FragmentSettings interface");
            }
    
            settings = (FragmentSettings) owner;
            owner.getApplicationContext().bindService(new Intent(owner, BtleService.class), this, Context.BIND_AUTO_CREATE);
    
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
    
            ///< Unbind the service when the activity is destroyed
            Objects.requireNonNull(getActivity()).getApplicationContext().unbindService(this);
    
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            setRetainInstance(true);
            return inflater.inflate(R.layout.fragment_device_setup, container, false);
        }
    
       //cycle of data collection is supposed to happen here
        @Override
        public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
    
            //get the date
            year = Calendar.getInstance().get(Calendar.YEAR);
            month = Calendar.getInstance().get(Calendar.MONTH) + 1;
            day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
    
            //on-click listener for the logger for START button
            view.findViewById(R.id.acc_start);
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //sets up a route with the log capability
                    accelerometer.acceleration().addRouteAsync(new RouteBuilder() {
                        @Override
                        public void configure(RouteComponent source) {
                            source.log(new Subscriber() {
                                @Override
                                public void apply(Data data, Object... env) {
                                    // Read Accel and Prepare for writing to CSV
                                    final Acceleration value = data.value(Acceleration.class);
                                    Log.i("accLog", value.x() + ":: " + value.y() + "::" + value.z());
                                    Log.i("Data: ", data.toString());
    
                                }
                            });
                        }
                    }).continueWith(task -> {
    
    
                        logging.start(false);
                        Log.i(LOG_KEY2, "Logging started.");
    
                        accelerometer.acceleration().start();
                        Log.i(LOG_KEY, "accelerator service started");
    
                        accelerometer.start();
                        Log.i(LOG_KEY, "sensor started");
    
    
                        return null;
    
                    });
                }
            });
    
            //on-click listener for the STOP button
            view.findViewById(R.id.acc_stop);
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //this is where the timer logic and download info needs to go
                    //if stop button is pressed, end the Timer task, then do the following:
    
                    logging.stop();
                    Log.i(LOG_KEY, "Logging stopped.");
    
                    accelerometer.stop();
                    Log.i(LOG_KEY, "Sensor stop");
    
                    accelerometer.acceleration().stop();
                    Log.i(LOG_KEY, "Accel service stopped");
    
    
                    logging.downloadAsync(100, (nEntriesLeft, totalEntries) -> {
                        Log.i("Logging", "Progress Update = " + nEntriesLeft + "/" + totalEntries);
                        Log.i("TEST1", accelStrX);
                    }).continueWith((Continuation<Void, Void>) task -> {
    
                        if (task.isFaulted()) {
                            Log.e("Logging", "Error occurred");
                        } else {
                            Log.i("Logging", "Downloaded");
                        }
                        return null;
                    });
    
    
                    logging.clearEntries();
                    metawear.tearDown();
                }
            });
            view.findViewById(R.id.show_info).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Snackbar.make(v, getString(R.string.info_snackbar), Snackbar.LENGTH_LONG)
                            .show();
    
                }
            });
    
        }
    
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            metawear = ((BtleService.LocalBinder) service).getMetaWearBoard(settings.getBtDevice());
    
            //retrieves a reference to the Accelerometer, Logging & Timer and configures the sensor
            try {
                accelerometer = metawear.getModule(Accelerometer.class);
                logging = metawear.getModule(Logging.class);
                timer = metawear.getModule(Timer.class);
                accelerometer.configure().odr(ACC_FREQ).range(ACC_RANGE).commit();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
        @Override
        public void onServiceDisconnected(ComponentName name) {    }
    
          public void reconnected() {    }
    
    
    }
    
  • edited June 28

    Unfortunately saving data to files is not in the scope of the MetaWear APis. You just need to fine a proper tutorial on the net.
    Shortly, I will be putting the MetaBase Java App source code online (on github). This does have a save file functionality which you can also look at.

  • Thanks Laura. I'll keep plugging away at it in the meantime. I know it's something silly I'm missing as it usually is with coding.

Sign In or Register to comment.