Server interface

The communication interface is realised via sockets passed over Ethernet. Communication is done on a client-server basis, where the client (SPM control programme operated by user) sends some message to the server and gets some response. Messages are passed as GwyFileObject structures serialised by Gwyfile library, with a variable number of items inside, depending on the message type and user’s wishes on the number of parameters that should be passed at the moment. For deserialization, the Gwyfile library can be used again, or custom implementation based on the Gwyddion file format description can be done.

Messages to get or set status of the microscope

state: sets and gets the general behaviour of the microscope, namely aspects that affect how the feedback loop will work in general. The mode parameter should match some of the modes defined in hwserver.ini file located on the server, which might be e.g. “proportional” for a general feedback loop operation proportional to the input, “ncamplitude”, which might be tapping mode based on amplitude feedback, etc. The real number of modes depends on the hardware and their names are provided by this command. Switching the mode to off has nothing to do with switching the feedback on and off (see the set_feedback message). The main goal of this command is to connect all the wires inside the digital feedback loop.

The various mode parameters can also be read. What will be returned will correspond to the actually selected mode parameters. Many of these parameters can’t be yet set as most of them depend on wiring in the electronics and values in hwserver.ini file should match them.

The following parameters can be get/set:

mode (string): use one from the list provided by this command.
mux1 (int): multiplexer settings for RP fast ADC 1
mux2 (int): multiplexer settings for RP fast ADC 2
bitshift (int): error signal bit shift inside the FPGA
input1_range (int): 0/1 for small/full RP1 ADC range
input2_range (int): 0/1 for small/full RP2 ADC range
lockin1_hr (int): use high resolution small signal option for lock-in1
lockin2_hr (int): use high resolution small signal option for lock-in2
lockin1_filter_amplitude (int): low pass filter amplitude result from lock-in1
lockin1_filter_phase (int): low pass filter phase result from lock-in1
lockin2_filter_amplitude (int): low pass filter amplitude result from lock-in2
lockin2_filter_phase (int): low pass filter phase result from lock-in2
lockin1_nwaves (int): number of waves to be evaluated by the lock-in, 0-6 means this sequence: 1 wave, 2 waves, 4, 8, 32, 128 and 512 waves
lockin2_nwaves (int): number of waves to be evaluated by the lock-in, 0-6 means this sequence: 1 wave, 2 waves, 4, 8, 32, 128 and 512 waves
pidskip (int): feedback loop speed: 0: 125 MHz, 1: 1 MHz, 2: 120 kHz, 3: 15 kHz
pllskip (int): feedback loop speed: 0: 125 MHz, 1: 1 MHz, 2: 120 kHz, 3: 15 kHz
swap_in (boolean): swap the error signal direction in the feedback loop

On top of it, the following general hardware related parameters can be obtained, but not set (they should be set in hwserver configuration file, not by user, and should match together):

error_source (int): error source: (0: RP1, 1: RP2, 2: A1, 3: P1, 4: A2, 5: P2, 6: PLL freq)
swap_in (boolean): swap the error signal direction in the feedback loop
swap_out (boolean): swap the piezo direction
pll (boolean): use of PLL
pll_input (int): input for PLL: 1: lock-in1 phase, 2: lock-in2 phase
out1 (int): routing for RP fast DAC 1 (0: gen1, 1: gen2, 2: dac1, 3: dac2, 4: pid, 5: off, 6: excs)
out2 (int): routing for RP fast DAC 2 (0: gen1, 1: gen2, 2: dac1, 3: dac2, 4: pid, 5: off, 6: excs)
outhr (int); routing for FPGA connected HR DAC
x_cal_factor (double): conversion factor of x position to voltage
y_cal_factor (double): conversion factor of y position to voltage
z_cal_factor (double): conversion factor of z position to voltage
x_shift_factor (double): conversion factor of x position to voltage
y_shift_factor (double): conversion factor of y position to voltage
z_shift_factor (double): conversion factor of z position to voltage
x_range (double): maximum scan range in the x direction in metres
y_range (double): maximum scan range in the y direction in metres
z_range (double): maximum range in the z direction in metres
dds1_range (int): full or half range of DDS generator 1
dds2_range (int): full or half range of DDS generator 2
rp1_input_hv (int): 1 if the jumper on RP board input 1 is on HV (only special cases)
rp2_input_hv (int): 1 if the jumper on RP board input 1 is on HV (only special cases)
hrdac_range (int): xy 20bit DAC range option: 0: +-10V, 1: 0-10 V
zpiezo_hrdac (boolean): use external 20bit DAC for z piezo motion
zpiezo_hrdac_range: z 20bit DAC range option: 0: +-10V, 1: 0-10 V
scan_mode (int): scan regime 0: nothing, 1: voltage scan, 2: PI RS232 scan, 3: RP 2D scan

