#!/usr/bin/perl # # (c) 20060318 by Ewald # http://www.oiepoie.nl use Device::SerialPort; # to read serial port data use Getopt::Std; # to handle cmdline options my $V="0.9 20060318"; # version and date of latest modification my $DEBUG = 0; # do we want debugging output? my $WAIT = 300; # how many seconds to wait between reads my $ONCE = 0; # run only once? my $UT = 0; # display timestamp in Unix format? my $DONE = 0; my $now; my $TS=1; # do we want timestamps at all? (yes) my $C=1; # display C to denote Celsius? (yes) my $P = "/dev/ttyS0"; # default serial port to monitor my %Options; $ok = getopts('t:w:1uhdnc', \%Options); if (defined $Options{h}) { print "logger.pl version: $V\n"; print "Program to read temperature data from Papouch serial temp probe\n"; print "Possible options:\n"; print "-h Help (this output)\n"; print "-d print debugging output\n"; print "-c Don't print C for celsius after values?\n"; print "-n Don't display timestamps\n"; print "-1 Output temperature and exit\n"; print "-u show timestamp in Unix format (seconds since epoch)\n"; print "-t x read data from /dev/ttySx (default: $P) \n"; print "-w N wait N seconds between readouts (default $WAIT)\n"; exit 0; } $ONCE = 1 if defined $Options{1}; $DEBUG = 1 if defined $Options{d}; $TS = 0 if defined $Options{n}; $C = 0 if defined $Options{c}; $WAIT = $Options{w} if defined $Options{w}; $UT = $Options{u} if defined $Options{u}; if (defined $Options{t}) { $P = "/dev/ttyS"; $P .= $Options{t}; } $DEBUG && print "monitoring serial port: $P\n"; $DEBUG && print "wait interval is $WAIT\n"; $DEBUG && print "run once? $ONCE\n"; $DEBUG && print "Unix timestamps? $UT\n"; # Serial Port initialization my $port=Device::SerialPort->new($P) || die "cannot open $P: $!"; $port->user_msg(ON); $port->error_msg(ON); $DEBUG && $port->debug($DEBUG); $port->baudrate(9600) || die "failed setting baudrate"; $port->parity("none") || die "failed setting parity"; $port->databits(8) || die "failed setting databits"; $port->stopbits(2) || die "failed setting databits"; $port->handshake("none") || die "failed setting handshake"; $port->write_settings || die "cannot write settings"; # unset RTS and DTR $port->rts_active(0); $port->dtr_active(0); sleep 1; # just a little wait to be sure we get stable data later on if (($port->can_modemlines) && $DEBUG) { $ModemStatus = $port->modemlines; if ($ModemStatus & $port->MS_RTS_ON) { print "RTS ON\n"; } else { print "RTS OFF\n"; } if ($ModemStatus & $port->MS_DTR_ON) { print "DTR ON\n"; } else { print "DTR OFF\n"; } print "\n"; } # by setting RTS and DTR high we supply power to the device # and in return it will supply us with data $port->rts_active(1); $port->dtr_active(1); if (($port->can_modemlines) && $DEBUG) { $ModemStatus = $port->modemlines; if ($ModemStatus & $port->MS_RTS_ON) { print "RTS ON\n"; } else { print "RTS OFF\n"; } if ($ModemStatus & $port->MS_DTR_ON) { print "DTR ON\n"; } else { print "DTR OFF\n"; } print "\n"; } $port->read_char_time(0); # don't wait for each character $port->read_const_time(1000); # 1 second per unfulfilled "read" call while (!$DONE) { my ($count,$saw)=$port->read(8); # we should get 8 chars if ($count > 0) { $port->rts_active(0); # power-off device for now $port->dtr_active(0); $saw =~ s/([\+\-]\S+C)\r/$1/e; # value will be something like: +020.9C^M or -001.3C^M # so we want to strip of the ^M (\r) if (!$C) { $saw =~ s/(\S+)C/$1/e; } # strip of the C char if ($TS) { if ($UT) { $now = time; # UNIX timestamp } else { $now = localtime time; # human readable timestamp } printf "%s\t%s\n", $now,$saw; } else { printf "%s\n", $saw; # output just the data } if ($ONCE) { # are we done? $DONE = 1; } else { sleep $WAIT; # sleep a little while before reading the next value $port->rts_active(1); # power-on $port->dtr_active(1); } } else { print "ERR: we got $count bytes of data\n"; } } $port->rts_active(0); # power-off device $port->dtr_active(0); undef $port;