File Coverage

blib/lib/Lab/Instrument/Agilent34420A.pm
Criterion Covered Total %
statement 17 345 4.9
branch 0 172 0.0
condition 0 93 0.0
subroutine 6 38 15.7
pod 18 27 66.6
total 41 675 6.0


line stmt bran cond sub pod time code
1             package Lab::Instrument::Agilent34420A;
2             #ABSTRACT: HP/Agilent/Keysight 34420A or 34421A digital multimeter
3             $Lab::Instrument::Agilent34420A::VERSION = '3.880';
4 1     1   1904 use v5.20;
  1         4  
5              
6 1     1   7 use strict;
  1         8  
  1         21  
7 1     1   5 use Lab::Instrument;
  1         2  
  1         19  
8 1     1   4 use Lab::MultiChannelInstrument;
  1         3  
  1         21  
9 1     1   4 use Time::HiRes qw (usleep);
  1         2  
  1         8  
10 1     1   93 use Data::Dumper;
  1         2  
  1         6224  
11              
12             our @ISA = ( "Lab::MultiChannelInstrument", "Lab::Instrument" );
13              
14             our %fields = (
15             supported_connections => [ 'VISA', 'VISA_GPIB', 'GPIB', 'DEBUG' ],
16              
17             # default settings for the supported connections
18             connection_settings => {
19             gpib_board => 0,
20             gpib_address => undef,
21             timeout => 2,
22             },
23              
24             device_settings => {
25             pl_freq => 50,
26              
27             channels => {
28             Ch1 => 1,
29             Ch2 => 2
30             },
31             channel_default => 'Ch1',
32             channel => undef
33             },
34              
35             device_cache => {
36             function => undef,
37             range => undef,
38             autorange => undef,
39             nplc => undef,
40             resolution => undef,
41             value => undef,
42             channel => undef
43              
44             # TO DO: add range and resolution + get/setter
45             },
46              
47             device_cache_order => [ 'function', 'range', 'autorange', 'nplc' ],
48              
49             multichannel_shared_cache => [ 'function', 'nplc', 'channel' ],
50              
51             );
52              
53             sub new {
54 0     0 1   my $proto = shift;
55 0   0       my $class = ref($proto) || $proto;
56 0           my $self = $class->SUPER::new(@_);
57 0           $self->${ \( __PACKAGE__ . '::_construct' ) }(__PACKAGE__);
  0            
58              
59 0           return $self;
60             }
61              
62             sub _device_init {
63 0     0     my $self = shift;
64              
65 0           $self->write("InPut:FILTer:STATe OFF");
66             }
67              
68             sub get_error {
69 0     0 1   my $self = shift;
70 0           chomp( my $err = $self->query("SYSTem:ERRor?") );
71 0           my ( $err_num, $err_msg ) = split ",", $err;
72 0           $err_msg =~ s/\"//g;
73 0           my $result;
74 0           $result->{'err_num'} = $err_num;
75 0           $result->{'err_msg'} = $err_msg;
76 0           return $result;
77             }
78              
79             sub reset { # basic
80 0     0 1   my $self = shift;
81 0           $self->write("*RST");
82             }
83              
84             sub selftest {
85 0     0 0   my $self = shift;
86              
87             # internal selftest:
88             # returns 0 if passed and 1 if failed
89              
90 0           $self->write("*TST?");
91 0           usleep(10e6);
92 0           return $self->read();
93             }
94              
95             # ------------------------------- sense ---------------------------------------------------------
96              
97             sub set_function { # basic
98 0     0 1   my $self = shift;
99              
100             # any parameters given?
101 0 0         if ( not defined @_[0] ) {
102 0           print Lab::Exception::CorruptParameter->new(
103             error => "no values given in " . ref($self) . " \n" );
104 0           return;
105             }
106              
107 0           my ( $function, $tail ) = $self->_check_args( \@_, ['function'] );
108              
109             # \nAgilent 34420A:\n
110             # Expected values for function are:\n
111             # voltage:dc, voltage:dc:ratio, voltage:dc:difference, resistance or Fresistance --> to set both input channels\n
112             # sense1:voltage:dc, sense1:voltage:dc:ratio, sense1:voltage:dc:difference, sense1:resistance or sense1:Fresistance --> to set input channel 1 only\n
113             # sense2:voltage:dc, sense2:voltage:dc:ratio, sense2:voltage:dc:difference, sense2:resistance or sense2:Fresistance --> to set input channel 2 only\n
114             #
115              
116 0           $function =~ s/\s+//g; #remove all whitespaces
117 0           $function = "\L$function"
118             ; # transform all uppercase letters to lowercase letters
119              
120 0 0         return if $function eq $self->get_function( { read_mode => 'cache' } );
121              
122 0 0 0       if ( $function
123             =~ /^(voltage:dc|voltage|volt:dc|volt|voltage:dc:ratio|voltage:ratio|volt:dc:ratio|volt:ratio|voltage:dc:diff|voltage:diff|volt:dc:diff|volt:diff)$/
124             or $function =~ /^(resistance|fresistance|res|fres)$/ ) {
125 0           $function
126             = $self->write( sprintf( "FUNCTION '%s'", $function ), $tail );
127 0           $self->get_range( { channel => 1 } );
128 0 0         $self->get_range( { channel => 2 } )
129             if $function =~ /^(voltage:dc|voltage|volt:dc|volt)$/;
130 0           $self->get_nplc();
131 0           $self->get_resolution();
132             }
133             else {
134 0           Lab::Exception::CorruptParameter->throw( error =>
135             "\nAgilent 34420A:\nunexpected value for FUNCTION in sub set_function. Expected values are:\nvoltage:dc, resistance or Fresistance --> to set both input channels\nsense1:voltage:dc, sense1:voltage:dc:ratio, sense1:voltage:dc:difference, sense1:resistance or sense1:Fresistance --> to set input channel 1 only\nsense2:voltage:dc, sense2:voltage:dc:ratio, sense2:voltage:dc:difference, sense2:resistance or sense2:Fresistance --> to set input channel 2 only\n"
136             );
137             }
138              
139             }
140              
141             sub get_function {
142 0     0 0   my $self = shift;
143              
144 0           my ($tail) = $self->_check_args( \@_ );
145              
146 0           my $function = $self->query( "FUNCTION?", $tail );
147              
148 0 0         if ( $function =~ /([\w:]+)/ ) {
149 0           my $function = $1;
150 0           $function =~ s/\s+//g; #remove all whitespaces
151 0           $function = "\L$function"
152             ; # transform all uppercase letters to lowercase letters
153 0           return $function;
154             }
155              
156             }
157              
158             sub set_range { # basic
159 0     0 1   my $self = shift;
160              
161             # any parameters given?
162 0 0         if ( not defined @_[0] ) {
163 0           print Lab::Exception::CorruptParameter->new(
164             error => "no values given in " . ref($self) . " \n" );
165 0           return;
166             }
167              
168 0           my ( $range, $function, $channel, $tail )
169             = $self->_check_args( \@_, [ 'range', 'function', 'channel' ] );
170              
171 0 0         if ( not defined $channel ) {
172             $channel = $self->{channel}
173 0   0       || $self->get_channel( { read_mode => 'cache' } );
174             }
175              
176 0 0         if ( not defined $function ) {
177 0           $function = $self->get_function( { read_mode => 'cache' }, $tail );
178             }
179 0           $function =~ s/\s+//g; #remove all whitespaces
180 0           $function = "\L$function"
181             ; # transform all uppercase letters to lowercase letters
182              
183             # \nAgilent 34420A:\n
184             # Expected values for function are:\n
185             # voltage:dc, voltage:dc:ratio, voltage:dc:difference, resistance or Fresistance --> to set both input channels\n
186             # sense1:voltage:dc, sense1:voltage:dc:ratio, sense1:voltage:dc:difference, sense1:resistance or sense1:Fresistance --> to set input channel 1 only\n
187             # sense2:voltage:dc, sense2:voltage:dc:ratio, sense2:voltage:dc:difference, sense2:resistance or sense2:Fresistance --> to set input channel 2 only\n
188             #
189             # Expected values for RANGE are:\n
190             # sense1:voltage:dc --> 1mV...100V
191             # sense2:voltage:dc --> 1mV...10V
192             # resistance and Fresistance --> 1...1e6 Ohm
193              
194             # check data
195 0 0         if ( $function
    0          
196             =~ /^(voltage:dc|voltage|volt:dc|volt|voltage:dc:ratio|voltage:ratio|volt:dc:ratio|volt:ratio|voltage:dc:diff|voltage:diff|volt:dc:diff|volt:diff)$/
197             ) {
198 0 0 0       if ( $channel == 1 and abs($range) > 100 ) {
199 0           Lab::Exception::CorruptParameter->throw( error =>
200             "\nAgilent 34420A:\nunexpected value for RANGE in sub set_range. Expected values are for sense1:voltage:dc 1mV...100V and for sense2:voltage:dc 1mV...10V\n"
201             );
202             }
203 0 0 0       if ( $channel == 2 and abs($range) > 10 ) {
204 0           Lab::Exception::CorruptParameter->throw( error =>
205             "\nAgilent 34420A:\nunexpected value for RANGE in sub set_range. Expected values are for sense1:voltage:dc 1mV...100V and for sense2:voltage:dc 1mV...10V\n"
206             );
207             }
208             }
209             elsif ( $function =~ /^(resistance|fresistance|res|fres)$/ ) {
210 0 0 0       if ( $range < 0 or $range > 1e6 ) {
211 0           Lab::Exception::CorruptParameter->throw( error =>
212             "\nAgilent 34420A:\nunexpected value for RANGE in sub set_range. Expected values are for resistance and Fresistance mode 1...1e6 Ohm."
213             );
214             }
215             }
216             else {
217 0           Lab::Exception::CorruptParameter->throw( error =>
218             "\nAgilent 34420A:\nunexpected value for FUNCTION in sub set_range. Expected values are:\nvoltage:dc, voltage, volt, resistance or fresistance \n"
219             );
220             }
221              
222             # check which channel is currently
223              
224             # set range
225 0 0         if ( $range =~ /^(MIN|min|MAX|max|DEF|def)$/ ) {
    0          
226 0           $self->set_autorange( 'OFF', $function, $tail );
227 0           return $self->write(
228             sprintf( "SENSE%d:%s:RANGE %s", $channel, $function, $range ),
229             $tail
230             );
231             }
232             elsif ( $range =~ /^(AUTO|auto)$/ ) {
233 0           return $self->set_autorange( 'ON', $function, $tail );
234             }
235             else {
236              
237 0 0         return if ( $range == $self->get_range( { read_mode => 'cache' } ) );
238 0           $self->set_autorange( 'OFF', $function, $tail );
239 0           return $self->write(
240             sprintf( "SENSE%d:%s:RANGE %e", $channel, $function, $range ),
241             $tail
242             );
243             }
244              
245             }
246              
247             sub get_range {
248 0     0 0   my $self = shift;
249              
250 0           my ( $function, $channel, $tail )
251             = $self->_check_args( \@_, [ 'function', 'channel' ] );
252              
253 0 0         if ( not defined $channel ) {
254             $channel = $self->{channel}
255 0   0       || $self->get_channel( { read_mode => 'cache' } );
256             }
257              
258 0 0         if ( not defined $function ) {
259 0           $function = $self->get_function( { read_mode => 'cache' }, $tail );
260             }
261              
262 0 0 0       if (
263             not( $function
264             =~ /^(voltage:dc|voltage|volt:dc|volt|sense1:voltage:dc|sense1:voltage|sense1:volt:dc|sense1:volt|sense2:voltage:dc|sense2:voltage|sense2:volt:dc|sense2:volt|voltage:dc:ratio|voltage:ratio|volt:dc:ratio|volt:ratio|voltage:dc:diff|voltage:diff|volt:dc:diff|volt:diff)$/
265             or $function =~ /^(resistance|fresistance|res|fres)$/ )
266             ) {
267 0           Lab::Exception::CorruptParameter->throw( error =>
268             "\nAgilent 34420A:\nunexpected value for FUNCTION ($function) in sub get_nplc. Expected values are:\nvoltage:dc, resistance or Fresistance --> to set both input channels\nsense1:voltage:dc, sense1:voltage:dc:ratio, sense1:voltage:dc:difference, sense1:resistance or sense1:Fresistance --> to set input channel 1 only\nsense2:voltage:dc, sense2:voltage:dc:ratio, sense2:voltage:dc:difference, sense2:resistance or sense2:Fresistance --> to set input channel 2 only\n"
269             );
270             }
271 0 0 0       if ( $channel != 1 and $channel != 2 ) {
272 0           Lab::Exception::CorruptParameter->throw( error =>
273             "Unexpected value for channel. Allowed values are 1 or 2." );
274             }
275              
276 0           return $self->query(
277             sprintf( "SENSE%d:%s:RANGE?", $channel, $function ),
278             $tail
279             );
280              
281             }
282              
283             sub set_autorange {
284 0     0 0   my $self = shift;
285              
286             # any parameters given?
287 0 0         if ( not defined @_[0] ) {
288 0           print Lab::Exception::CorruptParameter->new(
289             error => "no values given in " . ref($self) . " \n" );
290 0           return;
291             }
292              
293 0           my ( $autorange, $function, $channel, $tail )
294             = $self->_check_args( \@_, [ 'autorange', 'function', 'channel' ] );
295              
296 0 0         if ( not defined $channel ) {
297             $channel = $self->{channel}
298 0   0       || $self->get_channel( { read_mode => 'cache' } );
299             }
300              
301 0 0         if ( not defined $function ) {
302 0           $function = $self->get_function( { read_mode => 'cache' }, $tail );
303             }
304              
305 0           $autorange =~ s/\s+//g; #remove all whitespaces
306 0           $autorange = "\U$autorange"
307             ; # transform all lowercase letters to uppercase letters
308 0 0         if ( $autorange =~ /ON|OFF/ ) {
309 0           $self->write(
310             sprintf(
311             "SENSE%d:%s:RANGE:AUTO %s",
312             $channel, $function, $autorange
313             ),
314             $tail
315             );
316             }
317             else {
318 0           print Lab::Exception::CorruptParameter->new( error =>
319             "unexpected value for AUTORANGE given in sub set_autorange ($autorange). expected values are 'ON' and 'OFF'.\n"
320             );
321 0           return;
322             }
323              
324             }
325              
326             sub get_autorange {
327 0     0 0   my $self = shift;
328              
329 0           my ( $function, $channel, $tail )
330             = $self->_check_args( \@_, [ 'function', 'channel' ] );
331              
332 0 0         if ( not defined $channel ) {
333             $channel = $self->{channel}
334 0   0       || $self->get_channel( { read_mode => 'cache' } );
335             }
336              
337 0 0         if ( not defined $function ) {
338 0           $function = $self->get_function( { read_mode => 'cache' }, $tail );
339             }
340              
341             $self->query(
342 0           sprintf( "SENSE%d:%s:RANGE:AUTO?", $channel, $function ),
343             $tail
344             );
345              
346             }
347              
348             sub set_nplc { # basic
349 0     0 1   my $self = shift;
350              
351             # any parameters given?
352 0 0         if ( not defined @_[0] ) {
353 0           print Lab::Exception::CorruptParameter->new(
354             error => "no values given in " . ref($self) . " \n" );
355 0           return;
356             }
357              
358             # Agilent 34420A:\n
359             # Expected values for function are:\n
360             # voltage:dc, voltage:dc:ratio, voltage:dc:difference, resistance or Fresistance --> to set both input channels\n
361             # sense1:voltage:dc, sense1:voltage:dc:ratio, sense1:voltage:dc:difference, sense1:resistance or sense1:Fresistance --> to set input channel 1 only\n
362             # sense2:voltage:dc, sense2:voltage:dc:ratio, sense2:voltage:dc:difference, sense2:resistance or sense2:Fresistance --> to set input channel 2 only\n
363             #
364             # Agilent 34420A:
365             # unexpected value for NPLC in sub set_nplc.
366             # Expected values are between 0.02 ... 200 power-line-cycles (50Hz).
367              
368 0           my ( $nplc, $function, $tail )
369             = $self->_check_args( \@_, [ 'nplc', 'function' ] );
370              
371 0 0         return if ( $nplc == $self->get_nplc( { read_mode => 'cache' } ) );
372              
373 0 0         if ( not defined $function ) {
374 0           $function = $self->get_function( { read_mode => 'cache' }, $tail );
375             }
376              
377 0           $function =~ s/\s+//g; #remove all whitespaces
378 0           $function = "\L$function"
379             ; # transform all uppercase letters to lowercase letters
380 0 0         if ( $function =~ /AC|ac/ ) {
381 0           warn "WARNING: cannot set nplc for "
382             . $self->get_id($tail)
383             . " in ac measurement mode.";
384 0           return;
385             }
386              
387 0 0 0       if ( $function
388             =~ /^(voltage:dc|voltage|volt:dc|volt|sense1:voltage:dc|sense1:voltage|sense1:volt:dc|sense1:volt|sense2:voltage:dc|sense2:voltage|sense2:volt:dc|sense2:volt|voltage:dc:ratio|voltage:ratio|volt:dc:ratio|volt:ratio|voltage:dc:diff|voltage:diff|volt:dc:diff|volt:diff)$/
389             or $function =~ /^(resistance|fresistance|res|fres)$/ ) {
390 0 0 0       if ( $nplc >= 0.02 and $nplc <= 200 ) #
    0          
391             {
392 0           return $self->write(
393             sprintf( "%s:NPLC %.3f", $function, $nplc ),
394             $tail
395             );
396             }
397             elsif ( $nplc =~ /^(MIN|min|MAX|max|DEF|def)$/ ) {
398 0           $self->write( sprintf( "%s:NPLC %s", $function, $nplc ), $tail );
399 0           $self->get_resolution();
400             }
401             else {
402 0           Lab::Exception::CorruptParameter->throw( error =>
403             "\nAgilent 34420A:\nunexpected value for NPLC in sub set_nplc. Expected values are between 0.02 ... 200 power-line-cycles (50Hz)."
404             );
405             }
406             }
407             else {
408 0           Lab::Exception::CorruptParameter->throw( error =>
409             "\nAgilent 34420A:\nunexpected value for FUNCTION in sub set_nplc. Expected values are:\nvoltage:dc, resistance or Fresistance --> to set both input channels\nsense1:voltage:dc, sense1:voltage:dc:ratio, sense1:voltage:dc:difference, sense1:resistance or sense1:Fresistance --> to set input channel 1 only\nsense2:voltage:dc, sense2:voltage:dc:ratio, sense2:voltage:dc:difference, sense2:resistance or sense2:Fresistance --> to set input channel 2 only\n"
410             );
411             }
412              
413             }
414              
415             sub get_nplc { # basic
416 0     0 0   my $self = shift;
417              
418 0           my ( $function, $tail ) = $self->_check_args( \@_, ['function'] );
419              
420 0 0         if ( not defined $function ) {
421 0           $function = $self->get_function( { read_mode => 'cache' } );
422             }
423              
424 0 0 0       if (
425             (
426             $function
427             =~ /^(voltage:dc|voltage|volt:dc|volt|sense1:voltage:dc|sense1:voltage|sense1:volt:dc|sense1:volt|sense2:voltage:dc|sense2:voltage|sense2:volt:dc|sense2:volt|voltage:dc:ratio|voltage:ratio|volt:dc:ratio|volt:ratio|voltage:dc:diff|voltage:diff|volt:dc:diff|volt:diff)$/
428             or $function =~ /^(resistance|fresistance|res|fres)$/
429             )
430             ) {
431 0           return $self->query( sprintf( "%s:NPLC?", $function ) );
432             }
433             else {
434 0           Lab::Exception::CorruptParameter->throw( error =>
435             "\nAgilent 34420A:\nunexpected value for FUNCTION ($function) in sub get_nplc. Expected values are:\nvoltage:dc, resistance or Fresistance --> to set both input channels\nsense1:voltage:dc, sense1:voltage:dc:ratio, sense1:voltage:dc:difference, sense1:resistance or sense1:Fresistance --> to set input channel 1 only\nsense2:voltage:dc, sense2:voltage:dc:ratio, sense2:voltage:dc:difference, sense2:resistance or sense2:Fresistance --> to set input channel 2 only\n"
436             );
437             }
438             }
439              
440             sub set_resolution { # basic
441              
442 0     0 1   my $self = shift;
443              
444             # any parameters given?
445 0 0         if ( not defined @_[0] ) {
446 0           print Lab::Exception::CorruptParameter->new(
447             error => "no values given in " . ref($self) . " \n" );
448 0           return;
449             }
450              
451             # Agilent 34420A:\n
452             # Expected values for FUNCTION are:\n
453             # voltage:dc, voltage:dc:ratio, voltage:dc:difference, resistance or Fresistance --> to set both input channels\n
454             # sense1:voltage:dc, sense1:voltage:dc:ratio, sense1:voltage:dc:difference, sense1:resistance or sense1:Fresistance --> to set input channel 1 only\n
455             # sense2:voltage:dc, sense2:voltage:dc:ratio, sense2:voltage:dc:difference, sense2:resistance or sense2:Fresistance --> to set input channel 2 only\n
456             #
457             # Agilent 34420A:
458             # unexpected value for resOLUTION
459             # Expected values are between 0.0001xRANGE ... 0.00000022xRANGE
460              
461 0           my ( $resolution, $function, $tail )
462             = $self->_check_args( \@_, [ 'resolution', 'function' ] );
463              
464             return
465             if (
466 0 0         $resolution == $self->get_resolution( { read_mode => 'cache' } ) );
467              
468 0 0         if ( not defined $function ) {
469 0           $function = $self->get_function( { read_mode => 'cache' }, $tail );
470             }
471              
472 0           $function =~ s/\s+//g; #remove all whitespaces
473 0           $function = "\L$function"
474             ; # transform all uppercase letters to lowercase letters
475 0 0         if ( $function =~ /AC|ac/ ) {
476 0           warn "WARNING: cannot set resolution for "
477             . $self->get_id()
478             . " in ac measurement mode.";
479 0           return;
480             }
481              
482             # get resolution:
483 0 0 0       if ( $function
484             =~ /^(voltage:dc|voltage|volt:dc|volt|sense1:voltage:dc|sense1:voltage|sense1:volt:dc|sense1:volt|sense2:voltage:dc|sense2:voltage|sense2:volt:dc|sense2:volt|voltage:dc:ratio|voltage:ratio|volt:dc:ratio|volt:ratio|voltage:dc:diff|voltage:diff|volt:dc:diff|volt:diff)$/
485             or $function =~ /^(resistance|fresistance|res|fres)$/ ) {
486 0           my $range
487             = $self->get_range( $function, { read_mode => 'cache' }, $tail );
488 0           $self->set_autorange( 'OFF', $function )
489             ; # switch off autorange function if activated.
490              
491 0 0 0       if ( $resolution >= 0.0001 * $range
    0          
492             and $resolution <= 0.00000022 * $range ) {
493 0           $self->write(
494             sprintf( "%s:res %.3f", $function, $resolution ),
495             $tail
496             );
497             }
498             elsif ( $resolution =~ /^(MIN|min|MAX|max|DEF|def)$/ ) {
499 0           $self->write(
500             sprintf( "%s:res %s", $function, $resolution ),
501             $tail
502             );
503             }
504             else {
505 0           Lab::Exception::CorruptParameter->throw( error =>
506             "\nAgilent 34420A:\nunexpected value for resOLUTION in sub set_resolution. Expected values are between 0.0001xRANGE ... 0.0000022xRANGE."
507             );
508             }
509 0           $self->get_nplc();
510             }
511             else {
512 0           Lab::Exception::CorruptParameter->throw( error =>
513             "\nAgilent 34420A:\nunexpected value for FUNCTION in sub set_resolution. Expected values are:\nvoltage:dc, resistance or Fresistance --> to set both input channels\nsense1:voltage:dc, sense1:voltage:dc:ratio, sense1:voltage:dc:difference, sense1:resistance or sense1:Fresistance --> to set input channel 1 only\nsense2:voltage:dc, sense2:voltage:dc:ratio, sense2:voltage:dc:difference, sense2:resistance or sense2:Fresistance --> to set input channel 2 only\n"
514             );
515             }
516              
517             }
518              
519             sub get_resolution { # basic
520 0     0 0   my $self = shift;
521              
522 0           my ( $function, $tail ) = $self->_check_args( \@_, ['function'] );
523              
524 0 0         if ( not defined $function ) {
525 0           $function = $self->get_function( { read_mode => 'cache' } );
526             }
527              
528 0 0 0       if (
529             (
530             $function
531             =~ /^(voltage:dc|voltage|volt:dc|volt|sense1:voltage:dc|sense1:voltage|sense1:volt:dc|sense1:volt|sense2:voltage:dc|sense2:voltage|sense2:volt:dc|sense2:volt|voltage:dc:ratio|voltage:ratio|volt:dc:ratio|volt:ratio|voltage:dc:diff|voltage:diff|volt:dc:diff|volt:diff)$/
532             or $function =~ /^(resistance|fresistance|res|fres)$/
533             )
534             ) {
535 0           return $self->query( sprintf( "%s:resOLUTION?", $function ), $tail );
536             }
537             }
538              
539             sub set_channel { # basic
540 0     0 1   my $self = shift;
541 0           my ( $terminal, $tail ) = $self->_check_args( \@_, ['channel'] );
542              
543 0           my $function = $self->get_function( { read_mode => 'cache' }, $tail );
544 0           $function =~ s/\s+//g; #remove all whitespaces
545 0           $function = "\L$function"
546             ; # transform all uppercase letters to lowercase letters
547              
548 0 0         if ( $function
549             =~ /(voltage:dc|voltage|volt:dc|volt|sense1:voltage:dc|sense1:voltage|sense1:volt:dc|sense1:volt|sense2:voltage:dc|sense2:voltage|sense2:volt:dc|sense2:volt)/
550             ) {
551 0 0 0       if ( $self->get_channel( { read_mode => 'cache' }, $tail )
    0          
552             == $terminal ) {
553 0           return;
554             }
555             elsif ( ( $terminal == 1 or $terminal == 2 ) ) {
556 0           $self->write(
557             sprintf( "ROUTE:TERMINALS FRONT%d", $terminal ),
558             $tail
559             );
560             }
561             else {
562 0           Lab::Exception::CorruptParameter->throw( error =>
563             "\nAgilent 34420A:\nunexpected value for CHANNEL in sub set_channel. Expected values are:\n 1 --> for channel 1\n 2 --> for channel 2\n"
564             );
565             }
566             }
567             else {
568 0           Lab::Exception::CorruptParameter->throw(
569             error => "Can't route CHANNEL in resistance/Fresistance mode." );
570             }
571              
572             }
573              
574             sub get_channel {
575 0     0 0   my $self = shift;
576 0           my ($tail) = $self->_check_args( \@_ );
577              
578 0           my $function = $self->get_function( { read_mode => 'cache' }, $tail );
579 0           $function =~ s/\s+//g; #remove all whitespaces
580 0           $function = "\L$function"
581             ; # transform all uppercase letters to lowercase letters
582              
583 0 0         if ( $function
584             =~ /(voltage:dc|voltage|volt:dc|volt|sense1:voltage:dc|sense1:voltage|sense1:volt:dc|sense1:volt|sense2:voltage:dc|sense2:voltage|sense2:volt:dc|sense2:volt)/
585             ) {
586 0           my $result = $self->query("ROUTE:TERMINALS?");
587 0 0         if ( $result eq "FRON" ) {
    0          
588 0           return 1;
589             }
590             elsif ( $result eq "FRON2" ) {
591 0           return 2;
592             }
593             }
594             else {
595 0           Lab::Exception::CorruptParameter->throw(
596             error => "Can't route CHANNEL in resistance/Fresistance mode." );
597             }
598              
599             }
600              
601             sub set_averaging { # to be implemented
602 0     0 0   my $self = shift;
603 0           my $value = shift;
604              
605             #INPut:FILTer
606             #:STATe {OFF|ON}
607             #:TYPE {ANAlog | DIGital | BOTH}
608             #:DIGital:resPonse {SLOW|MEDium|FAST}
609             #:DIGital:PRECharge {ON | OFF}
610             }
611              
612             # ----------------------------- TAKE DATA ---------------------------------------------------------
613              
614             sub get_value { # basic
615 0     0 1   my $self = shift;
616              
617             # parameter == hash??
618 0           my ( $channel, $function, $range, $nplc, $resolution, $tail )
619             = $self->_check_args(
620             \@_,
621             [ 'channel', 'function', 'range', 'nplc', 'resolution' ]
622             );
623              
624 0           my ( $int_time, $int_mode );
625              
626 0 0 0       if ( defined $nplc ) {
    0          
    0          
627 0           $int_mode = "nplc";
628 0           $int_time = $nplc;
629             }
630             elsif ( defined $resolution ) {
631 0           $int_mode = "res";
632 0           $int_time = $resolution;
633             }
634             elsif ( defined $resolution and defined $nplc ) {
635 0           Lab::Exception::CorruptParameter->throw(
636             error => "NPLC and resolution may not be defined concurrently." );
637             }
638              
639 0 0         if ( not defined $channel ) {
640             $channel = $self->{channel}
641 0   0       || $self->get_channel( { read_mode => 'cache' } );
642             }
643              
644 0           $self->set_channel( $channel, $tail );
645              
646 0 0         if ( not defined $function ) {
647 0           $function = $self->get_function( { read_mode => 'cache' }, $tail );
648             }
649              
650 0           $function =~ s/\s+//g; #remove all whitespaces
651 0           $function = "\L$function"
652             ; # transform all uppercase letters to lowercase letters
653              
654 0 0         if (
655             not $function
656             =~ /^(voltage:dc|voltage|volt:dc|volt|voltage:dc:ratio|voltage:ratio|volt:dc:ratio|volt:ratio|voltage:dc:diff|voltage:diff|volt:dc:diff|volt:diff|resistance|resisitance|res|res|Fresistance|fresistance|fres|fres)$/
657             ) {
658 0           Lab::Exception::CorruptParameter->throw( error =>
659             "\nAgilent 34420A:\nunexpected value for FUNCTION in sub get_value. Expected values are voltage:dc|voltage|volt:dc|volt|voltage:dc:ratio|voltage:ratio|volt:dc:ratio|volt:ratio|voltage:dc:diff|voltage:diff|volt:dc:diff|volt:diff|resistance|resisitance|res|res|Fresistance|fresistance|fres|fres"
660             );
661             }
662              
663             # check input parameter
664              
665 0 0         if ( not defined $range ) {
666 0           $range = $self->get_range( { read_mode => 'cache' }, $tail );
667             }
668              
669 0           $range =~ s/\s+//g; #remove all whitespaces
670 0 0         if ( $function =~ $function
    0          
671             =~ /^(voltage:dc|voltage|volt:dc|volt|voltage:dc:ratio|voltage:ratio|volt:dc:ratio|volt:ratio|voltage:dc:diff|voltage:diff|volt:dc:diff|volt:diff)$/
672             ) {
673 0 0 0       if ( abs($range) > 100
674             and not $range =~ /^(MIN|min|MAX|max|DEF|def|AUTO|auto)$/ ) {
675 0           Lab::Exception::CorruptParameter->throw( error =>
676             "\nAgilent 34420A:\nunexpected value for RANGE in sub get_value. Expected values are for voltage and resistance mode 0.1...100V or 0...1e6 Ohms respectivly"
677             );
678             }
679             }
680             elsif ( $function
681             =~ /^(resistance|resisitance|res|res|Fresistance|fresistance|fres|fres)$/
682             ) {
683 0 0 0       if ( abs($range) > 1e6
684             and not $range =~ /^(MIN|min|MAX|max|DEF|def|AUTO|auto)$/ ) {
685 0           Lab::Exception::CorruptParameter->throw( error =>
686             "\nAgilent 34420A:\nunexpected value for RANGE in sub get_value. Expected values are for voltage and resistance mode 0.1...100V or 0...1e6 Ohms respectivly"
687             );
688             }
689             }
690              
691 0           $int_mode =~ s/\s+//g; #remove all whitespaces
692 0           $int_mode = "\L$int_mode"
693             ; # transform all uppercase letters to lowercase letters
694 0 0         if ( $int_mode =~ /resolution|res/ ) {
    0          
    0          
695 0           $int_mode = "res";
696 0 0 0       if ( $int_time < 0.22e-6 * $range
697             and not $int_time =~ /^(MIN|min|MAX|max|DEF|def)$/ ) {
698 0           Lab::Exception::CorruptParameter->throw( error =>
699             "unexpected value for RESOLUTION in sub get_value. Expected values are from 0.22e-6xRANGE ... 30e-6xRANGE."
700             );
701             }
702             }
703             elsif ( $int_mode eq "nplc" ) {
704 0 0 0       if ( ( $int_time < 0.02 or $int_time > 200 )
      0        
705             and not $int_time =~ /^(MIN|min|MAX|max|DEF|def)$/ ) {
706 0           Lab::Exception::CorruptParameter->throw( error =>
707             "unexpected value for NPLC in sub get_value. Expected values are from 0.02 ... 200."
708             );
709             }
710             }
711             elsif ( defined $int_time ) {
712 0           $int_mode = 'nplc';
713 0 0 0       if ( ( $int_time < 0.02 or $int_time > 200 )
      0        
714             and not $int_time =~ /^(MIN|min|MAX|max|DEF|def)$/ ) {
715 0           Lab::Exception::CorruptParameter->throw( error =>
716             "unexpected value for NPLC in sub get_value. Expected values are from 0.02 ... 200."
717             );
718             }
719             }
720              
721 0           $self->set_function( $function, $tail );
722              
723 0           $self->set_range($range);
724              
725 0 0         if ( $int_mode eq 'res' ) {
    0          
726 0           $self->set_resolution($int_time);
727              
728             #$self->write( ":SENS:$function:ZERO:AUTO OFF; RES $int_time");
729             }
730             elsif ( $int_mode eq 'nplc' ) {
731 0           $self->set_nplc($int_time);
732              
733             #$self->write( ":SENS:$function:ZERO:AUTO OFF; NPLC $int_time");
734             }
735              
736 0           return $self->request( ":read?", $tail );
737              
738             }
739              
740             sub config_measurement { # basic
741 0     0 1   my $self = shift;
742 0           my ( $function, $nop, $nplc, $range, $trigger, $tail )
743             = $self->_check_args(
744             \@_,
745             [ 'function', 'nop', 'nplc', 'range', 'trigger' ]
746             );
747              
748             # check input data
749 0 0         if ( not defined $trigger ) {
750 0           $trigger = 'BUS';
751             }
752 0 0         if ( not defined $range ) {
753 0           $range = 'DEF';
754             }
755 0 0         if ( not defined $nplc ) {
756 0           $nplc = 2;
757             }
758 0 0         if ( not defined $nop ) {
759 0           Lab::Exception::CorruptParameter->throw( error =>
760             "too view arguments given in sub config_measurement. Expected arguments are FUNCTION, #POINTS, NPLC, <RANGE>, <TRIGGERSOURCE>"
761             );
762             }
763              
764 0           print "--------------------------------------\n";
765 0           print "Agilent34410A: sub config_measurement:\n";
766              
767             # clear buffer
768 0           my $points = $self->query("DATA:POINTS?");
769 0 0         if ( $points > 0 ) {
770 0           $points = $self->{vi}->LongQuery("DATA:FETCH?");
771             }
772              
773             # set function
774              
775 0           print "set_function: " . $self->set_function( $function, $tail ) . "\n";
776              
777             # set range
778 0           print "set_range: " . $self->set_range( $range, $function, $tail ) . "\n";
779              
780             # set nplc/tc
781 0           print "set_nplc: " . $self->set_nplc( $nplc, $function, $tail ) . "\n";
782 0           my $time = $nop * $nplc / 50;
783 0           print "TIME for measurement trace => $time\n";
784              
785             # set some status registes
786 0           $self->write("*CLS");
787 0           $self->write("*ESE 128");
788              
789             # triggering
790 0           print "set Trigger Source: " . $self->_set_triggersource("BUS") . "\n";
791 0           print "set Trigger Count: " . $self->_set_triggercount(1) . "\n";
792 0           print "set Trigger Delay: " . $self->_set_triggerdelay("MIN") . "\n";
793              
794 0           print "set Sample Count: " . $self->_set_samplecount($nop) . "\n";
795 0           print "init()\n";
796 0           $self->write("INIT");
797 0           usleep(50e3)
798             ; # wait 50ms; it takes 20ms until the WAIT-FOR-TRIGGER-STATE has been setteled;
799              
800 0           print "Agilent34410A: sub config_measurement complete\n";
801 0           print "--------------------------------------\n";
802              
803 0           return $time;
804             }
805              
806             sub trg { # basic
807 0     0 1   my $self = shift;
808 0           $self->write("*TRG");
809             }
810              
811             sub abort
812             { # doesn't work, because Agilent 34420A doesn't accept any new SPCI COMMAND until last COMMAND has been completed.
813 0     0 1   my $self = shift;
814              
815             #$self->write("ABOR"); # ??
816             #$self->write("SYSTEM:LOCAL");
817             }
818              
819             sub get_data { # basic
820 0     0 1   my $self = shift;
821 0           my $data;
822             my @data;
823              
824             # wait until data are available
825 0           $self->write("*STB?");
826 0           while (1) {
827 0           eval '$self->read(100)';
828 0 0         if ( index( $@, "Error while reading:" ) >= 0 ) {
829 0           print "waiting for data ...\n";
830             }
831 0           else { last; }
832             }
833              
834             # read data
835 0           $data = $self->{vi}->LongQuery("FETC?");
836 0           chomp $data;
837 0           @data = split( ",", $data );
838 0           return @data;
839             }
840              
841             # ------------------ TRIGGER and SAMPLE settings ---------------------- #
842              
843             sub _set_triggersource { # internal only
844 0     0     my $self = shift;
845 0           my ( $source, $tail ) = $self->_check_args( \@_, ['value'] );
846              
847 0 0         if ( not defined $source ) {
848 0           $source = $self->query( sprintf("TRIGGER:SOURCE?") );
849 0           chomp($source);
850 0           return $source;
851             }
852              
853 0 0         if ( $source =~ /^(IMM|imm|EXT|ext|BUS|bus)$/ ) {
854 0           Lab::Exception::CorruptParameter->throw( error =>
855             "\nAgilent 34420A:\nunexpected value for TRIGGER_SOURCE in sub _set_triggersource. Expected values are:\n IMM --> immediate trigger signal\n EXT --> external trigger\n BUS --> software trigger signal via bus\n"
856             );
857             }
858             $source
859 0           = $self->query( sprintf( "TRIGGER:SOURCE %s; SOURCE?", $source ) );
860              
861 0           return $source;
862             }
863              
864             sub _set_triggercount { # internal only
865 0     0     my $self = shift;
866 0           my ( $count, $tail ) = $self->_check_args( \@_, ['value'] );
867              
868 0 0         if ( not defined $count ) {
869 0           $count = $self->query( sprintf("TRIGGER:COUNT?") );
870 0           chomp($count);
871 0           return $count;
872             }
873              
874 0 0 0       if ( $count < 0 or $count >= 50000 ) {
875 0           Lab::Exception::CorruptParameter->throw( error =>
876             "\nAgilent 34420A:\nunexpected value for COUNT in sub _set_triggercount. Expected values are between 1 ... 50.000\n"
877             );
878             }
879              
880 0           return $self->query( sprintf( "TRIGGER:COUNT %d; COUNT?", $count ) );
881             }
882              
883             sub _set_triggerdelay { # internal only
884 0     0     my $self = shift;
885 0           my ( $delay, $tail ) = $self->_check_args( \@_, ['value'] );
886              
887 0 0         if ( not defined $delay ) {
888 0           $delay = $self->query( sprintf("TRIGGER:DELAY?") );
889 0           chomp($delay);
890 0           return $delay;
891             }
892              
893 0 0 0       if ( ( $delay < 0 or $delay > 3600 )
      0        
894             and $delay =~ /^(MIN|min|MAX|max|DEF|def)$/ ) {
895 0           Lab::Exception::CorruptParameter->throw( error =>
896             "\nAgilent 34420A:\nunexpected value for DELAY in sub _set_triggerdelay. Expected values are between 1 ... 3600, or 'MIN = 0', 'MAX = 3600' or 'AUTO'\n"
897             );
898             }
899              
900 0 0         if ( $delay =~ /^(AUTO|auto)$/ ) {
    0          
901 0           $self->query( sprintf( "TRIGGER:DELAY:AUTO ON; AUTO?", $delay ) );
902 0           return "AUTO ON";
903             }
904             elsif ( $delay =~ /^(MIN|min|MAX|max|DEF|def)$/ ) {
905 0           return $self->query( sprintf( "TRIGGER:DELAY %s; DELAY?", $delay ) );
906             }
907             else {
908 0           return $self->query(
909             sprintf( "TRIGGER:DELAY %.5f; DELAY?", $delay ) );
910             }
911             }
912              
913             sub _set_samplecount { # internal only
914 0     0     my $self = shift;
915 0           my ( $count, $tail ) = $self->_check_args( \@_, ['value'] );
916              
917 0 0 0       if ( not defined $count ) {
    0          
918 0           $count = $self->query( sprintf("SAMPLE:COUNT?") );
919 0           chomp($count);
920 0           return $count;
921             }
922              
923             elsif ( $count < 0 or $count > 1024 ) {
924 0           Lab::Exception::CorruptParameter->throw( error =>
925             "\nAgilent 34420A:\nunexpected value for COUNT in sub _set_samplecount. Expected values are between 1 ... 1024\n"
926             );
927             }
928             else {
929 0           return $self->query( sprintf( "SAMPLE:COUNT %d; COUNT?", $count ) );
930             }
931             }
932              
933             # ------------------------------- DISPLAY and BEEPER --------------------------------------------
934              
935             sub display_text { # basic
936 0     0 1   my $self = shift;
937 0           my ( $text, $tail ) = $self->_check_args( \@_, ['text'] );
938              
939 0 0         if ($text) {
940 0           $self->write(qq(DISPlay:TEXT "$text"));
941             }
942             else {
943 0           chomp( $text = $self->query(qq(DISPlay:TEXT?)) );
944 0           $text =~ s/\"//g;
945             }
946 0           return $text;
947             }
948              
949             sub display_on { # basic
950 0     0 1   my $self = shift;
951 0           $self->write("DISPLAY ON");
952             }
953              
954             sub display_off { # basic
955 0     0 1   my $self = shift;
956 0           $self->write("DISPLAY OFF");
957             }
958              
959             sub display_clear { # basic
960 0     0 1   my $self = shift;
961 0           $self->write("DISPLAY:TEXT:CLEAR");
962             }
963              
964             sub beep { # basic
965 0     0 1   my $self = shift;
966 0           $self->write("SYSTEM:BEEPER");
967             }
968              
969             1;
970              
971             __END__
972              
973             =pod
974              
975             =encoding UTF-8
976              
977             =head1 NAME
978              
979             Lab::Instrument::Agilent34420A - HP/Agilent/Keysight 34420A or 34421A digital multimeter
980              
981             =head1 VERSION
982              
983             version 3.880
984              
985             =head1 SYNOPSIS
986              
987             use Lab::Instrument::Agilent34420A;
988             my $agilent=new Lab::Instrument::Agilent34420A(0,22);
989             print $agilent->get_value();
990              
991             =head1 DESCRIPTION
992              
993             The Lab::Instrument::Agilent34420A class implements an interface to the 34420A and 34421A digital multimeters by
994             Agilent (formerly HP). Note that the module Lab::Instrument::Agilent34420A still works for those older multimeter
995             models.
996              
997             =head1 CONSTRUCTOR
998              
999             my $agilent=new(\%options);
1000              
1001             =head1 METHODS
1002              
1003             =head2 get_value
1004              
1005             $value=$agilent->get_value(<$function>,<$range>,<$integration>);
1006              
1007             Request a measurement value. If optinal paramters are defined, some device paramters can be preset befor the request of a measurement value.
1008              
1009             =over 4
1010              
1011             =item $function
1012              
1013             C<FUNCTION> can be one of the measurement methods of the Agilent34420A.
1014              
1015             "voltage" --> voltage measurement using the currently selected sense
1016             "sense1:voltage" --> voltage measurement useing sense #1
1017             "sense2:voltage" --> voltage measurement useing sense #2
1018             "voltage:ratio" --> voltage measurment + calculation V[sense #1]/ V[sense #2]
1019             "voltage:diff" --> voltage measurment + calculation V[sense #1] - V[sense #2]
1020             "resistance" --> resistance measurement (2-wire)
1021             "fresistance" --> resistance measurement (4-wire)
1022              
1023             =item $range
1024              
1025             C<RANGE> is given in terms of volts or ohms and can be C<1mV...100V|MIN|MAX|DEF|AUTO> or C<1...1e6|MIN|MAX|DEF|AUTO>.
1026             C<DEF> is default C<AUTO> activates the C<AUTORANGE-mode>.
1027             C<DEF> will be set, if no value is given.
1028              
1029             =item <$resolution>
1030              
1031             C<INTEGratioN> controlles the integration mode and the integration time. It is composed of two parts:
1032              
1033             1.) Integration mode:
1034            
1035             'nplc=' --> Number of Power Line Cycles MODE
1036             'res=' --> Resolution-MODE
1037              
1038             If no Integration mode is given, the 'Number of Power Line Cycles MODE' will be selected as default.
1039              
1040             2.) Integration Time:
1041            
1042             Floating point number or MIN, MAX, DEF.
1043              
1044             For detailed information about the valid range for the integration time see
1045             L<set_resolution>, L<set_nplc>
1046              
1047             Examples:
1048              
1049             a) $integration = 'nplc=5'
1050             --> Integration mode = Number of Power Line Cycles MODE
1051             --> Integration Time = 5 Powerline cycles = 5 * 1/50 Hz = 0.1 seconds
1052            
1053             b) $integration = 'res=0.00001'
1054             --> Integration mode = Resolution-MODE
1055             --> Integration Time = will be choosen automaticly to guarantee the requested resolution
1056            
1057             c) $integration = '1'
1058             --> Integration mode = Number of Power Line Cycles MODE
1059             --> Integration Time = 1 Powerline cycles = 1 * 1/50 Hz = 0.02 seconds
1060              
1061             =back
1062              
1063             =head2 config_measurement
1064              
1065             $agilent->config_measurement($function, $number_of_points, <$nplc>, <$range>);
1066              
1067             Preset the Agilent34420A nanovoltmeter for a TRIGGERED measurement.
1068             Returns the duration to record the defined trace.
1069              
1070             NOTE:
1071             The Agilent34420A nanovoltmeter allows only specified values for the integration time, namely 0.02, 0.2, 1, 2, 10, 20, 100, or 200 Power-line-cycles.
1072             --> the duration to recored one trace depends on these specific values and the number of points to be recorded.
1073              
1074             =over 4
1075              
1076             =item $function
1077              
1078             C<FUNCTION> can be one of the measurement methods of the Agilent34420A.
1079              
1080             "voltage" --> voltage measurement using the currently selected sense
1081             "sense1:voltage" --> voltage measurement useing sense #1
1082             "sense2:voltage" --> voltage measurement useing sense #2
1083             "voltage:ratio" --> voltage measurment + calculation V[sense #1]/ V[sense #2]
1084             "voltage:diff" --> voltage measurment + calculation V[sense #1] - V[sense #2]
1085             "resistance" --> resistance measurement (2-wire)
1086             "fresistance" --> resistance measurement (4-wire)
1087              
1088             =item $number_of_points
1089              
1090             Preset the C<NUMBER OF POINTS> to be taken for one measurement trace.
1091             The single measured points will be stored in the internal memory of the Agilent34420A nanovoltmeter.
1092             for the Agilent34420A nanovoltmeter the internal memory is limited to 1024 values.
1093              
1094             =item <$nplc>
1095              
1096             Preset the C<NUMBER of POWER LINE CYCLES> which is actually something similar to an integration time for recording a single measurement value.
1097             The values for $nplc can be any value between 0.02 ... 200 but internally the Agilent34420A nanovoltmeter selects the value closest to one of the following fixed values C<0.02 | 0.2 | 1 | 2 | 10 | 20 | 100 | 200 | MIN | MAX>.
1098              
1099             Example:
1100             Assuming $nplc to be 20 and assuming a netfrequency of 50Hz this results in an integration time of 20*50Hz = 0.4 seconds for each measured value. Assuming $number_of_points to be 100 it takes in total 40 seconds to record all values for the trace.
1101              
1102             =item <$range>
1103              
1104             C<RANGE> is given in terms of volts or ohms and can be C<1mV...100V|MIN|MAX|DEF|AUTO> or C<1...1e6|MIN|MAX|DEF|AUTO>.
1105             C<DEF> is default C<AUTO> activates the C<AUTORANGE-mode>.
1106             C<DEF> will be set, if no value is given.
1107              
1108             =back
1109              
1110             =head2 trg
1111              
1112             $agilent->trg();
1113              
1114             Sends a trigger signal via the GPIB-BUS to start the predefined measurement.
1115             The Agilent34420A nanovoltmeter won't accept any new commands until data-recording has been finished. Unfortunatelly it is not possible to stop an once started measurement.
1116             The LabVisa-script can immediatally be continued, e.g. to start another triggered measurement using a second Agilent34420A nanovoltmeter.
1117              
1118             =head2 abort
1119              
1120             $agilent->abort();
1121              
1122             doesn't work, because Agilent 34420A doesn't accept any new C<SPCI COMMANDS> until last C<COMMAND> has been completed.
1123              
1124             =head2 get_data
1125              
1126             @data = $agilent->get_data();
1127              
1128             Reads all recorded values from the internal buffer and returnes them as an array of floatingpoint values.
1129             Reading the buffer will not start before all predevined measurement values ($number_of_points) have been recorded.
1130              
1131             =head2 set_function
1132              
1133             $agilent->set_function($function);
1134              
1135             Set a new value for the measurement function of the Agilent34420A nanovoltmeter.
1136              
1137             =over 4
1138              
1139             =item $function
1140              
1141             FUNCTION can be one of the measurement methods of the Agilent34420A.
1142              
1143             "voltage" --> voltage measurement using the currently selected sense
1144             "sense1:voltage" --> voltage measurement useing sense #1
1145             "sense2:voltage" --> voltage measurement useing sense #2
1146             "voltage:ratio" --> voltage measurment + calculation V[sense #1]/ V[sense #2]
1147             "voltage:diff" --> voltage measurment + calculation V[sense #1] - V[sense #2]
1148             "resistance" --> resistance measurement (2-wire)
1149             "fresistance" --> resistance measurement (4-wire)
1150              
1151             =back
1152              
1153             =head2 set_range
1154              
1155             $agilent->set_range($range, $function);
1156              
1157             Set a new value for the predefined RANGE for the measurement function $function of the Agilent34420A nanovoltmeter.
1158              
1159             =over 4
1160              
1161             =item $function
1162              
1163             FUNCTION can be one of the measurement methods of the Agilent34420A.
1164              
1165             "voltage" --> voltage measurement using the currently selected sense
1166             "sense1:voltage" --> voltage measurement useing sense #1
1167             "sense2:voltage" --> voltage measurement useing sense #2
1168             "voltage:ratio" --> voltage measurment + calculation V[sense #1]/ V[sense #2]
1169             "voltage:diff" --> voltage measurment + calculation V[sense #1] - V[sense #2]
1170             "resistance" --> resistance measurement (2-wire)
1171             "fresistance" --> resistance measurement (4-wire)
1172              
1173             =item $range
1174              
1175             C<RANGE> is given in terms of volts or ohms and can be C<1mV...100V|MIN|MAX|DEF|AUTO> or C<1...1e6|MIN|MAX|DEF|AUTO>.
1176             C<DEF> is default C<AUTO> activates the C<AUTORANGE-mode>.
1177             C<DEF> will be set, if no value is given.
1178              
1179             =back
1180              
1181             =head2 set_nplc
1182              
1183             $agilent->set_nplc($nplc, $function);
1184              
1185             Set a new value for the predefined C<NUMBER of POWER LINE CYCLES> for the measurement function $function of the Agilent34420A nanovoltmeter.
1186              
1187             =over 4
1188              
1189             =item $function
1190              
1191             FUNCTION can be one of the measurement methods of the Agilent34420A.
1192              
1193             "voltage" --> voltage measurement using the currently selected sense
1194             "sense1:voltage" --> voltage measurement useing sense #1
1195             "sense2:voltage" --> voltage measurement useing sense #2
1196             "voltage:ratio" --> voltage measurment + calculation V[sense #1]/ V[sense #2]
1197             "voltage:diff" --> voltage measurment + calculation V[sense #1] - V[sense #2]
1198             "resistance" --> resistance measurement (2-wire)
1199             "fresistance" --> resistance measurement (4-wire)
1200              
1201             =item $nplc
1202              
1203             Preset the C<NUMBER of POWER LINE CYCLES> which is actually something similar to an integration time for recording a single measurement value.
1204             The values for $nplc can be any value between 0.02 ... 200 but internally the Agilent34420A nanovoltmeter selects the value closest to one of the following fixed values C<0.02 | 0.2 | 1 | 2 | 10 | 20 | 100 | 200 | MIN | MAX>.
1205              
1206             B<Example:>
1207             Assuming $nplc to be 20 and assuming a netfrequency of 50Hz this results in an integration time of 20*50Hz = 0.4 seconds for each measured value.
1208              
1209             =back
1210              
1211             =head2 set_resolution
1212              
1213             $agilent->set_resolution($resolution, $function);
1214              
1215             Set a new value for the predefined C<resOLUTION> for the measurement function $function of the Agilent34420A nanovoltmeter.
1216              
1217             =over 4
1218              
1219             =item $function
1220              
1221             FUNCTION can be one of the measurement methods of the Agilent34420A.
1222              
1223             "voltage" --> voltage measurement using the currently selected sense
1224             "sense1:voltage" --> voltage measurement useing sense #1
1225             "sense2:voltage" --> voltage measurement useing sense #2
1226             "voltage:ratio" --> voltage measurment + calculation V[sense #1]/ V[sense #2]
1227             "voltage:diff" --> voltage measurment + calculation V[sense #1] - V[sense #2]
1228             "resistance" --> resistance measurement (2-wire)
1229             "fresistance" --> resistance measurement (4-wire)
1230              
1231             =item $resolution
1232              
1233             C<resOLUTION> is given in terms of C<$resolution*$range> or C<[MIN|MAX|DEF]>.
1234             C<$resolution=0.0001> means 4 1/2 digits for example.
1235             $resolution can be 0.0001xRANGE ... 0.0000022xRANGE.
1236             The best resolution is 100nV: C<$range=0.1>; C<$resolution=0.000001>.
1237             C<DEF> will be set, if no value is given.
1238              
1239             =back
1240              
1241             =head2 set_channel
1242              
1243             $agilent->set_channel($channel);
1244              
1245             Select the active sensing terminal. This function can only be used if the active C<FUNCTION> is in the voltage mode ( not resistance or Fresistance).
1246              
1247             =over 4
1248              
1249             =item $channel
1250              
1251             C<CHANNEL> can be '1' for sense #1 or '2' for sense #2.
1252              
1253             =back
1254              
1255             =head2 display_on
1256              
1257             $agilent->display_on();
1258              
1259             Turn the front-panel display on.
1260              
1261             =head2 display_off
1262              
1263             $agilent->display_off();
1264              
1265             Turn the front-panel display off.
1266              
1267             =head2 display_text
1268              
1269             $agilent->display_text($text);
1270             print $agilent->display_text();
1271              
1272             Display a message on the front panel. The multimeter will display up to 12
1273             characters in a message; any additional characters are truncated.
1274             Without parameter the displayed message is returned.
1275              
1276             =head2 display_clear
1277              
1278             $agilent->display_clear();
1279              
1280             Clear the message displayed on the front panel.
1281              
1282             =head2 beep
1283              
1284             $agilent->beep();
1285              
1286             Issue a single beep immediately.
1287              
1288             =head2 get_error
1289              
1290             ($err_num,$err_msg)=$agilent->get_error();
1291              
1292             Query the multimeter's error queue. Up to 20 errors can be stored in the
1293             queue. Errors are retrieved in first-in-first out (FIFO) order.
1294              
1295             =head2 reset
1296              
1297             $agilent->reset();
1298              
1299             Reset the multimeter to its power-on configuration.
1300              
1301             =head2 id
1302              
1303             $id=$agilent->id();
1304              
1305             Returns the instruments ID string.
1306              
1307             =head1 CAVEATS/BUGS
1308              
1309             probably many
1310              
1311             =head1 SEE ALSO
1312              
1313             =over 4
1314              
1315             =item L<Lab::Instrument>
1316              
1317             =back
1318              
1319             =head1 COPYRIGHT AND LICENSE
1320              
1321             This software is copyright (c) 2023 by the Lab::Measurement team; in detail:
1322              
1323             Copyright 2013-2015 Christian Butschkow
1324             2016 Simon Reinhardt
1325             2017 Andreas K. Huettel
1326             2020 Andreas K. Huettel
1327              
1328              
1329             This is free software; you can redistribute it and/or modify it under
1330             the same terms as the Perl 5 programming language system itself.
1331              
1332             =cut