How to use Mobile Sensors as Instruments in PSLab Android App

This blog demonstrates how to use built-in mobile sensors in an Android application. This blog will mainly feature my work done in PSLab Android repository of making a Compass and Accelerometer instrument using built-in mobile sensors.

How to access built-in mobile sensors?

Android provides an abstract class called SensorManager which is able to communicate with the hardware i.e. here the sensors in the mobile. But the SensorManager can’t provide continuous data fetched by the sensor. For this, Android provides an interface known as SensorEventListener which receives notifications from SensorManager whenever there is a new sensor data.

How to implement the functionality of sensors in Android app?

Following is a step by step process on how to add support for different sensors in an Android app

  • First, make a new class which extends SensorEventListener and override the default methods.
public class SensorActivity extends Activity implements SensorEventListener {

     public SensorActivity() {
        // Default Constructor      
     }

     @Override
     public void onAccuracyChanged(Sensor sensor, int accuracy) {
     }

     @Override
     public void onSensorChanged(SensorEvent event) {
     }
 }

Here, the SensorActivity() is the default constructor of the class and the onAccuracyChanged() and onSensorChanged() methods will be explained soon.

  • Now declare the SensorManager and use the sensor needed in the app.
private final SensorManager mSensorManager;
private final Sensor mAccelerometer;

     public SensorActivity() {
         mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
         mAccelerometer =        mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
     }

Here, I have used Sensor.TYPE_ACCELEROMETER to use the built-in Accelerometer in the device. Some of the other options available are:

  1. TYPE_LIGHT – To measure ambient light
  2. TYPE_MAGNETOMETER – To measure magnetic field along different axis
  3. TYPE_GYROSCOPE – To measure movements (sudden changes) in any particular direction

The list of all available sensors in Android can be found in [1].

  • It is necessary to disable the sensors especially when the activity is paused. Failing to do so can drain the battery in just a few hours.

NOTE: The system will not disable sensors automatically when the screen turns off.

So, to save the battery and make the app efficient, we can use the registerListener method to notify the SensorManager to start fetching data from sensor and unregisterListener to notify it to stop.

@Override
protected void onResume() {
         super.onResume();
         mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
     }

@Override
     protected void onPause() {
         super.onPause();
         mSensorManager.unregisterListener(this);
     }


The onResume() method activates when the app is resumed from a paused state and the onPause() method is called when the app is paused i.e. some other app draws over the current app.

  • Now coming back to onAccuracyChanged() and onSensorChanged() methods, the onAccuracyChanged() method is used to set the accuracy of a sensor. For example, while using GeoLocation sensor, sometimes the position of the mobile isn’t very accurate and so we can define the accuracy level in this method so that the fetched data is used for calculations only if it is in the provided range. And the onSensorChanged() method is the main method where all the data is processed as soon as the new data is notified.

To get the latest value from the sensor, we can use

@Override
public void onSensorChanged(SensorEvent event) {
   data = Float.valueOf(event.values[0]);
   unRegisterListener();
}

Here, the event is an instance of the SensorEvent class which provides the updated data fetched from the sensor. Event.values is used to get the values for any of the three axis including the bias in their values. Following is the list of the index for which we can get a necessary value

values[0] = x_uncalib without bias compensation
values[1] = y_uncalib without bias compensation
values[2] = z_uncalib without bias compensation
values[3] = estimated x_bias
values[4] = estimated y_bias 
values[5] = estimated z_bias

So, in this way, we can add support for any built-in mobile sensor in our Android application.

Resources

Continue ReadingHow to use Mobile Sensors as Instruments in PSLab Android App

How to Add Icons or Menus into the PSLab Android App Toolbar

This blog demonstrates how to add different icons like help, play, pause, etc. and/or menu bar in the toolbar of an Android app along with setting their visibilities on the toolbar i.e. to display the icons only when space is available else to add them in the menu. The topic will be mainly explained by taking the example of menus and icons added to the PSLab app.

How to add a menu in a toolbar?

Following are the steps to add a menu or an icon in the toolbar widget of the Android app

  • First, add toolbar widget to the main layout file as follows
<android.support.v7.widget.Toolbar
   android:id="@+id/compass_toolbar"
   android:layout_width="match_parent"
   android:layout_height="?attr/actionBarSize"
   android:background="?attr/colorPrimary"
   app:popupTheme="@style/AppTheme.PopupOverlay"
   app:title="@string/compass" />

