—package
Lab::Moose::Instrument::Keithley2450;
$Lab::Moose::Instrument::Keithley2450::VERSION
=
'3.930'
;
#ABSTRACT: Keithley 2450 voltage/current sourcemeter.
use
v5.20;
use
Moose;
qw/validated_getter validated_setter setter_params/
;
use
Carp;
use
namespace::autoclean;
around
default_connection_options
=>
sub
{
my
$orig
=
shift
;
my
$self
=
shift
;
my
$options
=
$self
->
$orig
();
my
$usb_opts
= {
vid
=> 0x05e6,
pid
=> 0x2450 };
# FIXME
$options
->{USB} =
$usb_opts
;
$options
->{
'VISA::USB'
} =
$usb_opts
;
return
$options
;
};
has
[
qw/max_units_per_second max_units_per_step min_units max_units/
] =>
(
is
=>
'ro'
,
isa
=>
'Num'
,
required
=> 1 );
has
source_level_timestamp
=> (
is
=>
'rw'
,
isa
=>
'Num'
,
init_arg
=>
undef
,
);
has
verbose
=> (
is
=>
'ro'
,
isa
=>
'Bool'
,
default
=> 1
);
sub
BUILD {
my
$self
=
shift
;
$self
->clear();
$self
->cls();
}
sub
set_level {
my
(
$self
,
$value
,
%args
) = validated_setter(
\
@_
,
value
=> {
isa
=>
'Num'
},
);
return
$self
->linear_step_sweep(
to
=>
$value
,
verbose
=>
$self
->verbose,
%args
);
}
sub
get_value {
my
(
$self
,
%args
) = validated_getter( \
@_
);
return
$self
->query(
command
=>
'READ?'
,
%args
);
}
sub
source_limit {
my
(
$self
,
$value
,
%args
) = validated_setter(
\
@_
,
value
=> {
isa
=>
'Num'
},
);
my
$func
=
$self
->cached_source_function();
my
$lim_func
;
if
(
$func
eq
'VOLT'
) {
$lim_func
=
'I'
;
}
elsif
(
$func
eq
'CURR'
) {
$lim_func
=
'V'
;
}
else
{
croak(
"unknown source function $func (must one of VOLT or CURR)"
);
}
$self
->
write
(
command
=>
"SOUR:${func}:${lim_func}LIM $value"
,
%args
);
}
sub
source_limit_query {
my
(
$self
,
%args
) = validated_getter( \
@_
);
my
$func
=
$self
->cached_source_function();
my
$lim_func
;
if
(
$func
eq
'VOLT'
) {
$lim_func
=
'I'
;
}
elsif
(
$func
eq
'CURR'
) {
$lim_func
=
'V'
;
}
else
{
croak(
"unknown source function $func (must one of VOLT or CURR)"
);
}
return
$self
->query(
command
=>
"SOUR:${func}:${lim_func}LIM?"
,
%args
);
}
#
# Aliases for Lab::XPRESS::Sweep API
#
sub
cached_level {
my
$self
=
shift
;
return
$self
->cached_source_level(
@_
);
}
sub
get_level {
my
$self
=
shift
;
return
$self
->source_level_query(
@_
);
}
sub
set_voltage {
my
$self
=
shift
;
my
$value
=
shift
;
return
$self
->set_level(
value
=>
$value
);
}
with
qw(
Lab::Moose::Instrument::SCPI::Output::State
Lab::Moose::Instrument::SCPI::Sense::Function
Lab::Moose::Instrument::SCPI::Sense::Range
Lab::Moose::Instrument::SCPI::Sense::NPLC
Lab::Moose::Instrument::SCPI::Source::Function
Lab::Moose::Instrument::SCPI::Source::Level
Lab::Moose::Instrument::SCPI::Source::Range
Lab::Moose::Instrument::LinearStepSweep
)
;
__PACKAGE__->meta()->make_immutable();
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Lab::Moose::Instrument::Keithley2450 - Keithley 2450 voltage/current sourcemeter.
=head1 VERSION
version 3.930
=head1 SYNOPSIS
use Lab::Moose;
my $smu = instrument(
type => 'Keithley2450',
connection_type => 'LinuxGPIB',
connection_options => {gpib_address => 15},
# mandatory protection settings
max_units_per_step => 0.001, # max step is 1mV/1mA
max_units_per_second => 0.01,
min_units => -10,
max_units => 10,
);
### Sourcing
# Source voltage
$smu->source_function(value => 'VOLT');
$smu->source_range(value => 210);
# Step-sweep to new level.
# Stepsize and speed is given by (max|min)_units* settings.
$smu->set_level(value => 9);
# Get current level from device cache (without sending a query to the
# instrument):
my $level = $smu->cached_level();
### Measurement
# Measure current
$smu->sense_function(value => 'CURR');
$smu->sense_nplc(value => 2);
# Get value of current
my $current = $smu->get_value();
=head1 METHODS
Used roles:
=over
=item L<Lab::Moose::Instrument::Common>
=item L<Lab::Moose::Instrument::SCPI::Output::State>
=item L<Lab::Moose::Instrument::SCPI::Sense::Range>
=item L<Lab::Moose::Instrument::SCPI::Sense::NPLC>
=item L<Lab::Moose::Instrument::SCPI::Source::Function>
=item L<Lab::Moose::Instrument::SCPI::Source::Level>
=item L<Lab::Moose::Instrument::SCPI::Source::Range>
=item L<Lab::Moose::Instrument::LinearStepSweep>
=back
=head2 set_level
$smu->set_level(value => $new_level);
Go to new level. Sweep with multiple steps if the distance between current and
new level is larger than C<max_units_per_step>.
=head2 get_value
my $value = $smu->get_value();
Perform measurement of value defined by C<sense_function>.
=head2 source_limit/source_limit_query
Set current compliance limit of voltage source to 1mA
$smu->source_function(value => 'VOLT');
$smu->source_limit(value => 1e-3);
Set voltage compliance limit of current source to 1V
$smu->source_function(value => 'CURR');
$smu->source_limit(value => 1);
Get current source limit
my $limit = $smu->source_limit_query();
=head2 cached_level
my $current_level = $smu->cached_level();
Get current value from device cache.
=head2 get_level
my $current_level = $smu->get_level();
Query current level.
=head2 set_voltage
$smu->set_voltage($value);
For XPRESS voltage sweep. Equivalent to C<< set_level(value => $value) >>.
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2025 by the Lab::Measurement team; in detail:
Copyright 2021 Simon Reinhardt
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut