-
Notifications
You must be signed in to change notification settings - Fork 9
Making Your Program
This page serves as an illustrated example of how to go about building a comprehensive experiment control and data acquisition program using the simplified tools offered by JISA
. This specific example shall be designed to control a set-up for making temperature-dependent FET output-curve measurements.
When you being you will likely have the basic Java program structure given to you by your IDE:
public class Main {
public static void main(String[] args) {
// Code goes here
}
}
The first two things we should start thinking about is that our code is liable to throw exceptions, and that we will be using GUI elements. As a result we need to tell Java that our main(...)
method might throw an exception and make Main
extend GUI
so that it can set-up the GUI thread properly:
public class Main extends GUI {
public static void main(String[] args) throws Exception {
}
}
This is the simplest (but some might say most ineffective) way of dealing with exceptions. If an exception is indeed thrown by main(...)
, with it being the first method to be run thus having nothing above it to throw the exception up to, it will simply crash the program and output error text from the exception to the terminal. However, for our application this will do.
The next thing to think about is what variables/objects we want to store "globally". That is what will we want to be stored and accessible from all methods we write in our Main
class? The obvious examples to start with are the instruments/devices to be used by the program. Since we're wanting to perform temperature-dependent output-curve measurements, we will be using:
- 1 SMU or SMU channel for Source-Drain
- 1 SMU or SMU channel for Source-Gate
- 1 temperature controller
Therefore we can preemptively add these as static
variables in Main
:
public class Main extends GUI {
private static SMU sdSMU;
private static SMU sgSMU;
private static TController tCont;
public static main(String[] args) throws Exception {
}
}
(I have made them private
here because there's no need to be able to access them from outside our Main
class. It doesn't matter that much, but generally it is best practice to make things private
unless they need to be public
. For example, main
needs to be public
because it gets called externally by Java itself when run)
You may have noticed that we have given these variables the more "generic" types of SMU
and TController
as opposed to something like K2450
and ITC503
. This is because we do not know what specific models of SMU and temperature-controller we will be using. In-fact we will be making a part of the program to allow us to graphically select and configure which instruments we want to use instead of hard-coding them into the program.
We will also want some storage for results. For this, we can create a ResultList
, then initialise it in main
:
public class Main extends GUI {
private static SMU sdSMU;
private static SMU sgSMU;
private static TController tCont;
private static ResultList results;
public static main(String[] args) throws Exception {
results = new ResultList(
"Temperature"
"SD Voltage",
"SD Current",
"SG Voltage",
"SG Current"
);
results.setUnits("K", "V", "A", "V", "A");
}
}
Finally, we will be wanting the user to input experimental parameters for us to use. These will be coming from a Fields
object which gives us handles on the input-fields we create as Field
objects. Therefore, it makes sense that we store those statically so that they can be accessed by all methods in Main
:
public class Main extends GUI {
// ... all that other stuff ...
private static Field<Double> minSD; // Min SD Voltage
private static Field<Double> maxSD; // Max SD Voltage
private static Field<Integer> stepsSD; // Number of steps in SD Voltage
private static Field<Double> minSG; // Min SG Voltage
private static Field<Double> maxSG; // Max SG Voltage
private static Field<Integer> stepsSG; // Number of steps in SG voltage
private static Field<Double> intTime; // Integration time
private static Field<Integer> delTime; // Delay time
private static Field<Double> iLimit; // Current limit/compliance
private static Field<Integer> avCount; // Averaging count
// ... all that other stuff ...
}
So let's do a quick recap on what we've done:
- Allowed our main method to throw exceptions - a bit "hacky" but it's good enough for us
- Made static variables to hold onto our instruments (for when we add them)
- Created a static
ResultList
to store results - Defined static
Field<...>
s to hold onto user-input fields for when we create them
Now we can start "filling in" those static Field<...>
s so that they're not just empty variables.
To start with we shall create two Fields
objects. One for the experimental parameters and the other for the more "configuration" type parameters. We shall contain this code in a new method called createGUI()
.
private static void createGUI() {
Fields params = new Fields("Experiment Parameters");
Fields config = new Fields("Instrument Configuration");
minSD = params.addDoubleField("Min SD Voltage [V]");
maxSD = params.addDoubleField("Max SD Voltage [V]");
stepSD = params.addIntegerField("No. Steps");
params.addSeparator();
minSG = params.addDoubleField("Min SG Voltage [V]");
maxSG = params.addDoubleField("Max SG Voltage [V]");
stepSG = params.addIntegerField("No. Steps");
intTime = config.addDoubleField("Integration Time [s]");
delTime = config.addIntegerField("Delay Time [ms]");
iLimit = config.addDoubleField("Current Limit [A]");
avCount = config.addIntegerField("Averaging Count");
}
We now have enough structure to begin writing the code to actually perform a measurement! Even though we haven't actually connected to any instruments or created an interface to allow the user to start the measurement, we do have enough written down to define what we want it to do.
Let's create a method to perform our measurements. Like with main
we want this method to be able to throw exceptions.
public class Main {
// ... all that stuff we wrote in the last section ...
private static void runMeasurement() throws Exception {
}
}
- Getting Started
- Object Orientation
- Choosing a Language
- Using JISA in Java
- Using JISA in Python
- Using JISA in Kotlin
- Exceptions
- Functions as Objects
- Instrument Basics
- SMUs
- Thermometers (and old TCs)
- PID and Temperature Controllers
- Lock-Ins
- Power Supplies
- Pre-Amplifiers
- Writing New Drivers