Here, popupTheme is the theme that activates when inflating the toolbar. Usually, it is kept similar to the default theme of the toolbar.

  • Now as the toolbar is ready, we can make the menu that needs to be inflated on the toolbar. For making a menu, make a folder named menu in the resources folder. Now, add a menu resource file in it by giving a proper name and then add the following code
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto">
   <item
       android:id="@+id/compass_help_icon"
       android:icon="@drawable/compass_help_icon"
       android:title="@string/show_axis_help"
       app:showAsAction="always" />
</menu>

A detailed explanation of the above code is as follows:

  1. The <menu>…</menu> covers all the items in the menu. There can be sub-menu and also sub-sub-menu too. To make a sub-menu, use <menu>…</menu> inside the main menu.
  2. The <item> tag inside the menu defines a specific item to be included in the menu. The icon attribute of an item is used to show the icon on the toolbar. The title attribute of an item is used to show the text inside the menu if space isn’t available to show the icon on the toolbar. The showAsAction attribute is used to define the method of an item i.e. how the item should be visible to the user. Following are some of the values that showAsAction attribute can take:
    • always – It is used to show the icon of the item on the toolbar everytime
    • never – It is used to show the item as a text in the menu everytime the activity is opened
    • ifRoom – It is used to show the icon on the toolbar if there is enough space else the item is included in the menu

NOTE: Always give IDs to menu items as they are used to distinctly identify the item in the java code.

Figure 1. Example of menu and icons in toolbar in PSLab app

As shown in figure 1, the first two icons have always value in their showAsAction attribute whereas other items have never values in their showAsAction attribute.

  • Now the layout and the menu are ready to be inflated from the Java code. First, the toolbar needs to be set up from the Java code. So find the toolbar with its id and then write the following line in the code.
setSupportActionBar(mToolbar);
  • Now the toolbar is ready and so the menu can be inflated on it. So, override the following method to inflate the menu
@Override
public boolean onCreateOptionsMenu(Menu menu) {
   MenuInflater inflater = getMenuInflater();
   inflater.inflate(R.menu.activity_compass_help_menu, menu);
   return true;
}

Here, the getMenuInflater() method is used to inflate the menu on the toolbar.

  • Now override the onCreateOptionsMenu() method to do the predefined task of selecting the icon or the item from the menu.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {
       case R.id.compass_help_icon:
           // Do something
           break;
       default:
           break;
   }
   return true;
}

So, in this way a menu can be made so that the number of items delivered to the user can be increased by using the minimum space possible.

Resources

  1. https://developer.android.com/guide/topics/ui/menus – Android Developers guide on how to make a menu in Android
Continue ReadingHow to Add Icons or Menus into the PSLab Android App Toolbar

Detecting Barometer sensor in PSLab Android App

The Pocket Science Lab Android app has Barometer Instrument implemented in it. Although the instrument  is currently working through the mobile sensors and not the PSLab i2c library as there were some issues in the i2c communication with PSLab device.

Thus as the barometer was completely working on through the mobile sensors, there was a major problem coming up. Majority of the mobiles don’t have the barometer sensor which was required, only a  few of the latest devices have the sensors in them.

This issues created problem as now anyone who would have used the barometer instrument would have made an impression that the App was itself not working.

Figure(1) : Showing the stagnant barometer Instrument

Thus this created a bad impression for both the app and it’s developers.

Solving the issue

To solve this major bug, it required to first detect the barometer instrument and then implementing an alert dialog-box showing that barometer sensor is not present in his device.

  • Detecting the Barometer Sensor[2]

The barometer sensor was detected using the sensorManager class of Java

sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensor = sensorManager != null ? sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) : null;

Thus using this code the barometer sensor is detected, if sensor was not present the  sensorManger would be null.

  • Implementing the alert-box[1]

Thus if the sensorManger variable was null it notified that the sensor was not present in           the device and corresponding to which an alert-box was implemeneted

if (sensor == null) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (!isFinishing()) {
                new AlertDialog.Builder(BarometerActivity.this)
                    .setTitle(R.string.barometer_alert_title)
                    .setMessage(R.string.barometer_alert_description)
                    .setCancelable(false)
                    .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    }).show();
            }
        }
    });

Thus as we can see in the code snippet the alert dialog-box will appear if  sensor is not present as shown in figure (2).

