Creating Activity for Visualizing Recorded Sensor Data from List Items

In previous blog Using RealmRecyclerView Adapter to Show Recorded Sensor Experiments[2], I  have created a DataLoggerActivity in PSLab Android app containing RecyclerView showing a list having all the recorded experiments where every list item shows the date, time and the sensor instrument used for recording the data, but there arises below questions:-

  • What if the user wants to see the actual recorded data in form of a graph?
  • How the user can see the location recorded along with the data on the map?
  • How can the user export that data?

There is no way I could show all of that information just on a list item so I created another activity called “SensorGraphViewActivity” the layout of that activity is shown in the figure below:

Figure 1 shows the layout of the Activity as produced in Android editor

The layout contains three views:-

  1. At the top there is graph view which I created using Android MP chart which will show the recorded data plotted on it forming the exact same curve that was created while recording it, this way it is useful to visualize the data and also there is also a play button on the top which simulates the data as it was being plotted on the graph in real time.
  2. In the middle, there is a Card view containing two rows which will simply show the date and time of recording.
  3. At the bottom, there is a Map view which shows the location of the user which would be fetched when the user recorded the data.

This is the gist of the layout file created for the activity.

But now the question arises:-

How to show the data in the activity for the item that the user wanted?

For that, I implemented click listener on every list item by simply adding it inside the onBindViewHolder() method

@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
   SensorLogged temp = getItem(position);
   holder.sensor.setText(temp.getSensor());
   Date date = new Date(temp.getDateTimeStart());
   holder.dateTime.setText(String.valueOf(sdf.format(date)));
   holder.cardView.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View view) {
                    ...
       });
}

and inside the click listener I performed following three steps:-

  1. First I stored the position of the item clicked inside a variable.

    int positionVar = holder.getAdapterPosition();
  2. Then I used that position from the variable to fetch related data from the Realm database by simply using getItem() method which returns the SensorLogged[1] RealmObject at that position as I used a special type of RecyclerView Adapter called as RealmRecyclerViewAdapter[2].

    int positionVar = holder.getAdapterPosition();
  3. Then I created an Intent to open the SensorGraphViewActivity and passed the related data (i.e., sensortype, foreignkey, latitude, longitude, timezone, date, time) from SensorLogged[1] object to activity in form of extras.
    Intent intent = new Intent(context, SensorGraphViewActivity.class);
    intent.putExtra(SensorGraphViewActivity.TYPE_SENSOR, item.getSensor());
    intent.putExtra(SensorGraphViewActivity.DATA_FOREIGN_KEY, item.getUniqueRef());
    intent.putExtra(SensorGraphViewActivity.DATE_TIME_START,item.getDateTimeStart());
    intent.putExtra(SensorGraphViewActivity.DATE_TIME_END,item.getDateTimeEnd());
    intent.putExtra(SensorGraphViewActivity.TIME_ZONE,item.getTimeZone());
    intent.putExtra(SensorGraphViewActivity.LATITUDE,item.getLatitude());
    intent.putExtra(SensorGraphViewActivity.LONGITUDE,item.getLongitude());
    
    context.startActivity(intent);
    

And, in the SensorGraphViewActivity, I used getIntent() method to fetch all those extra data in the form of Bundle.
For showing the data in the graph I used the foreign key fetched from the intent and queried all the LuxData[1] RealmObject containing that foreignkey in the form of RealmResult<LuxData>[2] ArrayList and used that list to populate the graph.

Long foreignKey = intent.getLongExtra(DATA_FOREIGN_KEY, -1);
Realm realm = Realm.getDefaultInstance();
entries = new ArrayList<>();
RealmResults<LuxData> results = realm.where(LuxData.class).equalTo(DATA_FOREIGN_KEY, foreignKey).findAll();
for (LuxData item : results) {
   entries.add(new Entry((float) item.getTimeElapsed(), item.getLux()));
}

For the map, I fetched the latitude and longitude again from the intent and used the coordinates to show the location on the open street view map.

Thread thread = new Thread(new Runnable() {
   @Override
   public void run() {
       IMapController mapController = map.getController();
       mapController.setZoom((double) 9);
       GeoPoint startPoint = new GeoPoint(latitude, latitude);
       mapController.setCenter(startPoint);
   }
});

For map purposes, of course, I used a separate thread as it is a heavy and time-consuming process and it could lead the app to lag for a long time which could hamper the User Experience.

Thus after the data being plotted on the map and coordinated being plotted on the map, we can see the layout of the activity as shown in Figure 2.

Figure 2 shows the layout of the activity after being populated with data.

I also created the export button in the toolbar that will use the CSVLogger[3] class implemented inside the PSLab android app to export the data in the form of CSV file and save it in the external storage directory.

Resources

  1. Storing Recorded Sensor Data in Realm Database – My blog where I created the Realm Model classes to store recorded data.
  2. Using RealmRecyclerView Adapter to Show Recorded Sensor Experiments – My previous blog where I created the RecyclerView.
  3. Saving Sensor Data in CSV format – Blog by Padmal storing the data in CSV format.

Continue Reading

Implement Sensor Data Fetching Using AsyncTask

In PSLab android app we have implemented sensor data fetching of various sensors inbuilt in the mobile device like light sensor, accelerometer, gyrometer. We can use PSLab to log the data and show in the form of the graph or maybe export the data in the form of CSV format for future use.

But recording data from the phone sensor imposes a serious problem in the performance of the Android app as it is a costly to process in terms of memory, resources and time. In CS terms there is too much work that has to be done on the single main thread which sometimes leads to lag and compromises the UX.

