3.6 Remote monitoring

 

Here I will show how the Keithley 2450 (but also any other TSP-enabled Keithley instrument) can be used to measure and record data to a centralized server. This could be useful in a production setting were instruments measure components to ensure compliance to the manufacturer's specifications, or to continuously measure sensor data. The TSP scripting engine, implemented in Keithley's newest instruments, allows them to operate in a stand-alone way, completely eliminating the computer from the testing/measuring loop, and in this way reducing the time required to test components in a production settings, and at the same time lowering the complexity of the setup. The scripting environment is quite powerful, and allows the instrument to initiate a TCP connection to a TCP server. This is a great feature as it allows the instrument to be interfaced to instruments of other manufacturers or even to computer servers, just as an IoT device.

 

Here I will explore how the instrument could be used in a stand-alone way to upload the measured data to a server that will then display the data on a dashboard. Of course this could be implemented in several different ways, so I arbitrarily focused on simplicity and the use of well-established, open-source software solutions. The system that I designed looked like this:

 

 

I connected the SMU to a small solar cell to continuously measure the Voc, Isc, Vmax and Imax every minute. After each measurement, the SMU connected (if it was not already connected) to a Node-RED TCP server node to upload the measured values in CSV format. Node-RED took these values and saved them to a MariaDB database and finally Grafana through SQL queries processed the recorded data and made it available to a web-based dashboard. Lets take a closer look on how each part of the system works.

 

 

3.6.1 Keithley 2450

 

I connected the solar cell just as I did in Keithley 2450: Solar cell characterization, the solar cell parameters were also computed in the same way (Voc first by setting the instrument as a voltmeter, followed by a voltage sweep from 0 V to Voc to measure Isc, Vmax and Isc). I left the solar cell facing upwards and always behind the glass of window facing to the west, so the setup was far from optimal.

 

To measure and upload the parameter values to Node-RED I used the following script:

 

Node-RED.tsp

local address = "192.168.0.10"

local port    = 12345

local handle  = nil

 

local dt      = 60

local step    = 100

 

 

local function send(address, port, message)

    while true

    do

        while handle == nil

        do

            eventlog.clear()

            tspnet.reset()

            tspnet.timeout = 1.0

            handle = tspnet.connect(address, port, "")

             

            if handle == nil

            then

                delay(10)

            end

        end

 

        tspnet.write(handle, message)

   

        if eventlog.getcount(eventlog.SEV_ERROR | eventlog.SEV_WARN) == 0

        then

            break

        else

            tspnet.disconnect(handle)

            handle = nil

            eventlog.clear()

        end

    end

end

 

 

reset()

local t1 = localnode.gettime() - dt

 

while true

do

    delay(0.1)

    t0 = localnode.gettime()

   

    if t0 - t1 >= dt

    then

        t1 = t1 + dt * math.floor((t0 - t1) / dt)

   

        smu.measure.func = smu.FUNC_DC_VOLTAGE

        smu.source.func = smu.FUNC_DC_CURRENT

         

        smu.source.output = smu.ON

        local voc = smu.measure.read()

        smu.source.output = smu.OFF

           

        defbuffer1.clear()

           

        smu.measure.func = smu.FUNC_DC_CURRENT

        smu.source.func = smu.FUNC_DC_VOLTAGE

           

        smu.source.ilimit.level = 1

        smu.measure.autorangelow = 1e-6

        smu.source.sweeplinear("SolarCell", 0, voc, step)

           

        trigger.model.initiate()

        waitcomplete()

           

        local voltage = defbuffer1.sourcevalues

        local current = defbuffer1.readings

           

        local isc = current[1]

        local vmax = voltage[1]

        local imax = current[1]

        local pmax = voltage[1] * current[1]

           

        for i = 1, step

        do

            if voltage[i] * current[i] < pmax

            then

                vmax = voltage[i]

                imax = current[i]

                pmax = voltage[i] * current[i]

            end

        end

 

        send(address, port, t0 .. "," .. voc .. "," .. -isc .. "," .. vmax .. "," .. -imax .. "\n")

    end

end

 

 