Figure(2) : Screenshot showing alert-box

Resources

  1. Android Alert-box Example, Mkyong.com:
    https://www.mkyong.com/android/android-alert-dialog-example/
  2. Creating a Barometer Application for Android, medium.com:
    https://medium.com/@ssaurel/creating-a-barometer-application-for-android-1c0a5c10b20e
Continue ReadingDetecting Barometer sensor in PSLab Android App

Implementing Toolbar and Exporting Data in CSV format in Multimeter

The latest feature which was implemented in the  Pocket Science Lab Android app is the data exporting feature which was implemented in almost each and every sensor. Now in addition to sensors now the data saving functionality is also implemented in Multimeter and this blog is regarding how the data exporting functionality was implemented for multimeter.

For implementing the data exporting feature first the Toolbar was implemented in the PSLab Android App.

Implementing the Toolbar[1]

For implementing the firstly the front-end of multimeter was changed and the Toolbar was added to it.

<android.support.design.widget.AppBarLayout
  android:id="@+id/top_app_bar_layout"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:theme="@style/AppTheme.AppBarOverlay">

  <android.support.v7.widget.Toolbar
      android:id="@+id/multimeter_toolbar"
      android:layout_width="match_parent"
      android:layout_height="?attr/actionBarSize"
      android:background="?attr/colorPrimary"
      app:popupTheme="@style/AppTheme.PopupOverlay"
      app:title="Multimeter" />

The above xml codes shows the implementation of toolbar.

Figure (1): Showing the implementation of multimeter toolbar

  • Backend

For implementing the toolbar the onCreatemenu  was implemented for multimeter

@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.multimeter_log_menu, menu);
this.menu = menu;
return true;
}

For the same a separate menu was created for multimeter

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/record_pause_data"
android:icon="@drawable/record_icon"
android:title="@string/record_csv_data"
app:showAsAction="always" />
<item
android:id="@+id/delete_csv_data"
android:icon="@drawable/delete_icon"
android:title="@string/delete_csv_data"
app:showAsAction="ifRoom" />
<item
android:id="@+id/record_csv_data"
android:icon="@drawable/menu_icon_save"
android:title="@string/save_csv_data"
app:showAsAction="never" />
<item
android:id="@+id/settings"
android:title="@string/nav_settings"
app:showAsAction="never" />
</menu>

Figure(2): Showing Toolbar of Multimeter

Thus through this the basic UI of the toolbar was implemented.

Implementing the Data Export Feature[2]

After implementing the toolbar for multimeter the multimeter the data exporting feature was implemented through the toolbar. The data export feature was implemented in such a manner that the user can start data recording by clicking on the record button after which the recording starts.

Figure(3):Showing snackbar after the data recording is started

and then when the user wants to end the experiment he may click on the pause button after which he gets an option either to export the data in csv format or either to delete the data.

Figure(4):Showing the menu bar for exporting data in csv

After clicking on the export data button the snacker appears which finally tells the user that the data is exported in this particular location (mentioned in the snackbar)

Figure(5):Showing the snackbar for showing location of the CSV folder

Further going to the csv folder we get the excel sheet in which the data is exported

Figure(6):Showing the excel sheet of data recorded

And this is how the data exporting feature was implemented in the PSLab android app. The users can use this functionality to perform experiments using multimeter in PSLab.

Resources

  1. Medium, Android Toolbar for AppCompatActivity:
    https://medium.com/@101/android-toolbar-for-appcompatactivity-671b1d10f354
  2. Code Project, Exporting data in CSV format:
    https://www.codeproject.com/questions/491823/read-fwritepluscsvplusinplusplusandroid

 

Continue ReadingImplementing Toolbar and Exporting Data in CSV format in Multimeter

Measuring Current in PSLab Android App

The Pocket Science Lab Android app has got various functionality such as voltmeter, resistance measurement, capacitance measurement, frequency measurement as well as Count pulse measurement , one of the missing functionality among these is the Ammeter, currently in PSLab there is no direct way of measuring current. In this blog I will be discussing an indirect method of measuring current in PSLab.

Basics of measuring current

Generally in all multimeters , current is measured using  an Ammeter which uses the property of galvanometer to measure to measure current in PSLab. But as the PSLab doesn’t has any such embedded Galvanometer we cannot have a seperate Ammeter in it, but there is another method to measure the current, which is using the famous OHm’s law i.e V/I = R