So as a solution we applied a concept of the Multithreading provided by Java in which we can shift the heavy process to a separate background thread so that the main thread never gets interrupted during fetching the sensor data and the background thread handles all the fetching and updates the UI as soon as it gets the data, till then the Main thread continues to serves the user so to user the application remains always responsive.

For implementing this we used a special class provided by Android Framework called AsyncTask. Which provides below methods:-

  • doInBackground() : This method contains the code which needs to be executed in the background. In this method, we can send results multiple times to the UI thread by publishProgress() method.

  • onPreExecute() : This method contains the code which is executed before the background processing starts.

  • onPostExecute() : This method is called after doInBackground method completes processing. Result from doInBackground is passed to this method.

  • onProgressUpdate() : This method receives progress updates from doInBackground() method, which is published via publishProgress() method, and this method can use this progress update to update the UI thread.

  • onCancelled(): This method is called when the background task has been canceled. Here we can free up resources or write some cleanup code to avoid memory leaks.

We created a class SensorDataFetch and extended this AsyncTask class and override its methods according to our needs.

private class SensorDataFetch extends AsyncTask<Void, Void, Void> implements SensorEventListener {

   private float data;
   private long timeElapsed;

   @Override
   protected Void doInBackground(Void... params) {
      
       sensorManager.registerListener(this, sensor, updatePeriod);
       return null;
   }

   protected void onPostExecute(Void aVoid) {
       super.onPostExecute(aVoid);
       visualizeData();
   }

   @Override
   protected void onPreExecute() {
 super.onPreExecute();
   //do nothing
   }

   @Override
   protected void onProgressUpdate(Void... values) {
       super.onProgressUpdate(values);
          //do nothing
   }

   @Override
   protected void onCancelled() {
       super.onCancelled();
          //do nothing
   }

In doInBackground() method we implemented the fetching raw data from the sensor by registering the listener and in onPostExecute() method we updated that data on the UI to be viewed by the user.

When this process is being run in the background thread the Main UI thread is free and remains responsive to the user. We can see in Figure 1 below that the UI is responsive to the user swipe action even when the sensor data is updating continuously on the screen.

Figure 1 shows Lux Meter responding to user swipe while fetching sensor data flawlessly.

 

Resources

https://developer.android.com/reference/android/os/AsyncTask – Android Developer documentation for Async Task class.

Continue Reading

Snackbar Implementation in PSLab Android App

In PSLab android app we have developed the functionality of logging sensor data in CSV format. We can start and stop the data recording using the save button in the upper right corner of the menu bar and toast message was shown to notify the user for logging status whether it is started or stopped but it leads to some problem like:-

