How to get a cost effective PCB for Production

Designing a PCB for a DIY project involves in making up the schematics which then turned into a PCB layout. Components used in these PCBs will be mostly “Through Hole” which are commonly available in the market. Once the PCB is printed in either screen printing techniques or using photo resistive dry films, making alterations to the component mounting pads and connections will be somewhat possible.

When dealing with a professional PCB design, there are many properties we need to consider. DIY PCBs will simply be single sided in most cases. A professional printed circuit board will most likely to have more than one layer. The PCB for PSLab device has 4 layers. Adding more layers to a PCB design makes it easier to draw connections. But on the other hand, the cost will increase exponentially. The designer must try to optimize the design to have less layers as much as possible. The following table shows the estimated cost for printing for 10 PSLab devices if the device had that many layers.

One Layer Two Layers Four Layers Six Layers
$4.90 $4.90 $49.90 $305.92

Once the layer levels increase from 2, the other layers will be inner layers. The effective area of inner layers will be reduced if the designer adds more through hole components or vias which connects a connection from a one layer with a connection with another layer. The components used will then be limited to surface mount components.

Surface Mount components (SMD) are expensive compared to their Through Hole (TH) counterpart. But the smaller size of SMD makes it easier to place many components in a smaller area than to Through Hole components. Soldering and assembling Through Hole components can be done manually using hand soldering techniques. SMD components need special tools and soldering equipments to assemble and solder them. Much more precision is required when SMD components are soldered. Hence automated assembly is used in industry where robot arms are used to place components and reflow soldering techniques to solder the SMD components. This emphasizes that the number of SMD components used in the PCB will increase the assembly cost as well as the component cost but it will greatly reduce the size of the PCB.

SMD components comes in different packages. Passive components such as resistors, capacitors will come in 0.25 mm upto 7.4mm dimensions. PSLab device uses 0805/2012 sized package which is easier to find in the market and big enough to pick and assemble by hand. The packaging refers to its dimensions. 0805 reads as 0.08 inches long and 0.05 inches wide.

Finding the components in the market is the next challenging task. We can easily purchase components from an online store but the price will be pretty high. If the design can spare some space, it will be wise to have alternative pads for a Through Hole component for the SMD component as Through Hole components can be found much easier than SMD components in a local store.

The following image is taken from Sparkfun which illustrates different common IC packages. Selecting the correct footprint for the SMD IC and vise versa is very important. It is a good practice to check the stores for the availability and prices for the components before finalizing the PCB design with footprints and sending it to printing. We may find some ICs are not available for immediate purchase as the stocks ran out but a different package of the same IC is available. Then the designer can alter the foot print to the packaging and use the more common packaging type in the design.

Considering all the factors above, a cost effective PCB can be designed and manufactured once the design is optimized to have the minimum number of layers with components with the minimum cost for both assembly and components.


Creating Bill of Materials for PSLab using KiCAD

PSLab device consists of a hundreds of electronic components. Resistors, diodes, transistors, integrated circuits are to name a few. These components are of two types; Through hole and surface mounted.

Surface mount components (SMD) are smaller in size. Due to this reason, it is hard to hand solder these components onto a printed circuit board. We use wave soldering or reflow soldering to connect them with a circuit.

Through Hole components (TH) are fairly larger than their SMD counter part. They are made bigger to make it easy for hand soldering. These components can also be soldered using wave soldering.

Once a PCB has completed its design, the next step is to manufacture it with the help of a PCB manufacturer. They will require the circuit design in “gerber” format along with its Bill of Materials (BoM) for assembly. The common requirement of BoM is the file in a csv format. Some manufacturers will require the file in xml format. There are many plugins available in KiCAD which does the job.

KiCAD when first installed, doesn’t come configured with a BoM generation tool. But there are many scripts developed with python available online free of charge. KiBoM is one of the famous plugins available for the task.

Go to “Eeschema” editor in KiCAD where the schematic is present and then click on the “BoM” icon in the menu bar. This will open a dialog box to select which plugin to use to generate the bill of materials.

Initially there won’t be any plugins available in the “Plugins” section. As we are adding plugins to it, they will be listed down so that we can select which plugin we need. To add a plugin, click on the “Add Plugin” button to open the dialog box to browse to the specific plugin we have already downloaded. There are a set of available plugins in the KiCAD installation directory.

