File Coverage

blib/lib/Lab/Instrument/SR830.pm
Criterion Covered Total %
statement 17 150 11.3
branch 0 94 0.0
condition 0 5 0.0
subroutine 6 23 26.0
pod 12 17 70.5
total 35 289 12.1


line stmt bran cond sub pod time code
1             package Lab::Instrument::SR830;
2             $Lab::Instrument::SR830::VERSION = '3.880';
3             #ABSTRACT: Stanford Research SR830 lock-in amplifier
4              
5 1     1   1714 use v5.20;
  1         13  
6              
7 1     1   6 use strict;
  1         2  
  1         21  
8 1     1   12 use Lab::Instrument;
  1         1  
  1         20  
9 1     1   5 use Data::Dumper;
  1         2  
  1         56  
10 1     1   8 use Carp;
  1         2  
  1         68  
11 1     1   7 use Time::HiRes qw (usleep);
  1         2  
  1         7  
12              
13             our @ISA = ("Lab::Instrument");
14              
15             our %fields = ( supported_connections => [ 'GPIB', 'VISA_GPIB' ], );
16              
17             sub new {
18 0     0 1   my $proto = shift;
19 0   0       my $class = ref($proto) || $proto;
20 0           my $self = $class->SUPER::new(@_);
21 0           $self->${ \( __PACKAGE__ . '::_construct' ) }(__PACKAGE__);
  0            
22              
23 0           $self->empty_buffer();
24 0           return $self;
25             }
26              
27             #
28             # utility methods
29             #
30              
31             sub empty_buffer {
32 0     0 0   my $self = shift;
33 0           my ($times) = $self->_check_args( \@_, ['times'] );
34 0 0         if ($times) {
35 0           for ( my $i = 0; $i < $times; $i++ ) {
36 0           eval { $self->read( brutal => 1 ) };
  0            
37             }
38             }
39             else {
40 0           while ( $self->read( brutal => 1 ) ) {
41 0           print "Cleaning buffer.";
42             }
43             }
44             }
45              
46             sub set_frequency {
47 0     0 1   my ( $self, $freq ) = @_;
48 0           $self->write("FREQ $freq");
49             }
50              
51             sub set_frq {
52 0     0 0   my $self = shift;
53 0           my ($freq) = $self->_check_args( \@_, ['value'] );
54 0           $self->set_frequency($freq);
55             }
56              
57             sub get_frequency {
58 0     0 1   my $self = shift;
59 0           my $freq = $self->query("FREQ?");
60 0           chomp $freq;
61 0           return $freq; # frequency in Hz
62             }
63              
64             sub get_frq {
65 0     0 0   my $self = shift;
66 0           my $freq = $self->get_frequency();
67 0           return $freq;
68             }
69              
70             sub set_amplitude {
71 0     0 1   my $self = shift;
72 0           my ($ampl) = $self->_check_args( \@_, ['value'] );
73 0           $self->write("SLVL $ampl");
74 0           my $realampl = $self->query("SLVL?");
75 0           chomp $realampl;
76 0           return $realampl; # amplitude in V
77             }
78              
79             sub get_amplitude {
80 0     0 1   my $self = shift;
81 0           my $ampl = $self->query("SLVL?");
82 0           chomp $ampl;
83 0           return $ampl; # amplitude in V
84             }
85              
86             sub set_sens {
87              
88             # set sensitivity to value equal to or greater than argument (in V), Range 2nV..1V
89 0     0 1   my ( $self, $sens ) = @_;
90 0           my $nr = 26;
91              
92 0 0         if ( $sens < 2E-9 ) { $nr = 0; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
93 0           elsif ( $sens <= 5E-9 ) { $nr = 1; }
94 0           elsif ( $sens <= 1E-8 ) { $nr = 2; }
95 0           elsif ( $sens <= 2E-8 ) { $nr = 3; }
96 0           elsif ( $sens <= 5E-8 ) { $nr = 4; }
97 0           elsif ( $sens <= 1E-7 ) { $nr = 5; }
98 0           elsif ( $sens <= 2E-7 ) { $nr = 6; }
99 0           elsif ( $sens <= 5E-7 ) { $nr = 7; }
100 0           elsif ( $sens <= 1E-6 ) { $nr = 8; }
101 0           elsif ( $sens <= 2E-6 ) { $nr = 9; }
102 0           elsif ( $sens <= 5E-6 ) { $nr = 10; }
103 0           elsif ( $sens <= 1E-5 ) { $nr = 11; }
104 0           elsif ( $sens <= 2E-5 ) { $nr = 12; }
105 0           elsif ( $sens <= 5E-5 ) { $nr = 13; }
106 0           elsif ( $sens <= 1E-4 ) { $nr = 14; }
107 0           elsif ( $sens <= 2E-4 ) { $nr = 15; }
108 0           elsif ( $sens <= 5E-4 ) { $nr = 16; }
109 0           elsif ( $sens <= 1E-3 ) { $nr = 17; }
110 0           elsif ( $sens <= 2E-3 ) { $nr = 18; }
111 0           elsif ( $sens <= 5E-3 ) { $nr = 19; }
112 0           elsif ( $sens <= 1E-2 ) { $nr = 20; }
113 0           elsif ( $sens <= 2E-2 ) { $nr = 21; }
114 0           elsif ( $sens <= 5E-2 ) { $nr = 22; }
115 0           elsif ( $sens <= 1E-1 ) { $nr = 23; }
116 0           elsif ( $sens <= 2E-1 ) { $nr = 24; }
117 0           elsif ( $sens <= 5E-1 ) { $nr = 25; }
118              
119 0           $self->write("SENS $nr");
120              
121 0           my $realsens = $self->query("SENS?");
122 0           my @senses = (
123             "2e-9", "5e-9", "10e-9", "20e-9", "50e-9", "100e-9",
124             "200e-9", "500e-9", "1e-6", "2e-6", "5e-6", "10e-6",
125             "20e-6", "50e-6", "100e-6", "200e-6", "500e-6", "1e-3",
126             "2e-3", "5e-3", "10e-3", "20e-3", "50e-3", "100e-3",
127             "200e-3", "500e-3", "1"
128             );
129 0           return $senses[$realsens]; # in V
130             }
131              
132             sub get_sens {
133 0     0 1   my @senses = (
134             "2e-9", "5e-9", "10e-9", "20e-9", "50e-9", "100e-9",
135             "200e-9", "500e-9", "1e-6", "2e-6", "5e-6", "10e-6",
136             "20e-6", "50e-6", "100e-6", "200e-6", "500e-6", "1e-3",
137             "2e-3", "5e-3", "10e-3", "20e-3", "50e-3", "100e-3",
138             "200e-3", "500e-3", "1"
139             );
140 0           my $self = shift;
141 0           my $nr = $self->query("SENS?");
142 0           return $senses[$nr]; # in V
143             }
144              
145             #
146             # Set sensitivity to 2x the current amplitude (or $minimum_sensitivity, if given)
147             # set_sens_auto( $minimum_sensitivity );
148             #
149             sub set_sens_auto {
150 0     0 0   my $self = shift;
151 0   0       my $minsens = shift || 0;
152 0           my $V = get_amplitude();
153              
154             #print "V=$V\tminsens=$minsens\n";
155             #my ($lix, $liy) = $self->read_xy();
156 0 0         if ( abs($V) >= $minsens / 2 ) {
157 0           $self->set_sens( abs( $V * 2. ) );
158 0           my ( $lix, $liy ) = $self->get_xy();
159             }
160             else {
161 0           $self->set_sens( abs($minsens) );
162 0           my ( $lix, $liy ) = $self->get_xy();
163             }
164             }
165              
166             sub set_tc {
167              
168             # set time constant to value greater than or equal to argument given, value in s
169              
170 0     0 1   my ( $self, $tc ) = @_;
171 0           my $nr = 19;
172              
173 0 0         if ( $tc < 1E-5 ) { $nr = 0; }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
174 0           elsif ( $tc < 3E-5 ) { $nr = 1; }
175 0           elsif ( $tc < 1E-4 ) { $nr = 2; }
176 0           elsif ( $tc < 3E-4 ) { $nr = 3; }
177 0           elsif ( $tc < 1E-3 ) { $nr = 4; }
178 0           elsif ( $tc < 3E-3 ) { $nr = 5; }
179 0           elsif ( $tc < 1E-2 ) { $nr = 6; }
180 0           elsif ( $tc < 3E-2 ) { $nr = 7; }
181 0           elsif ( $tc < 1E-1 ) { $nr = 8; }
182 0           elsif ( $tc < 3E-1 ) { $nr = 9; }
183 0           elsif ( $tc < 1 ) { $nr = 10; }
184 0           elsif ( $tc < 3 ) { $nr = 11; }
185 0           elsif ( $tc < 10 ) { $nr = 12; }
186 0           elsif ( $tc < 30 ) { $nr = 13; }
187 0           elsif ( $tc < 100 ) { $nr = 14; }
188 0           elsif ( $tc < 300 ) { $nr = 15; }
189 0           elsif ( $tc < 1000 ) { $nr = 16; }
190 0           elsif ( $tc < 3000 ) { $nr = 17; }
191 0           elsif ( $tc < 10000 ) { $nr = 18; }
192              
193 0           $self->write("OFLT $nr");
194              
195 0           my @tc = (
196             "10e-6", "30e-6", "100e-6", "300e-6", "1e-3", "3e-3",
197             "10e-3", "30e-3", "100e-3", "300e-3", "1", "3",
198             "10", "30", "100", "300", "1e3", "3e3",
199             "10e3", "30e3"
200             );
201 0           my $realtc = $self->query("OFLT?");
202 0           return $tc[$realtc]; # in sec
203              
204             }
205              
206             sub get_tc {
207 0     0 1   my @tc = (
208             "10e-6", "30e-6", "100e-6", "300e-6", "1e-3", "3e-3",
209             "10e-3", "30e-3", "100e-3", "300e-3", "1", "3",
210             "10", "30", "100", "300", "1e3", "3e3",
211             "10e3", "30e3"
212             );
213              
214 0           my $self = shift;
215 0           my $nr = $self->query("OFLT?");
216 0           return $tc[$nr]; # in sec
217             }
218              
219             sub get_xy {
220              
221             # get value of X and Y channel (recorded simultaneously) as array
222 0     0 1   my $self = shift;
223 0           my $tmp = $self->query("SNAP?1,2");
224 0           chomp $tmp;
225 0           my @arr = split( /,/, $tmp );
226 0           return @arr;
227             }
228              
229             sub get_rphi {
230              
231             # get value of amplitude and phase (recorded simultaneously) as array
232 0     0 1   my $self = shift;
233 0           my $tmp = $self->query("SNAP?3,4");
234 0           chomp $tmp;
235 0           my @arr = split( /,/, $tmp );
236 0           return @arr;
237             }
238              
239             sub get_channels {
240              
241             # get value of channel1 and channel2 as array
242 0     0 0   my $self = shift;
243              
244 0           $self->query("OUTR?1");
245 0           $self->query("OUTR?2");
246 0           my $x = $self->query("OUTR?1");
247 0           my $y = $self->query("OUTR?2");
248 0           chomp $x;
249 0           chomp $y;
250 0           my @arr = ( $x, $y );
251 0           return @arr;
252             }
253              
254             sub id {
255 0     0 1   my $self = shift;
256 0           return $self->query('*IDN?');
257             }
258              
259             1;
260              
261             __END__
262              
263             =pod
264              
265             =encoding utf-8
266              
267             =head1 NAME
268              
269             Lab::Instrument::SR830 - Stanford Research SR830 lock-in amplifier
270              
271             =head1 VERSION
272              
273             version 3.880
274              
275             =head1 SYNOPSIS
276              
277             use Lab::Instrument::SR830;
278            
279             my $sr=new Lab::Instrument::SR830(
280             connection_type=>'LinuxGPIB',
281             gpib_address=>12,
282             );
283              
284             ($x,$y) = $sr->get_xy();
285             ($r,$phi) = $sr->get_rphi();
286              
287             =head1 DESCRIPTION
288              
289             The Lab::Instrument::SR830 class implements an interface to the
290             Stanford Research SR830 Lock-In Amplifier.
291              
292             =head1 CONSTRUCTOR
293              
294             $sr830=new Lab::Instrument::SR830($board,$gpib);
295              
296             =head1 METHODS
297              
298             =head2 get_xy
299              
300             ($x,$y)= $sr830->get_xy();
301              
302             Reads channels x and y simultaneously; returns an array.
303              
304             =head2 get_rphi
305              
306             ($r,$phi)= $sr830->get_rphi();
307              
308             Reads amplitude and phase simultaneously; returns an array.
309              
310             =head2 set_sens
311              
312             $string=$sr830->set_sens(1E-7);
313              
314             Sets sensitivity (value given in V); possible values are:
315             2 nV, 5 nV, 10 nV, 20 nV, 50 nV, 100 nV, ..., 100 mV, 200 mV, 500 mV, 1V
316             If the argument is not in this list, the next higher value will be chosen.
317              
318             Returns the value of the sensitivity that was actually set, as number in Volt.
319              
320             =head2 get_sens
321              
322             $sens = $sr830->get_sens();
323              
324             Returns the value of the sensitivity, as number in Volt.
325              
326             =head2 set_tc
327              
328             $string=$sr830->set_tc(1E-3);
329              
330             Sets time constant (value given in seconds); possible values are:
331             10 us, 30us, 100 us, 300 us, ..., 10000 s, 30000 s
332             If the argument is not in this list, the next higher value will be chosen.
333              
334             Returns the value of the time constant that was actually set, as number in seconds.
335              
336             =head2 get_tc
337              
338             $tc = $sr830->get_tc();
339              
340             Returns the time constant, as number in seconds.
341              
342             =head2 set_frequency
343              
344             $sr830->set_frequency(334);
345              
346             Sets reference frequency; value given in Hz. Values between 0.001 Hz and 102 kHz can be set.
347              
348             =head2 get_frequency
349              
350             $freq=$sr830->get_frequency();
351              
352             Returns reference frequency in Hz.
353              
354             =head2 set_amplitude
355              
356             $sr830->set_amplitude(0.005);
357              
358             Sets output amplitude to the value given (in V); values between 4 mV and 5 V are possible.
359              
360             =head2 get_amplitude
361              
362             $ampl=$sr830->get_amplitude();
363              
364             Returns amplitude of the sine output in V.
365              
366             =head2 id
367              
368             $id=$sr830->id();
369              
370             Returns the instruments ID string.
371              
372             =head1 CAVEATS/BUGS
373              
374             command to change a property like amplitude or time constant might have to be executed twice to take effect
375              
376             =head1 SEE ALSO
377              
378             =over 4
379              
380             =item Lab::Instrument
381              
382             =back
383              
384             =head1 COPYRIGHT AND LICENSE
385              
386             This software is copyright (c) 2023 by the Lab::Measurement team; in detail:
387              
388             Copyright 2009 Andreas K. Huettel, Daniela Taubert
389             2010 Andreas K. Huettel, Daniel Schroeer
390             2011 Andreas K. Huettel, Florian Olbrich
391             2013 Andreas K. Huettel
392             2014 Alois Dirnaichner, Andreas K. Huettel
393             2016 Simon Reinhardt
394             2017 Andreas K. Huettel
395             2019 Simon Reinhardt
396             2020 Andreas K. Huettel
397              
398              
399             This is free software; you can redistribute it and/or modify it under
400             the same terms as the Perl 5 programming language system itself.
401              
402             =cut