  • The user doesn’t know where the logged file has been created in the external storage.
  • If the user accidentally clicked on the save button the data logging will start the user have to manually go the storage location and delete the recently created unwanted CSV file.

What’s the solution?

The solution to both these problem is solved by implementing Snackbar instead of Toast message.

According to Material Design documentation:-

The Snackbar widget provides brief feedback about an operation through a message at the bottom of the screen. Snackbar disappears automatically, either after a timeout or after a user interaction elsewhere on the screen, and can also be swiped off the screen.

Snackbar can also offer the ability to perform an action, such as undoing an action that was just taken or retrying an action that had failed.

 

Figure 1 shows a Snackbar sample
(Source: – https://material.io/develop/android/components/snackbar/ )

 

To implement the Snackbar in our Android app I started by creating a custom snack bar class which contains all the code to create and show the Snackbar on the screen.

public class CustomSnackBar {

   public static void showSnackBar(@NonNull CoordinatorLayout holderLayout,  
                                   @NonNull String displayText,
                                   String actionText, 
                                   View.OnClickListener clickListener){
       
   Snackbar snackbar =     
              Snackbar.make(holderLayout,displayText,Snackbar.LENGTH_LONG)
              .setAction(actionText, clickListener);

  //do your customization here
}

The custom class contains a static method ‘showSnackBar()’ having parameters:

Parameter Return Type Description
holderLayout CoordinatorLayout Container layout in which the snack bar will be shown at the bottom (should not be null)
displayText String Text to be displayed in the content of Snackbar (should not be null)
actionText String Clickable text which has some action associated with it
clickListener View.OnClickListener On click listener specifying an action to be performed when actionText is clicked

 

Inside the method, I called the static make()  method provided by the Snackbar class and passed holderlayout, displayText and duration of Snackbar in this case Snackbar.LENGTH_LONG as parameters.

Then I called setAction() and passed in the actionText and the clickListener as parameters in it to set the action text. If we pass in null no action text will be generated.

Then, if we want to changes the action text color we can do that by calling setActionTextColor() and passing in the desired color.

snackbar.setActionTextColor(ContextCompat.getColor(holderLayout.getContext(), R.color.colorPrimary));

And if we want to change the content text color then we need to first get the view then we need to get the instance of TextView containing the content text using findViewById() and passing android.support.design.R.id.snackbar_text which is default ID for context TextView, and then call setTextColor() to set the desired color.

View sbView = snackbar.getView();
   TextView textView =     
             sbView.findViewById(android.support.design.R.id.snackbar_text);
       textView.setTextColor(Color.WHITE);
   }

So, now our Snackbar engine is complete now we need to call CustomSnackBar class static method showSnackbar() in our sensor data logger.

For doing this I replaced all the instances of the Toast message with the ‘CustomSnackBar’ by passing in the desired messages that were being passed in Toast message.

But I still need to find the location of our stored CSV file and a method to delete the current generated CSV file.

For that, I did below modification to the CSVLogger class in PSLab android app.

public class CSVLogger {
   private static final String CSV_DIRECTORY = "PSLab";
   public CSVLogger(String category) {
       this.category = category;
       setupPath();
   }
   /*Below methods are included at the bottom of the class */
   public String getCurrentFilePath() {
       return Environment.getExternalStorageDirectory().getAbsolutePath() +
               File.separator + CSV_DIRECTORY + File.separator + category;
   }
   public void deleteFile() {
       csvFile.delete();
   }
}

Now for passing the location of the stored file and implementing delete option, I called the below method when the CSV logging is stopped by the user:

CustomSnackBar.showSnackBar((CoordinatorLayout) parent.findViewById(R.id.cl),

                    “CSV File stored at” + " " +lux_logger.getCurrentFilePath(),
  
                    “DELETE”,

                    new View.OnClickListener() {
                              Override
                              public void onClick(View view) {
                                             lux_logger.deleteFile();    
                              });

By doing this I get a Snackbar as shown in Figure 2, clicking on the “DELETE” text deletes the current CSV file.

Figure 2 shows snackbar showing file stored location and delete option

 

So, implementing Snackbar helped to make the app interactive and keeps user notified and control the data logging.

Resources

  1. https://www.journaldev.com/10324/android-snackbar-example-tutorial – Android SnackBar example implemetation tutorial
  2. https://material.io/develop/android/components/snackbar/ – Android Material Desing implementation of Snackbar.

Continue Reading

Creating Instruction Guide using Bottomsheet

The PSLab android app consists of different instruments like oscilloscope, multimeter, wave generator etc and each instrument has different functionality and usage so it is necessary that there should be an instruction guide for every instrument so that the user can easily read the instruction to understand the functionality of the instrument.

In this we will create an instruction guide for the Wave Generator which will contain information about the instrument, it’s functionalities, steps for how to use the instrument.

The main component that I used to create instruction guide is Bottom SheetBottom Sheet is introduced in Android Support v23.2 . It is a special UI widget which slide up from the bottom of the screen and it can be used to reveal some extra information that we cannot show on the main layout like bottom menus,  instructions etc.

They are of two types :

  1. Modal Bottom Sheet:–  This Bottom Sheet has properties very similar to normal dialogs present in Android like elevation only difference is that they pop up from the bottom of screen with proper animation and they are implemented using BottomSheetDialogFragment Class.

  2. Persistent Bottom Sheet:– This Bottom Sheet is included as a part of the layout and they can be slid up and down to reveal extra information. They are implemented using BottomSheetBehaviour Class.

For my project, I used persistent Bottom Sheet as modal Bottom Sheet can’t be slid up and down by the swipe of the finger whereas persistent Bottom Sheet can be slid up and down and can be hidden by swipe features.

Implementing the Bottom Sheet

Step 1: Adding the Dependency

To start using Bottom Sheet we have to add the dependency (We have also include Jake Wharton-Butterknife library for view binding but it is optional.)

dependencies {

   implementation fileTree(include: ['*.jar'], dir: 'libs')

   implementation "com.android.support:appcompat-v7:26.0.1"
   implementation "com.android.support:design:26.0.1"
   implementation "com.jakewharton:butterknife:8.8.1"

   annotationProcessor "com.jakewharton:butterknife-compiler:8.8.1"

Step 2: Creating Bottom Sheet layout file

In this step, we will create the layout of the Bottom Sheet, as our purpose of making Bottom Sheet is to show extra information regarding the instrument so we will include ImageView and TextView inside the layout that will be used to show the content later.

Some attributes in the layout worth noting are:

  • app:layout_behavior: This attribute makes the layout act as Bottom Sheet.
  • app:behavior_peekHeight: This is the height of the Bottom Sheet when it is minimized.
  • app:behavior_hideable: Defines if the Bottom Sheet can be hidden by swiping it down.

Here, we will also create one extra LinearLayout having height equal to the peek_height. This  LinearLayout will be at the top of the BottomSheet as shown in Figure 1 and it will be visible when the BottomSheet is in a minimized state(not hidden). Here we will put text view with like “Show guide” and an arrow pointing upwards so that it is easier for the user to understand that sheet can be viewed by sliding up.

Figure 1 LinearLayout containing textview and imageview

Here is the gist[2] that contains code for the layout of the Bottom Sheet guide

After this step, we can see a layout of Bottom Sheet in our Android Editor as shown in Figure 2

Figure 2 shows the layout of the Bottom Sheet

Step 3: Creating the Container view layout containing content and Bottom Sheet

For container view, we will create new layout under Res Layout and name it “container_view_wavegenerator.xml”

In this layout, we will use ‘Coordinator Layout’ as ViewGroup because persistent Bottom Sheet is implemented using BottomSheetBehavior class which can only be applied to the child of ‘CoordinatorLayout’.

Then add the main layout of our instrument and the layout of the Bottom Sheet inside this layout as its child.

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <include layout="@layout/activity_wave_generator" />

   <include layout="@layout/bottom_sheet_custom" />

Step 4: Setting Up Bottom Sheet and Handling callbacks

Now we will head over to the “WaveGenerator.java” file(or any instrument java file)Here we will handle set up Bottom Sheet and handle callbacks by using following classes:

BottomSheetBehavior provides callbacks and makes the Bottom Sheet work with CoordinatorLayout.

BottomSheetBehavior.BottomSheetCallback() provides the callback when the Bottom Sheet changes its state. It has two methods that need to be overridden:

  1. public void onSlide(@NonNull View bottomSheet, float slideOffset)

    This method is called when the Bottom Sheet slides up and down on the screen. It has slideOffset as a parameter whose value varies from -1.0 to 0.0 when the Bottom Sheet comes from the hidden state to collapsed and 0.0 to 1.0 when it goes from collapsed state to expanded state.

  2. public void onStateChanged(@NonNull View bottomSheet, int newState)

    This method is called when BottomSheet changed its state. Here, let us also understand the different states which can be attained by the Bottom Sheet:

    • BottomSheetBehavior.STATE_EXPANDED : When the Bottom Sheet is fully expanded showing all the content.
    • BottomSheetBehavior.STATE_HIDDEN : When the Bottom Sheet is hidden at the bottom of the layout.
    • BottomSheetBehavior.STATE_COLLAPSED : When the Bottom Sheet is in a collapsed state that is only the peek_height view part of the layout is visible.
    • BottomSheetBehavior.STATE_DRAGGING : When the Bottom Sheet is dragging.
    • BottomSheetBehavior.STATE_SETTLING : When the Bottom Sheet is settling either at expanded height or at collapsed height.

We will implement these methods in our instrument class, and also put the content that needs to be put inside the Bottom Sheet.

@BindView(R.id.bottom_sheet)
LinearLayout bottomsheet;
@BindView(R.id.guide_title)
TextView bottomSheetGuideTitle;
@BindView(R.id.custom_dialog_schematic)
ImageView bottomSheetSchematic;
@BindView(R.id.custom_dialog_desc)
TextView bottomSheetDesc;

BottomSheetBehavior bottomSheetBehavior;

@Override
protected void onCreate(Bundle savedInstanceState) { 
              
           //main instrument implementation code

           setUpBottomSheet()
}

private void setUpBottomSheet() {

   bottomSheetBehavior = BottomSheetBehavior.from(bottomsheet);

    bottomSheetGuideTitle.setText(R.string.wave_generator);
   bottomSheetSchematic.setImageResource(R.drawable.sin_wave_guide);
   bottomSheetDesc.setText(R.string.wave_gen_guide_desc);

  bottomSheetBehavior.setBottomSheetCallback(new 
  BottomSheetBehavior.BottomSheetCallback() {
       @Override
       public void onStateChanged(@NonNull View bottomSheet, int newState) {
           if (newState == BottomSheetBehavior.STATE_EXPANDED) {
               bottomSheetSlideText.setText(R.string.hide_guide_text);
           } else {
               bottomSheetSlideText.setText(R.string.show_guide_text);
           }
       }

       @Override
       public void onSlide(@NonNull View bottomSheet, float slideOffset) {
           Log.w("SlideOffset", String.valueOf(slideOffset));
        }
      });
}

After following all the above steps the Bottom Sheet will start working properly in the Instrument layout as shown in Figure 3

Figure 3 shows the Bottom Sheet in two different states

To read more about implementing Bottom Sheet in layout refer this: AndroidHive article- working with bottomsheet

Resources

  1. Developer Documentation – BottomSheetBehaviour
  2. Gist containing xml file for layout of Custom Bottomsheet

Continue Reading

Creating the Mockup for Wave Generator using Moqups

PSLab is a versatile device that can be used as a waveform signal generator, as it is capable of producing different types of waves. It provides a cheap and portable alternative as compared to the physical wave generators available in markets.

The current UI of the Wave Generator present in the PSLab app as shown in Figure 1 is very basic and makes use of some basic UI components which are not able to properly expose all the functionalities of the wave generator. This affects the user experience negatively.

Figure 1 shows the current layout of Wave Generator in PSLab android app

In this blog, we will discuss creating a mockup for the PSLab wave generator using modern design to improve the UI/UX of the app. I will try to keep the layout simple enough so that users can easily understand it. 

Understanding the Functionality of Waveform Generator

Figure 2 shows the schematic pin diagram of the PSLab

We can observe from the image that PSLab provide:

  • Two pins named W1 and W2 which are capable of producing two different sine or saw-tooth waves having different characteristics simultaneously.
  • Four Pins named SQ1, SQ2, SQ3, SQ4 which are capable of producing Square Wave and Pulse Width modulation signals.
  • It also allows us to change the properties of these waves such as frequency, phase, duty cycle.

Before starting with the mockup a physical commodity Waveform Signal Generator as shown in Figure 3 was inspected.

Figure 3 shows digital Wave Generator by HP

Most waveform generators in the market have a control panel with buttons and a monitor screen so that the user can view the changes while controlling the characteristics of the wave. I will try to create a layout similar to this in following steps by dividing it into two halves:

  1. Upper half containing monitor screens
  2. Lower half containing controlling panel having buttons

Steps for creating the mockup

Step 1: Choosing the Tool

The tool that we will be using here to create a mockup is moqups[1].

I have chosen this software because:-

  • It is an online tool and doesn’t require it to be set up first
  • It is very efficient and powerful tool for creating mobile or web wireframes.
  • It doesn’t require any prior knowledge of programming language.
  • It has a palette to drag & drop UI elements like Buttons, Textboxes, Checkboxes etc. on the left-hand side, allows modifying the features of each element (here on the right) and other options at the top related to prototyping, previewing etc as shown in figure 4.
Figure 4  shows Moqups prototyping tool webpage

Step 2: Creating the base of the layout

The mockup tool moqups[1] have a built-in template of Android screen which we can drag and drop from the palette and use it as our base.

Figure 5 shows the Android mobile template picked from the palette of available design elements in the ‘moqups’ application.

Step 3: Creating the Lower Half

Now as discussed above I will create controlling panel containing buttons in the lower half of the screen, for this I will drag and drop buttons from the palette on the right-hand side and design them according to the theme of the app that is making their border round shape, changing their color to match the theme color and editing text in them. As the PSLab has two groups of pins so I will create two different panels with buttons for properties related to the pins of that group.

At this point we have a layout looking like this:

Figure 6 shows the lower panel containing buttons being drawn for Wave Generator UI. At right-hand side, it shows the palette having different UI elements.

I will create the monitor screens in the upper half, for our purpose as I have two panels we will create two monitor screen as shown in Figure 6. The left panel will correspond to the left panel and the right monitor will correspond to the right panel.

Step 4: Creating the Upper Half

For creating monitor, I will use simple rectangles with rounded borders and give the background black to resemble the monitor in physical devices.

I will also create some partitions in the monitor to make compartment. I will use these compartments to position the text view that represents the characteristics of the wave so that they are clearly visible.

Figure 7 shows two monitor layout with the black background being drawn using text areas and lines

So, in this layout the user will be able to see all the properties corresponding to one type of waveform on the monitor together so he/she doesn’t have to click the buttons, again and again, to see the different properties as he/she have to do in a physical device.

For instance let’s say, if the user wants to generate sine wave he/she will have to click the Wave 1 button in the panel below and on clicking,all the values of characteristics related to waveform produced by W1 pin will be visible together to the user in one screen which makes it easier for the user to analyze and set the values.

Therefore, the final layout produced is shown in Figure 7

Figure 8 shows final Wave Generator Mockup.

As we can see this layout is quite interactive and looks very appealing to the user and this will help to improve UI/UX of the app.

Resources

  1. Moqups prototyping tool website: https://moqups.com
  2. Youtube Video – How to use moqups

Continue Reading

Circuit Protection Measurements in PSLab Hardware

Pocket Science Lab by FOSSASIA is a versatile analytical tool which can be used by a variety of user. They span from school kids to professional engineers who need a measurement device to ease up their task. In electronics and electrical fields, circuits do get damaged a lot. There is no perfect method to keep the circuit damage proof but the only thing we can do it minimize the damaging causes as much as possible. PSLab is no exception.

Since PSLab has an audience involving school children, it is quite possible for a short circuit to happen in devices while using. A short circuit is simply a non-resistive path between a supply pin and a ground connection. When a short circuit happens, there is a huge amount of electrons flowing through a small path which will eventually melts if there is no safety mechanism to stop the rapid electron flow.

PSLab contains a plenty of sensitive integrated circuits to support its wide variety of features. They will easily burn if a short happens and the user will have to dispose the device as it will no longer be functional. That is the case if there is no safety feature embedded in the printed circuit board to fight against damages of that nature. We have included a special type of fuses to overcome damages occur due to short circuits.

A fuse is a passive component which allows the flow of current up to a threshold value. When the current increases, the fuse blows and the flow is disrupted. A normal fuse will require replacement. But in PSLab, we have included a special type of fuse known as a polyfuse. This type of fuse does not require replacement. In the following figure it is shown as “F1”

Figure 1: Position of fuse in PSLab V4 PCB

The speciality about poly fuses is that they will recover its current carrying capabilities once the short circuit is open. The auxiliary name “Resettable Fuse” will make sense as it will reset to its original state once the circuit is safe.

The working principle behind a polyfuse mainly depends on its resistance. When the current flow through a polyfuse is at the rated values, it will have a minimum resistance between the input and output terminals.

Figure 2: A poly fuse

As the current flow increases, the particles inside the fuse will start moving fast. The slow motion of these particles are the ones keeping a smooth current flow across the fuse. When the particles are moving rapidly, it will oppose the current flow through them.

Imagine a situation where a short circuit happens. There will be sudden rapid flow of electrons. These electrons will collide with the particles inside polyfuse which were at a calm and steady motion. Now their motion is disturbed and the movements will be random and fast. This will cause the fuse to heat up to a high temperature. As the graph in figure 3 illustrates, it’s resistance highly increases with the temperature.

Figure 3: Temperature vs Current graph of a poly fuse

The rapid electron flow will have no opening to go as the fuse path is now heavily resistive. When the current flow is stopped, PSLab will turn off. All these things happen so quickly that the short circuit would not damage any internal components anymore. Once the user sees that the PSLab is off and he solves the cause for the short circuit, the fuse will cool down which results in a lesser resistance. Now the current flow will come back to normal making the PSLab device working again.

Reference:

Polyfuse – Mouser: https://www.mouser.com/datasheet/2/240/Littelfuse_PTC_LoRho_Datasheet.pdf-365270.pdf

Continue Reading

Automatic Signing and Publishing of Android Apps from Travis

As I discussed about preparing the apps in Play Store for automatic deployment and Google App Signing in previous blogs, in this blog, I’ll talk about how to use Travis Ci to automatically sign and publish the apps using fastlane, as well as how to upload sensitive information like signing keys and publishing JSON to the Open Source repository. This method will be used to publish the following Android Apps:

Current Project Structure

The example project I have used to set up the process has the following structure:

It’s a normal Android Project with some .travis.yml and some additional bash scripts in scripts folder. The update-apk.sh file is standard app build and repo push file found in FOSSASIA projects. The process used to develop it is documented in previous blogs. First, we’ll see how to upload our keys to the repo after encrypting them.

Encrypting keys using Travis

Travis provides a very nice documentation on encrypting files containing sensitive information, but a crucial information is buried below the page. As you’d normally want to upload two things to the repo – the app signing key, and API JSON file for release manager API of Google Play for Fastlane, you can’t do it separately by using standard file encryption command for travis as it will override the previous encrypted file’s secret. In order to do so, you need to create a tarball of all the files that need to be encrypted and encrypt that tar instead. Along with this, before you need to use the file, you’ll have to decrypt in in the travis build and also uncompress it for use.

So, first install Travis CLI tool and login using travis login (You should have right access to the repo and Travis CI in order to encrypt the files for it)

Then add the signing key and fastlane json in the scripts folder. Let’s assume the names of the files are key.jks and fastlane.json

Then, go to scripts folder and run this command to create a tar of these files:

tar cvf secrets.tar fastlane.json key.jks

 

secrets.tar will be created in the folder. Now, run this command to encrypt the file

travis encrypt-file secrets.tar

 

A new file secrets.tar.enc will be created in the folder. Now delete the original files and secrets tar so they do not get added to the repo by mistake. The output log will show the the command for decryption of the file to be added to the .travis.yml file.

Decrypting keys using Travis

But if we add it there, the keys will be decrypted for each commit on each branch. We want it to happen only for master branch as we only require publishing from that branch. So, we’ll create a bash script prep-key.sh for the task with following content

#!/bin/sh
set -e

export DEPLOY_BRANCH=${DEPLOY_BRANCH:-master}

if [ "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_REPO_SLUG" != "iamareebjamal/android-test-fastlane" -o "$TRAVIS_BRANCH" != "$DEPLOY_BRANCH" ]; then
    echo "We decrypt key only for pushes to the master branch and not PRs. So, skip."
    exit 0
fi

openssl aes-256-cbc -K $encrypted_4dd7_key -iv $encrypted_4dd7_iv -in ./scripts/secrets.tar.enc -out ./scripts/secrets.tar -d
tar xvf ./scripts/secrets.tar -C scripts/

 

Of course, you’ll have to change the commands and arguments according to your need and repo. Specially, the decryption command keys ID

The script checks if the repo and branch are correct, and the commit is not of a PR, then decrypts the file and extracts them in appropriate directory

Before signing the app, you’ll need to store the keystore password, alias and key password in Travis Environment Variables. Once you have done that, you can proceed to signing the app. I’ll assume the variable names to be $STORE_PASS, $ALIAS and $KEY_PASS respectively

Signing App

Now, come to the part in upload-apk.sh script where you have the unsigned release app built. Let’s assume its name is app-release-unsigned.apk.Then run this command to sign it

cp app-release-unsigned.apk app-release-unaligned.apk
jarsigner -verbose -tsa http://timestamp.comodoca.com/rfc3161 -sigalg SHA1withRSA -digestalg SHA1 -keystore ../scripts/key.jks -storepass $STORE_PASS -keypass $KEY_PASS app-release-unaligned.apk $ALIAS

 

Then run this command to zipalign the app

${ANDROID_HOME}/build-tools/25.0.2/zipalign -v -p 4 app-release-unaligned.apk app-release.apk

 

Remember that the build tools version should be the same as the one specified in .travis.yml

This will create an apk named app-release.apk

Publishing App

This is the easiest step. First install fastlane using this command

gem install fastlane

 

Then run this command to publish the app to alpha channel on Play Store

fastlane supply --apk app-release.apk --track alpha --json_key ../scripts/fastlane.json --package_name com.iamareebjamal.fastlane

 

You can always configure the arguments according to your need. Also notice that you have to provide the package name for Fastlane to know which app to update. This can also be stored as an environment variable.

This is all for this blog, you can read more about travis CLI, fastlane features and signing process in these links below:

Continue Reading

Electrical Experiments with PSLab

PSLab has the capability to perform a variety of experiments. The PSLab Android App and the PSLab Desktop App have built-in support for over 70 experiments which are commonly performed by students. In addition to that, it can be used in other experiments conveniently. This blog post is in continuation with the previous two posts regarding performing experiments (links in the reference) and this blog deals with another category of experiments that can be performed using PSLab.

The blog lists experiments which mainly involve the basic circuit elements like resistors, capacitors and inductors. These experiments involve the study of R-C, L-R, L-C and L-C-R circuits. These circuits have properties which make them important in real life applications and this blog attempts to give a rough picture of their importance.

Ohm’s Law, Capacitive Reactance and Inductive Reactance

These experiments involve the study of each of the basic circuit element individually. The current and voltage characteristics of each of the elements is studied.

The definitions of the above are:

Ohm’s Law – This is a law familiar to most. It relates the voltage and current of a purely resistive circuit stating that the voltage and current are proportional to each other and their ratio is a constant called the resistance. In this case, the current and voltage are in the same phase.

Capacitive Reactance – Across a capacitor in an AC circuit, the current and voltage are not in the same phase and the current leads the voltage. For a purely capacitive circuit, this difference is 90o.

Inductive Reactance –  Across an inductor in an AC circuit, the current and voltage are not in the same phase and the current lags behind the voltage. For a purely inductive circuit, this difference is 90o.

The reactance is given for capacitor and inductor is given by 1/wC and wL respectively, where C & L are the values of capacitance and inductance respectively and w is the frequency of the AC signal.

The circuit for the setup is shown below. We need to observe the plot of the input waveform and the plot of the voltage across individual elements to observe the phase shift.

  1. Connect CH1 & GND across the input terminals and CH2 & GND across the terminals of any of the elements.
  2. An external signal can be used or can be generated using the PSLab. Use the PSLab to generate a sinusoidal signal of frequency 1000 Hz. by connecting the ends of PV1 in the circuit.
  3. Observe the waveforms. In case of the resistor, there should be no observable phase lag between the two. In case of the capacitor and inductor, there will be an observable phase difference of 90o.
  4. For the capacitive and inductive circuits, just replace the resistor in the above circuit with capacitor/inductor.

RC Circuits

Drawing their names from their respective calculus functions, the integrator produces a voltage output proportional to the product (multiplication) of the input voltage and time; and the differentiator (not to be confused with differential) produces a voltage output proportional to the input voltage’s rate of change.

RC Integrator circuit

For constructing the RC integrator circuit, connect the circuit as shown in the diagram.

  • Construction of the integrator circuit is fairly simple once the differentiator circuit is done.
  • Interchange the positions of the capacitor and resistor in the above circuit and the circuit for the integrator is complete.
  • Observe the output waveform. Plot both the CH1 and CH2 data simultaneously to compare the waveforms.

RC Differentiator circuit

For constructing the RC differentiator circuit, connect the circuit as shown in the diagram.

  • The values of resistance and capacitance used here are 10k ohm and 0.01uF.
  • Connect the CH1 and GND pins of the board with the input side marked as Vi. Ensure that GND is connected to the GND of the circuit.
  • Similarly, connect CH2 and GND with the corresponding ends of the output side marked as Vo.
  • PSLab can also be used for supplying the input to the circuit. Connect the ends of W1 and GND across Vi. W1 can be used to generate a square wave of 10V peak to peak voltage with a frequency of 500 Hz.
  • Observe the output waveform. Plot both the CH1 and CH2 data simultaneously to compare the waveforms.

RL Circuits

RL Integrator Circuit.

For constructing the RL integrator circuit, connect the circuit as shown in the diagram.

  • Construction of the integrator circuit is fairly simple once the differentiator circuit is done.
  • Interchange the positions of the inductor and resistor in the above circuit and the circuit for the integrator is complete.
  • Observe the output waveform. Plot both the CH1 and CH2 data simultaneously to compare the waveforms.

RL Differentiator Circuit

For constructing the RL differentiator circuit, connect the circuit as shown in the diagram.

  • The values of resistance and inductance used here are 470 ohm and 10mH.
  • Connect the CH1 and GND pins of the board with the input side marked as Vi. Ensure that GND is connected to the GND of the circuit.
  • Similarly, connect CH2 and GND with the corresponding ends of the output side marked as Vo.
  • PSLab can also be used for supplying the input to the circuit. Connect the ends of W1 and GND across Vi. W1 can be used to generate a square wave of 2V peak to peak voltage with a frequency of 5000 Hz.
  • Observe the output waveform. Plot both the CH1 and CH2 data simultaneously to compare the waveforms.

Frequency Response

Frequency Response of an electric or electronics circuit allows us to see exactly how the output gain (known as the magnitude response) and the phase (known as the phase response) changes at a particular single frequency, or over a whole range of different frequencies from 0Hz, (d.c.) to many thousands of megahertz, (MHz) depending upon the design characteristics of the circuit.

Frequency response of a circuit can be studied using different tools like Bode plots, phase plots etc. However, this blog would limit to using simple RC and RL circuits as they can be easily visualised using an oscilloscope.

RC Circuits

  • For observing the frequency response of RC circuits, the circuit can be constructed as shown below.
  • The values of resistance and capacitance used here are 10k ohm and 0.01uF.
  • Connect the CH1 and GND pins of the board with the input side marked as Vi. Ensure that GND is connected to the GND of the circuit.
  • Similarly, connect CH2 and GND with the corresponding ends of the output side marked as Vo.
  • PSLab can also be used for supplying the input to the circuit. Connect the ends of W1 and GND across Vi. W1 can be used to generate a square wave of 10V peak to peak voltage with a frequencies ranging from 100 Hz to 5000 Hz.
  • Switch to the X-Y mode of the oscilloscope and observe the waveform formed.

RL Circuits

  • For observing the frequency response of RL circuits, the circuit can be constructed as shown below.
  • The values of resistance and inductance used here are 470 ohm and 10mH.
  • Connect the CH1 and GND pins of the board with the input side marked as Vi. Ensure that GND is connected to the GND of the circuit.
  • Similarly, connect CH2 and GND with the corresponding ends of the output side marked as Vo.
  • Note: PSLab in this case cannot be used as an AC source as the maximum frequency of waveforms produced by PSLab is limited to 5kHz. However, this experiment would also need frequencies much higher than 5 Hz i.e upto 50 kHz. So, a dedicated function generator is needed. However, the oscilloscope would work just fine.
  • Switch to the X-Y mode of the oscilloscope and observe the waveform formed.

References:

  1. The previous blog on experiments using PSLab focusing in electronics https://blog.fossasia.org/electronics-experiments-with-pslab/
  2. The previous blog on experiments using PSLab involving some general experiments https://blog.fossasia.org/fascinating-experiments-with-pslab/
  3. Read more about differentiators and integrators and their uses https://www.allaboutcircuits.com/textbook/semiconductors/chpt-8/differentiator-integrator-circuits/

Continue Reading

Enabling Google App Signing for Android Project

Signing key management of Android Apps is a hectic procedure and can grow out of hand rather quickly for large organizations with several independent projects. We, at FOSSASIA also had to face similar difficulties in management of individual keys by project maintainers and wanted to gather all these Android Projects under singular key management platform:

To handle the complexities and security aspect of the process, this year Google announced App Signing optional program where Google takes your existing key’s encrypted file and stores it on their servers and asks you to create a new upload key which will be used to sign further updates of the app. It takes the certificates of your new upload key and maps it to the managed private key. Now, whenever there is a new upload of the app, it’s signing certificate is matched with the upload key certificate and after verification, the app is signed by the original private key on the server itself and delivered to the user. The advantage comes where you lose your key, its password or it is compromised. Before App Signing program, if your key got lost, you had to launch your app under a new package name, losing your existing user base. With Google managing your key, if you lose your upload key, then the account owner can request Google to reassign a new upload key as the private key is secure on their servers.

There is no difference in the delivered app from the previous one as it is still finally signed by the original private key as it was before, except that Google also optimizes the app by splitting it into multiple APKs according to hardware, demographic and other factors, resulting in a much smaller app! This blog will take you through the steps in how to enable the program for existing and new apps. A bit of a warning though, for security reasons, opting in the program is permanent and once you do it, it is not possible to back out, so think it through before committing.

For existing apps:

First you need to go to the particular app’s detail section and then into Release Management > App Releases. There you would see the Get Started button for App Signing.

The account owner must first agree to its terms and conditions and once it’s done, a page like this will be presented with information about app signing infrastructure at top.

So, as per the instructions, download the PEPK jar file to encrypt your private key. For this process, you need to have your existing private key and its alias and password. It is fine if you don’t know the key password but store password is needed to generate the encrypted file. Then execute this command in the terminal as written in Step 2 of your Play console:

java -jar pepk.jar –keystore={{keystore_path}} –alias={{alias}} –output={{encrypted_file_output_path}} –encryptionkey=eb10fe8f7c7c9df715022017b00c6471f8ba8170b13049a11e6c09ffe3056a104a3bbe4ac5a955f4ba4fe93fc8cef27558a3eb9d2a529a2092761fb833b656cd48b9de6a

You will have to change the bold text inside curly braces to the correct keystore path, alias and the output file path you want respectively.

Note: The encryption key has been same for me for 3 different Play Store accounts, but might be different for you. So please confirm in Play console first

When you execute the command, it will ask you for the keystore password, and once you enter it, the encrypted file will be generated on the path you specified. You can upload it using the button on console.

After this, you’ll need to generate a new upload key. You can do this using several methods listed here, but for demonstration we’ll be using command line to do so:

keytool -genkey -v -keystore {{keystore_path}} -alias {{alias_name}} -keyalg RSA -keysize 2048 -validity 10000

The command will ask you a couple of questions related to the passwords and signing information and then the key will be generated. This will be your public key and be used for further signing of your apps. So keep it and the password secure and handy (even if it is expendable now).

After this step, you need to create a PEM upload certificate for this key, and in order to do so, execute this command:

keytool -export -rfc -keystore {{keystore_path}} -alias {{alias_name}} -file {{upload_certificate.pem}}

After this is executed, it’ll ask you the keystore password, and once you enter it, the PEM file will be generated and you will have to upload it to the Play console.

If everything goes right, your Play console will look something like this:

 

Click enrol and you’re done! Now you can go to App Signing section of the Release Management console and see your app signing and new upload key certificates

 

You can use the SHA1 hash to confirm the keys as to which one corresponds to private and upload if ever in confusion.

For new apps:

For new apps, the process is like a walk in park. You just need to enable the App Signing, and you’ll get an option to continue, opt-out or re-use existing key.

 

If you re-use existing key, the process is finished then and there and an existing key is deployed as the upload key for this app. But if you choose to Continue, then App Signing will be enabled and Google will use an arbitrary key as private key for the app and the first app you upload will get its key registered as the upload key

 

This is the screenshot of the App Signing console when there is no first app uploaded and you can see that it still has an app signing certificate of a key which you did not upload or have access to.

If you want to know more about app signing program, check out these links:

Continue Reading

Preparing for Automatic Publishing of Android Apps in Play Store

I spent this week searching through libraries and services which provide a way to publish built apks directly through API so that the repositories for Android apps can trigger publishing automatically after each push on master branch. The projects to be auto-deployed are:

I had eyes on fastlane for a couple of months and it came out to be the best solution for the task. The tool not only allows publishing of APK files, but also Play Store listings, screenshots, and changelogs. And that is only a subset of its capabilities bundled in a subservice supply.

There is a process before getting started to use this service, which I will go through step by step in this blog. The process is also outlined in the README of the supply project.

Enabling API Access

The first step in the process is to enable API access in your Play Store Developer account if you haven’t done so. For that, you have to open the Play Dev Console and go to Settings > Developer Account > API access.

If this is the first time you are opening it, you’ll be presented with a confirmation dialog detailing about the ramifications of the action and if you agree to do so. Read carefully about the terms and click accept if you agree with them. Once you do, you’ll be presented with a setting panel like this:

Creating Service Account

As you can see there is no registered service account here and we need to create one. So, click on CREATE SERVICE ACCOUNT button and this dialog will pop up giving you the instructions on how to do so:

So, open the highlighted link in the new tab and Google API Console will open up, which will look something like this:

Click on Create Service Account and fill in these details:

Account Name: Any name you want

Role: Project > Service Account Actor

And then, select Furnish a new private key and select JSON. Click CREATE.

A new JSON key will be created and downloaded on your device. Keep this secret as anyone with access to it can at least change play store listings of your apps if not upload new apps in place of existing ones (as they are protected by signing keys).

Granting Access

Now return to the Play Console tab (we were there in Figure 2 at the start of Creating Service Account), and click done as you have created the Service Account now. And you should see the created service account listed like this:

Now click on grant access, choose Release Manager from Role dropdown, and select these PERMISSIONS:

Of course you don’t want the fastlane API to access financial data or manage orders. Other than that it is up to you on what to allow or disallow. Same choice with expiry date as we have left it to never expire. Click on ADD USER and you’ll see the Release Manager created in the user list like below:

Now you are ready to use the fastlane service, or any other release management service for that matter.

Using fastlane

Install fastlane by

sudo gem install fastlane

Go to your project folder and run

fastlane supply init

First it will ask the location of the private key JSON file you downloaded, and then the package name of the application you are trying to initialize fastlane for.

Then it will create metadata folder with listing information excluding the images. So you’ll have to download and place the images manually for the first time

After modifying the listing, images or APK, run the command:

fastlane supply run

That’s it. Your app along with the store listing has been updated!

This is a very brief introduction to the capabilities of the supply service. All interactive options can be supplied via command line arguments, certain parts of the metadata can be omitted and alpha beta management along with release rollout can be done in steps! Make sure to check out the links below:

Continue Reading
  • 1
  • 2
Close Menu