Click here to get back home

Reduce CPU time while using serialport?

 HomeNewsGroups | Search | About
 comp.lang.perl.modules    Post an article   get this group's latest topics as an RSS feed add this group's latest topics to your My MSN content add this group's latest topics to your My Yahoo content
Subject Author Date
Reduce CPU time while using serialport? jis 09-06-2007
Posted by Petr Vileta on September 9, 2007, 9:41 am
Please log in for more thread options


jis wrote:
>> 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.)



Posted by jis on September 9, 2007, 3:17 pm
Please log in for more thread options


> jis wrote:
> >> 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


Posted by Petr Vileta on September 9, 2007, 8:31 pm
Please log in for more thread options


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.)



Similar ThreadsPosted
Reduce colors with Image::Magick July 6, 2007, 7:06 am
Need help with Win32::SerialPort August 13, 2004, 5:43 am
need help with "SerialPort" module April 25, 2006, 11:34 pm
help on win32::serialport June 4, 2007, 5:12 pm
SerialPort error July 7, 2007, 10:58 pm
Please help on win32::serialport July 13, 2007, 12:41 pm
SerialPort write question October 28, 2004, 11:52 am
Serialport Read question October 28, 2004, 11:59 am
Loopback with Device::SerialPort? March 18, 2005, 1:24 pm
problem with Device::SerialPort November 30, 2005, 4:19 pm

Our other projects:

Art Dolls, Fairies and Mermaids - Sunnyfaces.net

Roy's Linux, Programming and Search Engines messages

1-Script XML SitemapXML Sitemap