Finally, the command sends a list of available modes as mode1 (string), mode2 (string), etc.

In the response, all the settings will be sent back. Sending a request with nothing to set is a way to get all the settings without altering anything. Depending on the hardware the lateral position can be controlled via voltage or via digital communication. When voltage position control should be used, the voltage is output from 20 bit DAC as out = length*cal_factor + shift_factor, where length is in metres.


set: sets selected feedback parameters, like the PID loop settings, setpoint and hardware time that is used to report how long things take. This also includes an optional second feedback loop that is needed in some scanning regimes (e.g. KPFM) or second frequency generator and lock-in.

The following parameters can be set:

hwtime (double): hardware time, to be used to restart or alter the time elapsed by the server
pid_p (double): primary feedback loop P parameter
pid_i (double): primary feedback loop I parameter
pid_d (double): primary feedback loop D parameter
pid_setpoint (double): primary feedback loop setpoint, in basic units of particular quantity
freq1_f (double): primary frequency generator frequency, in Hz
freq1_a (double): primary frequency generator amplitude, in Volts, range 10 V
freq1_o (double): primary frequency generator offset, in Volts, range +-10 V
pid_pll_p (double): PLL feedback loop P parameter
pid_pll_i (double): PLL feedback loop I parameter
pid_pll_d (double): PLL feedback loop D parameter, used also for FM
pid_pll_setpoint (double): FM AFM PLL setpoint, in radians
pid_amplitude_p (double): FM mode amplitude feedback loop P parameter
pid_amplitude_i (double): FM mode amplitude feedback loop I parameter
pid_amplitude_d (double): FM mode amplitude feedback loop D parameter
pid_kpfm_p (double): KPFM feedback loop P parameter
pid_kpfm_i (double): KPFM feedback loop I parameter
pid_kpfm_d (double): KPFM feedback loop D parameter
pid_dart_p (double): DART feedback loop P parameter
pid_dart_i (double): DART feedback loop I parameter
pid_dart_d (double): DART feedback loop D parameter
freq2_f (double): secondary frequency generator frequency, in Hz
freq2_a (double): secondary frequency generator amplitude, in Volts, range 10 V
freq2_o (double): secondary frequency offset, in Volts, range +-10 V
freq3_f (double): auxiliary internal generator frequency, to be passed to lock-in output instead of , in Hz
filter1 (integer): adc filter 1, range 0-12, larger value means higher cut-on, 0 means off
filter2 (integer): adc filter 2, range 0-12, larger value means higher cut-on, 0 means off
pll_phase_limit_factor (integer): range is 0-7, about 1/32 of range to full range
pll_frequency_limit_factor (integer): range is 0-7, meaning approx 4 to 480 Hz
oversampling (integer): range is 0-6, meaning no averaging to 64 samples averaging
kpfm_mode: set the KPFM mode: 0: none, 1: am manual, 2: fm manual, 3: am, 4: fm
kpfm_feedback_source: lockin-data for feedback: 0: signal*sin, 1: signal*cos, 2: sin-cos, 3: sin+cos
kpfm_feedback_direction: 0: up, 1: down
kpfm_no_autoset: 0: start/stop kpfm automatically when doing profile scan, 1: don’t do this
phaseshift1: phase shift of evaluated signal in lock-in, 0-3, meaning 0, 90, 180 and 270 deg
phaseshift2: phase shift of evaluated signal in lock-in, 0-3, meaning 0, 90, 180 and 270 deg
dart_mode: 0:off, 1:manual (no feedback), 2: on
dart_frequency: central excitation frequency, in Hz
dart_amplitude: excitation amplitude, in Volts
dart_freqspan: frequency to be subtracted and added from central frequency, in Hz

