File Coverage

blib/lib/Lab/Moose/Instrument/ProStep4.pm
Criterion Covered Total %
statement 20 307 6.5
branch 0 90 0.0
condition 0 51 0.0
subroutine 7 24 29.1
pod 0 15 0.0
total 27 487 5.5


line stmt bran cond sub pod time code
1             package Lab::Moose::Instrument::ProStep4;
2             $Lab::Moose::Instrument::ProStep4::VERSION = '3.880';
3             #ABSTRACT: ProStep4 step motor
4             #TODO: Documentation!!!
5              
6 1     1   8910 use v5.20;
  1         4  
7              
8 1     1   7 use Moose;
  1         2  
  1         8  
9 1     1   8465 use Moose::Util::TypeConstraints qw/enum/;
  1         5  
  1         12  
10 1     1   595 use MooseX::Params::Validate;
  1         3  
  1         10  
11 1         77 use Lab::Moose::Instrument qw/
12 1     1   541 validated_getter validated_setter validated_no_param_setter setter_params /;
  1         3  
13 1     1   7 use Carp;
  1         435  
  1         90  
14 1     1   8 use namespace::autoclean;
  1         2  
  1         12  
15              
16             extends 'Lab::Moose::Instrument';
17              
18              
19             #has AXIS => (
20             # is => 'ro',
21             # isa => 'Int',
22             # default => 1
23             #);
24             #
25             #has RESOLUTION => (
26             # is => 'ro',
27             # isa => 'Int',
28             # default => 1024
29             #);
30             #
31             #has GETRIEBEMULTIPLIKATOR => (
32             # is => 'ro',
33             # isa => 'Num',
34             # default => 0.015
35             #);
36             #
37             #has NULL => (
38             # is => 'ro',
39             # isa => 'Int',
40             # default => 32768
41             #);
42             #
43             #has STEPS_PER_ROUND => (
44             # is => 'ro',
45             # isa => 'Int',
46             # default => 400
47             #);
48             #
49             #has BACKLASH => (
50             # is => 'ro',
51             # isa => 'Int',
52             # default => 200
53             #);
54             #
55             #has AA => (
56             # is => 'ro',
57             # isa => 'Int',
58             # default => 200
59             #);
60             #
61             #has AE => (
62             # is => 'ro',
63             # isa => 'Int',
64             # default => 200
65             #);
66             #
67             #has VA => (
68             # is => 'ro',
69             # isa => 'Int',
70             # default => 0
71             #);
72             #
73             #has VE => (
74             # is => 'ro',
75             # isa => 'Int',
76             # default => 30
77             #);
78             #
79             #has VM => (
80             # is => 'ro',
81             # isa => 'Int',
82             # default => 30
83             #);
84              
85             has on => (
86             is => 'rw',
87             isa => 'Int',
88             default => 0
89             );
90              
91             has request => (
92             is => 'rw',
93             isa => 'Int',
94             default => 0
95             );
96              
97             has value => (
98             is => 'rw',
99             isa => 'Int',
100             );
101              
102             # Save all important data in hashes for better readability
103             my %device_props = (
104             AXIS => 1,
105             RESOLUTION => 1024,
106             GETRIEBEMULTIPLIKATOR => 0.015,
107             NULL => 32768,
108             STEPS_PER_ROUND => 400,
109             BACKLASH => 200,
110             AA => 200,
111             AE => 200,
112             VA => 0,
113             VE => 30,
114             VM => 30,
115             );
116              
117             my %device_settings = (
118             read_default => 'device',
119             pos_mode => 'ABS',
120             speed_max => 180,
121             upper_limit => 180,
122             lower_limit => -180,
123             );
124              
125             my %device_cache = (
126             position => undef,
127             target => undef,
128             );
129              
130             sub BUILD {
131 0     0 0   my $self = shift;
132              
133             # Since RS232 was dropped in Moose, only the VISA connection is left.
134             # In the original driver just the termchar was set...
135             # Is the enable_read_termchar() necessary?
136 0           $self->connection->set_termchar( termchar => "\r" );
137 0           $self->connection->enable_read_termchar();
138             }
139              
140             sub _device_init {
141 0     0     my $self = shift;
142              
143 0           $self->query("C:\r\n");
144             $self->InitEncoder( $device_props{'STEPS_PER_ROUND'},
145             $device_props{'RESOLUTION'},
146 0           $device_props{'NULL'}
147             );
148             $self->InitRamp( $device_props{'AXIS'}, $device_props{'AA'},
149             $device_props{'AE'}, $device_props{'VA'},
150 0           $device_props{'VE'}, $device_props{'VM'}
151             );
152 0           $self->clear();
153              
154 0           $self->init_limits();
155             }
156              
157             sub InitEncoder {
158 0     0 0   my ( $self, %args ) = validated_getter(
159             \@_,
160             steps => { isa => 'Lab::Moose::Int' },
161             res => { isa => 'Lab::Moose::Int' },
162             null => { isa => 'Lab::Moose::Int' },
163             );
164              
165             my ( $steps, $res, $null )
166 0           = delete @args{ qw/steps res null/ };
167              
168 0           $self->write( command => "encoder: $steps $res $null\r\n" );
169 0           my $result = $self->read( command => { read_length => 300 } );
170              
171 0           return $result;
172             }
173              
174             sub InitRamp {
175 0     0 0   my ( $self, %args ) = validated_getter(
176             \@_,
177             axis => { isa => 'Lab::Moose::Int' },
178             aa => { isa => 'Lab::Moose::Int' },
179             ae => { isa => 'Lab::Moose::Int' },
180             va => { isa => 'Lab::Moose::Int' },
181             ve => { isa => 'Lab::Moose::Int' },
182             vm => { isa => 'Lab::Moose::Int' },
183             );
184              
185             my ( $axis, $aa, $ae, $va, $ve, $vm, )
186 0           = delete @args{ qw/axis aa ae va ve vm/ };
187              
188 0           $self->write( command => "tp: $axis $aa $ae $va $ve $vm\r\n" );
189 0           my $result = $self->read( command => { read_length => 100 } );
190              
191 0           return $result;
192             }
193              
194             sub move {
195 0     0 0   my ( $self, %args ) = validated_getter(
196             \@_,
197             position => {isa => 'Lab::Moose::Int' },
198             speed => {isa => 'Lab::Moose::Int' },
199             mode => {isa => 'Lab::Moose::Int' },
200             );
201              
202             my ( $position, $speed, $mode )
203 0           = delete @args{ qw/position speed mode/ };
204              
205 0 0         if ( not defined $mode ) {
206 0           $mode = $device_settings{'pos_mode'};
207             }
208 0 0         if ( not $mode =~ /ABS|abs|REL|rel/ ) {
209 0           croak "unexpected value for <MODE> in sub move.
210             expected values are ABS and REL."
211             }
212 0 0         if ( not defined $speed ) {
213 0           $speed = $device_settings{speed_max};
214             }
215 0 0         if ( not defined $position ) {
    0          
216 0           croak $self->get_id() . ": No target given in sub move!"
217             }
218             elsif (
219             not $position =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/ )
220             {
221 0           croak $self->get_id()
222             . ": Illegal Value given for POSITION in sub move!"
223             }
224              
225             # this sets the upper limit for the positioning speed:
226 0           $speed = abs($speed);
227 0 0         if ( $speed > $device_settings{speed_max} ) {
228 0           warn "Warning in sub move: <SPEED> = $speed is too high.
229             Reduce <SPEED> to its maximum value defined by internal
230             limit settings of $device_settings{speed_max}";
231 0           $speed = $device_settings{speed_max};
232             }
233              
234 0           $speed = $self->angle2steps($speed) / 60;
235              
236             # Moving in ABS or REL mode:
237 0           my $CP = $self->get_position();
238              
239 0 0 0       if ( $mode eq "ABS"
    0 0        
      0        
      0        
      0        
      0        
240             or $mode eq "abs"
241             or $mode eq "ABSOLUTE"
242             or $mode eq "absolute" ) {
243 0 0 0       if ( $position < $device_settings{lower_limit}
244             or $position > $device_settings{upper_limit} ) {
245             croak "unexpected value for NEW POSITION in sub move.
246             Expected values are between "
247             . $device_settings{lower_limit} . " ... "
248             . $device_settings{upper_limit}
249 0           }
250 0           $device_cache{target} = $position;
251 0           $self->_save_motorlog( $CP, $position );
252 0           $self->save_motorinitdata();
253 0           $self->query(
254             command => "ma$device_props{'AXIS'} "
255             . $self->angle2steps($position) . " $speed\r\n" );
256             }
257             elsif ($mode eq "REL"
258             or $mode eq "rel"
259             or $mode eq "RELATIVE"
260             or $mode eq "relative" ) {
261 0 0 0       if ( $CP + $position < $device_settings{lower_limit}
262             or $CP + $position > $device_settings{upper_limit} ) {
263             croak "ERROR in sub move.
264             Can't execute move; TARGET POSITION ("
265             . ( $CP + $position )
266             . ") is out of valid limits ("
267             . $device_settings{lower_limit} . " ... "
268             . $device_settings{upper_limit}
269 0           . ")"
270             }
271 0           $device_cache{target} = $CP + $position;
272 0           $self->_save_motorlog( $CP, $CP + $position );
273 0           $self->save_motorinitdata();
274 0           $self->query(
275             command => "mr$device_props{'AXIS'} "
276             . $self->angle2steps($position) . " $speed\r\n" );
277              
278             }
279              
280 0           return 1;
281              
282             }
283              
284             sub active {
285 0     0 0   my $self = shift;
286              
287 0           my $result = $self->get_position();
288              
289 0           return $self->active;
290              
291             }
292              
293             sub wait {
294 0     0 0   my $self = shift;
295              
296 0           my $flag = 1;
297             # ???
298 0           local $| = 1;
299              
300 0           while ( $self->active() ) {
301 0           my $current = $device_cache{position};
302 0 0 0       if ( $flag <= 1.1 and $flag >= 0.9 ) {
    0          
303 0           print $self->get_id()
304             . sprintf( " is sweeping (%.2f\370)\r", $current );
305             }
306             elsif ( $flag <= 0 ) {
307 0           print $self->get_id()
308             . sprintf( " is (%.2f\370)\r", $current );
309 0           $flag = 2;
310             }
311 0           $flag -= 0.1;
312 0           usleep(2e3);
313             }
314              
315 0           print "\t\t\t\t\t\t\t\t\t\r";
316 0           $| = 0;
317              
318 0           return 1;
319             }
320              
321             sub abort {
322 0     0 0   my $self = shift;
323 0           while(1) {
324 0           $self->query( command => "sa$device_props{'AXIS'}\r\n" );
325 0 0         if ( not $self->active() ) {
326 0           last;
327             }
328             }
329 0           print "Motor stoped at " . $self->get_position() . "\n";
330 0           return;
331             }
332              
333             sub init_limits {
334 0     0 0   my $self = shift;
335 0           my $lowerlimit;
336             my $upperlimit;
337              
338 0 0         if ( $self->read_motorinitdata() ) {
339 0           while (1) {
340 0           print
341             "Motor-Init data found.
342             Do you want to keep the reference point
343             and the limits? (y/n) ";
344 0           my $input = <>;
345 0           chomp $input;
346 0 0         if ( $input =~ /YES|yes|Y|y/ ) {
    0          
347 0           return 1;
348             }
349             elsif ( $input =~ /NO|no|N|n/ ) {
350             # ???
351 0           my $result = $self->query(command => "sa$device_props{'AXIS'}\r\n");
352 0           $result = $self->query(command => "nullen\r\n");
353 0           $device_settings{lower_limit} = -360;
354 0           $device_settings{upper_limit} = 360;
355 0           last;
356             }
357             }
358             }
359              
360 0           print "\n\n";
361 0           print "----------------------------------------------\n";
362 0           print "----------- Init Motor ProStep4 -------------\n";
363 0           print "----------------------------------------------\n";
364 0           print "\n";
365 0           print
366             "This procedure will help you to initialize the Motor ProStep4 correctly.\n\n";
367 0           print "Steps to go:\n";
368 0           print " 1.) Define the REFERENCE POINT.\n";
369 0           print " 2.) Define the LOWER and UPPER LIMITS for rotation.\n";
370 0           print " 3.) Confirm the LOWER and UPPER LIMITS.\n";
371 0           print "\n\n";
372              
373 0           print "----------------------------\n";
374 0           print "1.) Define the REFERENCE POINT:\n\n";
375 0           print "--> Move the motor position to the REFERENCE POINT.\n";
376 0           print "--> Enter a (relative) angle between -180 ... +180 deg.\n";
377 0           print
378             "--> Repeat until you have reached the position you want to define as the REFERENCE POINT.\n";
379 0           print
380             "--> Enter 'REF' to confirm the actual position as the REFERENCE POINT.\n\n";
381              
382 0           while (1) {
383 0           print "MOVE: ";
384 0           my $value = <>;
385 0           chomp $value;
386 0 0 0       if ( $value eq "REF" or $value eq "ref" ) {
    0 0        
      0        
387              
388             # set actual position as reference point Zero
389 0           $device_cache{position} = 0; # for testing only
390             # ???
391 0           my $result = $self->query(command => "sa$device_props{'AXIS'}\r\n");
392 0           $result = $self->query(command => "nullen\r\n");
393 0           last;
394             }
395             elsif ( $value =~ /^[+-]?\d+$/ and $value >= -180 and $value <= 180 )
396             {
397 0           $self->move( $value, { mode => 'REL' } );
398 0           $self->wait();
399             }
400             else {
401 0           print
402             "Please move the motor position to the REFERENCE POINT. Enter an angle between -180\370 ... +180\370.\n";
403             }
404             }
405              
406 0           print "----------------------------\n";
407 0           print "2.) Define the LOWER and UPPER LIMITS for rotation:\n\n";
408 0           print "--> Enter LOWER LIMIT\n";
409 0           print "--> Enter UPPER LIMIT\n\n";
410              
411 0           while (1) {
412 0           print "LOWER LIMIT: ";
413 0           my $value = <>;
414 0           chomp $value;
415 0           $lowerlimit = $value;
416 0           $device_settings{lower_limit} = $lowerlimit;
417 0           print "UPPER LIMIT: ";
418 0           $value = <>;
419 0           chomp $value;
420 0           $upperlimit = $value;
421 0           $device_settings{upper_limit} = $upperlimit;
422              
423 0 0         if ( $lowerlimit < $upperlimit ) {
424 0           last;
425             }
426             else {
427 0           print "LOWER LIMIT >= UPPER LIMIT. Try again!\n";
428             }
429             }
430              
431 0           print "----------------------------\n";
432 0           print "3.) Confirm the LOWER and UPPER LIMITS:\n\n";
433 0           print "--> Motor will move to LOWER LIMIT in steps of 10 deg\n";
434 0           print "--> Motor will move to UPPER LIMIT in steps of 10 deg\n";
435 0           print
436             "--> Confirm each step with ENTER or type <STOP> to take the actual position as the limit value. \n\n";
437              
438 0           print "Moving to LOWER LIMIT ...\n";
439 0           while (1) {
440 0           print "MOVE +/-10: Please press <ENTER> to confirm.";
441 0           my $input = <>;
442 0           chomp $input;
443 0 0         if ( $input =~ /stop|STOP/ ) {
444 0           $lowerlimit = $self->get_position();
445 0           last;
446             }
447 0 0         if ( abs( $self->get_position() - $lowerlimit ) >= 10 ) {
448 0 0         if ( $lowerlimit <= 0 ) {
449 0           $self->move( command => "-10, { mode => 'REL' }" );
450 0           $self->wait();
451             }
452             else {
453 0           $self->move( command => "10, { mode => 'REL' }" );
454 0           $self->wait();
455             }
456             }
457             else {
458 0           $self->move( command => "$lowerlimit, { mode => 'ABS' }" );
459 0           $self->wait();
460 0           last;
461             }
462              
463             }
464 0           print "Reached LOWER LIMIT\n";
465 0           print "Please confirm the position of the LOWER LIMIT: ";
466 0           <>;
467 0           $device_settings{'lower_limit'} = $lowerlimit;
468 0           print "\n\n";
469 0           print "Moving to REFERENCE POINT ... \n";
470 0           $self->move( command => "0, { mode => 'ABS' }" );
471 0           $self->wait();
472 0           print "Moving to UPPER LIMIT ...\n";
473              
474 0           while (1) {
475 0           print "MOVE +/-10: Please press <ENTER> to confirm.";
476 0           my $input = <>;
477 0           chomp $input;
478 0 0         if ( $input =~ /stop|STOP/ ) {
479 0           $upperlimit = $self->get_position();
480 0           last;
481             }
482 0 0         if ( abs( $upperlimit - $self->get_position() ) >= 10 ) {
483 0           $self->move( command => "10, { mode => 'REL' }" );
484 0           $self->wait();
485             }
486             else {
487 0           $self->move( command => "$upperlimit, { mode => 'ABS' }" );
488 0           $self->wait();
489 0           last;
490             }
491              
492             }
493 0           print "Reached UPPER LIMIT\n";
494 0           print "Please confirm the position of the UPPER LIMIT: ";
495 0           <>;
496 0           $device_settings{'upper_limit'} = $upperlimit;
497 0           print "\n\n";
498 0           $self->save_motorinitdata();
499              
500 0           print "moving to the reference point.\n";
501 0           $self->move( command => "0, { mode => 'ABS' }" );
502 0           $self->wait();
503 0           print "------------------------------------------------------\n";
504 0           print "------------ Motor ProStep4 initialized --------------\n";
505 0           print "------------------------------------------------------\n";
506 0           print "\n\n";
507              
508             }
509              
510             sub steps2angle {
511 0     0 0   my ( $self, %args ) = validated_hash(
512             \@_,
513             steps => { isa => 'Num' },
514             );
515              
516 0           my $steps = delete @args{qw/steps/};
517              
518 0           my $angle = $steps * $device_props{GETRIEBEMULTIPLIKATOR};
519 0           return $angle;
520             }
521              
522             sub angle2steps {
523 0     0 0   my ( $self, %args ) = validated_hash(
524             \@_,
525             angle => { isa => 'Num' },
526             );
527            
528 0           my $angle = delete @args{qw/angle/};
529              
530 0           my $steps = $angle / $device_props{GETRIEBEMULTIPLIKATOR};
531 0           return sprintf( "%0.f", $steps );
532             }
533              
534             sub get_value {
535 0     0 0   my ( $self, %args ) = validated_hash(
536             \@_,
537             read_mode => { isa => enum( [qw/device|cache|request|fetch/] ) },
538             );
539            
540 0           my $read_mode = delete @args{qw/read_mode/};
541              
542 0           return $self->get_position( command => "read_mode => $read_mode" );
543             }
544              
545             sub get_position {
546 0     0 0   my ( $self, %args ) = validated_hash(
547             \@_,
548             read_mode => { isa => enum( [qw/device|cache|request|fetch/] ) },
549             );
550              
551 0           my $read_mode = delete @args{qw/read_mode/};
552              
553 0           my $cmd = "a" . $device_props{'AXIS'} . "?\r\n";
554 0           my $result;
555              
556 0 0 0       if ( not defined $read_mode
557             or not $read_mode =~ /device|cache|request|fetch/ ) {
558 0           $read_mode = $device_settings{read_default};
559             }
560              
561 0 0 0       if ( $read_mode eq 'cache'
    0 0        
    0 0        
    0 0        
562             and defined $self->{'device_cache'}->{'position'} ) {
563 0           return $device_cache{'position'};
564             }
565             elsif ( $read_mode eq 'request' and $self->{request} == 0 ) {
566 0           $self->{request} = 1;
567 0           $self->write($cmd);
568 0           return;
569             }
570             elsif ( $read_mode eq 'request' and $self->{request} == 1 ) {
571 0           $result = $self->read();
572 0           $self->write( command => "$cmd" );
573 0           return;
574             }
575             elsif ( $read_mode eq 'fetch' and $self->{request} == 1 ) {
576 0           $self->{request} = 0;
577 0           $result = $self->read();
578             }
579             else {
580 0 0         if ( $self->{request} == 1 ) {
581 0           $result = $self->read();
582 0           $self->{request} = 0;
583 0           $result = $self->query( command => "$cmd" );
584             }
585             else {
586 0           $result = $self->query( command => "$cmd" );
587             }
588             }
589              
590 0           for ( 0 .. 2 ) {
591 0 0         if ( $result =~ m/Posi_$device_props{'AXIS'}:\s+([+-]?\d+)/ ) {
    0          
592 0           $device_cache{position} = $self->steps2angle(command => "$1" );
593 0           $self->{active} = 0;
594 0           last;
595             }
596             elsif ( $result
597             =~ m/Soll\/Ist\/Speed_$device_props{'AXIS'}:\s+([+-]?\d+)\s+([+-]?\d+)\s+([+-]?\d+)/
598             ) {
599 0           $device_cache{position} = $self->steps2angle( command => "$2" );
600 0           $self->{active} = 1;
601 0           last;
602             }
603             else {
604 0           $result
605             # ???
606             = $self->connection()->BrutalRead( command => "{ read_length => 100 }" );
607             }
608             }
609              
610 0           $self->save_motorinitdata();
611 0           $self->{value} = $device_cache{position};
612 0           return $device_cache{position};
613              
614             }
615              
616             sub save_motorinitdata {
617 0     0 0   my $self = shift;
618              
619 0 0         open my $dump, '>', "C:\\Perl\\site\\lib\\Lab\\Instrument\\ProStep4.ini"
620             or croak "Can't open ini file!";
621              
622 0           print {$dump} "POSITION: " . $device_cache{position} . "\n";
  0            
623 0           print {$dump} "TARGET: " . $device_cache{target} . "\n";
  0            
624 0           print {$dump} "SPEED_MAX: " . $device_settings{speed_max} . "\n";
  0            
625 0           print {$dump} "UPPER_LIMIT: "
626 0           . $device_settings{upper_limit} . "\n";
627 0           print {$dump} "LOWER_LIMIT: "
628 0           . $device_settings{lower_limit} . "\n";
629             # ??? Problem mit time()
630 0           print {$dump} "TIMESTAMP: " . time() . "\n";
  0            
631              
632 0           close $dump;
633             }
634              
635             sub _save_motorlog {
636 0     0     my ( $self, %args ) = validated_getter(
637             \@_,
638             init_pos => { isa => 'Num' },
639             end_pos => { isa => 'Num' },
640             );
641            
642             my ( $init_pos, $end_pos )
643 0           = delete @args{qw/init_pos end_pos/};
644            
645 0 0         open my $log, '>>', "C:\\Perl\\site\\lib\\Lab\\Instrument\\ProStep4.log"
646             or croak "Can't open log file!";
647              
648 0           print {$log} ( my_timestamp() ) . "\t move: $init_pos -> $end_pos \n";
  0            
649              
650 0           close $log;
651             }
652              
653             sub read_motorinitdata {
654 0     0 0   my $self = shift;
655              
656 0 0         open my $init_file, '<', "C:\\Perl\\site\\lib\\Lab\\Instrument\\ProStep4.ini"
657             or croak "Can't open init file!";
658              
659 0           while (<$init_file>) {
660 0           chomp($_);
661 0           my @line = split( /: /, $_ );
662 0 0         if ( $line[0] eq 'POSITION' ) {
    0          
    0          
    0          
    0          
663 0           $device_cache{position} = $line[1];
664             }
665             elsif ( $line[0] eq 'TARGET' ) {
666 0           $device_cache{target} = $line[1];
667             }
668             elsif ( $line[0] eq 'SPEED_MAX' ) {
669 0           $device_settings{speed_max} = $line[1];
670             }
671             elsif ( $line[0] eq 'UPPER_LIMIT' ) {
672 0           $device_settings{upper_limit} = $line[1];
673             }
674             elsif ( $line[0] eq 'LOWER_LIMIT' ) {
675 0           $device_settings{lower_limit} = $line[1];
676             }
677              
678             }
679              
680 0           print "\nread MOTOR-INIT-DATA\n";
681 0           print "--------------------\n";
682 0           print "POSITION: " . $device_cache{position} . "\n";
683 0           print "TARGET: " . $device_cache{target} . "\n";
684 0           print "SPEED_MAX: " . $device_settings{speed_max} . "\n";
685 0           print "UPPER_LIMIT: " . $device_settings{upper_limit} . "\n";
686 0           print "LOWER_LIMIT: " . $device_settings{lower_limit} . "\n";
687 0           print "--------------------\n";
688 0           return 1;
689             }
690              
691             sub my_timestamp {
692              
693             # ??? Ersatz für localtime
694             my (
695 0     0 0   $Sekunden, $Minuten, $Stunden, $Monatstag, $Monat,
696             $Jahr, $Wochentag, $Jahrestag, $Sommerzeit
697             ) = localtime(time);
698              
699 0           $Monat += 1;
700 0           $Jahrestag += 1;
701 0 0         $Monat = $Monat < 10 ? $Monat = "0" . $Monat : $Monat;
702 0 0         $Monatstag = $Monatstag < 10 ? $Monatstag = "0" . $Monatstag : $Monatstag;
703 0 0         $Stunden = $Stunden < 10 ? $Stunden = "0" . $Stunden : $Stunden;
704 0 0         $Minuten = $Minuten < 10 ? $Minuten = "0" . $Minuten : $Minuten;
705 0 0         $Sekunden = $Sekunden < 10 ? $Sekunden = "0" . $Sekunden : $Sekunden;
706 0           $Jahr += 1900;
707              
708 0           return "$Stunden:$Minuten:$Sekunden $Monatstag.$Monat.$Jahr\n";
709              
710             }
711              
712             1;
713              
714             __END__
715              
716             =pod
717              
718             =encoding utf8
719             =head1 SYNOPSIS
720              
721             =head1 NAME
722              
723             Lab::Moose::Instrument::ProStep4 - ProStep4 step motor
724              
725             =head1 VERSION
726              
727             version 3.880
728              
729             =head1 COPYRIGHT AND LICENSE
730              
731             This software is copyright (c) 2023 by the Lab::Measurement team; in detail:
732              
733             Copyright 2022-2023 Mia Schambeck
734              
735              
736             This is free software; you can redistribute it and/or modify it under
737             the same terms as the Perl 5 programming language system itself.
738              
739             =cut