Re: Serial Port programming - Reading DSR from port



msalerno <vagabondking@xxxxxxxxx> kirjoitti 11.07.2005:
> I have a device that uses the dsr for communications. Basically what I
> am trying to do is get a count of how many pulses it sends per second.
[snip]
> my $pulse = 0!=($ModemStatus & MS_DSR_ON);
[snip]
> if ($pulse == 1){
> usleep(1); # sleep one milisecond if change detected.
> }

Here's one major problem: $pulse will be 1 if the DSR line is on, not
if it has changed.

Anyway, here's how I'd rewrite your script:

#!/usr/bin/perl -w
use strict;
use Time::HiRes qw(time sleep);
use Device::SerialPort qw( :PARAM :STAT 0.07 );

use constant SAMPLE_STEP => 1/1000; # sample once per msec
use constant REPORT_STEP => 1; # report once per second

# Open Serial Port
my $PortObj = new Device::SerialPort ('/dev/ttyS0')
or die "Cannot open Port: $!\n";

my $lastdsr = $PortObj->modemlines & MS_DSR_ON;
my $t0 = time;

while (1) {
my $changes = 0;
while (time < $t0 + REPORT_STEP) {
my $dsr = $PortObj->modemlines & MS_DSR_ON;
$changes++ if $dsr xor $lastdsr;
$lastdsr = $dsr;
sleep SAMPLE_STEP;
}
printf "%02d-%02d-%02d: %d - %.2f - %.2f\n",
(localtime int $t0)[2, 1, 0], $changes,
$changes / (3.4 * REPORT_STEP),
$changes / (2.5 * REPORT_STEP);
$t0 += REPORT_STEP;
}

I haven't tested this code, as I don't have Device::SerialPort
installed, nor do I have any suitable signal source available either.
But I'm fairly confident it should work.

The code counts state changes in both directions. If you only want to
count transitions from off to on, replace "xor" with "and not".

I'm assuming that SAMPLE_STEP is sufficiently small that no pulses can
ever be missed. Therefore I haven't bothered to synchronize the inner
loop; the actual time between samples will be SAMPLE_STEP plus however
long it takes to execute the inner loop.

The outer loop, however, is synchronized, which means you'll get
reports exactly once every REPORT_STEP seconds on average, and there
should be no statistical bias in the output (ignoring possible
floating point roundoff errors). Actually, I think your original code
would've worked the same way, had it worked correctly at all.

Note that there's really nothing Perl-specific about this. The same
code could be trivially ported to C or Java or just about any other
language. Only the interfaces to the serial port and the system timer
would change.

--
Ilmari Karonen
To reply by e-mail, please replace ".invalid" with ".net" in address.
.



Relevant Pages

  • Re: Precision peak detector
    ... will be used as an feedback for closed loop system therefore amplitude ... Do you have pulses that may go either above or below ground? ... Digital is a crock for high accuracy feedback loops running at any sort of speed. ...
    (sci.electronics.design)
  • Re: Precision peak detector
    ... Phil Hobbs wrote: ... will be used as an feedback for closed loop system therefore amplitude ... Do you have pulses that may go either above or below ground? ...
    (sci.electronics.design)
  • Re: Cassette port input frequency range? And CPU MHz ranges.
    ... used positive pulses for the MSN and negative pulses for the ... to reliably send data if using a full symmetrical cycle. ... Zero crossings are what is sensed, so preserving symmetry preserves the DC ... If you are sensing the crossings in a counted loop, ...
    (comp.sys.apple2)
  • Re: Great, great Request
    ... It is urgent. ... I have a physical problem that I am solving in Matlab. ... Of course, I can copy 4 times the same loop for different pulses, but this loop is too big and it is very inconvenient. ...
    (comp.soft-sys.matlab)
  • Re: What evidence is there that a neuron is digital computer ?
    ... to synchronize their pulses to some high frequency master ... was re-aligned in time to match this high frequency master ... much at all and with hindsight I regret wasting my time ...
    (comp.ai.philosophy)