tspnet.connect() attempts to open a TCP link by connecting to a TCP server, while tspnet.write() attempts to send data through an open TCP link. If for whatever reason an error occurs, the error is logged in the event log. The send() function makes a TCP connection to the server if it has not already been made, if it can't, it tries again every 10 seconds until it succeeds. After the connection has been made, it attempts to send data, but if it can't (ie: TCP link got closed) it will try to reconnect and send the data to the server until it succeeds.

 

The data is sent to the server as CSV containing 5 values: Epoch time, Voc, Isc, Vmax and Imax.

 

 

3.6.2 Node-RED graph

 

Node-RED is an open-source data-flow visual programming platform that allows easy interfacing of hardware and services. I used it to simplify the connection between the SMU and the database. The flow contains 4 nodes:

 

 

 

The "TCP Server" node listens to TCP connections at an arbitrarily selected port (12345). The "Solar Cell Values" node is a Javascript function node that extracts the 5 CSV values.

 

"Solar Cell Values" Javascript function

s = msg.payload.split(/,/);

Epoch = parseInt(s[0]);

Voc   = parseFloat(s[1]);

Isc   = parseFloat(s[2]);

Vmax  = parseFloat(s[3]);

Imax  = parseFloat(s[4]);

Pmax  = Vmax * Imax;

return {Epoch: Epoch, Voc: Voc, Isc: Isc, Vmax: Vmax, Imax: Imax, Pmax: Pmax};

 

 

The "SQL Query" node is a Javascript function that creates the SQL query string that will be used to store the 5 values into an SQL database.

 

"SQL Query" Javascript function

var csv = msg.Epoch + "," + msg.Voc + "," + msg.Isc + "," + msg.Vmax + "," + msg.Imax;

var query = "INSERT INTO SolarCell VALUES (" + csv + ");"

return {topic: query};

 

 

And finally the SMU database node receives the SQL query and performs an "INSERT" into the "SolarCell" table of the "smu" MariaDB database.

 

 

3.6.3 MariaDB

 

MariaDB is a fork of MySQL, an open-source relational database management system (RDBMS). The "smu" database and "SolarCell" table were created with just 3 lines:

 

CREATE DATABASE smu;

USE smu;

CREATE TABLE SolarCell (Epoch INT PRIMARY KEY, Voc REAL, Isc REAL, Vmax REAL, Imax REAL);

 

 

3.6.4 Grafana

 

The data streamed to the database can be used in many different ways. I decided to use Grafana, an open-source data visualization and analytics web application, to build a dashboard to display the recorded data.

 

Grafana is relatively easy to setup and can be done through a web browser. To create a dashboard, panels must be created and then edited with Grafana's panel editor. The panel editor, as it can be seen in the image, is divided in 3 sections, the top shows a preview of the panel with the current settings, the bottom is used to set the database queries, and at the right section to set the panel style.

 

 

 

To test Grafana, I created a simple dashboard made of 4 sections:

  • A section to display the date and time of the last database update
  • A section to displays an XY plot of the historic parameter values.
  • A section to displays the most current parameter values.
  • And a section to display the minimum, the maximum and the mean of the parameter values within the last 24 hours.

 

It took me around 3 hours to set the dashboard right to nicely fit all the panels on the screen. But I suspect it would have taken me 1/3 of that time if I had previous experience with the system.

 

The final dashboard looked like this:

 

 

 

3.6.5 Conclusions

 

When deciding what IoT infrastructure to use, multiple factors have to be evaluated, such as the:

  • Communication protocol
  • Number of devices/instruments
  • Server/cloud infrastructure
  • Database system
  • Frontend system

 

As always, there is no best solution, and one must decide what to prioritize when selecting one.

 

Here I showed how to initiate the TCP connection from the instrument to the computer, but the connection could have been made the other way around, from the computer to the instrument, both methods have their pros and cons.

 

Managing few instruments, or a single one as I did, is much easier than a large number. When working with large number of instruments it's important to identify them in some way, such as their serial number (which is stored in the localnode.serialno attribute), and also be able to update the scripts automatically, without having to do it one by one.

 

As the server that I used was not accessible from the internet I did not restrict the access to the TCP server or encrypt the transmitted data, but things would have had to be done completely different if the server had internet access.

 

I used a RDBMS because I'm familiar with them, but a time series database (TSDB) could probably have made more sense for the data that I used here.

 

To visualize the data I chose Grafana just because it was a free and popular, as I didn't have any experience with these type of tools.