File Coverage

blib/lib/Lab/Instrument/HP34401A.pm
Criterion Covered Total %
statement 23 195 11.7
branch 0 86 0.0
condition 0 26 0.0
subroutine 8 35 22.8
pod 22 24 91.6
total 53 366 14.4


line stmt bran cond sub pod time code
1             package Lab::Instrument::HP34401A;
2             #ABSTRACT: HP/Agilent 34401A digital multimeter
3             $Lab::Instrument::HP34401A::VERSION = '3.881';
4 1     1   1765 use v5.20;
  1         4  
5              
6 1     1   5 use strict;
  1         2  
  1         27  
7 1     1   17 use Scalar::Util qw(weaken);
  1         4  
  1         49  
8 1     1   7 use Lab::Instrument;
  1         11  
  1         27  
9 1     1   6 use Carp;
  1         2  
  1         59  
10 1     1   8 use Data::Dumper;
  1         2  
  1         41  
11 1     1   6 use Lab::Instrument::Multimeter;
  1         3  
  1         2741  
12              
13             our @ISA = ("Lab::Instrument::Multimeter");
14              
15             our %fields = (
16             supported_connections => ['GPIB'],
17              
18             # default settings for the supported connections
19             connection_settings => {
20             gpib_board => 0,
21             gpib_address => undef,
22             },
23              
24             device_settings => {
25             pl_freq => 50,
26             },
27              
28             device_cache => {
29              
30             # TO DO: add range and resolution + get/setter
31             }
32              
33             );
34              
35             sub new {
36 0     0 1   my $proto = shift;
37 0   0       my $class = ref($proto) || $proto;
38 0           my $self = $class->SUPER::new(@_);
39 0           $self->${ \( __PACKAGE__ . '::_construct' ) }(__PACKAGE__);
  0            
40 0           return $self;
41             }
42              
43             #
44             # first, all internal stuff
45             #
46              
47             #
48             # all methods that fill in general Multimeter methods
49             #
50              
51             sub _display_clear {
52 0     0     my $self = shift;
53 0           $self->connection()->Write( command => "DISPlay:TEXT:CLEar" );
54             }
55              
56             sub _id {
57 0     0     my $self = shift;
58 0           return $self->query('*IDN?');
59             }
60              
61             sub get_value {
62 0     0 1   my $self = shift;
63 0           my $value = $self->query('READ?');
64 0           chomp $value;
65 0           return $value;
66             }
67              
68             sub _device_init {
69 0     0     my $self = shift;
70              
71             }
72              
73             #
74             # all methods that are called directly
75             #
76              
77             sub get_resistance {
78 0     0 1   my $self = shift;
79 0           my ( $range, $resolution ) = @_;
80              
81 0 0         $range = "DEF" unless ( defined $range );
82 0 0         $resolution = "DEF" unless ( defined $resolution );
83              
84 0           my $cmd
85             = sprintf( "MEASure:SCALar:RESIStance? %s,%s", $range, $resolution );
86 0           my $value = $self->query($cmd);
87 0           return $value;
88             }
89              
90             sub get_4wresistance {
91 0     0 1   my $self = shift;
92 0           my ( $range, $resolution ) = @_;
93              
94 0 0         $range = "DEF" unless ( defined $range );
95 0 0         $resolution = "DEF" unless ( defined $resolution );
96              
97 0           my $cmd
98             = sprintf( "MEASure:SCALar:FRESIStance? %s,%s", $range, $resolution );
99 0           my $value = $self->query($cmd);
100 0           return $value;
101             }
102              
103             sub get_voltage_dc {
104 0     0 1   my $self = shift;
105 0           my ( $range, $resolution ) = @_;
106              
107 0 0         $range = "DEF" unless ( defined $range );
108 0 0         $resolution = "DEF" unless ( defined $resolution );
109              
110 0           my $cmd = sprintf( "MEASure:VOLTage:DC? %s,%s", $range, $resolution );
111 0           my $value = $self->query($cmd);
112 0           return $value;
113             }
114              
115             sub get_voltage_ac {
116 0     0 1   my $self = shift;
117 0           my ( $range, $resolution ) = @_;
118              
119 0 0         $range = "DEF" unless ( defined $range );
120 0 0         $resolution = "DEF" unless ( defined $resolution );
121              
122 0           my $cmd = sprintf( "MEASure:VOLTage:AC? %s,%s", $range, $resolution );
123 0           my $value = $self->query($cmd);
124 0           return $value;
125             }
126              
127             sub get_current_dc {
128 0     0 1   my $self = shift;
129 0           my ( $range, $resolution ) = @_;
130              
131 0 0         $range = "DEF" unless ( defined $range );
132 0 0         $resolution = "DEF" unless ( defined $resolution );
133              
134 0           my $cmd = sprintf( "MEASure:CURRent:DC? %s,%s", $range, $resolution );
135 0           my $value = $self->query($cmd);
136 0           return $value;
137             }
138              
139             sub get_current_ac {
140 0     0 1   my $self = shift;
141 0           my ( $range, $resolution ) = @_;
142              
143 0 0         $range = "DEF" unless ( defined $range );
144 0 0         $resolution = "DEF" unless ( defined $resolution );
145              
146 0           my $cmd = sprintf( "MEASure:CURRent:AC? %s,%s", $range, $resolution );
147 0           my $value = $self->query($cmd);
148 0           return $value;
149             }
150              
151             sub beep {
152 0     0 1   my $self = shift;
153 0           $self->write("SYSTem:BEEPer");
154             }
155              
156             sub get_error {
157 0     0 1   my $self = shift;
158 0           my $error = $self->query("SYST:ERR?");
159 0 0         if ( $error !~ /\+0,/ ) {
160 0 0         if ( $error =~ /^(\+[0-9]*)\,\"?(.*)\"?$/ ) {
161 0           return ( $1, $2 ); # ($code, $message)
162             }
163             else {
164 0           return $error;
165             }
166             }
167             else {
168 0           return undef;
169             }
170             }
171              
172             sub get_status {
173 0     0 1   my $self = shift;
174              
175             # This is to be implemented with code that queries the status bit
176              
177 0           my $request = shift;
178 0           my $status = {};
179              
180             (
181             $status->{NOT_USED1}, $status->{NOT_USED2}, $status->{NOT_USED3},
182             $status->{CORR_DATA}, $status->{MSG_AVAIL}, $status->{EVNT},
183             $status->{SRQ}, $status->{NOT_USED4}
184 0           ) = $self->connection()->serial_poll();
185 0 0         return $status->{$request} if defined $request;
186 0           return $status;
187             }
188              
189             sub set_display_state {
190 0     0 1   my $self = shift;
191 0           my $value = shift;
192              
193 0 0 0       if ( $value == 1 || $value =~ /on/i ) {
    0 0        
194 0           $self->write( "DISP ON", @_ );
195             }
196             elsif ( $value == 0 || $value =~ /off/i ) {
197 0           $self->write( "DISP OFF", @_ );
198             }
199             else {
200 0           Lab::Exception::CorruptParameter->throw(
201             "set_display_state(): Illegal parameter.\n");
202             }
203             }
204              
205             sub set_display_text {
206 0     0 1   my $self = shift;
207 0           my $text = shift;
208 0 0         if ( $text
209             !~ /^[A-Za-z0-9\ \!\#\$\%\&\'\(\)\^\\\/\@\;\:\[\]\,\.\+\-\=\<\>\?\_]*$/
210             ) { # characters allowed by the 3458A
211 0           Lab::Exception::CorruptParameter->throw(
212             "set_display_text(): Illegal characters in given text.\n");
213             }
214 0           $self->write("DISP:TEXT $text");
215              
216 0           $self->check_errors();
217             }
218              
219             sub set_range {
220 0     0 0   my $self = shift;
221              
222             # This is the range set function, to be implemented.
223             }
224              
225             sub reset {
226 0     0 1   my $self = shift;
227 0           $self->connection()->Write( command => "*CLS" );
228 0           $self->connection()->Write( command => "*RST" );
229              
230             # $self->connection()->InstrumentClear($self->instrument_handle());
231             }
232              
233             sub wait_done {
234 0     0 0   my $self = shift;
235              
236             # wait until currently running program is finished.
237              
238 0           while ( !$self->get_status()->{"EVNT"} ) {
239 0           sleep 1;
240             }
241              
242             }
243              
244             sub autozero {
245 0     0 1   my $self = shift;
246 0           my $enable = shift;
247 0           my $az_status = undef;
248 0           my $command = "";
249              
250 0 0         if ( !defined $enable ) {
251              
252             # read autozero setting
253 0           $command = "ZERO:AUTO?";
254 0           $az_status = $self->query( $command, error_check => 1 );
255             }
256             else {
257 0 0         if ( $enable =~ /^ONCE$/i ) {
    0          
    0          
258 0           $command = "ZERO:AUTO ONCE";
259             }
260             elsif ( $enable =~ /^(ON|1)$/i ) {
261 0           $command = "ZERO:AUTO ONCE";
262             }
263             elsif ( $enable =~ /^(OFF|0)$/i ) {
264 0           $command = "ZERO:AUTO OFF";
265             }
266             else {
267 0           Lab::Exception::CorruptParameter->throw( error =>
268             "HP34401A::autozero() can be set to 'ON'/1, 'OFF'/0 or 'ONCE'. Received '${enable}'\n"
269             );
270             }
271 0           $self->write( $command, error_check => 1 );
272             }
273              
274 0           return $az_status;
275             }
276              
277             sub configure_voltage_dc {
278 0     0 1   my $self = shift;
279 0           my $range = shift; # in V, or "AUTO", "MIN", "MAX"
280 0           my $tint = shift; # integration time in sec, "DEFAULT", "MIN", "MAX"
281 0           my $res_cmd = shift;
282              
283 0 0 0       if ( $range eq 'AUTO' || !defined($range) ) {
    0          
    0          
284 0           $range = 'DEF';
285             }
286             elsif ( $range =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/ ) {
287              
288             #$range = sprintf("%e",abs($range));
289             }
290             elsif ( $range !~ /^(MIN|MAX)$/ ) {
291 0           Lab::Exception::CorruptParameter->throw( error =>
292             "Range has to be set to a decimal value or 'AUTO', 'MIN' or 'MAX' in HP34401A::configure_voltage_dc()\n"
293             );
294             }
295              
296 0 0         if ( $tint =~ /^([+]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/ ) {
    0          
297              
298             # Convert seconds to PLC (power line cycles)
299 0           $tint *= $self->pl_freq();
300             }
301             elsif ( $tint !~ /^(MIN|MAX|DEFAULT)$/ ) {
302 0           Lab::Exception::CorruptParameter->throw( error =>
303             "Integration time has to be set to a positive value or 'AUTO', 'MIN' or 'MAX' in HP34401A::configure_voltage_dc()\n"
304             );
305             }
306              
307 0 0         if ( !defined($res_cmd) ) {
308 0           $res_cmd = '';
309             }
310              
311             # do it
312 0           $self->write( "CONF:VOLT:DC ${range} ${res_cmd}", error_check => 1 );
313 0 0         $self->write( "VOLT:DC:NPLC ${tint}", error_check => 1 )
314             if $res_cmd eq
315             ''; # integration time implicitly set through resolution
316             }
317              
318             sub configure_voltage_dc_trigger {
319 0     0 1   my $self = shift;
320              
321 0           my ( $range, $tint, $count, $delay, $res_cmd ) = $self->_check_args(
322             \@_,
323             [ 'range', 'tint', 'count', 'delay', 'resolution' ]
324             );
325              
326             ### Check the parameters for errors
327              
328 0 0         $count = 1 if !defined($count);
329 0 0 0       Lab::Exception::CorruptParameter->throw(
      0        
330             error => "Sample count has to be an integer between 1 and 512\n" )
331             if ( $count !~ /^[0-9]*$/ || $count < 1 || $count > 512 );
332              
333 0 0         $delay = 0 if !defined($delay);
334 0 0         Lab::Exception::CorruptParameter->throw(
335             error => "Trigger delay has to be a positive decimal value\n" )
336             if ( $count !~ /^([+]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/ );
337              
338 0 0         if ( !defined($tint) ) {
    0          
    0          
339 0           $tint = "DEF";
340             }
341             elsif ( $tint =~ /^([+]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/ ) {
342              
343             # Convert seconds to PLC (power line cycles)
344 0           $tint *= $self->pl_freq();
345 0 0 0       if ( $tint > 100 || $tint < 0.02 ) {
346 0           Lab::Exception::CorruptParameter->throw( error =>
347             "Integration time out of bounds (int. time = $tint) in HP34401A::configure_voltage_dc()\n"
348             );
349             }
350             }
351             elsif ( $tint !~ /^(MIN|MAX|DEF)$/ ) {
352 0           Lab::Exception::CorruptParameter->throw( error =>
353             "Integration time has to be set to a positive value, 'DEFAULT', 'MIN' or 'MAX' in HP34401A::configure_voltage_dc()\n"
354             );
355             }
356              
357 0 0 0       if ( $range eq 'AUTO' || !defined($range) ) {
    0          
    0          
358 0           $range = 'DEF';
359             }
360             elsif ( $range =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/ ) {
361 0           $range = sprintf( "%e", abs($range) );
362             }
363             elsif ( $range !~ /^(MIN|MAX)$/ ) {
364 0           Lab::Exception::CorruptParameter->throw( error =>
365             "Range has to be set to a decimal value or 'AUTO', 'MIN' or 'MAX' in HP34401A::configure_voltage_dc()\n"
366             );
367             }
368              
369 0 0         if ( !defined($res_cmd) ) {
370 0           $res_cmd = '';
371             }
372              
373 0           $self->write( "CONF:VOLT:DC ${range} ${res_cmd}", error_check => 1 );
374 0 0         $self->write( "VOLT:DC:NPLC ${tint}", error_check => 1 )
375             if $res_cmd eq
376             ''; # integration time implicitly set if resolution not given
377              
378 0           $self->write( "*ESE 1", error_check => 1 );
379 0           $self->write( "*CLS", error_check => 1 );
380              
381 0           $self->write( "TRIG:SOURce BUS", error_check => 1 );
382 0           $self->write( "SAMPle:COUNt $count", error_check => 1 );
383 0           $self->write( "TRIG:DELay $delay", error_check => 1 );
384              
385             }
386              
387             sub read_trig {
388 0     0 1   my $self = shift;
389              
390 0           $self->write("*TRG");
391 0           $self->write("*OPC");
392              
393             }
394              
395             sub fetch {
396 0     0 1   my $self = shift;
397              
398 0           my $value = $self->query("FETCh?");
399              
400 0           chomp $value;
401              
402 0           my @valarray = split( ",", $value );
403              
404 0           return @valarray;
405             }
406              
407             sub init {
408 0     0 1   my $self = shift;
409 0           $self->write("INIT");
410             }
411              
412             sub triggered_read {
413 0     0 1   my $self = shift;
414 0           my $args = undef;
415 0 0         if ( ref $_[0] eq 'HASH' ) { $args = shift }
  0            
416 0           else { $args = {@_} }
417              
418             #$args->{'timeout'} = $args->{'timeout'} || $self->timeout();
419              
420 0           $self->init();
421 0           $self->read_trig();
422 0           $self->wait_done();
423 0           my $value = $self->query( "FETCh?", $args );
424              
425 0           chomp $value;
426              
427 0           my @valarray = split( ",", $value );
428              
429 0           return @valarray;
430             }
431              
432             sub scroll_message {
433 1     1   9 use Time::HiRes (qw/usleep/);
  1         3  
  1         15  
434 0     0 1   my $self = shift;
435 0   0       my $message = shift
436             || " Lab::Measurement - designed to make measuring fun! ";
437 0           for my $i ( 0 .. ( length($message) - 12 ) ) {
438 0           $self->display_text( sprintf "%12.12s", substr( $message, $i ) );
439 0           usleep(100000);
440             }
441 0           $self->display_clear();
442             }
443              
444             1;
445              
446             __END__
447              
448             =pod
449              
450             =encoding utf-8
451              
452             =head1 NAME
453              
454             Lab::Instrument::HP34401A - HP/Agilent 34401A digital multimeter
455              
456             =head1 VERSION
457              
458             version 3.881
459              
460             =head1 SYNOPSIS
461              
462             use Lab::Instrument::HP34401A;
463            
464             my $Agi = new Lab::Instrument::HP34401A({
465             connection => new Lab::Connection::GPIB(
466             gpib_board => 0,
467             gpib_address => 14,
468             ),
469             }
470              
471             =head1 DESCRIPTION
472              
473             The Lab::Instrument::HP34401A class implements an interface to the 34401A digital
474             multimeter by Agilent (formerly HP). This module can also be used to address the newer
475             34410A and 34411A multimeters, but doesn't include new functions. Use the
476             L<Lab::Instrument::HP34411A> class for full functionality (not ported yet).
477              
478             =head1 CONSTRUCTOR
479              
480             my $Agi=new(\%options);
481              
482             =head1 METHODS
483              
484             =head2 fetch
485              
486             $hp->fetch();
487              
488             Fetches the instrument buffer. Returns an array of values.
489              
490             =head2 autozero
491              
492             $hp->autozero($setting);
493              
494             $setting can be 1/'ON', 0/'OFF' or 'ONCE'.
495              
496             When set to "ON", the device takes a zero reading after every measurement.
497             "ONCE" perform one zero reading and disables the automatic zero reading.
498             "OFF" does... you get it.
499              
500             =head2 configure_voltage_dc
501              
502             $hp->configure_voltage_dc($range, $integration_time, $resolution);
503              
504             Configures all the details of the device's DC voltage measurement function.
505              
506             $range is a positive numeric value (the largest expected value to be measured) or one of 'MIN', 'MAX', 'AUTO'.
507             It specifies the largest value to be measured. You can set any value, but the HP/Agilent 34401A effectively uses
508             one of the values 0.1, 1, 10, 100 and 1000V.
509              
510             $integration_time is the integration time in seconds or MIN MAX DEF. This implicitly sets the provided resolution.
511              
512             $resolution sets the resolution of the measurment. If set, $integration_time is overwritten.
513              
514             =head2 configure_voltage_dc_trigger
515              
516             $hp->configure_voltage_dc_trigger($range, $integration_time, $count, $delay, $resolution)
517              
518             Configures the device for successive triggered reading events. Does not initiate the trigger facility.
519             Reading can then be performed calling triggered_read().
520             The first three parameters are just passed to configure_voltage_dc.
521              
522             $count is an integer for the number of successive readings that follow one single trigger event.
523              
524             $delay is the delay in seconds between these readings.
525              
526             =head2 triggered_read
527              
528             @data = $hp->triggered_read();
529              
530             Sends a trigger pulse and fetches the values from the instrument buffer once the reading is finished.
531              
532             =head2 read_trig()
533              
534             Sends a read trigger to the device. It does not initialize the trigger facility.
535              
536             =head2 init()
537              
538             Initializes the trigger facility. The device is then in the state "waiting for trigger".
539              
540             =head2 get_value
541              
542             $data = hp->get_value();
543              
544             Inherited from L<Lab::Instrument::Multimeter>. Performs a single reading in the current configuration.
545              
546             =head2 get_voltage_dc
547              
548             $datum=$Agi->get_voltage_dc($range,$resolution);
549              
550             Preset and make a dc voltage measurement with the specified range
551             and resolution.
552              
553             =head2 get_voltage_ac
554              
555             $datum=$Agi->get_voltage_ac($range,$resolution);
556              
557             Preset and make a ac voltage measurement with the specified range
558             and resolution.
559              
560             =head2 get_current_dc
561              
562             $datum = $hp->get_current_dc($range,$resolution);
563              
564             Preset and make a dc current measurement with the specified range
565             and resolution.
566              
567             =head2 get_current_ac
568              
569             $datum = $hp->get_current_ac($range,$resolution);
570              
571             Preset and make a ac current measurement with the specified range
572             and resolution.
573              
574             =head2 get_resistance
575              
576             $resistance=$Agi->get_resistance($range,$resolution);
577              
578             Preset and measure resistance with specified range and resolution.
579              
580             =head2 get_4wresistance
581              
582             $resistance=$Agi->get_4wresistance($range,$resolution);
583              
584             Preset and measure the four way resistance with specified range and resolution.
585              
586             =head2 get_status()
587              
588             Returns a status string from the device.
589              
590             =head2 get_error()
591              
592             Returns the error string from the device.
593              
594             =head2 pl_freq
595             Parameter: pl_freq
596              
597             $hp->pl_freq($new_freq);
598             $npl_freq = $hp->pl_freq();
599              
600             Get/set the power line frequency at your location (50 Hz for most countries, which is the default). This
601             is the basis of the integration time setting (which is internally specified as a count of power
602             line cycles, or PLCs). The integration time will be set incorrectly if this parameter is set incorrectly.
603              
604             =head2 set_display_text
605              
606             $Agi->display_text($text);
607             print $Agi->display_text();
608              
609             Display a message on the front panel. The multimeter will display up to 12
610             characters in a message; any additional characters are truncated.
611             Without parameter the displayed message is returned.
612             Inherited from L<Lab::Instrument::Multimeter>
613              
614             =head2 set_display_state
615              
616             $Agi->set_display_state($state);
617              
618             Turn the front-panel display on ($state = "ON") or off ($state = "OFF").
619              
620             =over 4
621              
622             =item $range
623              
624             Range is given in terms of volts and can be C<[0.1|1|10|100|1000|MIN|MAX|DEF]>. C<DEF> is default.
625              
626             =item $resolution
627              
628             Resolution is given in terms of C<$range> or C<[MIN|MAX|DEF]>.
629             C<$resolution=0.0001> means 4 1/2 digits for example.
630             The best resolution is 100nV: C<$range=0.1>; C<$resolution=0.000001>.
631              
632             =back
633              
634             =head2 get_voltage_ac
635              
636             $datum=$Agi->get_voltage_ac($range,$resolution);
637              
638             Preset and make an ac voltage measurement with the specified range
639             and resolution. For ac measurements, resolution is actually fixed
640             at 6 1/2 digits. The resolution parameter only affects the front-panel display.
641              
642             =head2 get_current_dc
643              
644             $datum=$Agi->get_current_dc($range,$resolution);
645              
646             Preset and make a dc current measurement with the specified range
647             and resolution.
648              
649             =head2 get_current_ac
650              
651             $datum=$Agi->get_current_ac($range,$resolution);
652              
653             Preset and make an ac current measurement with the specified range
654             and resolution. For ac measurements, resolution is actually fixed
655             at 6 1/2 digits. The resolution parameter only affects the front-panel display.
656              
657             =head2 configure_voltage_dc_trigger
658              
659             $device->trigger_mode($intt, $range, $count, $delay, $resolution)
660              
661             Configure the multimeter for a triggered reading.
662              
663             =over 4
664              
665             =item $intt
666              
667             The integration time in seconds. You can also set "MIN" or "MAX". This value is overwritten if the resolution is specified.
668              
669             =item $range
670              
671             The range for the measurment.
672              
673             =item $count
674              
675             The number of measurements which are performed after one single trigger impulse.
676              
677             =item $delay
678              
679             The delay between the C<$count> measurements (the integration time is not included).
680              
681             =item $resolution
682              
683             The resolution for the measurement. If given, this overwrites the C<$intt> parameter.
684              
685             =back
686              
687             =head2 trigger_read
688              
689             $data = $device->trigger_read()
690              
691             Sends a trigger signal and fetches the value(s) from the multimeter.
692              
693             =head2 trigger
694              
695             $device->trigger()
696              
697             Sends a trigger signal to the device.
698              
699             =head2 fetch
700              
701             $data = $device->fetch()
702              
703             Fetches the data which is currently in the output buffer of the device.
704              
705             =head2 scroll_message
706              
707             $Agi->scroll_message($message);
708              
709             Scrolls the message C<$message> on the display of the HP.
710              
711             =head2 beep
712              
713             $Agi->beep();
714              
715             Issue a single beep immediately.
716              
717             =head2 get_error
718              
719             ($err_num,$err_msg)=$Agi->get_error();
720              
721             Query the multimeter's error queue. Up to 20 errors can be stored in the
722             queue. Errors are retrieved in first-in-first out (FIFO) order.
723              
724             =head2 reset
725              
726             $Agi->reset();
727              
728             Reset the multimeter to its power-on configuration.
729              
730             =head1 CAVEATS/BUGS
731              
732             probably many
733              
734             =head1 SEE ALSO
735              
736             =over 4
737              
738             =item * L<Lab::Instrument>
739              
740             =item * L<Lab::Instrument::Multimeter>
741              
742             =item * L<Lab::Instrument::HP3458A>
743              
744             =back
745              
746             =head1 COPYRIGHT AND LICENSE
747              
748             This software is copyright (c) 2023 by the Lab::Measurement team; in detail:
749              
750             Copyright 2005-2006 Daniel Schroeer
751             2009 Andreas K. Huettel, Daniela Taubert
752             2010 Andreas K. Huettel, Daniel Schroeer
753             2011 Andreas K. Huettel, Florian Olbrich
754             2012 Alois Dirnaichner, Florian Olbrich
755             2013 Alois Dirnaichner, Andreas K. Huettel
756             2016 Simon Reinhardt
757             2017 Andreas K. Huettel
758             2020 Andreas K. Huettel
759              
760              
761             This is free software; you can redistribute it and/or modify it under
762             the same terms as the Perl 5 programming language system itself.
763              
764             =cut