Real time Sensor Data Analysis on PSLab Android
PSLab device has the capacity to connect plug and play sensors through the I2C bus. The sensors are capable of providing data in real time. So, the PSLab Android App and the Desktop app need to have the feature to fetch real time sensor values and display the same in the user interface along with plotting the values on a simple graph.
The UI was made following the guidelines of Google’s Material Design and incorporating some ideas from the Science Journal app. Cards are used for making each section of the UI. There are segregated sections for real time updates and plotting where the real time data can be visualised. A methods for fetching the data are run continuously in the background which receive the data from the sensor and then update the screen.
The following section denotes a small portion of the UI responsible for displaying the data on the screen continuously and are quite simple enough. There are a number of TextViews which are being constantly updated on the screen. Their number depends on the type and volume of data sent by the sensor.
<TextView android:layout_width="wrap_content" android:layout_height="30dp" android:layout_gravity="start" android:text="@string/ax" android:textAlignment="textStart" android:textColor="@color/black" android:textSize="@dimen/textsize_edittext" android:textStyle="bold" />
<TextView android:id="@+id/tv_sensor_mpu6050_ax" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_gravity="start" android:textAlignment="textStart" android:textColor="@color/black" android:textSize="@dimen/textsize_edittext" android:textStyle="bold" />
The section here represents the portion of the UI responsible for displaying the graph. Like all other parts of the UI of PSLab Android, MPAndroidChart is being used here for plotting the graph.
<LinearLayout android:layout_width="match_parent" android:layout_height="160dp" android:layout_marginTop="40dp"> <com.github.mikephil.charting.charts.LineChart android:id="@+id/chart_sensor_mpu6050" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000" /> </LinearLayout>
Since the updates needs to continuous, a process should be continuously run for updating the display of the data and the graph. There are a variety of options available in Android in this regard like using a Timer on the UI thread and keep updating the data continuously, using ASyncTask to run a process in the background etc.
The issue with the former is that since all the processes i.e. fetching the data and updating the textviews & graph will run on the UI thread, the UI will become laggy. So, the developer team chose to use ASyncTask and make all the processes run in the background so that the UI thread functions smoothly.
A new class SensorDataFetch which extends AsyncTask is defined and its object is created in a runnable and the use of runnable ensures that the thread is run continuously till the time the fragment is used by the user.
scienceLab = ScienceLabCommon.scienceLab; i2c = scienceLab.i2c; try { MPU6050 = new MPU6050(i2c); } catch (IOException e) { e.printStackTrace(); } Runnable runnable = new Runnable() { @Override public void run() { while (true) { if (scienceLab.isConnected()) { try { sensorDataFetch = new SensorDataFetch(); } catch (IOException e) { e.printStackTrace(); } sensorDataFetch.execute(); } } } }; new Thread(runnable).start();
The following is the code for the ASyncTask created. There are two methods defined here doInBackground and onPostExecute which are responsible for fetching the data and updating the display respectively.
The raw data is fetched using the getRaw method of the MPU6050 object and stored in an ArrayList. The data type responsible for storing the data will depend on the return type of the getRaw method of each sensor class and might be different for other sensors. The data returned by getRaw is semi-processed and the data just needs to be split in sections before presenting it for display.
The PSLab Android app’s sensor files can be viewed here and they can give a better idea about how the sensors are calibrated, how the intrinsic nonlinearity is taken care of, how the communication actually works etc.
After the data is stored, the control moves to the onPostExecute method, here the textviews on the display and the chart are updated. The updation is slowed down a bit so that the user can visualize the data received.
private class SensorDataFetch extends AsyncTask<Void, Void, Void> { MPU6050 MPU6050 = new MPU6050(i2c); ArrayList<Double> dataMPU6050 = new ArrayList<Double>(); private SensorDataFetch(MPU6050 MPU6050) throws IOException { } @Override protected Void doInBackground(Void... params) { try { if (MPU6050 != null) { dataMPU6050 = MPU6050.getRaw(); } } catch (IOException e) { e.printStackTrace(); } return null; } protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); tvSensorMPU6050ax.setText(String.valueOf(dataMPU6050.get(0))); tvSensorMPU6050ay.setText(String.valueOf(dataMPU6050.get(1))); tvSensorMPU6050az.setText(String.valueOf(dataMPU6050.get(2))); tvSensorMPU6050gx.setText(String.valueOf(dataMPU6050.get(3))); tvSensorMPU6050gy.setText(String.valueOf(dataMPU6050.get(4))); tvSensorMPU6050gz.setText(String.valueOf(dataMPU6050.get(5))); tvSensorMPU6050temp.setText(String.valueOf(dataMPU6050.get(6))); } }
The detailed implementation of the same can be found here.
Additional Resources
- Learn more about how real time sensor data analysis can be used in various fields like IOT http://ieeexplore.ieee.org/document/7248401/
- Google Fit guide on how to use native built-in sensors on phones, smart watches etc. https://developers.google.com/fit/android/sensors
- A simple starter guide to build an app capable of real time sensor data analysis http://developer.telerik.com/products/building-an-android-app-that-displays-live-accelerometer-data/
- Learn more about using AsyncTask https://developer.android.com/reference/android/os/AsyncTask.html