In the response, the altered settings are sent back.


get: gets only selected parameters, not setting anything (if there are values passed in the message, they are ignored). The same parameters as in set command can be returned. There are also some additional values that cannot be set but can be obtained:

version (string): hwserver version
moving (boolean): scanner is still moving
scanning_adaptive (boolean): adaptive scan in progress
scanning_line (boolean): line scan in progress
scanning_script (boolean): script scan in progress
ramp_running (boolean): ramp run in progress


reset_spi: resets the internal controller communication, to be used after cycling the power on external boards connected by SPI interface.

Function has no parameters.


Messages to read live data

set_standby_storage: set which additional channels should be acquired internally in the free running regime. By default, all the available channels would be read, which is slow and mostly unnecessary. This function limits the storage to only what is needed and in this way speeds up everything. The function clears the so far measured data and previously set storage parameters. Some of the channels can be duplicated, depending on the feedback regime - e.g. the error signal will be equal to amplitude in the amplitude based tapping mode. The XYZ positions, timestamp, error signal and raw adc data are acquired and sent always.

The following parameters can be set to be acquired:

a1 (boolean): on/off, amplitude of primary lock-in signal
p1 (boolean): on/off, phase of primary lock-in signal
a2 (boolean): on/off, amplitude of secondary lock-in signal
p2 (boolean): on/off, phase of secondary lock-in signal
in1 (boolean): on/off, auxiliary ADC analog input 1
.
.
.
in16 (boolean): on/off, auxiliary ADC analog input 16
fmdrive (boolean): drive amplitude of the FM signal
kpfm (boolean): KPFM result (voltage)
l1x (boolean): primary lock-in x component
l1y (boolean): primary lock-in y component
l2x (boolean): secondary lock-in x component
l2y (boolean): secondary lock-in y component
dart (boolean): DART result (frequency)

In the response the function sends a full set of parameters.


read: get all the synchronously acquired data (default parameters plus all channels set by set_standby_storage commands).

Function has no parameters.

In the response, it sends a single set of all the available data (parameter names are the channel names). The values are doubles. All values are in basic SI units and are coded by following strings: x, y, z, e (error signal), adc1, adc2 a1, p1, a2, p2, ch1...ch16, ts (timestamp), fmd (fmdrive), kpfm. Values adc1 and adc2 are the raw data from FPGA high speed input.


Messages to set digital and analog outputs manually

The electronics has three types of analog outputs. High speed (RF) Red Pitaya outputs are supposed to be externally connected to dither piezo and to excitation of the Kelvin probe signal. Slow 20bit DAC outputs are supposed to be connected to scanners in all three axes, to control them, use the move_to command. Finally, there are 16 general purpose DACs that can be fed by anything, based on the user's wishes, so only these outputs are configurable using the set_out and route_out commands. The electronics also has four digital outputs that can be set by the set_out command. Note that the electronics also has some inputs, even if these are not discussed in this section. There are 16 general purpose simultaneous inputs. These are not configurable (user can read them, set to store them or not, but not alter the routing, which depends on mode of operation). Similarly, the two fast RF inputs to the Red Pitaya FPGA are configured automatically based on the mode of operation. The details on how everything should be connected are given elsewhere.

set_out: sets static values of individual general purpose analog or digital outputs. These can be connected anywhere (e.g. to form tip or sample bias, or to control some electronics). They can be set at any moment, even during scan. Note that some measurement options can override the signals, e.g. when ramp is requested on any of the channels. After the ramp is finished, the values are recovered.

The following parameters can be set:

out1 (double): value of auxiliary analog output 1, in Volts
.
.
.
out16 (double): value of auxiliary analog output 16, in Volts
dout1 (boolean): status of digital output 1
dout2 (boolean): status of digital output 2
dout3 (boolean): status of digital output 3
dout4 (boolean): status of digital output 4

In the response, the altered values are sent back to confirm that the requested operation had happened.


set_routing: sets routing of general purpose analog outputs. By default, a constant value set by the set_out command is passed to them (which corresponds to the routing option “nothing”). If the routing option is e.g. “in1”, the signal from auxiliary analog input is fed to output. This is done on the software side, so some small delay might be expected. If the routing option is x, y, z, the actual values of voltage sent digitally to DACs for scanners/piezos are passed to the analog outputs. This can be useful for synchronisation to other instruments.

