Reduce CPU time while using serialport?

Reduce CPU time while using serialport?

am 06.09.2007 22:18:38 von jis

Hi,

I am using Win32::serialport for reading a data through a scanner
which is connected to the serial port.
I use polling as below.But this consumes 99% of my CPU time. and
slows down the system.
while(!($data=~/\r/))
{
$data=$Scanner->input(); #read the scanner port
$labeldata=$labeldata.$data; #append
}

Is there any way I implement interrupts or events using perl. Or is
there any other method to solve this issue.
I use WIndows NT4(its old..but i have to...)

Pls share your ideas.

Cheers,
jis

Re: Reduce CPU time while using serialport?

am 08.09.2007 16:11:10 von nobull67

On 6 Sep, 21:18, jis wrote:
> I am using Win32::serialport for reading a data through a scanner
> which is connected to the serial port.
> I use polling as below.But this consumes 99% of my CPU time. and
> slows down the system.
> while(!($data=~/\r/))
> {
> $data=$Scanner->input(); #read the scanner port
> $labeldata=$labeldata.$data; #append
> }
>
> Is there any way I implement interrupts or events using perl. Or is
> there any other method to solve this issue.

Is there any particular reason you couldn't simply use a blocking read
rather than a non-blocking one?

Re: Reduce CPU time while using serialport?

am 08.09.2007 17:29:52 von jis

On Sep 8, 9:11 am, Brian McCauley wrote:
> On 6 Sep, 21:18, jis wrote:
>
> > I am using Win32::serialport for reading a data through a scanner
> > which is connected to the serial port.
> > I use polling as below.But this consumes 99% of my CPU time. and
> > slows down the system.
> > while(!($data=~/\r/))
> > {
> > $data=$Scanner->input(); #read the scanner port
> > $labeldata=$labeldata.$data; #append
> > }
>
> > Is there any way I implement interrupts or events using perl. Or is
> > there any other method to solve this issue.
>
> Is there any particular reason you couldn't simply use a blocking read
> rather than a non-blocking one?

I am now trying to use $Scanner->lookfor which is a blocking read i
believe. But main issue now is I am using a perl tk window in the
program. The tk window needs continuous update.The call lookfor takes
me to unknownloop and prevents me from servicing tk window.

Appreciate your help.

Cheers,
jis

Re: Reduce CPU time while using serialport?

am 09.09.2007 04:28:10 von Petr Vileta

jis wrote:
> On Sep 8, 9:11 am, Brian McCauley wrote:
>> On 6 Sep, 21:18, jis wrote:
>>
>>> I am using Win32::serialport for reading a data through a scanner
>>> which is connected to the serial port.
>>> I use polling as below.But this consumes 99% of my CPU time. and
>>> slows down the system.
>>> while(!($data=~/\r/))
>>> {
>>> $data=$Scanner->input(); #read the scanner port
>>> $labeldata=$labeldata.$data; #append
>>> }
>>
>>> Is there any way I implement interrupts or events using perl. Or is
>>> there any other method to solve this issue.
>>
>> Is there any particular reason you couldn't simply use a blocking
>> read rather than a non-blocking one?
>
> I am now trying to use $Scanner->lookfor which is a blocking read i
> believe. But main issue now is I am using a perl tk window in the
> program. The tk window needs continuous update.The call lookfor takes
> me to unknownloop and prevents me from servicing tk window.
>
> Appreciate your help.
>
Do not use $Scanner->lookfor but create "timer" and test $Scanner->status
value. Take a look to Tk::After and repeat() function. All PCs have 8-16
bytes buffer for COM ports and you can test $Scanner->status value say every
50 miliseconds and if status will indicate some bytes in input buffer then
you will read this, in other case you will can to update some Tk widget.
--

Petr Vileta, Czech republic
(My server rejects all messages from Yahoo and Hotmail. Send me your mail
from another non-spammer site please.)

Re: Reduce CPU time while using serialport?

am 09.09.2007 04:52:46 von jis