In PSLab we can measure the voltage across any elements, plus we can also measure  the resistance of any circuit element in PSLab, the theory used for measuring current is stated as follows.

  1. We connect the current-source to any known resistant(or any resistance) and then measure the voltage across the resistor.
  2. Finally using ohm’s law the current will be voltage / resistance.[2]

Step-by-step guide on measuring the current

Here is the step by step guide on how to measure the current in PSLab:-

  1. Take any arbitrary resistor and measure it’s resistance. To measure the resistance follow these steps :-
    1. Take a resistance and connect it to any two pins of breadboard
    2. Connect one end to the sen pin and the other end to the GND pin of PSLab device.
    3. Now go to the Android app and select multimeter instrument.
    4. Now in the multimeter instrument set the knob to resistance, in the measure section
    5. Now click on the read button and then it will show the resistance of the resistor
  2. Now that you have measured the resistance of the resistor, now connect the current source across the resistors.
  3. Now finally measure the voltage across the resistor. To measure the voltage follow these steps.
    1. Take two male to male wires and connect it’s two individual ends to the two ends of the resistor.
    2. Now connect one of the other two ends of the wire to the any one of the CH1, CH2 or CH3 and the other end to GND respectively.
    3. Now go to the Android app and select multimeter instrument.
    4. Now in the multimeter instrument set the knob to the channel which you have selected i.e CH1, CH2 or CH3 , in the voltage section.
    5. Now click on the read button and then it will show the voltage across the resistor.
  4. Now using the using ohm’s law the current will be voltage / resistance.

Thus using these steps one can find the current in PSLab Android App.

Images for the Experiment

Figure (1): Showing resistance measurement

Figure(2) Showing voltage measurement

Resources

  1. Using-a-Multimeter, dengarden.com:
    https://dengarden.com/home-improvement/Using-a-Multimeter
  2. Wikipedia, Ohm’s Law:
    https://en.wikipedia.org/wiki/Ohm%27s_law
Continue ReadingMeasuring Current in PSLab Android App

Implementing Layouts for Different Screens in Android PSLab App

The Pocket Science Lab Android app has various functionalities implemented in it, one of the major implemented functionalities is the knob in the multimeter, In my previous blog I have mentioned about the knobs and how exactly it has been implemented, one the major problems in the knob is that it doesn’t fits correctly in all layouts, even though constraint layout is used , as it has different text-views positioned in a circular constraint in which exact circular radius has to be mentioned (which cannot be constrained), mentioned in my previous-blog there comes the idea of creating different layouts for different-screens in android.

Need to create multiple layouts for different screen

There arises this question of the use of creating multiple layouts for different screens when you can create a flexible layout using tools such as constraint layout. The answer to this question is that in some cases such as as the case of circular constraint or using a linear-layout  one has to use use hard-coded dimensions which thus makes difference in various screens on, there comes the need of using size and orientation quantifiers i.e making layout according to screen sizes. Als

Figure 1:Screenshot

Figure 1 shows how different layouts are made for multimeter according to the screen-size.

Size quantifiers in android

Size quantifier is a name that specifies an individual configuration (in this case size) corresponding to which resources can be used.

For example, here are some default and alternative resources:

res/
   drawable/
       icon.png
       background.png
   drawable-hdpi/
       icon.png
       background.png

In this case -hdpi is a size quantifier, there are default size quantifiers at the drawable folder.

Making different layouts according to size-quantifiers[1][2]

This blog will give a step by step guide on how to make layouts using size quantifiers.

  1. Right click the res folder in android studio and select New-> Android Resource directory.
  2. A screen like below will appear
  3. Change the resource type to layout.
  4. From the available quantifiers select the quantifier which you would require, (in our case it is size).
  5. After selecting the quantifier click the >> button after which the following screen will get displayed.
  6. Now select the screen-size and click ok to make the directory, note that only one directory can be made in a single go.
  7. After this make different layouts according to the screen-sizes and then save the respective alternative resources in this new directory. The resource files must be named exactly the same as the default resource files.

Thus by following these steps one can make different layouts according to screen-sizes in android.

Resources

  1. Support different screen sizes, Android developers https://developer.android.com/training/multiscreen/screensizes#TaskUseSizeQuali (Link to repo)
  2. App resources overview, Android developers https://developer.android.com/guide/topics/resources/providing-resources#ScreenSizeQualifier