The following parameters can be set:
ch1...ch16 (string) routing: nothing, x, y, z,, in1,...,in16, error, zpiezo, amplitude1, phase1, amplitude2, phase2, fmresult, amresult, adc1, adc2 (string).

Command returns a complete routing table. Routing “nothing” does not affect the present settings, output value can be e.g. constant set by set_out command. Some of the results are scaled to provide reasonable voltage values: x, y, z and zpiezo are multiplied by 10000, so +-100 um converts to +-1 V, fmresult (frequency shift) is divided by 100, so the shift +-100 Hz converts to +- 1 V.


Messages to set feedback

There are not yet any messages for automated approach as the coarse z motion depends on instrumentation heavily. The approach still can be done manually, by using digital outputs to control the motor, using analog outputs to control piezo and monitoring the deflection signal on the client side. After that the feedback should be manually switched on.

set_feedback: switches the state of feedback from user control of z-piezo to feedback control or the PLL.

The following parameters can be set:

feedback (boolean): feedback state
feedback_pll (boolean): feedback state
feedback_amplitude (boolean): feedback state
feedback_kpfm (boolean): feedback state
zpiezo (double): the z piezo value in meters

In the response it sends the feedback status. Feedback is related to the main feedback loop, feedback_pll to the PLL frequency feedback and feedback_ampitude to the PLL amplitude feedback, in this case the setpoint value is the current value recorded at the time when the parameter is set. Zpiezo value is applied only when feedback is off and is applied immediately without any ramp. When the feedback is on, the zpiezo value still can be set, it does not impact the immediate value, however it will be used after the feedback is switched off (otherwise any other last known value of zpiezo would be used). The other additional feedback loops (e.g. KPFM, DART) are controlled internally.


Messages to move somewhere

move_to: move the stage to some absolute position. Global speed settings are used.

The following parameters can be set

xreq (double), in metres
yreq (double), in metres
zreq (double), in metres

Zreq is applied only when feedback is off. In contrast to setting zpiezo from set_feedback command where it is applied instantly, here it ramps to the value. Speed is controlled by set_scan command and is independent for xy and for z.


stop: stop everything immediately.

This function stops all the motion, including scan or ramp if they are running.


Messages to scan something

Scanning starts by issuing a scan command. Different variants of scan commands are available. point by point scanning and storage based on xyz data (using Gwyscan library), using run_scan_path command continuous scanning on a line given by end points, storing automatically regularly sampled data using run_scan_line command custom scanning using Lua script that controls the whole scanning and data storage process on the server side using run_scan_script command. The measured data are stored on hwserver and can be requested by user. Starting a scan clears the data scanned so far and eventually also re-allocates the amount of memory reserved for the storage. Scan then runs automatically - in case of run_scan_path or run_scan_script commands the whole image is collected and in case of run_scan_line a single line is collected. Client software can read the data scanned so far at any moment using commands get_scan_ndata and get_scan_data. A scan can also be stopped at any moment by stop_scan command or paused and started again by pause_scan command. Prior to starting scan, client software can request that only a subset of available channels should be allocated and collected to speed up the microscope operation, by using the set_storage command. However, some channels are collected always for internal reasons, e.g. the positions.

set_scan_storage: set which additional channels should be stored internally during scan. By default, all the available channels are stored, which is slow and in most cases unnecessary. This function limits the storage to only what is needed and in this way speeds up everything. XYZ positions and error signal are always stored. The function clears the so far measured data and previously set storage parameters. Some of the channels can be duplicated, depending on the feedback regime - e.g. the error signal will be equal to amplitude in the amplitude based tapping mode.

The following parameters can be set to be acquired:

a1 (boolean): on/off, amplitude of primary lock-in signal
p1 (boolean): on/off, phase of primary lock-in signal
a2 (boolean): on/off, amplitude of secondary lock-in signal
p2 (boolean): on/off, phase of secondary lock-in signal
in1 (boolean): on/off, auxiliary ADC analog input 1
.
.
.
in16 (boolean): on/off, auxiliary ADC analog input 16
fmdrive (boolean): drive amplitude of the FM signal
kpfm (boolean): KPFM result
dart (boolean): DART result
l1x (boolean): primary lock-in x component
l1y (boolean): primary lock-in y component
l2x (boolean): secondary lock-in x component
l2y (boolean): secondary lock-in y component
set (boolean): sets of data to be used to distinguish different data when scanned from Lua script