On Sep 8, 9:28 pm, "Petr Vileta" wrote:
> jis wrote:
> > On Sep 8, 9:11 am, Brian McCauley wrote:
> >> On 6 Sep, 21:18, jis wrote:
>
> >>> I am using Win32::serialport for reading a data through a scanner
> >>> which is connected to the serial port.
> >>> I use polling as below.But this consumes 99% of my CPU time. and
> >>> slows down the system.
> >>> while(!($data=~/\r/))
> >>> {
> >>> $data=$Scanner->input(); #read the scanner port
> >>> $labeldata=$labeldata.$data; #append
> >>> }
>
> >>> Is there any way I implement interrupts or events using perl. Or is
> >>> there any other method to solve this issue.
>
> >> Is there any particular reason you couldn't simply use a blocking
> >> read rather than a non-blocking one?
>
> > I am now trying to use $Scanner->lookfor which is a blocking read i
> > believe. But main issue now is I am using a perl tk window in the
> > program. The tk window needs continuous update.The call lookfor takes
> > me to unknownloop and prevents me from servicing tk window.
>
> > Appreciate your help.
>
> Do not use $Scanner->lookfor but create "timer" and test $Scanner->status
> value. Take a look to Tk::After and repeat() function. All PCs have 8-16
> bytes buffer for COM ports and you can test $Scanner->status value say every
> 50 miliseconds and if status will indicate some bytes in input buffer then
> you will read this, in other case you will can to update some Tk widget.
> --
>
> Petr Vileta, Czech republic
> (My server rejects all messages from Yahoo and Hotmail. Send me your mail
> from another non-spammer site please.)- Hide quoted text -
>
> - Show quoted text -

thanks for tthe info.it was helpful. But is there any problem using
$scanner->lookfor?
It luks to me even lookfor polls the com port effectively .

regards,
jis

Re: Reduce CPU time while using serialport?

am 09.09.2007 15:41:01 von Petr Vileta

jis wrote:
> On Sep 8, 9:28 pm, "Petr Vileta" wrote:
>> jis wrote:
>>> On Sep 8, 9:11 am, Brian McCauley wrote:
>>>> On 6 Sep, 21:18, jis wrote:
>>
>>>>> I am using Win32::serialport for reading a data through a scanner
>>>>> which is connected to the serial port.
>>>>> I use polling as below.But this consumes 99% of my CPU time. and
>>>>> slows down the system.
>>>>> while(!($data=~/\r/))
>>>>> {
>>>>> $data=$Scanner->input(); #read the scanner port
>>>>> $labeldata=$labeldata.$data; #append
>>>>> }
>>
>>>>> Is there any way I implement interrupts or events using perl. Or
>>>>> is there any other method to solve this issue.
>>
>>>> Is there any particular reason you couldn't simply use a blocking
>>>> read rather than a non-blocking one?
>>
>>> I am now trying to use $Scanner->lookfor which is a blocking read i
>>> believe. But main issue now is I am using a perl tk window in the
>>> program. The tk window needs continuous update.The call lookfor
>>> takes me to unknownloop and prevents me from servicing tk window.
>>
>>> Appreciate your help.
>>
>> Do not use $Scanner->lookfor but create "timer" and test
>> $Scanner->status value. Take a look to Tk::After and repeat()
>> function. All PCs have 8-16 bytes buffer for COM ports and you can
>> test $Scanner->status value say every 50 miliseconds and if status
>> will indicate some bytes in input buffer then you will read this, in
>> other case you will can to update some Tk widget. --
>>
>> Petr Vileta, Czech republic
>> (My server rejects all messages from Yahoo and Hotmail. Send me your
>> mail from another non-spammer site please.)- Hide quoted text -
>>
>> - Show quoted text -
>
> thanks for tthe info.it was helpful. But is there any problem using
> $scanner->lookfor?
> It luks to me even lookfor polls the com port effectively .
>
I never used lookfor() because I like to have all under my own control ;-)

use Tk;
use Tk::after
use Win32::SerialPort;