The path is most probably will be (unless you have made any changes to the installation);


Once a plugin is selected, click on “Generate” button to generate the bom file. “Plugin Info” will display where the file was made and it’s name.

Make sure we have made the BoM file compatible to the file required by the manufacturer. That is; removed all the extra content and added necessary details such as manufacturer’s part numbers and references replacing the auto generated part numbers.


KiCAD Simulation to Validate Circuitry in PSLab Device

A circuit is a combination of passive or active electronic components which are interconnected with wires and provided to power to perform a specific task. Bringing a conceptual circuit design into an actual model includes several steps. It all starts with a problem definition such as a “Power module to regulate input voltage to output 5V”. The next step is to design the schematic with the help of a designing tool. Once the schematic is complete, the PCB layout can be made which will be later printed out as the final circuit.

The importance of testing the schematic circuit for performance and functionalities is very important as once the circuit is printed out, there is no way to modify the wiring or components. That is when the SPICE simulation comes into picture.

PSLab device is consisted of hundreds of circuit components and they are interconnected using a 4 layer printed circuit board. A fault in one sub circuitry may fail the complete device. Hence each of them must be tested and simulated using proper tools to ensure functionality against a test input data set.

KiCAD requires an external SPICE engine to be installed. Ngspice is a famous SPICE tool used in the industry.

The test procedures carried out to ensure the circuitry functions in PSLab device is described in this blog. Once the circuit is complete, generate the spice netlist. This will open up a dialog box and in the “Spice” tab, select “Prefix references ‘U’ and ‘IC’ with ‘X’”.

U and IC prefixes are used with chips which cannot be simulated with SPICE. Click “Generate” to build the netlist. Note that this is not the netlist we use to build up the PCB but a netlist which can be used in SPICE simulation.

Now browse to the project folder and rename the file extension of cir to cki to make them compatible with command line SPICE commands.

cp <filename>.cir <filename>.cki

Then open the file using a text editor and modify the GND connection to have a global ground connection by replacing “GND” with “0” which is required in SPICE simulation. Once the SPICE code is complete run the following commands to get the SPICE script compiled;

ngspice -b -r <filename>.raw <filename>.cki
ngnutmeg SPIce.raw

This will open up a data analysis and manipulation program provided with ngspice to plot graphs and analyse SPICE simulations. Using this we can verify if the circuit can produce expected outputs with respect to the inputs we are providing and make adjustments if necessary.


Creating an Installer for PSLab Desktop App

PSLab device is made useful with applications running on two platforms. One is Android and the other one is a desktop application developed using Python frameworks. Desktop application uses half a dozen of dependent libraries and they are required to be installed prior to installing the application itself.

For someone with zero or less knowledge on how to install packages in a Linux environment, this task will be quite difficult. To ease up the process of installing the desktop application in a computer, we can use a script to run specific commands which will install the dependencies and the application.

Dependencies required by PSLab  Desktop app

  • PyQt 4.7
  • Python 2.6, 2.7 or 3.x
  • NumPy, Scipy
  • pyqt4-dev-tools
  • Pyqtgraph
  • pyopengl and qt-opengl
  • iPython-qtconsole

These dependencies can be made installed using a bash script running with root permission. A bash script will have the file extension “.sh” and a header line;


A bash script needs to be made executable by the user himself. To do this, user needs to type a one line command in the terminal as follows and enter his password;

sudo chmod +x <Name_of_the_script>.sh

The keyword “sudo” interprets as “Super User DO” and the line follows will be executed with root permission. In other words with administrative privileges to modify system settings such as copying content to system folders.

The keyword “chmod” stands for “Change Mode” which will alter the mode of a file. In current context, the file is made executable by adding the executable property to the bash script using “+x” syntax.

Once the script is made executable, it can be executed using;

sudo ./<Name_of_the_script>.sh

An installer can be made attractive by using different colors rather than the plain old text outputs. For this purpose we can use color syntax in bash script. They are represented using ANSI escape codes and following is a list of commonly used colors;