Continue ReadingImplementing Layouts for Different Screens in Android PSLab App

Implementing Custom Rotary Knobs and Circular Positioning in the Multimeter in the PSLab Android App

In my previous blog [2I have discussed about how to implement  normal rotary knob using an open source library, this blog will be about the new user interface (UI) of multimeter in the PSLab Android app, how a custom rotary knob is implemented in it and how how the text views are positioned circular in them.

Implementation of Custom Rotary Knob

In the PSLab device  the rotary knob is implemented using the BeppiMenozzi Knob library[1] as by doing this we don’t have to manually create the extra class for the knob and we don’t have to write the code from scratch.

Figure 1: A basic rotary knob

Figure 1 shows a basic knob implemented using the BeppiMenozzi library whereas figure 2 shows the implementation of a custom knob using the basic knob.

Figure 2: A custom Knob

Steps of making a Custom-Knob using a simple Knob

  1. Implement the the basic knob using the steps given in my previous knobs explained in my previous blogs.
  2. Download the images of the knob which has to be implemented.
android:layout_weight="1"
android:rotation="15"
app:kDefaultState="2"
app:kIndicatorWidth="@dimen/multimeter_length_0"
app:kKnobCenterColor="@color/colorPrimaryDark"
app:kKnobColor="@color/white"
app:kKnobDrawable="@drawable/knob"
  1. Using the above code amend the knob as per the requirement. The advantage of using the beppiMonzi library is that the knob is fully amenable  , we can even define the minimum and maximum angle and many more stuffs can be done using the library.

                 

 

 

 

 

Figure 3: Showing the implementation of other custom knobs

The above figure shows the example of custom knobs implemented using the simple knob and by following the steps.

Implementation Circular positioning

One of the other major issues while making the new UI of the multimeter is the positioning of text-view around the circular knob. The issue was made overcome by implementing a circular positioning constraints in the text-views.

Steps of implementing circular positioning

  1. Use the constraint layout version 1.1.0 or above as the previous versions do not support the circular positioning feature.
  2. Add the circular constraint individually to every text-view.
app:layout_constraintCircle="@id/knobs"
app:layout_constraintCircleAngle="105"
app:layout_constraintCircleRadius="@dimen/multimeter_knobcircle_radius_1"

The above code snippets shows the addition od circular constraints added to a text-view. Using these constraint it decides positions the views relative to another views at a particular angle which thus makes up circular positioning.

Thus, this is how we can implement circular positioning in the views.

Resources

  1. BeppiMenozzi Knob Library
    https://github.com/BeppiMenozzi/Knob
  2. Rotary knob Blog
    https://docs.google.com/document/d/1IU_lpdt4sHI4euM543bBlHwYpv8vwwjxoB76sW1i5HA/edit?usp=sharing
Continue ReadingImplementing Custom Rotary Knobs and Circular Positioning in the Multimeter in the PSLab Android App

Measuring capacitor in PSLab and its Bugs

In this blog I will discuss about how we have measured capacitance in Pocket Science Lab and the  issues in capacitance measurement which was finally solved.

Measuring capacitance in PSLab device

To measure capacitance we need to go to the multimeter instrument from the instrument section of the PSLab

Figure 1.  Showing Multimeter Tile

Capacitance in PSLab is measured by keeping the capacitor or the element of which capacitance is to be measured between the CAP and ground pin.

 Figure 2.  Showing CAP pins in PSLab

For measuring capacitance in PSLab we use a specific method in which we supply a constant current to the CAP pin and thus we charge the capacitor to the maximum level, the math involved in it is as follow:-

We know that

Q{charge stored} = C*V

Also

Q= I * time

Where

I=current (constant)

Thus the capacitance

C = Q / V

Therefore

C = I*time / V (measured). – (1)

Therefore we know the current supplied, we know the voltage measured and we have also set the time to charge the capacitor and thus we get the capacitance from equation (1).

Code implementation for measuring capacitance

This is the primary code for getting the data for measuring capacitance in which we pass the current range and the current time through which the data gets fetched from the device which is then further processed in another function in which we finally get the capacitance.

public double[] getCapacitance(int currentRange, int chargeTime) { // time in uSec
        try {
            mPacketHandler.sendByte(mCommandsProto.COMMON);
            mPacketHandler.sendByte(mCommandsProto.GET_CAPACITANCE);
            mPacketHandler.sendByte(currentRange);
            mPacketHandler.sendInt(chargeTime);
            Thread.sleep((long)(chargeTime * 1e-6 + .02));
            int VCode;
            do VCode = mPacketHandler.getVoltageSummation();
            while (VCode == -1);
            double v = 3.3 * VCode / 4095;
            mPacketHandler.getAcknowledgement();
            double chargeCurrent = this.currents[currentRange];
            double c = 0;
            if (v != 0)
                c = (chargeCurrent * chargeTime * 1e-6 / v - this.SOCKET_CAPACITANCE) / this.currentScalars[currentRange];
            return new double[] {
                v,
                c
            };
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return null;

In the above function we can clearly see how we send the bytes in the device by the sendByte function through which various functions are sending current, setting voltage, setting current range etc are done in the device and then we can see how the voltage measured is taken using the getVoltageSummition method (of packet Handler class) , how we get the current and finally using them in equation (1) we get the capacitance of the element.

The following implementation is taken from the PSLab desktop app where the same method is used to measure capacitance.

Bugs in measuring capacitance

The capacitance measurement although was working in the desktop app but had bugs in the android app. It could never read the correct value also everytime gave a null value for capacitance.

Figure 3.  Showing null value for capacitance  PSLab

Solving the Bug [2]

After a deep research in the inside  the code of the capacitance measurement it was found that the error was caused while fetching the incorrect data from the device and processing it. The device gives a negative one value when there is any error in capacitance measurement  and that was being processed, thus the error was solved by introducing a do while loop as shown

 do VCode = mPacketHandler.getVoltageSummation();
 while (VCode == -1);

And thus now only the correct data fetched is processed further and thus the bug was solved after which the capacitance measurement was correct.

Resources

Continue ReadingMeasuring capacitor in PSLab and its Bugs

Channel Communications Error of PSLab

The Pocket Science Lab multimeter has got three channels namely CH1,CH2 and CH3 with different ranges for measuring the voltages, but there was a channel communication error occuring at CH1 and CH2 pins of PSLab. This blogs will give a brief description of the channel communication error and how was it solved by me.

In the previous blog I have discussed about the channel communication of PSLab and how it works. In this blog i will be discussing about the channel communication error which was occuring while using CH1 and CH2 pins of PSLab android.

Communication between PSLab device and Android App

As discussed in the previous blog the communication between the PSLab and the android occurs with the help of the USBManger class of android.

One of the major function which makes it possible is the bulk transfer function of the android

amtWritten = mConnection.bulkTransfer(mWriteEndpoint, src, written, writeLength, timeoutMillis);

As shown in the above code, there is a timeout that some time required for this function to be executed, and otherwise this function will return a negative value which will mean that the communication is not successful.

Voltage Measuring Functions

The main function which gets called while pressing the button for measuring voltage is the getVoltage function which simultaneously calls the volmeterAutoRange function as well as the getAverage voltage function. The voltageAutoRnge function also calls the getAverage function inside of it.

public double getVoltage(String channelName, Integer sample) {
    this.voltmeterAutoRange(channelName);
    double Voltage = this.getAverageVoltage(channelName, sample);
    if (channelName.equals("CH3")) {
        return Voltage;
    } else {
        return 2 * Voltage;
    }
}

Calling both these functions simultaneously results in calling of the bulktranfer method

VoltmeterAutoRange function:-

private double voltmeterAutoRange(String channelName) {
    if (this.analogInputSources.get(channelName).gainPGA == 0)
        return 0;
    this.setGain(channelName, 0, true);
    double V = this.getAverageVoltage(channelName, null);
    return this.autoSelectRange(channelName, V);
}

The getAverage voltage function calls the getRawableVoltage function which thus calls the USBManger class functions of read and write, thus calling the bulkTranfer function.

Thus as the bulk transfer function is called simultaneously it caused problem in communication.

Solving the issue

The communication related  issues were finally solved when these bugs were spotted, the solution to this issue is that the voltageAutoRange function’s return value was never used in the codes and was thus not required.[2]The voltageAutoRange function was calling the getAverageVoltage function just to get a return value. Thus I formatted the function and now it looks like this-

private void voltmeterAutoRange(String channelName) {
    if (this.analogInputSources.get(channelName).gainPGA != 0) {
        this.setGain(channelName, 0, true);
    }
}

And thus finally the issue was solved and all things were working fine in channel communication.

Resources

Continue ReadingChannel Communications Error of PSLab

Working with Shared Preferences in PSLab App

This blog demonstrates how to work with Shared Preferences in an Android app. The blog includes a detailed explanation about what are the methods available to store data in Android and where to use Shared Preferences (a type of data storage method) to save extra memory usage and work efficiently. After the detailed explanation is a step by step guide on how to use Shared Preferences in any Android app by taking an example of one used in PSLab Android app under PR #1236

What are methods available in Android for data storage ?

Android provides a variety of methods to store data some of which are

  1. Shared Preferences
  2. Internal Storage
  3. External Storage
  4. SQLite Database

A very brief description of the above four data storage method would be

  • Shared Preference – Used to store key-data pair for a given app
  • Internal Storage – Used to store any type of data such as pictures, videos, etc. which can be used only within the app
  • External Storage – Used to store any type of data such as audio, video, etc. which can be shared between different apps or different systems
  • SQLite database – It is also a type of Internal Storage method but with a different programming language in use which is SQL

Where to use different data storage methods?

Following are some of the  distinct cases where the above-mentioned data storing methods can be differentiated

  • Shared Preference – Shared Preference should be used when a very small amount of data i.e. key-value pair data is to be stored. An example of it would be storing the state of a widget when an app is closed and restoring the state when the app is opened again.
  • Internal Storage – Internal storage should be used while storing data such as text files, audio, video, photographs, etc. but occupying a very less device memory space. So, internal storage should be used when a limited amount of data needs to be stored for app execution.
  • External Storage – External storage should be used when data to be stored is very large and as a result, Internal storage can’t be used. External Storage can also write data on external memories like SD Card, etc.

How to use Shared Preferences in an Android app?

Following is a step by step guide on how Shared Preferences were used in PSLab Android app

  • First, declare a variable using final and static keyword so as to make its value permanent because it will be used to differentiate current activity/fragment data from other activity/fragment data in a common folder of Shared Preference.
private static final String FRAG_CONFIG = "LuxMeterConfig";
  • Now, we can make Shared Preferences for current activity/fragment by using the code:

When in Activity:

final SharedPreferences settings = getSharedPreferences(FRAG_CONFIG, Context.MODE_PRIVATE);

When in fragment:

final SharedPreferences settings = getActivity().getSharedPreferences(FRAG_CONFIG, Context.MODE_PRIVATE);

Here Context.MODE_PRIVATE is a context through which we define our Shared Preference i.e. for the current context it means that the above made Shared Preference can only be used inside the current activity/fragment. A detailed description of other modes available can be found in [1].

  • Now, Shared Preference for current activity/fragment is ready for use and so now, we can add as many numbers of the key-value pair as we want by using the following code
settings.getInt("HighValue", 2000);

Here, “HighValue” is the key whereas 2000 is the value. The above method is used to give a default value when a pair is created.

  • Now to edit the value of any before-made pair, we can use the Editor method available in the Shared Preference class to edit the default value.
SharedPreferences.Editor editor = settings.edit();
editor.putInt("HighValue", 5000);
editor.apply();

Here, the editor is an instance of edit() method available in Shared Preference class. After changing the default value of the key, we can use apply() method to apply the changes to the default key-value pair.

Where to find the Shared Preference folder on the target device?

To find the Shared Preference folder for any Android application, do the following steps:

  • Connect the target device (device on which app is installed) to the system running Android Studio.
  • Now click on the “Device File Explorer” button in Android Studio as shown in figure 1.

Figure 1. Device File Explorer button in Android Studio

  • Now after clicking the button, a list of folders would pop up as shown in figure 2.

Figure 2. Screenshot of Android Studio showing list of folders on the device

  • Now follow the given path, and you can see the desired folder
/data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PACKAGE_NAME_preferences.xml

So, in this way, the Shared Preferences can be used for data storage in any Android application.

Resources

  1. https://www.androidauthority.com/how-to-store-data-locally-in-android-app-717190/ – Documentation on different modes available to define the context of Shared Preference
  2. https://stackoverflow.com/questions/6146106/where-are-shared-preferences-stored – StackOverflow Q/A for where the Shared Preferences are stored on the target device
Continue ReadingWorking with Shared Preferences in PSLab App