my $mw = MainWindow->new();
# create some widgets here
our $buffer = '';
our $PortObj = Win32::SerialPort->new ('COM1', 1) or die "Can't open serial
port COM1: $^E\n";
$PortObj->baudrate(57600) or die "fail setting baud rate";
$PortObj->parity("none") or die "fail setting parity";
$PortObj->databits(8) or die "fail setting databits";
$PortObj->stopbits(1) or die "fail setting stopbits";
$PortObj->handshake('none') or die "fail setting handshake";
$PortObj->write_settings or die "fail write settings";
my $rpt = $mw->repeat(50, \&checkbuffer);
# is you want to stop repeater then do $rpt->cancel
MainLoop;

sub checkbuffer
{
($BlockingFlags, $InBytes, $OutBytes, $LatchErrorFlags) = $PortObj->status;
return unless(InBytes);
my ($count, $input) = $PortObj->read($InBytes);
$buffer .= $input;
}

--

Petr Vileta, Czech republic
(My server rejects all messages from Yahoo and Hotmail. Send me your mail
from another non-spammer site please.)

Re: Reduce CPU time while using serialport?

am 09.09.2007 21:17:06 von jis

On Sep 9, 8:41 am, "Petr Vileta" wrote:
> jis wrote:
> > On Sep 8, 9:28 pm, "Petr Vileta" wrote:
> >> jis wrote:
> >>> On Sep 8, 9:11 am, Brian McCauley wrote:
> >>>> On 6 Sep, 21:18, jis wrote:
>
> >>>>> I am using Win32::serialport for reading a data through a scanner
> >>>>> which is connected to the serial port.
> >>>>> I use polling as below.But this consumes 99% of my CPU time. and
> >>>>> slows down the system.
> >>>>> while(!($data=~/\r/))
> >>>>> {
> >>>>> $data=$Scanner->input(); #read the scanner port
> >>>>> $labeldata=$labeldata.$data; #append
> >>>>> }
>
> >>>>> Is there any way I implement interrupts or events using perl. Or
> >>>>> is there any other method to solve this issue.
>
> >>>> Is there any particular reason you couldn't simply use a blocking
> >>>> read rather than a non-blocking one?
>
> >>> I am now trying to use $Scanner->lookfor which is a blocking read i
> >>> believe. But main issue now is I am using a perl tk window in the
> >>> program. The tk window needs continuous update.The call lookfor
> >>> takes me to unknownloop and prevents me from servicing tk window.
>
> >>> Appreciate your help.
>
> >> Do not use $Scanner->lookfor but create "timer" and test
> >> $Scanner->status value. Take a look to Tk::After and repeat()
> >> function. All PCs have 8-16 bytes buffer for COM ports and you can
> >> test $Scanner->status value say every 50 miliseconds and if status
> >> will indicate some bytes in input buffer then you will read this, in
> >> other case you will can to update some Tk widget. --
>
> >> Petr Vileta, Czech republic
> >> (My server rejects all messages from Yahoo and Hotmail. Send me your
> >> mail from another non-spammer site please.)- Hide quoted text -
>
> >> - Show quoted text -
>
> > thanks for tthe info.it was helpful. But is there any problem using
> > $scanner->lookfor?
> > It luks to me even lookfor polls the com port effectively .
>
> I never used lookfor() because I like to have all under my own control ;-)
>
> use Tk;
> use Tk::after
> use Win32::SerialPort;
>
> my $mw = MainWindow->new();
> # create some widgets here
> our $buffer = '';
> our $PortObj = Win32::SerialPort->new ('COM1', 1) or die "Can't open serial
> port COM1: $^E\n";
> $PortObj->baudrate(57600) or die "fail setting baud rate";
> $PortObj->parity("none") or die "fail setting parity";
> $PortObj->databits(8) or die "fail setting databits";
> $PortObj->stopbits(1) or die "fail setting stopbits";
> $PortObj->handshake('none') or die "fail setting handshake";
> $PortObj->write_settings or die "fail write settings";
> my $rpt = $mw->repeat(50, \&checkbuffer);
> # is you want to stop repeater then do $rpt->cancel
> MainLoop;
>
> sub checkbuffer
> {
> ($BlockingFlags, $InBytes, $OutBytes, $LatchErrorFlags) = $PortObj->status;
> return unless(InBytes);
> my ($count, $input) = $PortObj->read($InBytes);
> $buffer .= $input;
>
> }
>
> --
>
> Petr Vileta, Czech republic
> (My server rejects all messages from Yahoo and Hotmail. Send me your mail
> from another non-spammer site please.)- Hide quoted text -
>
> - Show quoted text -

