File Coverage

blib/lib/Lab/Moose/Instrument/YokogawaGS200.pm
Criterion Covered Total %
statement 40 103 38.8
branch 1 18 5.5
condition n/a
subroutine 15 22 68.1
pod 7 15 46.6
total 63 158 39.8


line stmt bran cond sub pod time code
1             package Lab::Moose::Instrument::YokogawaGS200;
2             $Lab::Moose::Instrument::YokogawaGS200::VERSION = '3.881';
3             #ABSTRACT: YokogawaGS200 voltage/current source.
4              
5 2     2   2988 use v5.20;
  2         11  
6              
7              
8 2     2   24 use Moose;
  2         4  
  2         21  
9 2     2   15727 use MooseX::Params::Validate;
  2         5  
  2         24  
10             use Lab::Moose::Instrument
11 2     2   1015 qw/validated_getter validated_setter setter_params/;
  2         5  
  2         138  
12 2     2   576 use Lab::Moose::Instrument::Cache;
  2         5  
  2         15  
13 2     2   1360 use Carp;
  2         5  
  2         153  
14 2     2   16 use namespace::autoclean;
  2         4  
  2         25  
15              
16             extends 'Lab::Moose::Instrument';
17              
18             around default_connection_options => sub {
19             my $orig = shift;
20             my $self = shift;
21             my $options = $self->$orig();
22             my $usb_opts = { vid => 0x0b21, pid => 0x0039 };
23             $options->{USB} = $usb_opts;
24             $options->{'VISA::USB'} = $usb_opts;
25             return $options;
26             };
27              
28             has [qw/max_units_per_second max_units_per_step min_units max_units/] =>
29             ( is => 'ro', isa => 'Num', required => 1 );
30              
31             has source_level_timestamp => (
32             is => 'rw',
33             isa => 'Num',
34             init_arg => undef,
35             );
36              
37             has verbose => (
38             is => 'ro',
39             isa => 'Bool',
40             default => 1
41             );
42              
43             sub BUILD {
44 1     1 0 3 my $self = shift;
45              
46             #
47              
48             # with USB-TMC, clear results in this error:
49             # error in libusb_control_transfer_write: Pipe error at /home/simon/.plenv/versions/5.24.0/lib/perl5/site_perl/5.24.0/x86_64-linux/USB/LibUSB/Device/Handle.pm line 22.
50             # apparently in USB::TMC::clear_feature_endpoint_out
51 1 50       29 if ( $self->connection_type eq 'USB' ) {
52 0         0 $self->clear( yoko => 1 );
53             }
54             else {
55 1         11 $self->clear();
56             }
57 1         7 $self->cls();
58             }
59              
60              
61             # The Source:Range commands are NOT SCPI compliant, as they do not include
62             # the Source:Function, like in SOUR:VOLT:RANG
63              
64              
65             cache source_range => ( getter => 'source_range_query' );
66              
67             sub source_range_query {
68 4     4 1 2105 my ( $self, %args ) = validated_getter( \@_ );
69              
70 4         2039 return $self->cached_source_range(
71             $self->query( command => "SOUR:RANG?", %args ) );
72             }
73              
74             sub source_range {
75 4     4 1 7231 my ( $self, $value, %args ) = validated_setter(
76             \@_,
77             );
78              
79 4         26 $self->write( command => "SOUR:RANG $value", %args );
80              
81 4         21 $self->cached_source_range($value);
82             }
83              
84             cache source_level => ( getter => 'source_level_query' );
85              
86             sub source_level_query {
87 4     4 0 1649 my ( $self, %args ) = validated_getter( \@_ );
88              
89 4         2016 return $self->cached_source_level(
90             $self->query( command => ":SOUR:LEV?", %args ) );
91             }
92              
93             sub source_level {
94 17     17 0 8976 my ( $self, $value, %args ) = validated_setter(
95             \@_,
96             value => { isa => 'Num' }
97             );
98              
99 17         207 $self->write(
100             command => sprintf( "SOUR:LEV %.15g", $value ),
101             %args
102             );
103 17         80 $self->cached_source_level($value);
104             }
105              
106              
107             sub set_level {
108 1     1 1 18 my ( $self, $value, %args ) = validated_setter(
109             \@_,
110             value => { isa => 'Num' },
111             );
112              
113 1         43 return $self->linear_step_sweep(
114             to => $value, verbose => $self->verbose,
115             %args
116             );
117             }
118              
119             #
120             # Aliases for Lab::XPRESS::Sweep API
121             #
122              
123              
124             sub cached_level {
125 1     1 1 8 my $self = shift;
126 1         4 return $self->cached_source_level(@_);
127             }
128              
129              
130             sub get_level {
131 1     1 1 4 my $self = shift;
132 1         5 return $self->source_level_query(@_);
133             }
134              
135              
136             sub set_voltage {
137 0     0 1   my $self = shift;
138 0           my $value = shift;
139 0           return $self->set_level( value => $value );
140             }
141              
142             sub config_sweep {
143 0     0 0   my ( $self, %args ) = validated_getter(
144             \@_,
145             point => { isa => 'Num' },
146             rate => { isa => 'Num' },
147             );
148              
149 0           my $target = delete $args{point};
150 0           my $rate = delete $args{rate};
151              
152 0           $self->cls(%args);
153              
154             # Enforce limits
155 0           $self->check_max_and_min($target);
156 0           my $max_rate = $self->max_units_per_second;
157 0 0         if ( $rate > $max_rate ) {
158 0           croak "Sweep rate $rate exceeds max_untis_per_second ($max_rate)";
159             }
160              
161 0           my $current_level = $self->get_level();
162 0           my $time = abs( ( $target - $current_level ) / $rate );
163 0 0         if ( $time < 0.1 ) {
164 0           carp "sweep time < 0.1 seconds; adjusting to 0.1 seconds";
165 0           $time = 0.1;
166             }
167 0 0         if ( $time > 3600 ) {
168 0           croak "sweep time needs to be <= 3600 seconds";
169             }
170              
171 0           $self->write( command => 'PROG:REP 0', %args );
172 0           $self->write( command => sprintf( 'PROG:INT %.17g', $time ), %args );
173 0           $self->write( command => sprintf( 'PROG:SLOP %.17g', $time ), %args );
174              
175 0           $self->write( command => 'PROG:EDIT:STAR', %args );
176              
177             # do not use 'source_level', no caching needed here
178 0           $self->write( command => sprintf( "SOUR:LEV %.15g", $target ), %args );
179 0           $self->write( command => 'PROG:EDIT:END', %args );
180             }
181              
182             sub wait {
183 0     0 0   my ( $self, %args ) = validated_getter(
184             \@_,
185             );
186 0           my $verbose = $self->verbose;
187 0           my $autoflush = STDOUT->autoflush();
188              
189 0           while (1) {
190 0 0         if ($verbose) {
191 0           my $level = $self->get_level(%args);
192 0           printf( "Level: %.5e \r", $level );
193             }
194 0 0         if ( not $self->active(%args) ) {
195 0           last;
196             }
197             }
198              
199 0 0         if ($verbose) {
200 0           print " " x 70 . "\r";
201             }
202              
203             # reset autoflush to previous value
204 0           STDOUT->autoflush($autoflush);
205              
206             }
207              
208             sub active {
209 0     0 0   my ( $self, %args ) = validated_getter( \@_ );
210              
211             # Set EOP (end of program) bit in Extended Event Enable Register
212 0           $self->write( command => 'STAT:ENAB 128', %args );
213              
214 0           my $status = $self->get_status(%args);
215 0 0         if ( $status->{'EES'} == 1 ) {
216 0           return 0;
217             }
218 0           return 1;
219             }
220              
221             # return hashref
222             sub get_status {
223 0     0 0   my ( $self, %args ) = validated_getter( \@_ );
224              
225 0           my $status = int( $self->query( command => '*STB?', %args ) );
226 0           my @flags = qw/NONE EES ESB MAX NONE EAV MSS NONE/;
227 0           my $result = {};
228 0           for my $i ( 0 .. 7 ) {
229 0           my $flag = $flags[$i];
230 0           $result->{$flag} = $status & 1;
231 0           $status >>= 1;
232             }
233 0           return $result;
234             }
235              
236             sub trg {
237 0     0 0   my ( $self, %args ) = validated_getter( \@_ );
238 0           my $output = $self->query( command => 'OUTP:STAT?', %args );
239 0 0         if ( $output == 0 ) {
240 0           croak "output needs to be on before running a program";
241             }
242 0           $self->write( command => 'PROG:RUN' );
243             }
244              
245              
246             sub sweep_to_level {
247 0     0 1   my ( $self, %args ) = validated_getter(
248             \@_,
249             target => { isa => 'Num' },
250             rate => { isa => 'Num' }
251             );
252              
253 0           my $target = delete $args{target};
254 0           my $rate = delete $args{rate};
255              
256 0           $self->config_sweep( point => $target, rate => $rate, %args );
257 0           $self->trg(%args);
258 0           $self->wait(%args);
259             }
260              
261             with qw(
262             Lab::Moose::Instrument::Common
263             Lab::Moose::Instrument::SCPI::Source::Function
264             Lab::Moose::Instrument::LinearStepSweep
265             );
266              
267             __PACKAGE__->meta()->make_immutable();
268              
269             1;
270              
271             __END__
272              
273             =pod
274              
275             =encoding UTF-8
276              
277             =head1 NAME
278              
279             Lab::Moose::Instrument::YokogawaGS200 - YokogawaGS200 voltage/current source.
280              
281             =head1 VERSION
282              
283             version 3.881
284              
285             =head1 SYNOPSIS
286              
287             use Lab::Moose;
288              
289             my $yoko = instrument(
290             type => 'YokogawaGS200',
291             connection_type => 'LinuxGPIB',
292             connection_options => {gpib_address => 15},
293             # mandatory protection settings
294             max_units_per_step => 0.001, # max step is 1mV/1mA
295             max_units_per_second => 0.01,
296             min_units => -10,
297             max_units => 10,
298             );
299              
300             # Step-sweep to new level.
301             # Stepsize and speed is given by (max|min)_units* settings.
302             $yoko->set_level(value => 9);
303              
304             # Get current level from device cache (without sending a query to the
305             # instrument):
306             my $level = $yoko->cached_level();
307              
308             =head1 METHODS
309              
310             Used roles:
311              
312             =over
313              
314             =item L<Lab::Moose::Instrument::Common>
315              
316             =item L<Lab::Moose::Instrument::SCPI::Source::Function>
317              
318             =item L<Lab::Moose::Instrument::LinearStepSweep>
319              
320             =back
321              
322             =head2 source_range/source_range_query
323              
324             Set/Get the output source range.
325              
326             =head2 set_level
327              
328             $yoko->set_level(value => $new_level);
329              
330             Go to new level. Sweep with multiple steps if the distance between current and
331             new level is larger than C<max_units_per_step>.
332              
333             =head2 cached_level
334              
335             my $current_level = $yoko->cached_level();
336              
337             Get current value from device cache.
338              
339             =head2 get_level
340              
341             my $current_level = $yoko->get_level();
342              
343             Query current level.
344              
345             =head2 set_voltage
346              
347             $yoko->set_voltage($value);
348              
349             For XPRESS voltage sweep. Equivalent to C<< set_level(value => $value) >>.
350              
351             =head2 sweep_to_level
352              
353             $yoko->sweep_to_level(target => $value, rate => $rate);
354              
355             =head1 COPYRIGHT AND LICENSE
356              
357             This software is copyright (c) 2023 by the Lab::Measurement team; in detail:
358              
359             Copyright 2017-2018 Simon Reinhardt
360             2020 Andreas K. Huettel
361              
362              
363             This is free software; you can redistribute it and/or modify it under
364             the same terms as the Perl 5 programming language system itself.
365              
366             =cut