View raw

1 #!/usr/bin/env perl 2 3 # Basic Atlas Scientific EZO probe smoke test. 4 5 use v5.32.1; 6 use strict; 7 use warnings; 8 9 use Test2::V0; 10 plan tests => 3; 11 use Device::SerialPort; 12 use Time::HiRes qw(usleep); 13 14 my $port = '/dev/ttyUSB0'; 15 my $baud = 9600; 16 17 my $serial = Device::SerialPort->new($port) 18 or die "Cannot open serial port: $port"; 19 20 $serial->baudrate($baud); 21 $serial->databits(8); 22 $serial->parity('none'); 23 $serial->stopbits(1); 24 25 $serial->read_char_time(0); 26 $serial->read_const_time(100); 27 28 note("Testing EZO probe on $port at $baud baud"); 29 30 my $info = ezo_command( $serial, 'I', 500_000 ); 31 note( "I => " . printable($info) ); 32 33 ok( $info ne '', 'probe is reachable' ); 34 like( $info, qr/(?:\?I,|EZO|PH|EC|DO|ORP)/i, 'probe is identifiable' ); 35 36 my $reading = ezo_command( $serial, 'R', 1_500_000 ); 37 note( "R => " . printable($reading) ); 38 39 like( $reading, qr/OK/, 'probe returns a single reading' ); 40 41 sub ezo_command { 42 my ( $serial, $command, $wait_us ) = @_; 43 44 drain_serial($serial); 45 46 my $written = $serial->write("$command\r"); 47 return '' unless defined $written && $written > 0; 48 49 usleep($wait_us); 50 51 my $reply = ''; 52 while (1) { 53 my ( $count, $buffer ) = $serial->read(255); 54 last unless $count; 55 $reply .= $buffer; 56 } 57 58 return clean_reply($reply); 59 } 60 61 sub drain_serial { 62 my ($serial) = @_; 63 64 while (1) { 65 my ( $count, undef ) = $serial->read(255); 66 last unless $count; 67 } 68 } 69 70 sub clean_reply { 71 my ($reply) = @_; 72 73 $reply =~ s/\r/\n/g; 74 $reply =~ s/\n+/\n/g; 75 $reply =~ s/^\n|\n$//g; 76 77 return $reply; 78 } 79 80 sub printable { 81 my ($value) = @_; 82 return $value eq '' ? '<no response>' : $value; 83 } 84