File Coverage

blib/lib/Lab/Moose/Instrument/Rigol_DG5000.pm
Criterion Covered Total %
statement 32 210 15.2
branch 0 18 0.0
condition 0 6 0.0
subroutine 11 70 15.7
pod 54 59 91.5
total 97 363 26.7


line stmt bran cond sub pod time code
1             package Lab::Moose::Instrument::Rigol_DG5000;
2             $Lab::Moose::Instrument::Rigol_DG5000::VERSION = '3.881';
3             #ABSTRACT: Rigol DG5000 series Function/Arbitrary Waveform Generator
4              
5 1     1   2661 use v5.20;
  1         5  
6              
7 1     1   5 use Moose;
  1         3  
  1         10  
8 1     1   7332 use MooseX::Params::Validate;
  1         2  
  1         9  
9 1     1   586 use Moose::Util::TypeConstraints qw/enum/;
  1         7  
  1         12  
10 1     1   581 use List::Util qw/sum/;
  1         2  
  1         83  
11 1     1   7 use List::MoreUtils qw/minmax/;
  1         3  
  1         10  
12 1     1   785 use Math::Round;
  1         2  
  1         82  
13             use Lab::Moose::Instrument
14 1     1   10 qw/validated_channel_getter validated_channel_setter validated_getter validated_setter/;
  1         3  
  1         83  
15 1     1   8 use Lab::Moose::Instrument::Cache;
  1         2  
  1         10  
16 1     1   777 use Carp 'croak';
  1         4  
  1         47  
17 1     1   9 use namespace::autoclean;
  1         12  
  1         10  