set_scan: set global parameters of scanning

The following parameters can be set:

speed (double): in m/s, the value to be used for all lateral motion
zspeed (double): speed used in z move_to command, in m/s
delay (double): in seconds, to wait before each point acquisition
xslope (double): in radians, the sample tilt in x-direction to be compensated in PID loop
yslope (double): in radians, the sample tilt in y-direction to be compensated in PID loop
xsloperef (double): in meters, sample tilt zero point in x direction (usually scan x offset)
ysloperef (double): in meters, sample tilt zero point in y direction (usually scan y offset)
subtract_slope (boolean): subtract the sample tilt when reporting z piezo data


get_scan_ndata: get information about the scanned and stored data

The following parameters are returned:

n (integer): number of scanned data points from beginning of the scan command


get_scan_data: get some part of already scanned and stored data.

The following parameters can be requested:

from (integer): where the returned arrays should start (use 0 or -1 to set it to beginning)
to (integer): where the returned arrays should end (use -1 to set it to entire data)

In the response, it sends all the scanned data of stored channels in the range from-to as individual arrays of doubles, with the same naming as for the read command (i.e. the array name will be e.g. “in1”). It also returns an integer representing the number of values in the passed arrays. From and to parameter control range of data to be returned.


set_scan_path_data: provide a set of individual xy(z) points that will be used for run_scan_path command. Optionally, also send some trajectory in z (e.g. for lift mode operation).

The following parameters can be set:

n (integer), total number of positions (xy pairs) in the scan
from (integer), xy pair number to start from when filling the array at server side
to (integer), xy pair number to end at when filling the array at server side
xydata (array of interleaved doubles), the x and y positions organised as x1, y1, x2, y2...
z (array of doubles with n data points): z values to be used for scan line when feedback is off.

For short scans (e.g. 100x100 pixels) the data can be sent at once, however for larger scans it is more robust to send them piecewise. Parameters from and to are used to pass the data to the right location. Parameter n is used to allocate the arrays and find that the data are complete.


run_scan_path: run scan along path, given by a set of individual xy(z) points that is sent prior to the command. Optionally, also follow some trajectory in z (e.g. for lift mode operation).

The following parameters can be set:

n (integer), number of positions to scan

Function starts scanning pixel by pixel until all the n positions are not scanned. Data points should be passed before calling this function by single or multiple calls of set_scan_path_data. The measured data are stored internally and can be requested by the get_scan_data function.


run_scan_line: run scan along a line determined by present position used as start point and end point. Optionally, also follow some trajectory in z (e.g. for lift mode operation).

The following parameters should be set:

xto (double), the end x position
yto (double), the end y position
regime (string): linear/smooth/sine
n (integer): number of data points to store
z (array of doubles with n data points): z values to be used for scan line when feedback is off. If this is missing, or feedback is on, no z motion is done.

Function checks and eventually reallocates the storage, calculates the x and y positions to stored data in regularly spaced data points (even if a sine pattern is used) and starts scanning and collecting data. Data points are stored internally and can be requested by the get_scan_data function. As the data points are corresponding to an equally sampled line profile, users could in future omit requesting the x and y values if a regular raster scan is supposed to be created, however these values are still stored internally and now sent for compatibility reasons.


run_scan_script: run Lua script to control scan and data points storage.

The following parameters can be set:

n (int): maximum number of data points to allocate for scanned data
script (string): script to perform the scan

More details can be found in the Lua scripting description.


set_script_param: add or change value of an entry to key-value table that can be read from Lua script.

The following parameters can be set:

key (string): the key to find the value in the table
value (double): the value

More details can be found in the Lua scripting description. At present up to 50 key/value pairs can be used.

clear_script_params: remove all the entries in the key-value table Function has no parameters. More details can be found in the Lua scripting description.


stop_scan: stop scan immediately. This function stops the scan and leaves the tip where it was at that moment. It does not alter the status of any of the control parameters including the feedback loop. Scanned data can be still retrieved, until the next scan command is entered.


pause_scan: pause or resume scan.

The following parameters can be set:

