Plotting Digital Logic Lines In PSLab Android App

The PSLab device offers the Logic Analyzer functionality. A Logic Analyzer is a laboratory instrument that can capture and display digital signals from a digital system or circuit. It is similar to what an oscilloscope is for analog signals and is used to study timing relationship between different logic lines. It plots the logic lines/timing diagram which tells us the information about the state of the Digital System at any instant of time. For example, in the image below we can study the states of digital signals from channels ID1, ID2, ID3 at different times and find parameters like the propagation delay. It’s also used to find errors in Integrated Circuits (ICs) and debug logic circuits.

How I plotted ideal logic lines using MPAndroid Chart library?

Conventional method of adding data points results in the plot as illustrated in the image below. By conventional method I mean basically adding Y-axis (logic state) values corresponding to X-axis values (timestamp).

Result with normal adding and plotting data-points

In the above plot, logic lines follow non-ideal behaviour i.e they take some time in changing their state from high to low. This non-ideal behaviour of these lines increases when the user zooms in graph to analyse timestamps.

Solution to how we can achieve ideal behaviour of logic lines:

A better solution is to make use of timestamps for generating logic lines i.e time instants at which logic made a transition from HIGH -> LOW or LOW -> HIGH. Lets try to figure out with an example:

Timestamps = { 1, 3, 5, 8, 12 } and initial state is HIGH ( i.e at t = 0, it’s HIGH ). This implies that at t = 1, transition from HIGH to LOW took place so at t = 0, it’s HIGH, t = 1 it’s both HIGH and LOW,  at t = 2 it’s LOW.
Now at t = 0 & t = 2, you can simple put y = 1 and 0 respectively. But how do you add data-point for t = 1. Trick is to see how transition is taking place, if it’s HIGH to LOW then add first 1 for t = 1 and then 0 for t = 1.
So the set of points look something like this:

( Y, X ) ( LOGIC , TIME ) -> ( 1, 0 ) ( 1, 1 ) ( 0, 1) ( 0, 2 ) ( 0, 3 ) ( 1, 3 )  ( 1, 4 ) …

Code snippet for adding coordinates in this fashion:

int[] time = timeStamps.get(j);
for (int i = 0; i < time.length; i++) {
   if (initialState) {
       // Transition from HIGH -> LOW
       tempInput.add(new Entry(time[i], 1));
       tempInput.add(new Entry(time[i], 0));
   } else {
       // Transition from LOW -> HIGH
       tempInput.add(new Entry(time[i], 0));
       tempInput.add(new Entry(time[i], 1));
   }

   // changing state variable
   initialState = !initialState;
}

After adding data-points in above mentioned way, we obtained ideal logic lines successfully as illustrated in the image given below

Resources

Environment Monitoring with PSLab

In this post, we shall explore the working principle and output signals of particulate matter sensors, and explore how the PSLab can be used as a data acquisition device for these.

Working Principle

A commonly used technique employed by particulate matter sensors is to study the diffraction of light by dust particles, and estimate the concentration based on a parameter termed the ‘occupancy factor’. The following image illustrates how the most elementary particle sensors work using a photogate, and a small heating element to ensure continuous air flow by convection.

Occupancy Rate

Each time a dust particle of aerodynamic diameters 2.5um passes through the lit area, a phenomenon called Mie scattering which defines scattering of an electromagnetic plane wave by a homogenous sphere of diameter comparable to the wavelength of incident light, results in a photo-signal to be detected by the photosensor.  In more accurate dust sensors, a single wavelength source with a high quality factor such as a laser is used instead of LEDs which typically have broader spectra.

The signal output from the photosensor is in the form of intermittent digital pulses whenever a particle is detected. The occupancy ratio can be determined by measuring the sum total of time when a positive signal was output from the sensor to the total averaging time. The readings can be taken over a fairly long amount of time such as 30 seconds in order to get a more accurate representation of the occupancy ratio.

Using the Logic analyzer to capture and interpret signals

The PSLab has a built-in logic analyzer that can acquire data signals up to 67 seconds long at its highest sampling rate, and this period is more than sufficient to record and interpret a dataset from a dust sensor. An inexpensive dust sensor, DSM501A was chosen for the readings, and the following results were obtained

Dust sensor readings from an indoor, climate controlled environment. After the 100 second mark, the windows were opened to expose the sensor to the outdoor environment.

A short averaging time has resulted in large fluctuations in the readings, and therefore it is important to maintain longer averaging times for stable measurements.

Recording data with a python script instead of the app

The output of the dust sensor must be connected to ID1 of the PSLab, and both devices must share a common ground which is a prerequisite for exchange of DC signals. All that is required is to start the logic analyzer in single channel mode, wait for a specified averging time, and interpret the acquired data

Record_dust_sensor.py

from PSL import sciencelab   #import the required library
import time
import numpy as np
I = sciencelab.connect()           #Create the instance
I.start_one_channel_LA(channel='ID1',channel_mode=1,trigger_mode=0)  #record all level changes
time.sleep(30)   #Wait for 30 seconds while the PSLab gathers data from the dust sensor
a,_,_,_,e =I.get_LA_initial_states()      #read the status of the logic analyzer
raw_data =I.fetch_long_data_from_LA(a,1)  #fetch number of samples available in chan #1
I.dchans[0].load_data(e,raw_data)  
stamps =I.dchans[0].timestamps    #Obtain a copy of the timestamps
if len(stamps)>2:   #If more than two timestamps are available (At least one dust particle was detected
		if not self.I.dchans[0].initial_state:   #Ensure the starting position of timestamps
			stamps = stamps[1:] - stamps[0]   # is in the LOW state
	diff = np.diff(stamps)   #create an array of individual time gaps between successive level changes


	lows = diff[::2]      #Array of time durations when a particle was not present
	highs = diff[1::2]    #Array of time durations when a particle was present
	low_occupancy = 100*sum(lows)/stamps[-1] #Occupancy ratio
print (low_occupancy) # datasheets of individual dust sensors also provide a mathematical
                      #equation to interpret the occupancy ratio as concentration of
				#particulate matter

Further Reading, and application notes:

[1] LED based  dust Sensor application note