18              
19             extends 'Lab::Moose::Instrument';
20              
21             has instrument_nselect => (
22             is => 'ro',
23             isa => 'Int',
24             default => 1
25             );
26              
27             around default_connection_options => sub {
28             my $orig = shift;
29             my $self = shift;
30             my $options = $self->$orig();
31             my $usb_opts = { vid => 0x1ab1, pid => 0x0640 };
32             $options->{USB} = $usb_opts;
33             $options->{'VISA::USB'} = $usb_opts;
34             return $options;
35             };
36              
37             sub BUILD {
38 0     0 0   my $self = shift;
39 0           $self->clear();
40 0           $self->cls();
41             }
42              
43             sub get_default_channel {
44 0     0 0   my $self = shift;
45 0           return $self->instrument_nselect;
46             }
47              
48              
49             #
50             # MY FUNCTIONS
51             #
52              
53              
54             sub gen_arb_step {
55 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter(
56             \@_,
57             sequence => { isa => 'ArrayRef' },
58             bdelay => { isa => 'Num', default => 0 },
59             bcycles => { isa => 'Num', default => 1 }
60             );
61             my ( $sequence, $bdelay, $bcycles )
62 0           = delete @args{qw/sequence bdelay bcycles/};
63 0           my @data = @$sequence; # Dereference the input data
64              
65             # If number of input data points is uneven croak
66 0 0         if ( @data % 2 != 0 ) {
67 0           croak "Please enter an even number of arguments with
68             the layout <amplitude1[V]>,<length1[s]>,<amplitude2[V]>,<length2[s]>,...";
69             }
70              
71             # Split input data into the time lengths and amplitude values...
72 0           my @times = @data[ grep { $_ % 2 == 1 } 0 .. @data - 1 ];
  0            
73 0           my @amps = @data[ grep { $_ % 2 == 0 } 0 .. @data - 1 ];
  0            
74              
75             # ...and compute the period lentgth as well as the min and max amplitude
76 0           my $period = sum @times;
77 0           my ( $minamp, $maxamp ) = minmax @amps;
78              
79             # now apply everything to the Rigol: Frequency = 1/T, amplitude and offset
80             # are computed, so that the whole waveform lies within that amplitude range
81 0           $self->source_apply_arb(
82             channel => $channel, freq => 1 / $period,
83             amp => 2 * abs($maxamp) + 2 * abs($minamp),
84             offset => $maxamp + $minamp, phase => 0.0
85             );
86 0           $self->arb_mode( channel => $channel, value => 'INTernal' );
87 0           $self->trace_data_points_interpolate( value => 'OFF' );
88              
89             # Convert all amplitudes into values from 0 to 16383 (14Bit) and generate
90             # 16384 data points in total
91 0           my $input = "";
92 0           my $counter;
93              
94             # go through each amp (or time) value
95 0           foreach ( 0 .. @amps - 1 ) {
96              
97             # Compute what length in units of the resolution (16384) each step has
98 0           my $c = round( 16383 * $times[$_] / $period );
99 0           $counter += $c; # Count them all up
100             # On the last iteration check, if there are really 16384 data points,
101             # there might be less because of rounding. Add the remaining at the end if
102             # necessary
103 0 0 0       if ( $_ == @amps - 1 && $counter != 16384 ) { $c += 16384 - $counter }
  0            
104              
105             # Lastly append the according amplitude value (in 14Bit resolution) to the
106             # whole string
107 0           $input = $input
108             . (
109             ","
110             . round(
111             16383 * $amps[$_] / ( 1.5 * $maxamp - 0.5 * $minamp )
112             )
113             ) x $c;
114             }
115              
116             # Finally download everything to the volatile memory
117 0           $self->trace_data_points( value => 16384 );
118 0           $self->trace_data_dac( value => $input );
119              
120             # WIP: If a burst delay and number of cycles is given, enable burst mode
121 0           my $off = 0;
122 0 0         if ( $bdelay > 0 ) {
123 0           $self->source_burst_mode( channel => $channel, value => 'TRIG' );
124 0           $self->source_burst_tdelay( channel => $channel, value => $bdelay );
125 0           $self->source_burst_ncycles( channel => $channel, value => $bcycles );
126 0           $self->source_burst_state( channel => $channel, value => 'ON' );
127              
128 0           $self->trace_data_value( point => 0, data => 0 );
129 0           $self->trace_data_value( point => 16383, data => 0 );
130 0           $off = $amps[0];
131             }
132             }
133              
134              
135             sub arb_mode {
136 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
137             \@_,
138             value => { isa => enum( [qw/INT INTernal PLAY/] ) }
139             );
140              
141 0           $self->write(
142             command => ":SOURCE${channel}:FUNCtion:ARB:MODE $value",
143             %args
144             );
145             }
146              
147              
148             sub play_coefficient {
149 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
150             \@_,
151             value => { isa => 'Num' }
152             );
153 0 0 0       if ( $value < 0 or $value > 268435456 ) {
154 0           croak
155             "The the frequency division coefficient must be between 0 and 268435456";
156             }
157              
158             $self->write(
159 0           command => ":SOURCE${channel}:FUNCtion:ARB:SAMPLE $value",
160             %args
161             );
162             }
163              
164              
165             sub phase_align {
166 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_, );
167              
168 0           $self->write( command => ":SOURce${channel}:PHASe:INITiate", %args );
169             }
170              
171              
172             sub output_on {
173 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
174              
175 0           $self->write( command => ":OUTPut${channel}:STATe ON" );
176             }
177              
178             sub output_off {
179 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
180              
181 0           $self->write( command => ":OUTPut${channel}:STATe OFF" );
182             }
183              
184              
185             sub set_pulsewidth {
186 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
187             \@_,
188             value => { isa => 'Num' },
189             constant_delay => { isa => 'Bool', default => 0 }
190             );
191 0           my $constant_delay = delete $args{'constant_delay'};
192 0 0         if ($constant_delay) {
193 0           my $delay = $self->get_pulsedelay();
194 0           $self->set_period( channel => $channel, value => $delay + $value );
195             }
196              
197 0           $self->write( command => ":SOURce${channel}:PULSe:WIDTh $value", %args );
198             }
199              
200             sub get_pulsewidth {
201 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
202              
203 0           return $self->query( command => ":SOURce${channel}:PULSe:WIDTh?", %args );
204             }
205              
206              
207             sub set_pulsedelay {
208 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
209             \@_,
210             value => { isa => 'Num' },
211             constant_width => { isa => 'Bool', default => 0 }
212             );
213 0           my $constant_width = delete $args{'constant_width'};
214 0 0         if ($constant_width) {
215 0           my $width = $self->get_pulsewidth();
216 0           $self->set_period( channel => $channel, value => $width + $value );
217             }
218              
219 0           $self->write( command => ":SOURce${channel}:PULSe:DELay $value", %args );
220             }
221              
222             sub get_pulsedelay {
223 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
224              
225 0           return $self->query( command => ":SOURce${channel}:PULSe:DELay?", %args );
226             }
227              
228              
229             sub set_period {
230 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
231             \@_,
232             value => { isa => 'Num' }
233             );
234              
235 0           $self->write( command => ":SOURce${channel}:PERiod $value", %args );
236             }
237              
238             sub get_period {
239 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
240              
241 0           return $self->query( command => ":SOURce${channel}:PERiod?", %args );
242             }
243              
244              
245             sub set_frq {
246 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
247             \@_,
248             value => { isa => 'Num' }
249             );
250              
251 0           $self->write( command => ":SOURce${channel}:FREQuency $value", %args );
252             }
253              
254             sub get_frq {
255 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
256              
257 0           return $self->query( command => ":SOURce${channel}:FREQuency?", %args );
258             }
259              
260              
261             sub set_voltage {
262 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
263             \@_,
264             value => { isa => 'Num' }
265             );
266              
267 0           $self->write(
268             command => ":SOURce${channel}:VOLTage:AMPLitude $value",
269             %args
270             );
271             }
272              
273             sub get_voltage {
274 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
275              
276 0           return $self->query(
277             command => ":SOURce${channel}:VOLTage:AMPLitude?",
278             %args
279             );
280             }
281              
282              
283             sub set_level {
284 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
285             \@_,
286             value => { isa => 'Num' }
287             );
288              
289 0           $self->write( command => ":SOURce${channel}:VOLTage:HIGH $value", %args );
290             }
291              
292             sub get_level {
293 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
294              
295 0           return $self->query(
296             command => ":SOURce${channel}:VOLTage:HIGH?",
297             %args
298             );
299             }
300              
301              
302             sub set_level_low {
303 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
304             \@_,
305             value => { isa => 'Num' }
306             );
307              
308 0           $self->write( command => ":SOURce${channel}:VOLTage:LOW $value", %args );
309             }
310              
311             sub get_level_low {
312 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
313              
314 0           return $self->query( command => ":SOURce${channel}:VOLTage:LOW?", %args );
315             }
316              
317              
318             sub set_offset {
319 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
320             \@_,
321             value => { isa => 'Num' }
322             );
323              
324 0           $self->write(
325             command => ":SOURce${channel}:AMPLitude:OFFSet $value",
326             %args
327             );
328             }
329              
330             sub get_offset {
331 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
332              
333 0           return $self->query(
334             command => ":SOURce${channel}:AMPLitude:OFFSet?",
335             %args
336             );
337             }
338              
339             #
340             # SOURCE APPLY
341             #
342              
343              
344             sub source_apply_pulse {
345 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter(
346             \@_,
347             freq => { isa => 'Num' },
348             amp => { isa => 'Num' },
349             offset => { isa => 'Num' },
350             delay => { isa => 'Num' },
351             );
352              
353             my ( $freq, $amp, $offset, $delay )
354 0           = delete @args{qw/freq amp offset delay/};
355              
356 0           $self->write(
357             command => "SOURCE${channel}:APPLY:PULSE $freq,$amp,$offset,$delay",
358             %args
359             );
360             }
361              
362              
363             sub source_apply_ramp {
364 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter(
365             \@_,
366             freq => { isa => 'Num' },
367             amp => { isa => 'Num' },
368             offset => { isa => 'Num' },
369             phase => { isa => 'Num' },
370             );
371              
372             my ( $freq, $amp, $offset, $phase )
373 0           = delete @args{qw/freq amp offset phase/};
374              
375 0           $self->write(
376             command => "SOURCE${channel}:APPLY:RAMP $freq,$amp,$offset,$phase",
377             %args
378             );
379             }
380              
381             sub source_apply_sinusoid {
382 0     0 0   my ( $self, $channel, %args ) = validated_channel_getter(
383             \@_,
384             freq => { isa => 'Num' },
385             amp => { isa => 'Num' },
386             offset => { isa => 'Num' },
387             phase => { isa => 'Num' },
388             );
389              
390             my ( $freq, $amp, $offset, $phase )
391 0           = delete @args{qw/freq amp offset phase/};
392              
393 0           $self->write(
394             command =>
395             "SOURCE${channel}:APPLY:SINUSOID $freq,$amp,$offset,$phase",
396             %args
397             );
398             }
399              
400             sub source_apply_square {
401 0     0 0   my ( $self, $channel, %args ) = validated_channel_getter(
402             \@_,
403             freq => { isa => 'Num' },
404             amp => { isa => 'Num' },
405             offset => { isa => 'Num' },
406             phase => { isa => 'Num' },
407             );
408              
409             my ( $freq, $amp, $offset, $phase )
410 0           = delete @args{qw/freq amp offset phase/};
411              
412 0           $self->write(
413             command => "SOURCE${channel}:APPLY:SQUare $freq,$amp,$offset,$phase",
414             %args
415             );
416             }
417              
418             sub source_apply_arb {
419 0     0 0   my ( $self, $channel, %args ) = validated_channel_getter(
420             \@_,
421             freq => { isa => 'Num' },
422             amp => { isa => 'Num' },
423             offset => { isa => 'Num' },
424             phase => { isa => 'Num' },
425             );
426              
427             my ( $freq, $amp, $offset, $phase )
428 0           = delete @args{qw/freq amp offset phase/};
429              
430 0           $self->write(
431             command => "SOURCE${channel}:APPLY:USER $freq,$amp,$offset,$phase",
432             %args
433             );
434             }
435              
436             #
437             # SOURCE BURST
438             #
439              
440              
441             sub source_burst_mode {
442 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
443             \@_,
444             value => { isa => enum( [qw/TRIG GAT INF/] ) }
445             );
446              
447 0           $self->write( command => "SOURCE${channel}:BURST:MODE $value", %args );
448             }
449              
450             sub source_burst_mode_query {
451 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
452 0           return $self->query( command => "SOURCE${channel}:BURST:MODE?", %args );
453             }
454              
455              
456             sub source_burst_ncycles {
457 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
458             \@_,
459             value => { isa => 'Lab::Moose::PosInt' }
460             );
461              
462 0           $self->write( command => "SOURCE${channel}:BURST:NCYCLES $value", %args );
463             }
464              
465             sub source_burst_ncycles_query {
466 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
467 0           return $self->query(
468             command => "SOURCE${channel}:BURST:NCYCLES?",
469             %args
470             );
471             }
472              
473              
474             sub source_burst_state {
475 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
476             \@_,
477             value => { isa => enum( [qw/ON OFF/] ) }
478             );
479              
480 0           $self->write( command => "SOURCE${channel}:BURST:STATE $value", %args );
481             }
482              
483             sub source_burst_state_query {
484 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
485 0           return $self->query( command => "SOURCE${channel}:BURST:STATE?", %args );
486             }
487              
488              
489             sub source_burst_tdelay {
490 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
491             \@_,
492             value => { isa => 'Lab::Moose::PosNum' }
493             );
494              
495 0           $self->write( command => "SOURCE${channel}:BURST:TDELAY $value", %args );
496             }
497              
498             sub source_burst_tdelay_query {
499 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
500 0           return $self->query( command => "SOURCE${channel}:BURST:TDELAY?", %args );
501             }
502              
503              
504             sub source_burst_trigger {
505 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
506 0           $self->write(
507             command => "SOURCE${channel}:BURST:TRIGGER:IMMEDIATE",
508             %args
509             );
510             }
511              
512              
513             sub source_burst_trigger_slope {
514 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
515             \@_,
516             value => { isa => enum( [qw/POS NEG/] ) }
517             );
518              
519 0           $self->write(
520             command => "SOURCE${channel}:BURST:TRIGGER:SLOPE $value",
521             %args
522             );
523             }
524              
525             sub source_burst_trigger_slope_query {
526 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
527 0           return $self->query(
528             command => "SOURCE${channel}:BURST:TRIGGER:SLOPE?",
529             %args
530             );
531             }
532              
533              
534             sub source_burst_trigger_trigout {
535 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
536             \@_,
537             value => { isa => enum( [qw/OFF POS NEG/] ) }
538             );
539              
540 0           $self->write(
541             command => "SOURCE${channel}:BURST:TRIGGER:TRIGOUT $value",
542             %args
543             );
544             }
545              
546             sub source_burst_trigger_trigout_query {
547 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
548 0           return $self->query(
549             command => "SOURCE${channel}:BURST:TRIGGER:TRIGOUT?",
550             %args
551             );
552             }
553              
554              
555             sub source_burst_trigger_source {
556 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
557             \@_,
558             value => { isa => enum( [qw/INT EXT/] ) }
559             );
560              
561 0           $self->write(
562             command => "SOURCE${channel}:BURST:TRIGGER:SOURCE $value",
563             %args
564             );
565             }
566              
567             sub source_burst_trigger_source_query {
568 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
569 0           return $self->query(
570             command => "SOURCE${channel}:BURST:TRIGGER:SOURCE?",
571             %args
572             );
573             }
574              
575              
576             sub source_burst_period {
577 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
578             \@_,
579             value => { isa => 'Lab::Moose::PosNum' }
580             );
581              
582 0           $self->write(
583             command => "SOURCE${channel}:BURST:INTERNAL:PERIOD $value",
584             %args
585             );
586             }
587              
588             #
589             # SOURCE FUNCTION
590             #
591              
592              
593             sub source_function_shape {
594 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
595             \@_,
596             value => {
597             isa => enum(
598             [
599             qw/SIN SQU RAMP PULSE NOISE USER DC SINC EXPR EXPF CARD GAUS HAV LOR ARBPULSE DUA/
600             ]
601             )
602             }
603             );
604              
605 0           $self->write(
606             command => "SOURCE${channel}:FUNCTION:SHAPE $value",
607             %args
608             );
609             }
610              
611             sub source_function_shape_query {
612 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
613 0           return $self->query(
614             command => "SOURCE${channel}:FUNCTION:SHAPE?",
615             %args
616             );
617             }
618              
619              
620             sub source_function_ramp_symmetry {
621 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
622             \@_,
623             value => { isa => 'Lab::Moose::PosNum' }
624             );
625              
626 0           $self->write(
627             command => "SOURCE${channel}:FUNCTION:RAMP:SYMMETRY $value",
628             %args
629             );
630             }
631              
632             sub source_function_ramp_symmetry_query {
633 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
634 0           return $self->query(
635             command => "SOURCE${channel}:FUNCTION:RAMP:SYMMETRY?", %args );
636             }
637              
638             #
639             # SOURCE PERIOD
640             #
641              
642              
643             sub source_period_fixed {
644 0     0 1   my ( $self, $channel, $value, %args ) = validated_channel_setter(
645             \@_,
646             value => { isa => 'Lab::Moose::PosNum' }
647             );
648              
649 0           $self->write( command => "SOURCE${channel}:PERIOD:FIXED $value", %args );
650             }
651              
652             sub source_period_fixed_query {
653 0     0 1   my ( $self, $channel, %args ) = validated_channel_getter( \@_ );
654 0           return $self->query( command => "SOURCE${channel}:PERIOD:FIXED?", %args );
655             }
656              
657             #
658             # TRACE
659             #
660              
661              
662             sub trace_data_data {
663 0     0 1   my ( $self, %args ) = validated_getter(
664             \@_,
665             data => { isa => 'ArrayRef[Num]' }
666             );
667              
668 0           my $data = delete $args{data};
669 0           my @data = @{$data};
  0            
670 0 0         if ( @data < 1 ) {
671 0           croak("empty data argument");
672             }
673              
674 0           $data = join( ',', @data );
675              
676 0           $self->write( command => "TRACE:DATA:DATA VOLATILE,$data", %args );
677             }
678              
679              
680             sub trace_data_value {
681 0     0 1   my ( $self, %args ) = validated_getter(
682             \@_,
683             point => { isa => 'Lab::Moose::PosInt' },
684             data => { isa => 'Num' }
685             );
686 0           my $point = delete $args{point};
687 0           my $data = delete $args{data};
688              
689 0           $self->write(
690             command => "TRACE:DATA:VALUE VOLATILE,$point,$data",
691             %args
692             );
693             }
694              
695             sub trace_data_value_query {
696 0     0 1   my ( $self, %args ) = validated_getter(
697             \@_,
698             point => { isa => 'Lab::Moose::PosInt' },
699             );
700 0           my $point = delete $args{point};
701              
702 0           return $self->query(
703             command => "TRACE:DATA:VALUE? VOLATILE,$point",
704             %args
705             );
706             }
707              
708              
709             sub trace_data_points {
710 0     0 1   my ( $self, $value, %args ) = validated_setter(
711             \@_,
712             value => { isa => 'Lab::Moose::PosInt' }
713             );
714              
715 0 0         if ( $value < 2 ) {
716 0           croak("The minimum number of inital data points is 2");
717             }
718              
719 0           $self->write( command => "TRACE:DATA:POINTS VOLATILE,$value", %args );
720             }
721              
722             sub trace_data_points_query {
723 0     0 1   my ( $self, %args ) = validated_getter( \@_ );
724 0           return $self->query( command => "TRACE:DATA:POINTS? VOLATILE", %args );
725             }
726              
727              
728             sub trace_data_points_interpolate {
729 0     0 1   my ( $self, $value, %args ) = validated_setter(
730             \@_,
731             value => { isa => enum( [qw/LIN SINC OFF/] ) },
732             );
733 0           $self->write( command => "TRACE:DATA:POINTS:INTERPOLATE $value", %args );
734             }
735              
736             sub trace_data_points_interpolate_query {
737 0     0 1   my ( $self, %args ) = validated_getter( \@_ );
738 0           return $self->query( command => "TRACE:DATA:POINTS:INTERPOLATE?", %args );
739             }
740              
741              
742             sub trace_data_dac {
743 0     0 1   my ( $self, $value, %args ) = validated_setter(
744             \@_,
745             value => { isa => 'Str' }
746             );
747 0 0         if ( substr( $value, 0, 1 ) eq ',' ) {
748 0           $self->write( command => "TRACE:DATA:DAC VOLATILE$value", %args );
749             }
750             else {
751 0           $self->write( command => "TRACE:DATA:DAC VOLATILE,$value", %args );
752             }
753             }
754              
755             with qw(
756             Lab::Moose::Instrument::Common
757             );
758              
759             __PACKAGE__->meta()->make_immutable();
760              
761             1;
762              
763             __END__
764              
765             =pod
766              
767             =encoding UTF-8
768              
769             =head1 NAME
770              
771             Lab::Moose::Instrument::Rigol_DG5000 - Rigol DG5000 series Function/Arbitrary Waveform Generator
772              
773             =head1 VERSION
774              
775             version 3.881
776              
777             =head1 SYNOPSIS
778              
779             use Lab::Moose;
780              
781             my $rigol = instrument(
782             type => 'Rigol_DG5000',
783             connection_type => 'USB', # For NT-VISA use 'VISA::USB'
784             instrument_nselect => 2,
785             );
786              
787             All C<source_*>, C<set_*> and C<get_*> commands accept a C<channel> argument,
788             which can be 1 or 2. On initalization an argument C<instrument_nselect> can be
789             passed to specify a default channel, though if C<instrument_nselect> is not passed
790             the default channel is 1:
791              
792             $rigol->source_function_shape(value => 'SIN'); # Channel 1
793             $rigol->source_function_shape(value => 'SQU', channel => 2); # Channel 2
794              
795             =head1 METHODS
796              
797             Used roles:
798              
799             =over
800              
801             =item L<Lab::Moose::Instrument::Common>
802              
803             =back
804              
805             =head2 gen_arb_step
806              
807             $rigol->gen_arb_step(channel => 1, sequence => [
808             0.2, 0.00002,
809             0.5, 0.0001,
810             0.35, 0.0001
811             ], bdelay => 0, bcycles => 1
812             );
813              
814             Generate an arbitrary voltage step function. With C<sequence> an array referrence is
815             passed to the function, containing data pairs of an amplitude and time value.
816             The example above repeatedly outputs a constant 200mV for 20µs, 500mV for
817             100µs and 350mV for 100µs.
818              
819             WORK IN PROGRESS: With C<bdelay> and C<bcycles> a delay between a specified
820             amount of cycles is enabled using the Rigols burst mode.
821              
822             C<bdelay> = 0 by default disabling burst mode.
823              
824             =head2 arb_mode
825              
826             $rigol->arb_mode(value => 'INTernal');
827              
828             Allowed values: C<INT, INTernal, PLAY>. In normal or internal mode he output
829             frequency ranges from 1 μHz to 50 MHz, and the sample rate is fixed at 1G Sa/s,
830             while the number of points is 16Mpts. Play mode is used once the number of points
831             of the arbitrary waveform to be output is greater than 16 Mpts, ranging up to
832             128Mpts. See the Rigols user manual page 3-4 and following for more information.
833              
834             =head2 play_coefficient
835              
836             $rigol->play_coefficient(value => 10);
837              
838             When using the arbitrary waveform in play mode, a frequency division coefficient
839             C<N> can be used to reduce the sample rate fs via the relations
840              
841             =over 4
842              
843             =item * fs = 1G/2^N, When N≤2
844              
845             =item * fs = 1G/((N-2)*8), when N>2
846              
847             =back
848              
849             The range of N is from 0 to 268435456 (2^28). See the Rigol user manual page
850             3-4 and following for more information.
851              
852             =head2 phase_align
853              
854             $rigol->phase_align();
855              
856             Phase-align the two output channels, only available if the output function is
857             either Sine, Square, Ramp or Arbitrary.
858              
859             =head2 output_on/output_off
860              
861             $rigol->output_on(channel => 1);
862             $rigol->output_off(channel => 2);
863              
864             Turn output channels on or off.
865              
866             =head2 set_pulsewidth/get_pulsewidth
867              
868             $rigol->set_pulsewidth(channel => 1, value => 0.0000001, constant_delay => 1);
869             $rigol->get_pulsewidth();
870              
871             When the output functon is C<PULSE> these subroutines set/get the pulses width
872             in s. This reduces the pulse delay however, since the pulse period stays the same.
873             An optional parameter C<constant_delay> can be passed to adapt the waveform period
874             and keep the delay constant.
875              
876             =head2 set_pulsedelay/get_pulsedelay
877              
878             $rigol->set_pulsedelay(channel => 1, value => 0.0000003, constant_width => 1);
879             $rigol->get_pulsedelay();
880              
881             When the output functon is C<PULSE> these subroutines set/get the pulses width
882             in s. This reduces the pulse delay however, since the pulse period stays the same.
883             As with the delay an optional parameter C<constant_width> can be passed to adapt
884             the waveform period and keep the width constant.
885              
886             =head2 set_period/get_period
887              
888             $rigol->set_period(channel => 1, value => 0.00000045);
889             $rigol->get_period();
890              
891             Set/query the current waveforms period in s.
892              
893             =head2 set_frq/get_frq
894              
895             $rigol->set_frq(channel => 1, value => 10000000);
896             $rigol->get_frq();
897              
898             Set/query the current waveforms frequency in Hz. This subroutine is used for
899             frequency sweeps.
900              
901             =head2 set_voltage/get_voltage
902              
903             $rigol->set_voltage(channel => 1, value => 1);
904             $rigol->get_voltage();
905              
906             Set/query the current waveforms peak-to-peak amplitude in volts.
907              
908             =head2 set_level/get_level
909              
910             $rigol->set_level(channel => 1, value => 1);
911             $rigol->get_level();
912              
913             Set/query the current waveforms maximum amplitude amplitude in volts. This
914             subroutine is used for voltage sweeps.
915              
916             =head2 set_level_low/get_level_low
917              
918             $rigol->set_level_low(channel => 1, value => 1);
919             $rigol->get_level_low();
920              
921             Set/query the current waveforms minimum amplitude amplitude in volts.
922              
923             =head2 set_offset/get_offset
924              
925             $rigol->set_offset(channel => 1, value => 0.5);
926             $rigol->get_offset();
927              
928             Set/query the current waveforms dc offset in volts.
929              
930             =head2 source_apply_pulse
931              
932             $rigol->source_apply_ramp(
933             freq => ...,
934             amp => ...,
935             offset => ...,
936             delay => ...
937             );
938              
939             Apply a pulse function with the given parameters,
940              
941             =over 4
942              
943             =item * C<freq> = frequency in Hz
944              
945             =item * C<amp> = amplitude in Volts
946              
947             =item * C<offset> = DC offset in Volts
948              
949             =item * C<delay> = pulse delay in seconds
950              
951             =back
952              
953             =head2 source_apply_ramp/square/arb
954              
955             $rigol->source_apply_ramp(
956             freq => ...,
957             amp => ...,
958             offset => ...,
959             phase => ...
960             );
961              
962             Apply a ramp, sine, square function or arbitrary waveform with the given parameters,
963              
964             =over 4
965              
966             =item * C<freq> = frequency in Hz
967              
968             =item * C<amp> = amplitude in Volts
969              
970             =item * C<offset> = DC offset in Volts
971              
972             =item * C<phase> = phase in degrees (0 to 360)
973              
974             =back
975              
976             =head2 source_burst_mode/source_burst_mode_query
977              
978             $rigol->source_burst_mode(value => 'TRIG');
979             say $rigol->source_burst_mode_query();
980              
981             Allowed values: C<TRIG, GAT, INF>.
982             For more information see the Rigols user manual page 7-3.
983              
984             =head2 source_burst_ncycles/source_burst_ncycles_query
985              
986             $rigol->source_burst_ncycles(value => 1);
987             say $rigol->source_burst_ncycles_query();
988              
989             Output a specified amount of full wave cycles, with a delay between them.
990             See source_burst_tdelay/source_burst_tdelay_query for more information.
991              
992             =head2 source_burst_state/source_burst_state_query
993              
994             $rigol->source_burst_state(value => 'ON');
995             say $rigol_source_burst_state_query();
996              
997             Allowed values: C<ON, OFF>
998             Turns the burst mode on or off.
999              
1000             =head2 source_burst_tdelay/source_burst_tdelay_query
1001              
1002             $rigol->source_burst_tdelay(value => 1e-3);
1003             say $rigol->source_burst_tdelay_query();
1004              
1005             Specify/query the delay between bursts in seconds.
1006              
1007             =head2 source_burst_trigger
1008              
1009             $rigol->source_burst_trigger();
1010              
1011             Trigger a burst via program.
1012              
1013             =head2 source_burst_trigger_slope/source_burst_trigger_slope_query
1014              
1015             $rigol->source_burst_trigger_slope(value => 'POS');
1016             say $rigol->source_burst_trigger_slope_query();
1017              
1018             Allowed values: C<POS, NEG>.
1019             In Gated mode, the generator will output burst at specified polarity of the
1020             gated signal received from the [ExtTrig] connector at the rear panel.
1021              
1022             =head2 source_burst_trigger_trigout/source_burst_trigger_trigout_query
1023              
1024             $rigol->source_burst_trigger_trigout(value => 'POS');
1025             $rigol->source_burst_trigger_trigout_query();
1026              
1027             Allowed values: C<POS, NEG, OFF>.
1028             In Burst mode, when “Internal” or “Manual” trigger source is selected, the generator
1029             will output a TTL compatible signal with specified polarity from the [ExtTrig] connector
1030             at the rear panel.
1031             For more information see the Rigols user manual page 7-7.
1032              
1033             =head2 source_burst_trigger_source/source_burst_trigger_source_query
1034              
1035             $rigol->source_burst_trigger_source(value => 'INT');
1036             $rigol->source_burst_trigger_source_query();
1037              
1038             Allowed values: C<INT, EXT>.
1039             Specify whether the trigger signal for a burst is controlled internally or
1040             externally via the [ExtTrig] connector.
1041             For more information see the Rigols user manual page 7-6.
1042              
1043             =head2 source_burst_period
1044              
1045             $rigol->source_burst_period(value => 0.00001);
1046              
1047             Defined as the time from the beginning of the N cycle burst to the beginning of
1048             the next burst. Only for N cycle burst in internal trigger mode.
1049              
1050             =head2 source_function_shape/source_function_shape_query
1051              
1052             $rigol->source_function_shape(value => 'SIN');
1053             say $rigol->source_function_shape_query();
1054              
1055             Allowed values: C<SIN, SQU, RAMP, PULSE, NOISE, USER, DC, SINC, EXPR, EXPF, CARD, GAUS, HAV, LOR, ARBPULSE, DUA>.
1056              
1057             =head2 source_function_ramp_symmetry/source_function_ramp_symmetry_query
1058              
1059             $rigol->source_function_ramp_symmetry(value => 100);
1060             say $rigol->source_function_ramp_symmetry_query();
1061              
1062             =head2 source_period_fixed/source_period_fixed_query
1063              
1064             $rigol->source_period_fixed(value => 1e-3);
1065             say $rigol->source_period_fixed_query();
1066              
1067             =head2 trace_data_data
1068              
1069             my $values = [-0.6,-0.5,-0.4,-0.3,-0.2,-0.1,0,0.1,0.2,0.3,0.4,0.5,0.6];
1070             $rigol->trace_data_data(data => $values);
1071              
1072             =head2 trace_data_value/trace_data_value_query
1073              
1074             $rigol->trace_data_value(point => 2, data => 8192);
1075              
1076             Modify the second point to the decimal number 8192.
1077              
1078             $rigol->trace_data_value_query(point => 2);
1079              
1080             =head2 trace_data_points/trace_data_points_query
1081              
1082             $rigol->trace_data_points(value => 3);
1083             say $rigol->trace_data_points_query();
1084              
1085             =head2 trace_data_points_interpolate/trace_data_points_interpolate_query
1086              
1087             $rigol->trace_data_points_interpolate(value => 'LIN');
1088             say $rigol->trace_data_points_interpolate_query();
1089              
1090             Allowed values: C<LIN, SINC, OFF>.
1091              
1092             =head2 trace_data_dac
1093              
1094             $rigol->trace_data_dac(value => '16383,8192,0,0,8192,8192,6345,0');
1095              
1096             Input a string of comma-seperated integers ranging from 0 to 16383 (14Bit). If
1097             there are less than 16384 data points given, the Rigol will automatically
1098             interpolate.
1099              
1100             =head1 COPYRIGHT AND LICENSE
1101              
1102             This software is copyright (c) 2023 by the Lab::Measurement team; in detail:
1103              
1104             Copyright 2020 Simon Reinhardt
1105             2021 Andreas K. Huettel, Fabian Weinelt, Simon Reinhardt
1106             2022 Simon Reinhardt
1107              
1108              
1109             This is free software; you can redistribute it and/or modify it under
1110             the same terms as the Perl 5 programming language system itself.
1111              
1112             =cut