That was cool.
But it wrote in slightly different way.
use Tk;
use Tk::after
use Win32::SerialPort;


my $mw = MainWindow->new();
# create some widgets here
our $buffer = '';
our $PortObj = Win32::SerialPort->new ('COM1', 1) or die "Can't open
serial
port COM1: $^E\n";
$PortObj->baudrate(57600) or die "fail setting baud rate";
$PortObj->parity("none") or die "fail setting parity";
$PortObj->databits(8) or die "fail setting databits";
$PortObj->stopbits(1) or die "fail setting stopbits";
$PortObj->handshake('none') or die "fail setting handshake";
$PortObj->write_settings or die "fail write settings";
my $rpt = $mw->repeat(50, \&checkbuffer);
# is you want to stop repeater then do $rpt->cancel
MainLoop;


sub checkbuffer
{
my($BlockingFlags, $InBytes, $OutBytes, $LatchErrorFlags) =
$Scanner->status;

if($InBytes)
{
my $data= 0;
my $labeldata= undef;
while(!($data=~/\r/))
{
$data=$Scanner->input(); #read the scanner port
$labeldata.= $data; #append
}

}
}

this works for me. any errors in this one?

cheers,
jis

Re: Reduce CPU time while using serialport?

am 10.09.2007 02:31:21 von Petr Vileta

jis wrote:
> use Tk;
> use Tk::after
> use Win32::SerialPort;
>
>
> my $mw = MainWindow->new();
> # create some widgets here
> our $buffer = '';
> our $PortObj = Win32::SerialPort->new ('COM1', 1) or die "Can't open
> serial
> port COM1: $^E\n";
> $PortObj->baudrate(57600) or die "fail setting baud rate";
> $PortObj->parity("none") or die "fail setting parity";
> $PortObj->databits(8) or die "fail setting databits";
> $PortObj->stopbits(1) or die "fail setting stopbits";
> $PortObj->handshake('none') or die "fail setting handshake";
> $PortObj->write_settings or die "fail write settings";
> my $rpt = $mw->repeat(50, \&checkbuffer);
> # is you want to stop repeater then do $rpt->cancel
> MainLoop;
>
>
> sub checkbuffer
> {
> my($BlockingFlags, $InBytes, $OutBytes, $LatchErrorFlags) =
> $Scanner->status;
>
> if($InBytes)
> {
> my $data= 0;
> my $labeldata= undef;
> while(!($data=~/\r/))
> {
> $data=$Scanner->input(); #read the scanner port
> $labeldata.= $data; #append
> }
>
> }
> }
>
> this works for me. any errors in this one?
>
> cheers,
> jis

The problem can occur in while() loop, so here is another version of
checkbuffer. Please keep in mind that variable $buffer is declared as our,
in other word as "public", visible from all subs.

sub checkbuffer
{
my($BlockingFlags, $InBytes, $OutBytes, $LatchErrorFlags) =
$Scanner->status;
return unless(InBytes);
my ($count, $input) = $PortObj->read($InBytes);
$buffer .= $input;
if($buffer =~m/^(.+?)\r(.*)/s)
{
my $labeldata = $1; # here you have all data to first \r but without
this delimiter
# you can call some your sub to do something with this $labeldata
variable
$buffer = $2; # buffer now contain remaining of data
}
}

--

Petr Vileta, Czech republic
(My server rejects all messages from Yahoo and Hotmail. Send me your mail
from another non-spammer site please.)