Black        0;30     Dark Gray     1;30
Red          0;31     Light Red     1;31
Green        0;32     Light Green   1;32
Brown/Orange 0;33     Yellow        1;33
Blue         0;34     Light Blue    1;34
Purple       0;35     Light Purple  1;35
Cyan         0;36     Light Cyan    1;36
Light Gray   0;37     White         1;37

As in any programming language, rather than using the same line in many places, we can define variables in a bash script. The syntax will be the variable name followed by an equal sign with the value. There cannot be spaces around the equal sign or it will generate an error.


These variables can be accessed using a special syntax as follows;


Finally we can output a message to the console using the “echo” command

echo -e "${GREEN}Welcome to PSLab Desktop app installer${NOCOLOR}"

Note that the keyword “-e” is used to enable interpretation of the following backslash escapes.

In order to install the packages and libraries, we use two package management tools. One is “apt” which stands for “Advanced Packaging Tool” and the second is “pip” which is used to download python related packages from “Python Package Index”. The following two lines illustrates how the two commands can be accessed.

apt-get install python-pip python-dev build-essential -y

pip install pyqtgraph

The keyword “-y” avoids the confirmation prompt in console to allow installation by pressing “Y” key every time it installs a package from “apt”.


Controlling Motors using PSLab Device

PSLab device is capable of building up a complete science lab almost anywhere. While the privilege is mostly taken by high school students and teachers to perform scientific experiments, electronic hobbyists can greatly be influenced from the device. One of the usages is to test and debug sensors and other electronic components before actually using them in their projects. In this blog it will be explained how hobbyist motors are made functional with the use of the PSLab device.

There are four types of motors generally used by hobbyists in their DIY(Do-It-Yourself) projects. They are;

  • DC Gear Motor
  • DC Brushless Motor
  • Servo Motor
  • Stepper Motor

DC motors do not require much of a control as their internal structure is simply a magnet and a shaft which was made rotatable around the magnetic field. The following image from slideshare illustrates the cross section of a motor. These motors require high currents and PSLab device as it is powered from a USB port from a PC or a mobile phone, cannot provide such high current. Hence these type of motors are not recommended to use with the device as there is a very high probability it might burn something.

In the current context, we are concerned about stepper motors and servo motors. They cannot be powered up using direct currents to them. Inside these motors, the structure is different and they require a set of controlled signals to function. The following diagram from electronics-tutorials illustrates the feedback loop inside a servo motor. A servo motor is functional using a PWM wave. Depending on the duty cycle, the rotational angle will be determined. PSLab device is capable of generating four different square waves at any duty cycle varying from 0% to 100%. This gives us freedom to acquire any angle we desire from a servo motor. The experiment “Servo Motors” implement the following method where it accepts four angles.

public void servo4(double angle1, double angle2, double angle3, double angle4)

The experiment supports control of four different servo motors at independant angles. Most of the servos available in the market support only 180 degree rotation where some servos can rotate indefinitely. In such a case, the servo will rotate one cycle and reach its initial position.

The last type of motor is stepper motor. As the name says it, this motor can produce steps. Inside of the motor, there are four coils and and five wires coming out of the motor body connecting these coils. The illustration from Wikipedia shows how four steps are acquired by powering up the respective coil in order. This powering up process needs to be controlled and hard to do manually. Using PSLab device experiment “Stepper Motor”, a user can acquire any number of steps just by entering the step value in the text box. The implementation consists of a set of method calls;

scienceLab.stepForward(steps, 100);

scienceLab.stepBackward(steps, 100);

A delay of 100 milliseconds is provided so that there is enough time to produce a step. Otherwise the shaft will not experience enough resultant force to move and will remain in the same position.

These two experiments are possible with PSLab because the amount of current drawn is quite small which can be delivered through a general USB port. It is worth mentioning that as industry grade servo and stepper motors may draw high current as they were built to interact with heavy loads, they are not suitable for this type of experiments.


How Switch Case improve performance in PSLab Saved Experiments

PSLab android application contains nearly 70 experiments one can experiment on using the PSLab device and the other necessary circuit components and devices. These experiments span over areas such as Electronics, Electrical, Physical and High school level. All these experiments are accessible via an android adapter in the repository named “PerformExperimentAdapter”. This adapter houses a tab view with two different tabs; one for the experiment details and the other for actual experiment and resultant graphs.

The adapter extends an inbuilt class FragmentPagerAdapter;

