Lab-Zhinst/lib/Lab/Zhinst.pm
=head1 NAME
Lab::Zhinst - Perl bindings to the LabOne API of Zurich Instruments
=head1 SYNOPSIS
use Lab::Zhinst;
####################################################
# LabOne's "Getting Started" example in Perl:
# Create connection object
my ($rv, $connection) = Lab::Zhinst->Init();
if ($rv) {
# handle error ...
}
# Connect to DataServer at localhost, port 8004.
($rv) = $connection->Connect("localhost", 8004);
# Set all demodulator rates of device dev1046 to 150 Hz.
my ($rv) = $connection->SetValueD("/dev1046/demods/*/rate", 150);
####################################################
# Read x and y value from the Lock-In demodulator:
my $device = "/dev3281";
my ($rv, $hash_ref) = $connection->GetDemodSample("$device/DEMODS/0/SAMPLE");
printf("x = %g, y = %g\n", $hash_ref->{x}, $hash_ref->{y});
=head1 INSTALLATION
=head2 Linux
=over
=item *
Download the LabOne API for Linux from L<https://www.zhinst.com>.
=item *
After unpacking, copy the header F<API/C/include/ziAPI.h> and the library
F<API/C/lib/ziAPI-linux64.so> into directories searched by the compiler and
linker (e.g. /usr/local/include and /usr/local/lib).
=item *
Use your favourite cpan client to install Lab::Zhinst.
=back
=head3 Non-root installation in home directory
you will need something like e.g. L<local::lib>,
L<plenv|https://github.com/tokuhirom/plenv> or
L<perlbrew|https://perlbrew.pl/>.
Add the directory which contains the shared library to the B<LIBRARY_PATH> and
B<LD_LIBRARY_PATH> environment variables and add the directory which contains
the header F<ziAPI.h> to the B<CPATH> environment variable.
You can then install Lab::Zhinst with your favourite cpan client.
See our L<Travis CI build
file|https://github.com/lab-measurement/Lab-Zhinst/blob/master/.travis.yml>
for the exact list of needed commands.
=head2 Windows
=over
=item *
For StrawberryPerl, version 5.26 or newer is required.
Especially with 64-bit StrawberryPerl it is currently not possible to use earlier versions (see L<https://rt.cpan.org/Public/Bug/Display.html?id=121219>).
=item *
Download and install the LabOne API for Windows (MSI installer).
=item *
Make sure that the library directory
F<C:\Program Files\Zurich Instruments\LabOne\API\C\lib> is included in the PATH
environment variable. Otherwise loading the dynamic library F<Zhinst.xs.dll>
will fail.
=item *
Use your favourite cpan client to install Lab::Zhinst.
=back
=head1 API CONSIDERATIONS
The API provided by this module is basically a one-one mapping of the LabOne
C API to Perl5.
For full semantics of the various library functions, we refer to the
L<LabOne manual|https://www.zhinst.com/manuals/programming>.
=head2 Object orientation
Most ziAPI functions receive a ZIConnection as their first argument. The C<Init>
method of this library will create a ZIConnection object and bless it into the
Lab::Zhinst class. Most library functions are then called on this Lab::Zhinst
object.
=head2 Return values and error handling
Most ziAPI functions return an error code. The Perl functions return lists,
where the first element is the error code:
my ($error_code, $first_return_value, $second_return_value) = $connection->foobar(@arguments);
The return values are only valid if C<$error_code> is 0.
=head1 FUNCTIONS/METHODS
All non-methods are exported by default.
=head2 Connecting to Data Server
=head3 Init
my ($rv, $connection) = Lab::Zhinst->Init();
Return Lab::Zhinst object. Automatically call C<ziAPIDestroy> on C<$connection>
when it goes out of scope.
=head3 Connect
my ($rv) = $connection->Connect($hostname, $port);
=head3 Disconnect
my ($rv) = $connection->Disconnect();
=head3 ziAPIListImplementations
my ($rv, $implementations) = ziAPIListImplementations();
=head3 GetConnectionAPILevel
my ($rv, $level) = $connection->GetConnectionAPILevel();
=head2 Tree
=head3 ListNodes
my ($rv, $nodes) = $connection->ListNodes($path, $bufferSize, $flags);
C<$flags> has to be bitwise or of ZI_LIST_NODES_NONE, ZI_LIST_NODES_RECURSIVE,
ZI_LIST_NODES_ABSOLUTE, ZI_LIST_NODES_LEAFSONLY, ZI_LIST_NODES_SETTINGSONLY.
=head2 Set and Get Parameters
=head3 GetValueD
my ($rv, $double) = $connection->GetValueD($path);
=head3 GetValueI
my ($rv, $integer) = $connection->GetValueI($path);
=head3 GetDemodSample
my ($rv, $hash_ref) = $connection->GetDemodSample($path);
# keys: timeStamp, x, y, frequency, phase, dioBits, trigger, auxIn0, auxIn1
=head3 GetDIOSample
my ($rv, $hash_ref) = $connection->GetDIOSample($path);
# keys: timeStamp, bits, reserved
=head3 GetAuxInSample
my ($rv, $hash_ref) = $connection->GetAuxInSample($path);
# keys: timeStamp, ch0, ch1
=head3 GetValueB
my ($rv, $byte_string) = $connection->GetValueB($path, $bufferSize);
=head3 SetValueD
my ($rv) = $connection->SetValueD($path, $double);
=head3 SetValueI
my ($rv) = $connection->SetValueI($path, $integer);
=head3 SetValueB
my ($rv) = $connection->SetValueB($path, $byte_string);
=head3 SyncSetValueD
my ($rv, $set_value) = $connection->SyncSetValueD($path, $double);
=head3 SyncSetValueI
my ($rv, $set_value) = $connection->SyncSetValueI($path, $integer);
=head3 SyncSetValueB
my ($rv, $set_value) = $connection->SyncSetValueB($path, $byte_array);
=head3 Sync
my ($rv) = $connection->Sync();
=head3 EchoDevice
my ($rv) = $connection->EchoDevice($device_serial);
=head2 Data Streaming
=head3 ziAPIAllocateEventEx
my ($event) = ziAPIAllocateEventEx();
Return Lab::Zhinst::ZIEvent object or undef on error.
C<ziAPIDeallocateEventEx> will be called on C<$event> when it goes out of
scope.
=head3 Subscribe
my ($rv) = $connection->Subscribe($path);
=head3 UnSubscribe
my ($rv) = $connection->UnSubscribe($path);
=head3 PollDataEx
my ($rv, $data) = $connection->PollDataEx($event, $timeout_milliseconds);
C<$data> holds a hashref representing a 'struct ZIEvent'. It has the following
structure:
$data = {
valueType => $valueType,
count => $count,
path => $path,
values => [@values],
};
For scalar data like ZIDoubleData, the elements of C<@values> are scalars. For
Samples (Demod, AuxIn, DIO, Impedance, ...) the elements are hashrefs.
=head3 GetValueAsPollData
my ($rv) = $connection->GetValueAsPollData($path);
=head2 Error Handling and Logging in the LabOne C API
=head3 ziAPIGetError
my ($rv, $error_string) = ziAPIGetError($result);
=head3 GetLastError
my ($rv, $error_string) = $connection->GetLastError($bufferSize);
=head3 ziAPISetDebugLevel
ziAPISetDebugLevel($level);
=head3 ziAPIWriteDebugLog
ziAPIWriteDebugLog($level, $message);
=head2 Device discovery
=head3 DiscoveryFind
my ($rv, $device_id) = $connection->DiscoveryFind($device_address);
=head3 DiscoveryGet
my ($rv, $json) = $connection->DiscoveryGet($device_id);
=head1 REPORTING BUGS
Please report bugs at L<https://github.com/lab-measurement/Lab-Zhinst/issues>.
=head1 CONTACT
Feel free to contact us at
=over
=item * The #labmeasurement channel on Freenode IRC.
=item * Our L<mailing list|https://www-mailman.uni-regensburg.de/mailman/listinfo/lab-measurement-users>.
=back
=head1 SEE ALSO
=over
=item * L<Blog post on Lab::Zhinst|http://blogs.perl.org/users/simon_reinhardt/2017/04/test.html>
=item * L<Lab::Measurement>
=item * L<USB::TMC>
=item * L<Lab::VXI11>
=item * L<Lab::VISA>
=back
=head1 AUTHOR
Simon Reinhardt, E<lt>simon.reinhardt@physik.uni-regensburg.deE<gt>
=head1 COPYRIGHT AND LICENSE
The following license only covers the perl front end to LabOne. LabOne uses
different licensing terms, and needs to be installed separately by the user.
Copyright (C) 2017 by Simon Reinhardt
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.24.0 or,
at your option, any later version of Perl 5 you may have available.
=cut
package Lab::Zhinst;
use strict;
use warnings;
use Carp;
require Exporter;
use AutoLoader;
our $VERSION = '2.04';
our @ISA = qw(Exporter);
our @EXPORT = qw(
ziAPIListImplementations
ziAPIAllocateEventEx
ziAPIGetError
ziAPISetDebugLevel
ziAPIWriteDebugLog
MAX_EVENT_SIZE
MAX_NAME_LEN
MAX_PATH_LEN
TREE_ACTION_ADD
TREE_ACTION_CHANGE
ZI_API_VERSION_0
ZI_API_VERSION_1
ZI_API_VERSION_4
ZI_API_VERSION_5
ZI_COMMAND
ZI_CONNECTION
ZI_DATA_AUXINSAMPLE
ZI_DATA_BYTEARRAY
ZI_DATA_DEMODSAMPLE
ZI_DATA_DIOSAMPLE
ZI_DATA_DOUBLE
ZI_DATA_INTEGER
ZI_DATA_NONE
ZI_DATA_SCOPEWAVE
ZI_DATA_TREE_CHANGED
ZI_DUPLICATE
ZI_ERROR
ZI_ERROR_BASE
ZI_ERROR_COMMAND
ZI_ERROR_CONNECTION
ZI_ERROR_DEVICE_CONNECTION_TIMEOUT
ZI_ERROR_DEVICE_DIFFERENT_INTERFACE
ZI_ERROR_DEVICE_INTERFACE
ZI_ERROR_DEVICE_IN_USE
ZI_ERROR_DEVICE_NEEDS_FW_UPGRADE
ZI_ERROR_DEVICE_NOT_FOUND
ZI_ERROR_DEVICE_NOT_VISIBLE
ZI_ERROR_DUPLICATE
ZI_ERROR_FILE
ZI_ERROR_GENERAL
ZI_ERROR_HOSTNAME
ZI_ERROR_LENGTH
ZI_ERROR_MALLOC
ZI_ERROR_MAX
ZI_ERROR_MUTEX_DESTROY
ZI_ERROR_MUTEX_INIT
ZI_ERROR_MUTEX_LOCK
ZI_ERROR_MUTEX_UNLOCK
ZI_ERROR_NOT_SUPPORTED
ZI_ERROR_READONLY
ZI_ERROR_SERVER_INTERNAL
ZI_ERROR_SOCKET_CONNECT
ZI_ERROR_SOCKET_INIT
ZI_ERROR_THREAD_JOIN
ZI_ERROR_THREAD_START
ZI_ERROR_TIMEOUT
ZI_ERROR_TOO_MANY_CONNECTIONS
ZI_ERROR_USB
ZI_ERROR_ZIEVENT_DATATYPE_MISMATCH
ZI_FILE
ZI_HOSTNAME
ZI_IMP_FLAGS_AUTORANGE_GATING
ZI_IMP_FLAGS_BWC_BIT0
ZI_IMP_FLAGS_BWC_BIT1
ZI_IMP_FLAGS_BWC_BIT2
ZI_IMP_FLAGS_BWC_BIT3
ZI_IMP_FLAGS_BWC_MASK
ZI_IMP_FLAGS_FREQLIMIT_RANGE_CURRENT
ZI_IMP_FLAGS_FREQLIMIT_RANGE_VOLTAGE
ZI_IMP_FLAGS_FREQ_EXACT
ZI_IMP_FLAGS_FREQ_EXTRAPOLATION
ZI_IMP_FLAGS_FREQ_INTERPOLATION
ZI_IMP_FLAGS_NEGATIVE_QFACTOR
ZI_IMP_FLAGS_NONE
ZI_IMP_FLAGS_OPEN_DETECTION
ZI_IMP_FLAGS_OVERFLOW_CURRENT
ZI_IMP_FLAGS_OVERFLOW_VOLTAGE
ZI_IMP_FLAGS_STRONGCOMPENSATION_PARAM0
ZI_IMP_FLAGS_STRONGCOMPENSATION_PARAM1
ZI_IMP_FLAGS_SUPPRESSION_PARAM0
ZI_IMP_FLAGS_SUPPRESSION_PARAM1
ZI_IMP_FLAGS_UNDERFLOW_CURRENT
ZI_IMP_FLAGS_UNDERFLOW_VOLTAGE
ZI_IMP_FLAGS_VALID_INTERNAL
ZI_IMP_FLAGS_VALID_USER
ZI_INFO_BASE
ZI_INFO_MAX
ZI_INFO_SUCCESS
ZI_LENGTH
ZI_LIST_ABSOLUTE
ZI_LIST_LEAFSONLY
ZI_LIST_NODES_ABSOLUTE
ZI_LIST_NODES_LEAFSONLY
ZI_LIST_NODES_NONE
ZI_LIST_NODES_RECURSIVE
ZI_LIST_NODES_SETTINGSONLY
ZI_LIST_NONE
ZI_LIST_RECURSIVE
ZI_LIST_SETTINGSONLY
ZI_MALLOC
ZI_MAX_ERROR
ZI_MAX_INFO
ZI_MAX_WARNING
ZI_MUTEX_DESTROY
ZI_MUTEX_INIT
ZI_MUTEX_LOCK
ZI_MUTEX_UNLOCK
ZI_NOTFOUND
ZI_OVERFLOW
ZI_READONLY
ZI_SERVER_INTERNAL
ZI_SOCKET_CONNECT
ZI_SOCKET_INIT
ZI_SUCCESS
ZI_THREAD_JOIN
ZI_THREAD_START
ZI_TIMEOUT
ZI_TREE_ACTION_ADD
ZI_TREE_ACTION_CHANGE
ZI_TREE_ACTION_REMOVE
ZI_UNDERRUN
ZI_USB
ZI_VALUE_TYPE_ADVISOR_WAVE
ZI_VALUE_TYPE_ASYNC_REPLY
ZI_VALUE_TYPE_AUXIN_SAMPLE
ZI_VALUE_TYPE_BYTE_ARRAY
ZI_VALUE_TYPE_BYTE_ARRAY_TS
ZI_VALUE_TYPE_CNT_SAMPLE
ZI_VALUE_TYPE_DEMOD_SAMPLE
ZI_VALUE_TYPE_DIO_SAMPLE
ZI_VALUE_TYPE_DOUBLE_DATA
ZI_VALUE_TYPE_DOUBLE_DATA_TS
ZI_VALUE_TYPE_IMPEDANCE_SAMPLE
ZI_VALUE_TYPE_INTEGER_DATA
ZI_VALUE_TYPE_INTEGER_DATA_TS
ZI_VALUE_TYPE_NONE
ZI_VALUE_TYPE_PWA_WAVE
ZI_VALUE_TYPE_SCOPE_WAVE
ZI_VALUE_TYPE_SCOPE_WAVE_EX
ZI_VALUE_TYPE_SCOPE_WAVE_OLD
ZI_VALUE_TYPE_SPECTRUM_WAVE
ZI_VALUE_TYPE_SWEEPER_WAVE
ZI_VALUE_TYPE_TREE_CHANGE_DATA
ZI_VALUE_TYPE_TREE_CHANGE_DATA_OLD
ZI_VALUE_TYPE_VECTOR_DATA
ZI_VECTOR_ELEMENT_TYPE_ASCIIZ
ZI_VECTOR_ELEMENT_TYPE_DOUBLE
ZI_VECTOR_ELEMENT_TYPE_FLOAT
ZI_VECTOR_ELEMENT_TYPE_UINT16
ZI_VECTOR_ELEMENT_TYPE_UINT32
ZI_VECTOR_ELEMENT_TYPE_UINT64
ZI_VECTOR_ELEMENT_TYPE_UINT8
ZI_WARNING
ZI_WARNING_BASE
ZI_WARNING_GENERAL
ZI_WARNING_MAX
ZI_WARNING_NOTFOUND
ZI_WARNING_NO_ASYNC
ZI_WARNING_OVERFLOW
ZI_WARNING_UNDERRUN
);
sub AUTOLOAD {
# This AUTOLOAD is used to 'autoload' constants from the constant()
# XS function.
my $constname;
our $AUTOLOAD;
($constname = $AUTOLOAD) =~ s/.*:://;
croak "&Lab::Zhinst::constant not defined" if $constname eq 'constant';
my ($error, $val) = constant($constname);
if ($error) { croak $error; }
{
no strict 'refs';
# Fixed between 5.005_53 and 5.005_61
#XXX if ($] >= 5.00561) {
#XXX *$AUTOLOAD = sub () { $val };
#XXX }
#XXX else {
*$AUTOLOAD = sub { $val };
#XXX }
}
goto &$AUTOLOAD;
}
require XSLoader;
XSLoader::load('Lab::Zhinst', $Lab::Zhinst::VERSION);
1;
__END__