pause (boolean): pause (true) or run again (false)

This function pauses the scan and leaves the tip where it was at that moment. It does not alter the status of any of the control parameters including the feedback loop. Scanned data can be still retrieved, until the next scan command is entered. When the pause is cancelled, the scan continues. This function should not replace command stop_scan if we want to really stop, as pausing scan does not do any cleanup and scan status is still preserved as running.


Messages to ramp something

To collect a dependence of some quantity on another quantity in a single scan point, the ramp set of commands can be used. Ramp means that one of the quantities is going towards peak value and then back, potentially with some wait times between and behaviour of other quantities is monitored. Ramp can be realised via different quantities (z piezo, tip bias, etc.), providing different spectroscopy options (force-distance, tunnelling current, etc.). To set up the parameters of the ramp the set_ramp command is used. A single ramp is then run by run_ramp command. To get the last ramp values the get_ramp_data command is used, which returns all the ramp data obtained so far. Next ramp clears the data buffer. During ramp data acquisition all available channels are stored. The client can choose which should be passed back within the get_ramp_data command.

set_ramp_storage: set which additional channels should be stored internally during ramp acquisition. By default, all the available channels are stored, which is slow and mostly unnecessary. This function limits the storage to only what is needed and in this way speeds up everything. XYZ positions and error signal are always stored. The function clears the so far measured data and previously set storage parameters. Some of the channels can be duplicated, depending on the feedback regime - e.g. the error signal will be equal to amplitude in the amplitude based tapping mode.

The following parameters can be set to be acquired:

a1 (boolean): on/off, amplitude of primary lock-in signal
p1 (boolean): on/off, phase of primary lock-in signal
a2 (boolean): on/off, amplitude of secondary lock-in signal
p2 (boolean): on/off, phase of secondary lock-in signal
in1 (boolean): on/off, auxiliary ADC analog input 1
.
.
.
in16 (boolean): on/off, auxiliary ADC analog input 16
fmdrive (boolean): drive amplitude of the FM signal
kpfm (boolean): KPFM result
dart (boolean): DART result
l1x (boolean): primary lock-in x component
l1y (boolean): primary lock-in y component
l2x (boolean): secondary lock-in x component
l2y (boolean): secondary lock-in y component


run_ramp: run a single ramp

The following parameters can be set:

quantity: z/out1/out2/…/time , the quantity that will be ramped
from (double): the ramp quantity start value, in real units
to (double): the ramp quantity peak value, in real units
start_delay (double): in seconds, time before ramp start
peak_delay (double): in seconds, time at peak position
time_up (double): in seconds, how long the way up should last
time_down (double): in seconds, how long the way down should last
n (double): number of points in the ramp half-period (from start to peak), the number going up and down is equal

If z is the ramp quantity, it refers to the actual z position in the feedback, the feedback is stopped for the ramp and then restored again.


stop_ramp: stop ramp immediately. This function stops the ramp and returns to the state before the ramp was issued. Measured data can still be retrieved, until the next scan command is entered.


get_ramp_ndata: get information about the scanned and stored data The following parameters are returned:

n (integer): number of scanned data points from beginning of the scan command.


get_ramp_data: Function returns ramp arrays in the specified order and number of data points in them (ndata). The behaviour is the same as for the get_scan_data function. Array `q` is the ramped quantity regardless it might or might not be also in some of the other fields.


Messages to stream data

Data streaming is a way how to quickly collect data from simultaneously sampled AD converters (plus from some other channels that are however not simulatenously sampled with them). When streaming is set, server collects data at every step of the internal timer loop and provides them as results. This regime is not intended to be used together with scanning or ramping, however it can be used in a special case when scanning is performed using external sources, e.g. signal generators in high-speed SPM.

set_stream_storage: set which channels should be stored internally during streaming regime. In contrast to other regimes, user has to supply all the channels, so nothing would be streamed if no selection is done. The names of the channels are same as for all the other storage commands.


run_stream: allocates streaming data and starts streaming. The following parameter has to be set:

n (integer): number of data points to allocate for streaming


stop_stream: stops streaming


get_stream_data: function returns all the unsent data, together with their span in the allocated array (from, to). In contrast to other data passing functions it does not take the range as arguments, it remembers the last data sent and sends all the unsent data.