public class PerformExperimentAdapter extends FragmentPagerAdapter

This class displays every page attached to its viewpager as a fragment. The good thing about using fragments is that they have a recyclable life cycle. Rather than creating new views for every instance of an experiment, the similar views can be recycled to use once again saving resources and improving performance. FragmentPagerAdapter needs to override a method to display the correct view on the tab select by user.

public Fragment getItem(int position) {


Depending on the value of position, relevant experiment documentation and the experiment implementation fragments are displayed determined using the experiment title. Performance can be critical in this place as if it takes too long to process and render a fragment, user will feel a lag.

The previous implementation was using consecutive if statements.

public Fragment getItem(int position) {
   switch (position) {
       case 0:
           if (experimentTitle.equals(context.getString(R.string.diode_iv)))
               return ExperimentDocFragment.newInstance("D_diodeIV.html");
           if (experimentTitle.equals(context.getString(R.string.zener_iv)))
               return ExperimentDocFragment.newInstance("D_ZenerIV.html");
       case 1:
           if (experimentTitle.equals(context.getString(R.string.diode_iv)))
               return ZenerSetupFragment.newInstance();
           if (experimentTitle.equals(context.getString(R.string.zener_iv)))
               return DiodeExperiment.newInstance(context.getString(R.string.half_wave_rectifier));
           return ExperimentDocFragment.newInstance("astable-multivibrator.html");

This setup was suitable for applications where there is less than around 5 choices to chose between. As the list grows, the elements in the end of the if layers will take more time to load as each of the previous if statements need to be evaluated false in order to reach the bottom statements.

This is when this implementation was replaced using switch case statements instead of consecutive if statements. The theory behind the performance improvement involves algorithm structures; Hash Tables

Hash Tables

Hash tables use a hash function to calculate the index of the destination cell. This operation on average has a complexity of O(1) which means it will take the same time to access any two elements which are randomly positioned.

This is possible because java uses the hash code of the string to determine the index where the target is situated at. This way it is much faster than consecutive if statement calls where in the worst case it will take O(n) time to reach the statement causing a lag in the application.

Current application uses switch cases in the PerformExperimentAdapter;

public Fragment getItem(int position) {
   switch (position) {
       case 0:
           switch (experimentTitle) {
               case "Diode IV Characteristics":
                   return ExperimentDocFragment.newInstance("D_diodeIV.html");
               case "Zener IV Characteristics":
                   return ExperimentDocFragment.newInstance("D_ZenerIV.html");
               case "Half Wave Rectifier":
                   return ExperimentDocFragment.newInstance("L_halfWave.html");
       case 1:
           switch (experimentTitle) {
               case "Diode IV Characteristics":
                   return ZenerSetupFragment.newInstance();
               case "Zener IV Characteristics":
                   return ZenerSetupFragment.newInstance();
               case "Half Wave Rectifier":
                   return DiodeExperiment.newInstance(context.getString(R.string.half_wave_rectifier));
           return ExperimentDocFragment.newInstance("astable-multivibrator.html");

There is one downfall in using switch case in the context. That is the inability to use string resources directly as Java requires a constant literals in the evaluation statement of a case.


Coloring Waveforms in PSLab Charts

Charts are used to display set of data in an analytical manner such that an observer can easily come to a conclusion by just looking at it without having to go through all the numerical data sets. Legends are used to differentiate a set of data set from another set. Generally, different colors and different names are used to form a legend in a chart.

MPAndroidChart is an amazing library with the capability of generating different types of graphs in an Android device. In PSLab several user interfaces are implemented using LineCharts to display different waveforms such as readings from channels attached to PSLab device, logic levels etc.

When several data sets are being plotted on the same graph area, legends are used. In PSLab Android application, Oscilloscope supports four different type of waveforms to be plotted on the same graph. Logic Analyzer implements one to four different types of logic level waveforms on the same plot. To identify which is which, legends with different colors can be used rather than just the names. For the legends to have different colors, it should be explicitly set which color should be held by which data set. Otherwise it will use the default color to all the legends making it hard to differentiate data lines when there are more than one data set is plotted.

Assume a data set is generated from a reading taken from a probe attached to PSLab device. The set will be added as an Entry to an array list as follows;

ArrayList<Entry> dataSet = new ArrayList<Entry>();

The next step will be to create a Line Data Set

LineDataSet lineData = new LineDataSet(dataSet, "DataSet 1");

This LineDataSet will contain sample values of the waveform captured by the microprocessor. A LineDataSet object support many methods to alter its look and feel. In order to set a color for the legend, setColor() method will be useful. This method accepts an integer as the color. This method can be accessed as follows;


MPAndroidChart provides different sets of colors under ColorTemplate. This class has several predefined colors with five colors in each color palette are added by the developers of the library and they can be accessed using the following line of code by simply calling the index value of the palette array list.


Set of color palettes available in the ColorTemplate class are;


The following demonstrates how the above activities produce a line chart with three different data sets with different colored legends.

This implementation can be used to enhance the readability of the waveforms letting user being able to differentiate between one waveform from another in PSLab Android application.


PSLab official web site:

Basics behind school level experiments with PSLab

Electronics is a fascinating subject to most kids. Turning on a LED bulb, making a simple circuit will make them dive into much more interesting areas in the field of electronics. PSLab android application with the help of PSLab device implements a set of experiments whose target audience is school children. To make them more interested in science and electronics, there are several experiments implemented such as measuring body resistance, lemon cell experiment etc.

This blog post brings out the basics in implementing these type of experiments and pre-requisite.

Lemon Cell Experiment

Lemon Cell experiment is a basic experiment which will make school kids interested in science experiments. The setup requires a fresh lemon and a pair of nails which is used to drive into the lemon as illustrated in the figure. The implementation in PSLab android application uses it’s Channel 1. The cell generates a low voltage which can be detected using the CH1 pin of PSLab device and it is sampled at a rate of 10 to read an accurate result.

float voltage = (float) scienceLab.getVoltage("CH1", 10);

2000 instances are recorded using this method and plotted against each instance. The output graph will show a decaying graph of voltage measured between the nails driven into the lemon.

for (int i = 0; i < timeAxis.size(); i++) {
   temp.add(new Entry(timeAxis.get(i), voltageAxis.get(i)));

Human Body Resistance Measurement Experiment

This experiment attracts most of the young people to do electronic experiments. This is implemented in the PSLab android application using Channel 3 and the Programmable Voltage Source 3 which can generate voltage up to 3.3V. The experiment requires a human with drippy palms so it makes a good conductance between device connection and the body itself.

The PSLab device has an internal resistance of 1M Ohms connected with the Channel 3 pin. Experiment requires a student to hold two wires with the metal core exposed; in both hands. One wire is connected to PV3 pin when the other wire is connected to CH3 pin. When a low voltage is supplied from the PV3 pin, due to heavy resistance in body and the PSLab device, a small current in the range of nano amperes will flow through body. Using the reading from CH3 pin and the following calculation, body resistance can be measured.

voltage = (float) scienceLab.getVoltage("CH3", 100);
current = voltage / M;
resistance = (M * (PV3Voltage - voltage)) / voltage;

This operation is executed inside a while loop to provide user with a continuous set of readings. Using Java threads there is a workaround to implement the functionalities inside the while loop without overwhelming the system. First step is to create a object without any attribute.

private final Object lock = new Object();

Java threads use synchronized methods where other threads won’t start until the first thread is completed or paused operation. We make use of that technique to provide enough time to read CH3 pin and display output.

while (true) {
   new MeasureResistance().execute();
   synchronized (lock) {
       try {
       } catch (InterruptedException e) {

Once the pin readings and value updates are complete the lock is released to execute the method once again.

synchronized (lock) {

Capacitor Discharge Experiment

This experiment is somewhat similar to the Lemon Cell Experiment as this experiments on electron storage and discharge. The experiment is carried out using two bulky electrolyte capacitors. PSLab device is capable of generating PWM waveforms with any duty cycle. Refer to this article to learn more about how PWM waves are generated using PSLab device to implement more features like sine wave generation.

Using the SQR1 pin of the PSLab device, one capacitor is charged to its fullest capacity using a PWM wave with 100% duty cycle at a 100 Hz.

scienceLab.setSqr1(100, 100, false);

This capacitor is then connected in parallel with the other capacitor which is empty. The voltage transfer is measured using CH1 pin at a sampling rate of 10

float voltage = (float) scienceLab.getVoltage("CH1", 10);

To provide a continuous update in the voltage transfer, a similar implementation is used using an object in the thread to control the implementation inside a while loop.


Basics behind BJT and FET experiments in PSLab

A high school student in his curriculum; will come across certain electronics and electrical experiments. One of them related to semiconductor devices such as Bipolar Junction Transistors (BJTs) and Field Effect Transistors (FETs). PSLab device is capable of function as a waveform generator, voltage and current source, oscilloscope and multimeter. Using these functionalities one can design an experiment. This blog post brings out the basics one should know about the experiment and the PSLab device to program an experiment in the saved experiments section.

Channels and Sources in the PSLab Device

The PSLab device has three pins dedicated to function as programmable voltage sources (PVS) and one pin for programmable current source (PCS).

Programmable Voltage Sources can generate voltages as follows;

  • PV1 →  -5V ~ +5V
  • PV2 → -3.3V ~ +3.3V
  • PV3 → 0 ~ +3.3V

Programmable Current Source (PCS) can generate current as follows;

  • PCS → 0 ~ 3.3mA

The device has 4 channel oscilloscope out of those CH1, CH2 and CH3 pins are useful in experiments of the current context type.

About BJTs and FETs

Every semiconductor device is made of Silicon(Si). Some are made of Germanium(Ge) but they are not widely used. Silicon material has a potential barrier of 0.7 V among P type and N type sections of a semiconductor device. This voltage value is really important in an experiment as in some practicals such as “BJT Amplifier”, there is no use of a voltage value setting below this value. So the experiment needs to be programmed to have 0.7V as the minimum voltage for Base terminal.

Basic BJT experiments

BJTs have three pins. Collector, Emitter and Base. Current to the Base pin will control the flow of electrons from Emitter to Collector creating a voltage difference between Collector and Emitter pins. This scenario can be taken down to three types as;

  • Input Characteristics → Relationship between Emitter current to VBE(Base to Emitter)
  • Output Characteristics → Relationship between IC(Collector) to VCB(Collector to Base)
  • Transfer Characteristics → Relationship between IC(Collector) to IE(Emitter)

Input Characteristics

Output Characteristics

Transfer Characteristics


Basic FET experiments

FETs have three pins. Drain, Source and Gate. Voltage to Gate terminal will control the electron flow from either direction from or to Source and Drain. This scenario results in two types of experiments;

  • Output Characteristics → Drain current to Drain to Source voltage difference
  • Transfer Characteristics → Gate to Source voltage to Drain current
Output Characteristics Transfer Characteristics

Using existing methods in PSLab android repository

Current implementation of the android application consists of all the methods required to read voltages and currents from the relevant pins and fetch waveforms from the channel pins and output voltages from PVS pins. class – This class implements all the methods required for any kind of an experiment. The methods that will be useful in designing BJT and FET related experiments are;

Set Voltages

public void setPV1(float value);

public void setPV2(float value);

public void setPV3(float value);

Set Currents

public void setPCS(float value);

Read Voltages

public double getVoltage(String channelName, Integer sample);

Read Currents

To read current there is no direct way implemented. The current flow between two nodes can be calculated using the PVS pin value and the voltage value read from the channel pins. It uses Ohm’s law to calculate the value using the known resistance between two nodes.

In the following schematic; the collector current can be calculated using known PV1 value and the measured CH1 value as follows;

IC = (PV1 – CH1) / 1000

This is how it is actually implemented in the existing experiments.

If one needs to implement a new experiment of any kind, these are the basics need to know. There can be so many new experiments implemented using these basics. Some of them could be;

  • Effect of Temperature coefficient in Collector current
  • The influence in β factor in Collector current


Implementing Tree View in PSLab Android App

When a task expands over sub tasks, it can be easily represented by a stem and leaf diagram. In the context of android it can be implemented using an expandable list view. But in a scenario where the subtasks has mini tasks appended to it, it is hard to implement it using the general two level expandable list views. PSLab android application supports many experiments to perform using the PSLab device. These experiments are divided into major sections and each experiments are listed under them.

The best way to implement this functionality in the android application is using a multi layer treeview implementation. In this context three layers are enough as follows;

This was implemented with the help from a library called AndroidTreeView. This blog will outline how to modify and implement it in PSLab android application.

Basic Idea

Tree view implementation simply follows the data structure “Tree” used in algorithms. Every tree has a root where it starts and from the root there will be branches which are connected using edges. Every edge will have a parent and child. To reach a child, one has to traverse through only one route.

Setting Up Dependencies

Implementing tree view begins with setting up dependencies in the gradle file in the project.

compile 'com.github.bmelnychuk:atv:1.2.+'

Creating UI for tree view

The speciality about this implementation is that it can be loaded into any kind of a layout such as a linearlayout, relativelayout, framelayout etc.

final TreeNode Root = TreeNode.root();
       // Add child nodes here
// Set up the tree view
AndroidTreeView experimentsListTree = new AndroidTreeView(getActivity(), Root);

Creating a node holder

Trees are made of a collection of tree nodes. A holder for a tree node can be created using an object which extends the BaseNodeViewHolder class provided by the library. BaseNodeViewHolder requires a holder class which is generally static so that it can be accessed without creating an instance which nests textviews, imageviews and buttons.

Once the holder extends the BaseNodeViewHolder, it should override two methods as follows;

public View createNodeView(final TreeNode node, ClassContainingNodeData header) {


public void toggle(boolean active) {


createNodeView() which inflate the view and toggle() method which can be used to toggle clicks on the tree node in the UI.

The following code snippet shows how to create an object which extends the above mentioned class with the overridden methods.

public class ExperimentHeaderHolder extends TreeNode.BaseNodeViewHolder<ExperimentHeaderHolder.ExperimentHeader> {

    private ImageView arrow;

    public ExperimentHeaderHolder(Context context) {

    public View createNodeView(final TreeNode node, ExperimentHeader header) {

            final LayoutInflater inflater = LayoutInflater.from(context);
            final View view = inflater.inflate(R.layout.header_holder, null, false);

            TextView title = (TextView) view.findViewById(;

            arrow = (ImageView) view.findViewById(;
            return view;

    public void toggle(boolean active) {
            arrow.setImageResource(active ? arrow_drop_up : arrow_drop_down);

    public static class ExperimentHeader {

            public String title;

            public ExperimentHeader(String title) {
               this.title = title;

Creating a TreeNode

Once the holder is complete, we can move on to creating an actual tree node. TreeNode class requires an object which extends the BaseNodeViewHolder class as mentioned earlier. Also it requires a viewholder which it can use to inflate the view in the tree layout. The viewholder can be a different class. The importance of this different implementation can be explained as follows;

TreeNode treeNode = new TreeNode(new ExperimentHeaderHolder.ExperimentHeader(“Title”))
       .setViewHolder(new ExperimentHeaderHolder(context));

In the Saved Experiments section of PSLab android application, all the three levels shouldn’t implement the toggle behavior as a user clicks on the experiment (last level item), he doesn’t expect the icon to change like the ones in headers where an arrow points up and down when he clicks on it. In this case we can reuse a holder which has the title attribute while creating only a holder which does not override the toggle function to ignore icon toggling at the last level of the tree view. This explanation can be illustrated using a code snippet as follows;

new TreeNode(new ExperimentHeaderHolder.ExperimentHeader(“Title”))
       .setViewHolder(new IndividualExperimentHolder(context));

Creating parent nodes and finally the Root node

The final part of the implementation is to create parent nodes to group up similar experiments together. The TreeNode object supports a method call addChild() and addChildren(). addChild() method allows adding one tree node to the specific tree node and addChildren() method allows adding many tree nodes at the same time. Following code snippet illustrates how to add many tree nodes to a node and make it a parent node.

treeDiodeExperiments.addChildren(treeZener, treeDiode, treeDiodeClamp, treeDiodeClip, treeHalfRectifier, treeFullWave);

Setting a click listener

Click listener is a very important implementation. Each tree node can be attached with a click listener using the interface provided by the library as follows;

treeNode.setClickListener(new TreeNode.TreeNodeClickListener() {
   public void onClick(TreeNode node, Object value) {


The value object is the class attached to the holder and its attributes can be retireved by casting it to the specific class using casting methods;

String title = ((ExperimentHeaderHolder.ExperimentHeader) value).title;