Skip to content

Using JISA in Kotlin

William Wood edited this page Apr 10, 2019 · 11 revisions

Using Kotlin

As mentioned, writing JISA in java allows for many different languages to be used. Kotlin is a relatively new language that is essentially a simplified form of Java. It still gets compiled down to java byte-code so it runs at similar speeds to Java (unlike Python).

If you're looking for something faster than Python, but similar in simplicity then this might be the language for you.

Kotlin scripts are easy to create and look like this:

import JISA.GUI.*;

fun main() {

    GUI.startGUI()
    println("This is the code that gets run when the program starts")
    
    var plot  = Plot("Title", "X", "Y")
    var table = Table("Title")
    var grid  = Grid("Title", plot, table)

    grid.addToolbarButton("Click Me!", ::clicked)
    grid.setExitOnClose(true)
    grid.show()

}

fun clicked() {
    GUI.infoAlert("Clicked", "Button Clicked", "You clicked the button. Well done.")
}

Creating a Kotlin script in IDEA

IDEA has Kotlin support built-in (since JetBrains are the people who originally designed the language). Start by creating a new project (File > New > Project...). Then select "Kotlin" on the left-hand side and make sure to select "Kotlin/JVM":

Then go ahead and create your project. As usual, you need to copy the JISA.jar file over into your project and add it as a library. You can then create a Kotlin file by right-clickin on the src folder then selecting New > Kotlin File/Class

Kotlin Basics

Kotlin is very similar to both Python and Java. Let's run over the basics.

Methods/Functions and the Main Method

The first thing you should do is create your main() method. This is what will run when the program starts. To define a method ("function") you use the keyword fun (because it's fun) and put the code between curly braces: { ... }, like so:

fun myFunction() {
    // Code goes here
}

As mentioned, we want to create main() {...}, so here's a simple "Hello World!" script:

fun main() {
    println("Hello World!")
}

When run, this program will output "Hello World!" to the terminal. Astounding.

Variables

To declare a variable in Kotlin, you don't need to specify the type like in Java (although you can if you want to). You just need to use the var keyword like so:

fun main() {
    var myVariable    = 12
    var otherVariable = "This is a string!"
}

As mentioned, if you want to specify the type you do so like this:

var myVariable : Int       = 12
var otherVariable : String = "This is a string!"

If you declare a variable outside a function, then it becomes a global variable

var myVar1 : Int    = 0
var myVar2 : String = ""

fun main() {
    myVar1 = 16
    myVar2 = "Great!"
    output()
}

fun output() {
    print("myVar1 = ")
    println(myVar1)
    print("myVar2 = ")
    println(myVar2)
}

which will output to the terminal:

myVar1 = 16
myVar2 = Great!

Interestingly, when writing a String (ie text between two quote marks), you can directly insert variables using $. Let's see how this could work with our output() method:

fun output() {
    println("myVar1 = $myVar1")
    println("myVar2 = $myVar2")
}

The result is the same as before:

myVar1 = 16
myVar2 = Great!

but with much simplified syntax.

If you don't want to initialise a global variable straight away but later on in your program, use the lateinit keyword with typing:

lateinit var myVar1 : Int
lateinit var myVar2 : String

fun main() {
    myVar1 = 16
    myVar2 = "Great!"	
}

Objects and Imports

Objects are treated the same a variables. The main difference compared to Java is that you no-longer use the new keyword when instantiating an object (just like with Python).

When using a class, you need to import it just like in Java and Python, by use of an import statement at the top of your file like so:

import JISA.Devices.K2450
import JISA.Addresses.GPIBAddress
import JISA.Util

fun main() {

    var smu = K2450(GPIBAddress(0,20))
    smu.turnOn()
    smu.setVoltage(5.0)
    Util.sleep(500)
    var current = smu.getCurrent()
    smu.turnOff()
    println("A current of $current Amps flows under 5 Volts")

}

Property Access

If an object has a pair of matching set.. and get...() methods, for example: setVoltage(...) and getVoltage(...) or setCurrent(...) and getCurrent(...), then Kotlin allows you to use them as if th object simply has a voltage or current property.

Consider the following code:

import JISA.Addresses.*
import JISA.Devices.*

fun main() {

    var smu = K2450(GPIBAddress(0,20))

    smu.setVoltage(5.0)
    
    var voltage = smu.getVoltage()
    var current = smu.getCurrent()

}

Instead we can write this in property access form:

import JISA.Addresses.*
import JISA.Devices.*

fun main() {

    var smu = K2450(GPIBAddress(0,20))

    smu.voltage = 5.0
    
    var voltage = smu.voltage
    var current = smu.current

}

This is certainly interesting.

Using GUI Elements

Just like in Java and Python, we should set setExitOnClose(true) on our main window, so that the program terminates when it is closed and doesn't just keep running in the background:

import JISA.GUI.*

fun main() {

    var plot  = Plot("Title", "X", "Y")
    var table = Table("Title")
    var grid  = Grid("Title", plot, table)

    // run function onClick() when button is clicked
    grid.addToolbarButton("Click Me!", ::onClick)

    grid.setExitOnClose(true)
    grid.show()
    
}

fun onClick() {
    GUI.infoAlert("Clicked", "Button Clicked", "You clicked the button. Well done.")
}

Full Example using GUI Elements

import JISA.GUI.*
import JISA.Devices.*
import JISA.Addresses.*
import JISA.Experiment.*
import JISA.Util
import javafx.scene.paint.Color
import kotlin.system.exitProcess

// Try to connect to SMU
var smu = connect()

// Create GUI elements
var results = ResultList("Voltage", "Current")
var params  = Fields("Parameters")
var minV    = params.addDoubleField("Start [V]")
var maxV    = params.addDoubleField("Stop [V]")
var numV    = params.addIntegerField("No. Steps")
var plot    = Plot("Plot of Results", "Voltage [V]", "Current [A]")
var grid    = Grid("Sweep Program", params, plot)

fun connect() : SMU {

    try {
        return K2600B(TCPIPAddress("192.168.0.5"))
    } catch (e : Exception) {
        GUI.errorAlert("Error", "Connection Error", e.message)
        exitProcess(0)
    }

}

fun main() {

    // Set units for results
    results.setUnits("V", "A")

    // Make the plot follow the results
    plot.watchList(results, 0, 1, "Sweep", Color.RED)

    // Run doMeasurement() when button is clicked
    grid.addToolbarButton("Start", ::doMeasurement)
    grid.setExitOnClose(true)
    grid.show()

}

fun doMeasurement() {

    smu.turnOff()

    var voltages = Util.makeLinearArray(minV.get(), maxV.get(), numV.get())

    // Make sure we start at the first voltage value
    smu.setVoltage(voltages[0])
    smu.turnOn()

    for (v in voltages) {

        smu.setVoltage(v)
        Util.sleep(500)
        results.addData(smu.getVoltage(), smu.getCurrent())

    }

    // Turn off now we 're done
    smu.turnOff()
}

Running this script gives:

which after entering in some parameters and pressing "Start" gives us:

Clone this wiki locally